2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
30 #include "nsswitch/winbind_client.h"
32 #include "talloc_dict.h"
33 #include "async_smb.h"
34 #include "libsmb/libsmb.h"
35 #include "libsmb/clirap.h"
37 #include "libsmb/nmblib.h"
38 #include "../lib/util/tevent_ntstatus.h"
40 #include "libsmb/read_smb.h"
45 static fstring host, workgroup, share, password, username, myname;
46 static int max_protocol = PROTOCOL_NT1;
47 static const char *sockops="TCP_NODELAY";
49 static int port_to_use=0;
50 int torture_numops=100;
51 int torture_blocksize=1024*1024;
52 static int procnum; /* records process count number when forking */
53 static struct cli_state *current_cli;
54 static fstring randomfname;
55 static bool use_oplocks;
56 static bool use_level_II_oplocks;
57 static const char *client_txt = "client_oplocks.txt";
58 static bool use_kerberos;
59 static fstring multishare_conn_fname;
60 static bool use_multishare_conn = False;
61 static bool do_encrypt;
62 static const char *local_path = NULL;
63 static int signing_state = Undefined;
66 bool torture_showall = False;
68 static double create_procs(bool (*fn)(int), bool *result);
71 /* return a pointer to a anonymous shared memory segment of size "size"
72 which will persist across fork() but will disappear when all processes
75 The memory is not zeroed
77 This function uses system5 shared memory. It takes advantage of a property
78 that the memory is not destroyed if it is attached when the id is removed
80 void *shm_setup(int size)
86 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
88 printf("can't get shared memory\n");
91 shm_unlink("private");
92 if (ftruncate(shmid, size) == -1) {
93 printf("can't set shared memory size\n");
96 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
97 if (ret == MAP_FAILED) {
98 printf("can't map shared memory\n");
102 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
104 printf("can't get shared memory\n");
107 ret = (void *)shmat(shmid, 0, 0);
108 if (!ret || ret == (void *)-1) {
109 printf("can't attach to shared memory\n");
112 /* the following releases the ipc, but note that this process
113 and all its children will still have access to the memory, its
114 just that the shmid is no longer valid for other shm calls. This
115 means we don't leave behind lots of shm segments after we exit
117 See Stevens "advanced programming in unix env" for details
119 shmctl(shmid, IPC_RMID, 0);
125 /********************************************************************
126 Ensure a connection is encrypted.
127 ********************************************************************/
129 static bool force_cli_encryption(struct cli_state *c,
130 const char *sharename)
133 uint32 caplow, caphigh;
136 if (!SERVER_HAS_UNIX_CIFS(c)) {
137 d_printf("Encryption required and "
138 "server that doesn't support "
139 "UNIX extensions - failing connect\n");
143 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
145 if (!NT_STATUS_IS_OK(status)) {
146 d_printf("Encryption required and "
147 "can't get UNIX CIFS extensions "
148 "version from server: %s\n", nt_errstr(status));
152 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
153 d_printf("Encryption required and "
154 "share %s doesn't support "
155 "encryption.\n", sharename);
159 if (c->use_kerberos) {
160 status = cli_gss_smb_encryption_start(c);
162 status = cli_raw_ntlm_smb_encryption_start(c,
168 if (!NT_STATUS_IS_OK(status)) {
169 d_printf("Encryption required and "
170 "setup failed with error %s.\n",
179 static struct cli_state *open_nbt_connection(void)
184 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
186 if (!NT_STATUS_IS_OK(status)) {
187 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
191 c->use_kerberos = use_kerberos;
193 c->timeout = 120000; /* set a really long timeout (2 minutes) */
194 if (use_oplocks) c->use_oplocks = True;
195 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
200 /****************************************************************************
201 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
202 ****************************************************************************/
204 static bool cli_bad_session_request(int fd,
205 struct nmb_name *calling, struct nmb_name *called)
214 uint8_t message_type;
217 frame = talloc_stackframe();
219 iov[0].iov_base = len_buf;
220 iov[0].iov_len = sizeof(len_buf);
222 /* put in the destination name */
224 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
226 if (iov[1].iov_base == NULL) {
229 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
230 talloc_get_size(iov[1].iov_base));
234 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
236 if (iov[2].iov_base == NULL) {
239 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
240 talloc_get_size(iov[2].iov_base));
242 /* Deliberately corrupt the name len (first byte) */
243 *((uint8_t *)iov[2].iov_base) = 100;
245 /* send a session request (RFC 1002) */
246 /* setup the packet length
247 * Remove four bytes from the length count, since the length
248 * field in the NBT Session Service header counts the number
249 * of bytes which follow. The cli_send_smb() function knows
250 * about this and accounts for those four bytes.
254 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
255 SCVAL(len_buf,0,0x81);
257 len = write_data_iov(fd, iov, 3);
261 len = read_smb(fd, talloc_tos(), &inbuf, &err);
267 message_type = CVAL(inbuf, 0);
268 if (message_type != 0x83) {
269 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
274 if (smb_len(inbuf) != 1) {
275 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
276 (int)smb_len(inbuf));
280 error = CVAL(inbuf, 4);
282 d_fprintf(stderr, "Expected error 0x82, got %d\n",
293 /* Insert a NULL at the first separator of the given path and return a pointer
294 * to the remainder of the string.
297 terminate_path_at_separator(char * path)
305 if ((p = strchr_m(path, '/'))) {
310 if ((p = strchr_m(path, '\\'))) {
320 parse a //server/share type UNC name
322 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
323 char **hostname, char **sharename)
327 *hostname = *sharename = NULL;
329 if (strncmp(unc_name, "\\\\", 2) &&
330 strncmp(unc_name, "//", 2)) {
334 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
335 p = terminate_path_at_separator(*hostname);
338 *sharename = talloc_strdup(mem_ctx, p);
339 terminate_path_at_separator(*sharename);
342 if (*hostname && *sharename) {
346 TALLOC_FREE(*hostname);
347 TALLOC_FREE(*sharename);
351 static bool torture_open_connection_share(struct cli_state **c,
352 const char *hostname,
353 const char *sharename)
359 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
361 flags |= CLI_FULL_CONNECTION_OPLOCKS;
362 if (use_level_II_oplocks)
363 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
365 status = cli_full_connection(c, myname,
366 hostname, NULL, port_to_use,
369 password, flags, signing_state);
370 if (!NT_STATUS_IS_OK(status)) {
371 printf("failed to open share connection: //%s/%s port:%d - %s\n",
372 hostname, sharename, port_to_use, nt_errstr(status));
376 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
379 return force_cli_encryption(*c,
385 bool torture_open_connection(struct cli_state **c, int conn_index)
387 char **unc_list = NULL;
388 int num_unc_names = 0;
391 if (use_multishare_conn==True) {
393 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
394 if (!unc_list || num_unc_names <= 0) {
395 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
399 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
401 printf("Failed to parse UNC name %s\n",
402 unc_list[conn_index % num_unc_names]);
403 TALLOC_FREE(unc_list);
407 result = torture_open_connection_share(c, h, s);
409 /* h, s were copied earlier */
410 TALLOC_FREE(unc_list);
414 return torture_open_connection_share(c, host, share);
417 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
419 uint16 old_vuid = cli->vuid;
420 fstring old_user_name;
421 size_t passlen = strlen(password);
425 fstrcpy(old_user_name, cli->user_name);
427 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
431 *new_vuid = cli->vuid;
432 cli->vuid = old_vuid;
433 status = cli_set_username(cli, old_user_name);
434 if (!NT_STATUS_IS_OK(status)) {
441 bool torture_close_connection(struct cli_state *c)
446 status = cli_tdis(c);
447 if (!NT_STATUS_IS_OK(status)) {
448 printf("tdis failed (%s)\n", nt_errstr(status));
458 /* check if the server produced the expected error code */
459 static bool check_error(int line, struct cli_state *c,
460 uint8 eclass, uint32 ecode, NTSTATUS nterr)
462 if (cli_is_dos_error(c)) {
466 /* Check DOS error */
468 cli_dos_error(c, &cclass, &num);
470 if (eclass != cclass || ecode != num) {
471 printf("unexpected error code class=%d code=%d\n",
472 (int)cclass, (int)num);
473 printf(" expected %d/%d %s (line=%d)\n",
474 (int)eclass, (int)ecode, nt_errstr(nterr), line);
483 status = cli_nt_error(c);
485 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
486 printf("unexpected error code %s\n", nt_errstr(status));
487 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
496 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
498 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
499 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
505 static bool rw_torture(struct cli_state *c)
507 const char *lockfname = "\\torture.lck";
511 pid_t pid2, pid = getpid();
517 memset(buf, '\0', sizeof(buf));
519 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
521 if (!NT_STATUS_IS_OK(status)) {
522 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
524 if (!NT_STATUS_IS_OK(status)) {
525 printf("open of %s failed (%s)\n",
526 lockfname, nt_errstr(status));
530 for (i=0;i<torture_numops;i++) {
531 unsigned n = (unsigned)sys_random()%10;
534 printf("%d\r", i); fflush(stdout);
536 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
538 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
542 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
544 if (!NT_STATUS_IS_OK(status)) {
545 printf("open failed (%s)\n", nt_errstr(status));
550 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
552 if (!NT_STATUS_IS_OK(status)) {
553 printf("write failed (%s)\n", nt_errstr(status));
558 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
559 sizeof(pid)+(j*sizeof(buf)),
561 if (!NT_STATUS_IS_OK(status)) {
562 printf("write failed (%s)\n",
570 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
571 printf("read failed (%s)\n", cli_errstr(c));
576 printf("data corruption!\n");
580 status = cli_close(c, fnum);
581 if (!NT_STATUS_IS_OK(status)) {
582 printf("close failed (%s)\n", nt_errstr(status));
586 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
587 if (!NT_STATUS_IS_OK(status)) {
588 printf("unlink failed (%s)\n", nt_errstr(status));
592 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
593 if (!NT_STATUS_IS_OK(status)) {
594 printf("unlock failed (%s)\n", nt_errstr(status));
600 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
607 static bool run_torture(int dummy)
609 struct cli_state *cli;
614 cli_sockopt(cli, sockops);
616 ret = rw_torture(cli);
618 if (!torture_close_connection(cli)) {
625 static bool rw_torture3(struct cli_state *c, char *lockfname)
627 uint16_t fnum = (uint16_t)-1;
632 unsigned countprev = 0;
635 NTSTATUS status = NT_STATUS_OK;
638 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
640 SIVAL(buf, i, sys_random());
647 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
648 if (!NT_STATUS_IS_OK(status)) {
649 printf("unlink failed (%s) (normal, this file should "
650 "not exist)\n", nt_errstr(status));
653 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
655 if (!NT_STATUS_IS_OK(status)) {
656 printf("first open read/write of %s failed (%s)\n",
657 lockfname, nt_errstr(status));
663 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
665 status = cli_open(c, lockfname, O_RDONLY,
667 if (!NT_STATUS_IS_OK(status)) {
672 if (!NT_STATUS_IS_OK(status)) {
673 printf("second open read-only of %s failed (%s)\n",
674 lockfname, nt_errstr(status));
680 for (count = 0; count < sizeof(buf); count += sent)
682 if (count >= countprev) {
683 printf("%d %8d\r", i, count);
686 countprev += (sizeof(buf) / 20);
691 sent = ((unsigned)sys_random()%(20))+ 1;
692 if (sent > sizeof(buf) - count)
694 sent = sizeof(buf) - count;
697 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
698 count, (size_t)sent, NULL);
699 if (!NT_STATUS_IS_OK(status)) {
700 printf("write failed (%s)\n",
707 sent = cli_read(c, fnum, buf_rd+count, count,
711 printf("read failed offset:%d size:%ld (%s)\n",
712 count, (unsigned long)sizeof(buf)-count,
719 if (memcmp(buf_rd+count, buf+count, sent) != 0)
721 printf("read/write compare failed\n");
722 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
731 status = cli_close(c, fnum);
732 if (!NT_STATUS_IS_OK(status)) {
733 printf("close failed (%s)\n", nt_errstr(status));
740 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
742 const char *lockfname = "\\torture2.lck";
752 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
753 if (!NT_STATUS_IS_OK(status)) {
754 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
757 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
759 if (!NT_STATUS_IS_OK(status)) {
760 printf("first open read/write of %s failed (%s)\n",
761 lockfname, nt_errstr(status));
765 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
766 if (!NT_STATUS_IS_OK(status)) {
767 printf("second open read-only of %s failed (%s)\n",
768 lockfname, nt_errstr(status));
769 cli_close(c1, fnum1);
773 for (i = 0; i < torture_numops; i++)
775 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
777 printf("%d\r", i); fflush(stdout);
780 generate_random_buffer((unsigned char *)buf, buf_size);
782 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
784 if (!NT_STATUS_IS_OK(status)) {
785 printf("write failed (%s)\n", nt_errstr(status));
790 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
791 printf("read failed (%s)\n", cli_errstr(c2));
792 printf("read %d, expected %ld\n", (int)bytes_read,
793 (unsigned long)buf_size);
798 if (memcmp(buf_rd, buf, buf_size) != 0)
800 printf("read/write compare failed\n");
806 status = cli_close(c2, fnum2);
807 if (!NT_STATUS_IS_OK(status)) {
808 printf("close failed (%s)\n", nt_errstr(status));
812 status = cli_close(c1, fnum1);
813 if (!NT_STATUS_IS_OK(status)) {
814 printf("close failed (%s)\n", nt_errstr(status));
818 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
819 if (!NT_STATUS_IS_OK(status)) {
820 printf("unlink failed (%s)\n", nt_errstr(status));
827 static bool run_readwritetest(int dummy)
829 struct cli_state *cli1, *cli2;
830 bool test1, test2 = False;
832 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
835 cli_sockopt(cli1, sockops);
836 cli_sockopt(cli2, sockops);
838 printf("starting readwritetest\n");
840 test1 = rw_torture2(cli1, cli2);
841 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
844 test2 = rw_torture2(cli1, cli1);
845 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
848 if (!torture_close_connection(cli1)) {
852 if (!torture_close_connection(cli2)) {
856 return (test1 && test2);
859 static bool run_readwritemulti(int dummy)
861 struct cli_state *cli;
866 cli_sockopt(cli, sockops);
868 printf("run_readwritemulti: fname %s\n", randomfname);
869 test = rw_torture3(cli, randomfname);
871 if (!torture_close_connection(cli)) {
878 static bool run_readwritelarge_internal(int max_xmit_k)
880 static struct cli_state *cli1;
882 const char *lockfname = "\\large.dat";
888 if (!torture_open_connection(&cli1, 0)) {
891 cli_sockopt(cli1, sockops);
892 memset(buf,'\0',sizeof(buf));
894 cli1->max_xmit = max_xmit_k*1024;
896 if (signing_state == Required) {
897 /* Horrible cheat to force
898 multiple signed outstanding
899 packets against a Samba server.
901 cli1->is_samba = false;
904 printf("starting readwritelarge_internal\n");
906 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
908 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
910 if (!NT_STATUS_IS_OK(status)) {
911 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
915 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
917 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
919 if (!NT_STATUS_IS_OK(status)) {
920 printf("qfileinfo failed (%s)\n", nt_errstr(status));
924 if (fsize == sizeof(buf))
925 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
926 (unsigned long)fsize);
928 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
929 (unsigned long)fsize);
933 status = cli_close(cli1, fnum1);
934 if (!NT_STATUS_IS_OK(status)) {
935 printf("close failed (%s)\n", nt_errstr(status));
939 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
940 if (!NT_STATUS_IS_OK(status)) {
941 printf("unlink failed (%s)\n", nt_errstr(status));
945 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
947 if (!NT_STATUS_IS_OK(status)) {
948 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
952 cli1->max_xmit = 4*1024;
954 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
956 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
958 if (!NT_STATUS_IS_OK(status)) {
959 printf("qfileinfo failed (%s)\n", nt_errstr(status));
963 if (fsize == sizeof(buf))
964 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
965 (unsigned long)fsize);
967 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
968 (unsigned long)fsize);
973 /* ToDo - set allocation. JRA */
974 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
975 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
978 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
980 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
984 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
987 status = cli_close(cli1, fnum1);
988 if (!NT_STATUS_IS_OK(status)) {
989 printf("close failed (%s)\n", nt_errstr(status));
993 if (!torture_close_connection(cli1)) {
999 static bool run_readwritelarge(int dummy)
1001 return run_readwritelarge_internal(128);
1004 static bool run_readwritelarge_signtest(int dummy)
1007 signing_state = Required;
1008 ret = run_readwritelarge_internal(2);
1009 signing_state = Undefined;
1016 #define ival(s) strtol(s, NULL, 0)
1018 /* run a test that simulates an approximate netbench client load */
1019 static bool run_netbench(int client)
1021 struct cli_state *cli;
1026 const char *params[20];
1027 bool correct = True;
1033 cli_sockopt(cli, sockops);
1037 slprintf(cname,sizeof(cname)-1, "client%d", client);
1039 f = fopen(client_txt, "r");
1046 while (fgets(line, sizeof(line)-1, f)) {
1050 line[strlen(line)-1] = 0;
1052 /* printf("[%d] %s\n", line_count, line); */
1054 all_string_sub(line,"client1", cname, sizeof(line));
1056 /* parse the command parameters */
1057 params[0] = strtok_r(line, " ", &saveptr);
1059 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1063 if (i < 2) continue;
1065 if (!strncmp(params[0],"SMB", 3)) {
1066 printf("ERROR: You are using a dbench 1 load file\n");
1070 if (!strcmp(params[0],"NTCreateX")) {
1071 nb_createx(params[1], ival(params[2]), ival(params[3]),
1073 } else if (!strcmp(params[0],"Close")) {
1074 nb_close(ival(params[1]));
1075 } else if (!strcmp(params[0],"Rename")) {
1076 nb_rename(params[1], params[2]);
1077 } else if (!strcmp(params[0],"Unlink")) {
1078 nb_unlink(params[1]);
1079 } else if (!strcmp(params[0],"Deltree")) {
1080 nb_deltree(params[1]);
1081 } else if (!strcmp(params[0],"Rmdir")) {
1082 nb_rmdir(params[1]);
1083 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1084 nb_qpathinfo(params[1]);
1085 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1086 nb_qfileinfo(ival(params[1]));
1087 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1088 nb_qfsinfo(ival(params[1]));
1089 } else if (!strcmp(params[0],"FIND_FIRST")) {
1090 nb_findfirst(params[1]);
1091 } else if (!strcmp(params[0],"WriteX")) {
1092 nb_writex(ival(params[1]),
1093 ival(params[2]), ival(params[3]), ival(params[4]));
1094 } else if (!strcmp(params[0],"ReadX")) {
1095 nb_readx(ival(params[1]),
1096 ival(params[2]), ival(params[3]), ival(params[4]));
1097 } else if (!strcmp(params[0],"Flush")) {
1098 nb_flush(ival(params[1]));
1100 printf("Unknown operation %s\n", params[0]);
1108 if (!torture_close_connection(cli)) {
1116 /* run a test that simulates an approximate netbench client load */
1117 static bool run_nbench(int dummy)
1120 bool correct = True;
1126 signal(SIGALRM, nb_alarm);
1128 t = create_procs(run_netbench, &correct);
1131 printf("\nThroughput %g MB/sec\n",
1132 1.0e-6 * nbio_total() / t);
1138 This test checks for two things:
1140 1) correct support for retaining locks over a close (ie. the server
1141 must not use posix semantics)
1142 2) support for lock timeouts
1144 static bool run_locktest1(int dummy)
1146 struct cli_state *cli1, *cli2;
1147 const char *fname = "\\lockt1.lck";
1148 uint16_t fnum1, fnum2, fnum3;
1150 unsigned lock_timeout;
1153 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1156 cli_sockopt(cli1, sockops);
1157 cli_sockopt(cli2, sockops);
1159 printf("starting locktest1\n");
1161 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1163 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1165 if (!NT_STATUS_IS_OK(status)) {
1166 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1170 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1171 if (!NT_STATUS_IS_OK(status)) {
1172 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1176 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1177 if (!NT_STATUS_IS_OK(status)) {
1178 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1182 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1183 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1188 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1189 printf("lock2 succeeded! This is a locking bug\n");
1192 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1193 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1197 lock_timeout = (1 + (random() % 20));
1198 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1200 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1201 printf("lock3 succeeded! This is a locking bug\n");
1204 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1205 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1209 if (ABS(t2 - t1) < lock_timeout-1) {
1210 printf("error: This server appears not to support timed lock requests\n");
1213 printf("server slept for %u seconds for a %u second timeout\n",
1214 (unsigned int)(t2-t1), lock_timeout);
1216 status = cli_close(cli1, fnum2);
1217 if (!NT_STATUS_IS_OK(status)) {
1218 printf("close1 failed (%s)\n", nt_errstr(status));
1222 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1223 printf("lock4 succeeded! This is a locking bug\n");
1226 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1227 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1230 status = cli_close(cli1, fnum1);
1231 if (!NT_STATUS_IS_OK(status)) {
1232 printf("close2 failed (%s)\n", nt_errstr(status));
1236 status = cli_close(cli2, fnum3);
1237 if (!NT_STATUS_IS_OK(status)) {
1238 printf("close3 failed (%s)\n", nt_errstr(status));
1242 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1243 if (!NT_STATUS_IS_OK(status)) {
1244 printf("unlink failed (%s)\n", nt_errstr(status));
1249 if (!torture_close_connection(cli1)) {
1253 if (!torture_close_connection(cli2)) {
1257 printf("Passed locktest1\n");
1262 this checks to see if a secondary tconx can use open files from an
1265 static bool run_tcon_test(int dummy)
1267 static struct cli_state *cli;
1268 const char *fname = "\\tcontest.tmp";
1270 uint16 cnum1, cnum2, cnum3;
1271 uint16 vuid1, vuid2;
1276 memset(buf, '\0', sizeof(buf));
1278 if (!torture_open_connection(&cli, 0)) {
1281 cli_sockopt(cli, sockops);
1283 printf("starting tcontest\n");
1285 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1287 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1288 if (!NT_STATUS_IS_OK(status)) {
1289 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1296 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1297 if (!NT_STATUS_IS_OK(status)) {
1298 printf("initial write failed (%s)", nt_errstr(status));
1302 status = cli_tcon_andx(cli, share, "?????",
1303 password, strlen(password)+1);
1304 if (!NT_STATUS_IS_OK(status)) {
1305 printf("%s refused 2nd tree connect (%s)\n", host,
1312 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1313 vuid2 = cli->vuid + 1;
1315 /* try a write with the wrong tid */
1318 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1319 if (NT_STATUS_IS_OK(status)) {
1320 printf("* server allows write with wrong TID\n");
1323 printf("server fails write with wrong TID : %s\n",
1328 /* try a write with an invalid tid */
1331 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1332 if (NT_STATUS_IS_OK(status)) {
1333 printf("* server allows write with invalid TID\n");
1336 printf("server fails write with invalid TID : %s\n",
1340 /* try a write with an invalid vuid */
1344 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1345 if (NT_STATUS_IS_OK(status)) {
1346 printf("* server allows write with invalid VUID\n");
1349 printf("server fails write with invalid VUID : %s\n",
1356 status = cli_close(cli, fnum1);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 printf("close failed (%s)\n", nt_errstr(status));
1364 status = cli_tdis(cli);
1365 if (!NT_STATUS_IS_OK(status)) {
1366 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1372 if (!torture_close_connection(cli)) {
1381 checks for old style tcon support
1383 static bool run_tcon2_test(int dummy)
1385 static struct cli_state *cli;
1386 uint16 cnum, max_xmit;
1390 if (!torture_open_connection(&cli, 0)) {
1393 cli_sockopt(cli, sockops);
1395 printf("starting tcon2 test\n");
1397 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1401 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 printf("tcon2 failed : %s\n", nt_errstr(status));
1408 printf("tcon OK : max_xmit=%d cnum=%d\n",
1409 (int)max_xmit, (int)cnum);
1412 if (!torture_close_connection(cli)) {
1416 printf("Passed tcon2 test\n");
1420 static bool tcon_devtest(struct cli_state *cli,
1421 const char *myshare, const char *devtype,
1422 const char *return_devtype,
1423 NTSTATUS expected_error)
1428 status = cli_tcon_andx(cli, myshare, devtype,
1429 password, strlen(password)+1);
1431 if (NT_STATUS_IS_OK(expected_error)) {
1432 if (NT_STATUS_IS_OK(status)) {
1433 if (strcmp(cli->dev, return_devtype) == 0) {
1436 printf("tconX to share %s with type %s "
1437 "succeeded but returned the wrong "
1438 "device type (got [%s] but should have got [%s])\n",
1439 myshare, devtype, cli->dev, return_devtype);
1443 printf("tconX to share %s with type %s "
1444 "should have succeeded but failed\n",
1450 if (NT_STATUS_IS_OK(status)) {
1451 printf("tconx to share %s with type %s "
1452 "should have failed but succeeded\n",
1456 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1460 printf("Returned unexpected error\n");
1469 checks for correct tconX support
1471 static bool run_tcon_devtype_test(int dummy)
1473 static struct cli_state *cli1 = NULL;
1478 status = cli_full_connection(&cli1, myname,
1479 host, NULL, port_to_use,
1481 username, workgroup,
1482 password, flags, signing_state);
1484 if (!NT_STATUS_IS_OK(status)) {
1485 printf("could not open connection\n");
1489 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1492 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1495 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1498 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1501 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1504 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1507 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1510 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1513 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1516 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1522 printf("Passed tcondevtest\n");
1529 This test checks that
1531 1) the server supports multiple locking contexts on the one SMB
1532 connection, distinguished by PID.
1534 2) the server correctly fails overlapping locks made by the same PID (this
1535 goes against POSIX behaviour, which is why it is tricky to implement)
1537 3) the server denies unlock requests by an incorrect client PID
1539 static bool run_locktest2(int dummy)
1541 static struct cli_state *cli;
1542 const char *fname = "\\lockt2.lck";
1543 uint16_t fnum1, fnum2, fnum3;
1544 bool correct = True;
1547 if (!torture_open_connection(&cli, 0)) {
1551 cli_sockopt(cli, sockops);
1553 printf("starting locktest2\n");
1555 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1559 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1560 if (!NT_STATUS_IS_OK(status)) {
1561 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1565 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1566 if (!NT_STATUS_IS_OK(status)) {
1567 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1573 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1574 if (!NT_STATUS_IS_OK(status)) {
1575 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1581 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1582 printf("lock1 failed (%s)\n", cli_errstr(cli));
1586 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1587 printf("WRITE lock1 succeeded! This is a locking bug\n");
1590 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1591 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1594 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1595 printf("WRITE lock2 succeeded! This is a locking bug\n");
1598 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1599 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1602 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1603 printf("READ lock2 succeeded! This is a locking bug\n");
1606 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1607 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1610 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1611 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1614 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1615 printf("unlock at 100 succeeded! This is a locking bug\n");
1619 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1620 printf("unlock1 succeeded! This is a locking bug\n");
1623 if (!check_error(__LINE__, cli,
1625 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1628 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1629 printf("unlock2 succeeded! This is a locking bug\n");
1632 if (!check_error(__LINE__, cli,
1634 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1637 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1638 printf("lock3 succeeded! This is a locking bug\n");
1641 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1646 status = cli_close(cli, fnum1);
1647 if (!NT_STATUS_IS_OK(status)) {
1648 printf("close1 failed (%s)\n", nt_errstr(status));
1652 status = cli_close(cli, fnum2);
1653 if (!NT_STATUS_IS_OK(status)) {
1654 printf("close2 failed (%s)\n", nt_errstr(status));
1658 status = cli_close(cli, fnum3);
1659 if (!NT_STATUS_IS_OK(status)) {
1660 printf("close3 failed (%s)\n", nt_errstr(status));
1664 if (!torture_close_connection(cli)) {
1668 printf("locktest2 finished\n");
1675 This test checks that
1677 1) the server supports the full offset range in lock requests
1679 static bool run_locktest3(int dummy)
1681 static struct cli_state *cli1, *cli2;
1682 const char *fname = "\\lockt3.lck";
1683 uint16_t fnum1, fnum2;
1686 bool correct = True;
1689 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1691 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1694 cli_sockopt(cli1, sockops);
1695 cli_sockopt(cli2, sockops);
1697 printf("starting locktest3\n");
1699 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1701 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1703 if (!NT_STATUS_IS_OK(status)) {
1704 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1708 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1709 if (!NT_STATUS_IS_OK(status)) {
1710 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1714 for (offset=i=0;i<torture_numops;i++) {
1716 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1717 printf("lock1 %d failed (%s)\n",
1723 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1724 printf("lock2 %d failed (%s)\n",
1731 for (offset=i=0;i<torture_numops;i++) {
1734 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1735 printf("error: lock1 %d succeeded!\n", i);
1739 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1740 printf("error: lock2 %d succeeded!\n", i);
1744 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1745 printf("error: lock3 %d succeeded!\n", i);
1749 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1750 printf("error: lock4 %d succeeded!\n", i);
1755 for (offset=i=0;i<torture_numops;i++) {
1758 status = cli_unlock(cli1, fnum1, offset-1, 1);
1759 if (!NT_STATUS_IS_OK(status)) {
1760 printf("unlock1 %d failed (%s)\n",
1766 status = cli_unlock(cli2, fnum2, offset-2, 1);
1767 if (!NT_STATUS_IS_OK(status)) {
1768 printf("unlock2 %d failed (%s)\n",
1775 status = cli_close(cli1, fnum1);
1776 if (!NT_STATUS_IS_OK(status)) {
1777 printf("close1 failed (%s)\n", nt_errstr(status));
1781 status = cli_close(cli2, fnum2);
1782 if (!NT_STATUS_IS_OK(status)) {
1783 printf("close2 failed (%s)\n", nt_errstr(status));
1787 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1788 if (!NT_STATUS_IS_OK(status)) {
1789 printf("unlink failed (%s)\n", nt_errstr(status));
1793 if (!torture_close_connection(cli1)) {
1797 if (!torture_close_connection(cli2)) {
1801 printf("finished locktest3\n");
1806 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1807 printf("** "); correct = False; \
1811 looks at overlapping locks
1813 static bool run_locktest4(int dummy)
1815 static struct cli_state *cli1, *cli2;
1816 const char *fname = "\\lockt4.lck";
1817 uint16_t fnum1, fnum2, f;
1820 bool correct = True;
1823 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1827 cli_sockopt(cli1, sockops);
1828 cli_sockopt(cli2, sockops);
1830 printf("starting locktest4\n");
1832 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1834 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1835 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1837 memset(buf, 0, sizeof(buf));
1839 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1841 if (!NT_STATUS_IS_OK(status)) {
1842 printf("Failed to create file: %s\n", nt_errstr(status));
1847 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1848 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1849 EXPECTED(ret, False);
1850 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1852 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1853 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1854 EXPECTED(ret, True);
1855 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1857 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1858 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1859 EXPECTED(ret, False);
1860 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1862 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1863 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1864 EXPECTED(ret, True);
1865 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1867 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1868 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1869 EXPECTED(ret, False);
1870 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1872 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1873 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1874 EXPECTED(ret, True);
1875 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1877 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1878 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1879 EXPECTED(ret, True);
1880 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1882 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1883 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1884 EXPECTED(ret, False);
1885 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1887 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1888 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1889 EXPECTED(ret, False);
1890 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1892 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1893 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1894 EXPECTED(ret, True);
1895 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1897 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1898 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1899 EXPECTED(ret, False);
1900 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1902 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1903 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1904 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1905 EXPECTED(ret, False);
1906 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1909 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1910 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1911 EXPECTED(ret, False);
1912 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1914 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1916 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1918 ret = NT_STATUS_IS_OK(status);
1920 EXPECTED(ret, False);
1921 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1924 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1925 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1926 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1927 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1928 EXPECTED(ret, True);
1929 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1932 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1933 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1934 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1935 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1936 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1938 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1939 EXPECTED(ret, True);
1940 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1942 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1943 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1944 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1946 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1947 EXPECTED(ret, True);
1948 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1950 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1951 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1952 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1954 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1955 EXPECTED(ret, True);
1956 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1958 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1959 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1960 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1961 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1963 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1964 EXPECTED(ret, True);
1965 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1967 cli_close(cli1, fnum1);
1968 cli_close(cli2, fnum2);
1969 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1970 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1971 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1972 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1973 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1974 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1975 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1977 cli_close(cli1, fnum1);
1978 EXPECTED(ret, True);
1979 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1982 cli_close(cli1, fnum1);
1983 cli_close(cli2, fnum2);
1984 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1985 torture_close_connection(cli1);
1986 torture_close_connection(cli2);
1988 printf("finished locktest4\n");
1993 looks at lock upgrade/downgrade.
1995 static bool run_locktest5(int dummy)
1997 static struct cli_state *cli1, *cli2;
1998 const char *fname = "\\lockt5.lck";
1999 uint16_t fnum1, fnum2, fnum3;
2002 bool correct = True;
2005 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2009 cli_sockopt(cli1, sockops);
2010 cli_sockopt(cli2, sockops);
2012 printf("starting locktest5\n");
2014 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2016 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2017 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2018 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2020 memset(buf, 0, sizeof(buf));
2022 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2024 if (!NT_STATUS_IS_OK(status)) {
2025 printf("Failed to create file: %s\n", nt_errstr(status));
2030 /* Check for NT bug... */
2031 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2032 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2033 cli_close(cli1, fnum1);
2034 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2035 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2036 EXPECTED(ret, True);
2037 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2038 cli_close(cli1, fnum1);
2039 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2040 cli_unlock(cli1, fnum3, 0, 1);
2042 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2043 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2044 EXPECTED(ret, True);
2045 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2047 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2048 EXPECTED(ret, False);
2050 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2052 /* Unlock the process 2 lock. */
2053 cli_unlock(cli2, fnum2, 0, 4);
2055 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2056 EXPECTED(ret, False);
2058 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2060 /* Unlock the process 1 fnum3 lock. */
2061 cli_unlock(cli1, fnum3, 0, 4);
2063 /* Stack 2 more locks here. */
2064 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2065 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2067 EXPECTED(ret, True);
2068 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2070 /* Unlock the first process lock, then check this was the WRITE lock that was
2073 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2074 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2076 EXPECTED(ret, True);
2077 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2079 /* Unlock the process 2 lock. */
2080 cli_unlock(cli2, fnum2, 0, 4);
2082 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2084 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2085 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2086 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2088 EXPECTED(ret, True);
2089 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2091 /* Ensure the next unlock fails. */
2092 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2093 EXPECTED(ret, False);
2094 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2096 /* Ensure connection 2 can get a write lock. */
2097 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2098 EXPECTED(ret, True);
2100 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2104 cli_close(cli1, fnum1);
2105 cli_close(cli2, fnum2);
2106 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2107 if (!torture_close_connection(cli1)) {
2110 if (!torture_close_connection(cli2)) {
2114 printf("finished locktest5\n");
2120 tries the unusual lockingX locktype bits
2122 static bool run_locktest6(int dummy)
2124 static struct cli_state *cli;
2125 const char *fname[1] = { "\\lock6.txt" };
2130 if (!torture_open_connection(&cli, 0)) {
2134 cli_sockopt(cli, sockops);
2136 printf("starting locktest6\n");
2139 printf("Testing %s\n", fname[i]);
2141 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2143 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2144 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2145 cli_close(cli, fnum);
2146 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2148 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2149 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2150 cli_close(cli, fnum);
2151 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2153 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2156 torture_close_connection(cli);
2158 printf("finished locktest6\n");
2162 static bool run_locktest7(int dummy)
2164 struct cli_state *cli1;
2165 const char *fname = "\\lockt7.lck";
2168 bool correct = False;
2171 if (!torture_open_connection(&cli1, 0)) {
2175 cli_sockopt(cli1, sockops);
2177 printf("starting locktest7\n");
2179 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2181 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2183 memset(buf, 0, sizeof(buf));
2185 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2187 if (!NT_STATUS_IS_OK(status)) {
2188 printf("Failed to create file: %s\n", nt_errstr(status));
2192 cli_setpid(cli1, 1);
2194 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2195 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2198 printf("pid1 successfully locked range 130:4 for READ\n");
2201 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2202 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2205 printf("pid1 successfully read the range 130:4\n");
2208 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2209 if (!NT_STATUS_IS_OK(status)) {
2210 printf("pid1 unable to write to the range 130:4, error was "
2211 "%s\n", nt_errstr(status));
2212 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2213 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2217 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2221 cli_setpid(cli1, 2);
2223 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2224 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2226 printf("pid2 successfully read the range 130:4\n");
2229 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2230 if (!NT_STATUS_IS_OK(status)) {
2231 printf("pid2 unable to write to the range 130:4, error was "
2232 "%s\n", nt_errstr(status));
2233 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2234 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2238 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2242 cli_setpid(cli1, 1);
2243 cli_unlock(cli1, fnum1, 130, 4);
2245 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2246 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2249 printf("pid1 successfully locked range 130:4 for WRITE\n");
2252 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2253 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2256 printf("pid1 successfully read the range 130:4\n");
2259 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2260 if (!NT_STATUS_IS_OK(status)) {
2261 printf("pid1 unable to write to the range 130:4, error was "
2262 "%s\n", nt_errstr(status));
2265 printf("pid1 successfully wrote to the range 130:4\n");
2268 cli_setpid(cli1, 2);
2270 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2271 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2272 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2273 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2277 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2281 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2282 if (!NT_STATUS_IS_OK(status)) {
2283 printf("pid2 unable to write to the range 130:4, error was "
2284 "%s\n", nt_errstr(status));
2285 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2286 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2290 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2294 cli_unlock(cli1, fnum1, 130, 0);
2298 cli_close(cli1, fnum1);
2299 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2300 torture_close_connection(cli1);
2302 printf("finished locktest7\n");
2307 * This demonstrates a problem with our use of GPFS share modes: A file
2308 * descriptor sitting in the pending close queue holding a GPFS share mode
2309 * blocks opening a file another time. Happens with Word 2007 temp files.
2310 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2311 * open is denied with NT_STATUS_SHARING_VIOLATION.
2314 static bool run_locktest8(int dummy)
2316 struct cli_state *cli1;
2317 const char *fname = "\\lockt8.lck";
2318 uint16_t fnum1, fnum2;
2320 bool correct = False;
2323 if (!torture_open_connection(&cli1, 0)) {
2327 cli_sockopt(cli1, sockops);
2329 printf("starting locktest8\n");
2331 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2333 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2335 if (!NT_STATUS_IS_OK(status)) {
2336 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2340 memset(buf, 0, sizeof(buf));
2342 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2343 if (!NT_STATUS_IS_OK(status)) {
2344 d_fprintf(stderr, "cli_open second time returned %s\n",
2349 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2350 printf("Unable to apply read lock on range 1:1, error was "
2351 "%s\n", cli_errstr(cli1));
2355 status = cli_close(cli1, fnum1);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2361 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 d_fprintf(stderr, "cli_open third time returned %s\n",
2371 cli_close(cli1, fnum1);
2372 cli_close(cli1, fnum2);
2373 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2374 torture_close_connection(cli1);
2376 printf("finished locktest8\n");
2381 * This test is designed to be run in conjunction with
2382 * external NFS or POSIX locks taken in the filesystem.
2383 * It checks that the smbd server will block until the
2384 * lock is released and then acquire it. JRA.
2387 static bool got_alarm;
2388 static int alarm_fd;
2390 static void alarm_handler(int dummy)
2395 static void alarm_handler_parent(int dummy)
2400 static void do_local_lock(int read_fd, int write_fd)
2405 const char *local_pathname = NULL;
2408 local_pathname = talloc_asprintf(talloc_tos(),
2409 "%s/lockt9.lck", local_path);
2410 if (!local_pathname) {
2411 printf("child: alloc fail\n");
2415 unlink(local_pathname);
2416 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2418 printf("child: open of %s failed %s.\n",
2419 local_pathname, strerror(errno));
2423 /* Now take a fcntl lock. */
2424 lock.l_type = F_WRLCK;
2425 lock.l_whence = SEEK_SET;
2428 lock.l_pid = getpid();
2430 ret = fcntl(fd,F_SETLK,&lock);
2432 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2433 local_pathname, strerror(errno));
2436 printf("child: got lock 0:4 on file %s.\n",
2441 CatchSignal(SIGALRM, alarm_handler);
2443 /* Signal the parent. */
2444 if (write(write_fd, &c, 1) != 1) {
2445 printf("child: start signal fail %s.\n",
2452 /* Wait for the parent to be ready. */
2453 if (read(read_fd, &c, 1) != 1) {
2454 printf("child: reply signal fail %s.\n",
2462 printf("child: released lock 0:4 on file %s.\n",
2468 static bool run_locktest9(int dummy)
2470 struct cli_state *cli1;
2471 const char *fname = "\\lockt9.lck";
2473 bool correct = False;
2474 int pipe_in[2], pipe_out[2];
2478 struct timeval start;
2482 printf("starting locktest9\n");
2484 if (local_path == NULL) {
2485 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2489 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2494 if (child_pid == -1) {
2498 if (child_pid == 0) {
2500 do_local_lock(pipe_out[0], pipe_in[1]);
2510 ret = read(pipe_in[0], &c, 1);
2512 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2517 if (!torture_open_connection(&cli1, 0)) {
2521 cli_sockopt(cli1, sockops);
2523 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2525 if (!NT_STATUS_IS_OK(status)) {
2526 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2530 /* Ensure the child has the lock. */
2531 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2532 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2535 d_printf("Child has the lock.\n");
2538 /* Tell the child to wait 5 seconds then exit. */
2539 ret = write(pipe_out[1], &c, 1);
2541 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2546 /* Wait 20 seconds for the lock. */
2547 alarm_fd = cli1->fd;
2548 CatchSignal(SIGALRM, alarm_handler_parent);
2551 start = timeval_current();
2553 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2554 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2555 "%s\n", cli_errstr(cli1));
2560 seconds = timeval_elapsed(&start);
2562 printf("Parent got the lock after %.2f seconds.\n",
2565 status = cli_close(cli1, fnum);
2566 if (!NT_STATUS_IS_OK(status)) {
2567 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2574 cli_close(cli1, fnum);
2575 torture_close_connection(cli1);
2579 printf("finished locktest9\n");
2584 test whether fnums and tids open on one VC are available on another (a major
2587 static bool run_fdpasstest(int dummy)
2589 struct cli_state *cli1, *cli2;
2590 const char *fname = "\\fdpass.tst";
2595 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2598 cli_sockopt(cli1, sockops);
2599 cli_sockopt(cli2, sockops);
2601 printf("starting fdpasstest\n");
2603 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2605 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2607 if (!NT_STATUS_IS_OK(status)) {
2608 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2612 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2614 if (!NT_STATUS_IS_OK(status)) {
2615 printf("write failed (%s)\n", nt_errstr(status));
2619 cli2->vuid = cli1->vuid;
2620 cli2->cnum = cli1->cnum;
2621 cli2->pid = cli1->pid;
2623 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2624 printf("read succeeded! nasty security hole [%s]\n",
2629 cli_close(cli1, fnum1);
2630 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2632 torture_close_connection(cli1);
2633 torture_close_connection(cli2);
2635 printf("finished fdpasstest\n");
2639 static bool run_fdsesstest(int dummy)
2641 struct cli_state *cli;
2646 const char *fname = "\\fdsess.tst";
2647 const char *fname1 = "\\fdsess1.tst";
2654 if (!torture_open_connection(&cli, 0))
2656 cli_sockopt(cli, sockops);
2658 if (!torture_cli_session_setup2(cli, &new_vuid))
2661 saved_cnum = cli->cnum;
2662 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2664 new_cnum = cli->cnum;
2665 cli->cnum = saved_cnum;
2667 printf("starting fdsesstest\n");
2669 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2670 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2672 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2673 if (!NT_STATUS_IS_OK(status)) {
2674 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2678 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2680 if (!NT_STATUS_IS_OK(status)) {
2681 printf("write failed (%s)\n", nt_errstr(status));
2685 saved_vuid = cli->vuid;
2686 cli->vuid = new_vuid;
2688 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2689 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2693 /* Try to open a file with different vuid, samba cnum. */
2694 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2695 printf("create with different vuid, same cnum succeeded.\n");
2696 cli_close(cli, fnum2);
2697 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2699 printf("create with different vuid, same cnum failed.\n");
2700 printf("This will cause problems with service clients.\n");
2704 cli->vuid = saved_vuid;
2706 /* Try with same vuid, different cnum. */
2707 cli->cnum = new_cnum;
2709 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2710 printf("read succeeded with different cnum![%s]\n",
2715 cli->cnum = saved_cnum;
2716 cli_close(cli, fnum1);
2717 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2719 torture_close_connection(cli);
2721 printf("finished fdsesstest\n");
2726 This test checks that
2728 1) the server does not allow an unlink on a file that is open
2730 static bool run_unlinktest(int dummy)
2732 struct cli_state *cli;
2733 const char *fname = "\\unlink.tst";
2735 bool correct = True;
2738 if (!torture_open_connection(&cli, 0)) {
2742 cli_sockopt(cli, sockops);
2744 printf("starting unlink test\n");
2746 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2750 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2751 if (!NT_STATUS_IS_OK(status)) {
2752 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2756 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2757 printf("error: server allowed unlink on an open file\n");
2760 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2761 NT_STATUS_SHARING_VIOLATION);
2764 cli_close(cli, fnum);
2765 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2767 if (!torture_close_connection(cli)) {
2771 printf("unlink test finished\n");
2778 test how many open files this server supports on the one socket
2780 static bool run_maxfidtest(int dummy)
2782 struct cli_state *cli;
2784 uint16_t fnums[0x11000];
2787 bool correct = True;
2793 printf("failed to connect\n");
2797 cli_sockopt(cli, sockops);
2799 for (i=0; i<0x11000; i++) {
2800 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2801 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2803 if (!NT_STATUS_IS_OK(status)) {
2804 printf("open of %s failed (%s)\n",
2805 fname, nt_errstr(status));
2806 printf("maximum fnum is %d\n", i);
2814 printf("cleaning up\n");
2816 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2817 cli_close(cli, fnums[i]);
2819 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2820 if (!NT_STATUS_IS_OK(status)) {
2821 printf("unlink of %s failed (%s)\n",
2822 fname, nt_errstr(status));
2829 printf("maxfid test finished\n");
2830 if (!torture_close_connection(cli)) {
2836 /* generate a random buffer */
2837 static void rand_buf(char *buf, int len)
2840 *buf = (char)sys_random();
2845 /* send smb negprot commands, not reading the response */
2846 static bool run_negprot_nowait(int dummy)
2848 struct tevent_context *ev;
2850 struct cli_state *cli;
2851 bool correct = True;
2853 printf("starting negprot nowait test\n");
2855 ev = tevent_context_init(talloc_tos());
2860 if (!(cli = open_nbt_connection())) {
2865 for (i=0;i<50000;i++) {
2866 struct tevent_req *req;
2868 req = cli_negprot_send(ev, ev, cli);
2873 if (!tevent_req_poll(req, ev)) {
2874 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2882 if (torture_close_connection(cli)) {
2886 printf("finished negprot nowait test\n");
2891 /* send smb negprot commands, not reading the response */
2892 static bool run_bad_nbt_session(int dummy)
2894 struct nmb_name called, calling;
2895 struct sockaddr_storage ss;
2900 printf("starting bad nbt session test\n");
2902 make_nmb_name(&calling, myname, 0x0);
2903 make_nmb_name(&called , host, 0x20);
2905 if (!resolve_name(host, &ss, 0x20, true)) {
2906 d_fprintf(stderr, "Could not resolve name %s\n", host);
2910 status = open_socket_out(&ss, 139, 10000, &fd);
2911 if (!NT_STATUS_IS_OK(status)) {
2912 d_fprintf(stderr, "open_socket_out failed: %s\n",
2917 ret = cli_bad_session_request(fd, &calling, &called);
2920 d_fprintf(stderr, "open_socket_out failed: %s\n",
2925 printf("finished bad nbt session test\n");
2929 /* send random IPC commands */
2930 static bool run_randomipc(int dummy)
2932 char *rparam = NULL;
2934 unsigned int rdrcnt,rprcnt;
2936 int api, param_len, i;
2937 struct cli_state *cli;
2938 bool correct = True;
2941 printf("starting random ipc test\n");
2943 if (!torture_open_connection(&cli, 0)) {
2947 for (i=0;i<count;i++) {
2948 api = sys_random() % 500;
2949 param_len = (sys_random() % 64);
2951 rand_buf(param, param_len);
2956 param, param_len, 8,
2957 NULL, 0, BUFFER_SIZE,
2961 printf("%d/%d\r", i,count);
2964 printf("%d/%d\n", i, count);
2966 if (!torture_close_connection(cli)) {
2970 printf("finished random ipc test\n");
2977 static void browse_callback(const char *sname, uint32 stype,
2978 const char *comment, void *state)
2980 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2986 This test checks the browse list code
2989 static bool run_browsetest(int dummy)
2991 static struct cli_state *cli;
2992 bool correct = True;
2994 printf("starting browse test\n");
2996 if (!torture_open_connection(&cli, 0)) {
3000 printf("domain list:\n");
3001 cli_NetServerEnum(cli, cli->server_domain,
3002 SV_TYPE_DOMAIN_ENUM,
3003 browse_callback, NULL);
3005 printf("machine list:\n");
3006 cli_NetServerEnum(cli, cli->server_domain,
3008 browse_callback, NULL);
3010 if (!torture_close_connection(cli)) {
3014 printf("browse test finished\n");
3022 This checks how the getatr calls works
3024 static bool run_attrtest(int dummy)
3026 struct cli_state *cli;
3029 const char *fname = "\\attrib123456789.tst";
3030 bool correct = True;
3033 printf("starting attrib test\n");
3035 if (!torture_open_connection(&cli, 0)) {
3039 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3040 cli_open(cli, fname,
3041 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3042 cli_close(cli, fnum);
3044 status = cli_getatr(cli, fname, NULL, NULL, &t);
3045 if (!NT_STATUS_IS_OK(status)) {
3046 printf("getatr failed (%s)\n", nt_errstr(status));
3050 if (abs(t - time(NULL)) > 60*60*24*10) {
3051 printf("ERROR: SMBgetatr bug. time is %s",
3057 t2 = t-60*60*24; /* 1 day ago */
3059 status = cli_setatr(cli, fname, 0, t2);
3060 if (!NT_STATUS_IS_OK(status)) {
3061 printf("setatr failed (%s)\n", nt_errstr(status));
3065 status = cli_getatr(cli, fname, NULL, NULL, &t);
3066 if (!NT_STATUS_IS_OK(status)) {
3067 printf("getatr failed (%s)\n", nt_errstr(status));
3072 printf("ERROR: getatr/setatr bug. times are\n%s",
3074 printf("%s", ctime(&t2));
3078 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3080 if (!torture_close_connection(cli)) {
3084 printf("attrib test finished\n");
3091 This checks a couple of trans2 calls
3093 static bool run_trans2test(int dummy)
3095 struct cli_state *cli;
3098 time_t c_time, a_time, m_time;
3099 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3100 const char *fname = "\\trans2.tst";
3101 const char *dname = "\\trans2";
3102 const char *fname2 = "\\trans2\\trans2.tst";
3104 bool correct = True;
3108 printf("starting trans2 test\n");
3110 if (!torture_open_connection(&cli, 0)) {
3114 status = cli_get_fs_attr_info(cli, &fs_attr);
3115 if (!NT_STATUS_IS_OK(status)) {
3116 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3121 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3122 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3123 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3124 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3125 if (!NT_STATUS_IS_OK(status)) {
3126 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3130 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3131 if (!NT_STATUS_IS_OK(status)) {
3132 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3136 if (strcmp(pname, fname)) {
3137 printf("qfilename gave different name? [%s] [%s]\n",
3142 cli_close(cli, fnum);
3146 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3147 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3149 if (!NT_STATUS_IS_OK(status)) {
3150 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3153 cli_close(cli, fnum);
3155 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3157 if (!NT_STATUS_IS_OK(status)) {
3158 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3161 if (c_time != m_time) {
3162 printf("create time=%s", ctime(&c_time));
3163 printf("modify time=%s", ctime(&m_time));
3164 printf("This system appears to have sticky create times\n");
3166 if (a_time % (60*60) == 0) {
3167 printf("access time=%s", ctime(&a_time));
3168 printf("This system appears to set a midnight access time\n");
3172 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3173 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3179 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3180 cli_open(cli, fname,
3181 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3182 cli_close(cli, fnum);
3183 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3184 &m_time_ts, &size, NULL, NULL);
3185 if (!NT_STATUS_IS_OK(status)) {
3186 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3189 if (w_time_ts.tv_sec < 60*60*24*2) {
3190 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3191 printf("This system appears to set a initial 0 write time\n");
3196 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3199 /* check if the server updates the directory modification time
3200 when creating a new file */
3201 status = cli_mkdir(cli, dname);
3202 if (!NT_STATUS_IS_OK(status)) {
3203 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3207 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3208 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3209 if (!NT_STATUS_IS_OK(status)) {
3210 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3214 cli_open(cli, fname2,
3215 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3216 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3217 cli_close(cli, fnum);
3218 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3219 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3220 if (!NT_STATUS_IS_OK(status)) {
3221 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3224 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3226 printf("This system does not update directory modification times\n");
3230 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3231 cli_rmdir(cli, dname);
3233 if (!torture_close_connection(cli)) {
3237 printf("trans2 test finished\n");
3243 This checks new W2K calls.
3246 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3248 uint8_t *buf = NULL;
3252 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3253 pcli->max_xmit, NULL, &buf, &len);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3258 printf("qfileinfo: level %d, len = %u\n", level, len);
3259 dump_data(0, (uint8 *)buf, len);
3266 static bool run_w2ktest(int dummy)
3268 struct cli_state *cli;
3270 const char *fname = "\\w2ktest\\w2k.tst";
3272 bool correct = True;
3274 printf("starting w2k test\n");
3276 if (!torture_open_connection(&cli, 0)) {
3280 cli_open(cli, fname,
3281 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3283 for (level = 1004; level < 1040; level++) {
3284 new_trans(cli, fnum, level);
3287 cli_close(cli, fnum);
3289 if (!torture_close_connection(cli)) {
3293 printf("w2k test finished\n");
3300 this is a harness for some oplock tests
3302 static bool run_oplock1(int dummy)
3304 struct cli_state *cli1;
3305 const char *fname = "\\lockt1.lck";
3307 bool correct = True;
3310 printf("starting oplock test 1\n");
3312 if (!torture_open_connection(&cli1, 0)) {
3316 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3318 cli_sockopt(cli1, sockops);
3320 cli1->use_oplocks = True;
3322 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3324 if (!NT_STATUS_IS_OK(status)) {
3325 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3329 cli1->use_oplocks = False;
3331 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3332 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3334 status = cli_close(cli1, fnum1);
3335 if (!NT_STATUS_IS_OK(status)) {
3336 printf("close2 failed (%s)\n", nt_errstr(status));
3340 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 printf("unlink failed (%s)\n", nt_errstr(status));
3346 if (!torture_close_connection(cli1)) {
3350 printf("finished oplock test 1\n");
3355 static bool run_oplock2(int dummy)
3357 struct cli_state *cli1, *cli2;
3358 const char *fname = "\\lockt2.lck";
3359 uint16_t fnum1, fnum2;
3360 int saved_use_oplocks = use_oplocks;
3362 bool correct = True;
3363 volatile bool *shared_correct;
3366 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3367 *shared_correct = True;
3369 use_level_II_oplocks = True;
3372 printf("starting oplock test 2\n");
3374 if (!torture_open_connection(&cli1, 0)) {
3375 use_level_II_oplocks = False;
3376 use_oplocks = saved_use_oplocks;
3380 cli1->use_oplocks = True;
3381 cli1->use_level_II_oplocks = True;
3383 if (!torture_open_connection(&cli2, 1)) {
3384 use_level_II_oplocks = False;
3385 use_oplocks = saved_use_oplocks;
3389 cli2->use_oplocks = True;
3390 cli2->use_level_II_oplocks = True;
3392 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3394 cli_sockopt(cli1, sockops);
3395 cli_sockopt(cli2, sockops);
3397 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3399 if (!NT_STATUS_IS_OK(status)) {
3400 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3404 /* Don't need the globals any more. */
3405 use_level_II_oplocks = False;
3406 use_oplocks = saved_use_oplocks;
3410 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3411 if (!NT_STATUS_IS_OK(status)) {
3412 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3413 *shared_correct = False;
3419 status = cli_close(cli2, fnum2);
3420 if (!NT_STATUS_IS_OK(status)) {
3421 printf("close2 failed (%s)\n", nt_errstr(status));
3422 *shared_correct = False;
3430 /* Ensure cli1 processes the break. Empty file should always return 0
3433 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3434 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3438 /* Should now be at level II. */
3439 /* Test if sending a write locks causes a break to none. */
3441 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3442 printf("lock failed (%s)\n", cli_errstr(cli1));
3446 cli_unlock(cli1, fnum1, 0, 4);
3450 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3451 printf("lock failed (%s)\n", cli_errstr(cli1));
3455 cli_unlock(cli1, fnum1, 0, 4);
3459 cli_read(cli1, fnum1, buf, 0, 4);
3461 status = cli_close(cli1, fnum1);
3462 if (!NT_STATUS_IS_OK(status)) {
3463 printf("close1 failed (%s)\n", nt_errstr(status));
3469 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3470 if (!NT_STATUS_IS_OK(status)) {
3471 printf("unlink failed (%s)\n", nt_errstr(status));
3475 if (!torture_close_connection(cli1)) {
3479 if (!*shared_correct) {
3483 printf("finished oplock test 2\n");
3488 struct oplock4_state {
3489 struct tevent_context *ev;
3490 struct cli_state *cli;
3495 static void oplock4_got_break(struct tevent_req *req);
3496 static void oplock4_got_open(struct tevent_req *req);
3498 static bool run_oplock4(int dummy)
3500 struct tevent_context *ev;
3501 struct cli_state *cli1, *cli2;
3502 struct tevent_req *oplock_req, *open_req;
3503 const char *fname = "\\lockt4.lck";
3504 const char *fname_ln = "\\lockt4_ln.lck";
3505 uint16_t fnum1, fnum2;
3506 int saved_use_oplocks = use_oplocks;
3508 bool correct = true;
3512 struct oplock4_state *state;
3514 printf("starting oplock test 4\n");
3516 if (!torture_open_connection(&cli1, 0)) {
3517 use_level_II_oplocks = false;
3518 use_oplocks = saved_use_oplocks;
3522 if (!torture_open_connection(&cli2, 1)) {
3523 use_level_II_oplocks = false;
3524 use_oplocks = saved_use_oplocks;
3528 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3529 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3531 cli_sockopt(cli1, sockops);
3532 cli_sockopt(cli2, sockops);
3534 /* Create the file. */
3535 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3537 if (!NT_STATUS_IS_OK(status)) {
3538 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3542 status = cli_close(cli1, fnum1);
3543 if (!NT_STATUS_IS_OK(status)) {
3544 printf("close1 failed (%s)\n", nt_errstr(status));
3548 /* Now create a hardlink. */
3549 status = cli_nt_hardlink(cli1, fname, fname_ln);
3550 if (!NT_STATUS_IS_OK(status)) {
3551 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3555 /* Prove that opening hardlinks cause deny modes to conflict. */
3556 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3557 if (!NT_STATUS_IS_OK(status)) {
3558 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3562 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3563 if (NT_STATUS_IS_OK(status)) {
3564 printf("open of %s succeeded - should fail with sharing violation.\n",
3569 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3570 printf("open of %s should fail with sharing violation. Got %s\n",
3571 fname_ln, nt_errstr(status));
3575 status = cli_close(cli1, fnum1);
3576 if (!NT_STATUS_IS_OK(status)) {
3577 printf("close1 failed (%s)\n", nt_errstr(status));
3581 cli1->use_oplocks = true;
3582 cli1->use_level_II_oplocks = true;
3584 cli2->use_oplocks = true;
3585 cli2->use_level_II_oplocks = true;
3587 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3588 if (!NT_STATUS_IS_OK(status)) {
3589 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3593 ev = tevent_context_init(talloc_tos());
3595 printf("tevent_req_create failed\n");
3599 state = talloc(ev, struct oplock4_state);
3600 if (state == NULL) {
3601 printf("talloc failed\n");
3606 state->got_break = &got_break;
3607 state->fnum2 = &fnum2;
3609 oplock_req = cli_smb_oplock_break_waiter_send(
3610 talloc_tos(), ev, cli1);
3611 if (oplock_req == NULL) {
3612 printf("cli_smb_oplock_break_waiter_send failed\n");
3615 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3617 open_req = cli_open_send(
3618 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3619 if (oplock_req == NULL) {
3620 printf("cli_open_send failed\n");
3623 tevent_req_set_callback(open_req, oplock4_got_open, state);
3628 while (!got_break || fnum2 == 0xffff) {
3630 ret = tevent_loop_once(ev);
3632 printf("tevent_loop_once failed: %s\n",
3638 status = cli_close(cli2, fnum2);
3639 if (!NT_STATUS_IS_OK(status)) {
3640 printf("close2 failed (%s)\n", nt_errstr(status));
3644 status = cli_close(cli1, fnum1);
3645 if (!NT_STATUS_IS_OK(status)) {
3646 printf("close1 failed (%s)\n", nt_errstr(status));
3650 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3651 if (!NT_STATUS_IS_OK(status)) {
3652 printf("unlink failed (%s)\n", nt_errstr(status));
3656 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3657 if (!NT_STATUS_IS_OK(status)) {
3658 printf("unlink failed (%s)\n", nt_errstr(status));
3662 if (!torture_close_connection(cli1)) {
3670 printf("finished oplock test 4\n");
3675 static void oplock4_got_break(struct tevent_req *req)
3677 struct oplock4_state *state = tevent_req_callback_data(
3678 req, struct oplock4_state);
3683 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3685 if (!NT_STATUS_IS_OK(status)) {
3686 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3690 *state->got_break = true;
3692 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3695 printf("cli_oplock_ack_send failed\n");
3700 static void oplock4_got_open(struct tevent_req *req)
3702 struct oplock4_state *state = tevent_req_callback_data(
3703 req, struct oplock4_state);
3706 status = cli_open_recv(req, state->fnum2);
3707 if (!NT_STATUS_IS_OK(status)) {
3708 printf("cli_open_recv returned %s\n", nt_errstr(status));
3709 *state->fnum2 = 0xffff;
3714 Test delete on close semantics.
3716 static bool run_deletetest(int dummy)
3718 struct cli_state *cli1 = NULL;
3719 struct cli_state *cli2 = NULL;
3720 const char *fname = "\\delete.file";
3721 uint16_t fnum1 = (uint16_t)-1;
3722 uint16_t fnum2 = (uint16_t)-1;
3723 bool correct = True;
3726 printf("starting delete test\n");
3728 if (!torture_open_connection(&cli1, 0)) {
3732 cli_sockopt(cli1, sockops);
3734 /* Test 1 - this should delete the file on close. */
3736 cli_setatr(cli1, fname, 0, 0);
3737 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3739 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3740 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3741 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3742 if (!NT_STATUS_IS_OK(status)) {
3743 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3748 status = cli_close(cli1, fnum1);
3749 if (!NT_STATUS_IS_OK(status)) {
3750 printf("[1] close failed (%s)\n", nt_errstr(status));
3755 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3756 printf("[1] open of %s succeeded (should fail)\n", fname);
3761 printf("first delete on close test succeeded.\n");
3763 /* Test 2 - this should delete the file on close. */
3765 cli_setatr(cli1, fname, 0, 0);
3766 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3768 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3769 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3770 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3771 if (!NT_STATUS_IS_OK(status)) {
3772 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3777 status = cli_nt_delete_on_close(cli1, fnum1, true);
3778 if (!NT_STATUS_IS_OK(status)) {
3779 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3784 status = cli_close(cli1, fnum1);
3785 if (!NT_STATUS_IS_OK(status)) {
3786 printf("[2] close failed (%s)\n", nt_errstr(status));
3791 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3792 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3793 status = cli_close(cli1, fnum1);
3794 if (!NT_STATUS_IS_OK(status)) {
3795 printf("[2] close failed (%s)\n", nt_errstr(status));
3799 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3801 printf("second delete on close test succeeded.\n");
3804 cli_setatr(cli1, fname, 0, 0);
3805 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3807 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3808 FILE_ATTRIBUTE_NORMAL,
3809 FILE_SHARE_READ|FILE_SHARE_WRITE,
3810 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3811 if (!NT_STATUS_IS_OK(status)) {
3812 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3817 /* This should fail with a sharing violation - open for delete is only compatible
3818 with SHARE_DELETE. */
3820 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3821 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3822 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3827 /* This should succeed. */
3828 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3829 FILE_ATTRIBUTE_NORMAL,
3830 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3831 FILE_OPEN, 0, 0, &fnum2);
3832 if (!NT_STATUS_IS_OK(status)) {
3833 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3838 status = cli_nt_delete_on_close(cli1, fnum1, true);
3839 if (!NT_STATUS_IS_OK(status)) {
3840 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3845 status = cli_close(cli1, fnum1);
3846 if (!NT_STATUS_IS_OK(status)) {
3847 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3852 status = cli_close(cli1, fnum2);
3853 if (!NT_STATUS_IS_OK(status)) {
3854 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3859 /* This should fail - file should no longer be there. */
3861 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3862 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3863 status = cli_close(cli1, fnum1);
3864 if (!NT_STATUS_IS_OK(status)) {
3865 printf("[3] close failed (%s)\n", nt_errstr(status));
3867 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3871 printf("third delete on close test succeeded.\n");
3874 cli_setatr(cli1, fname, 0, 0);
3875 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3877 status = cli_ntcreate(cli1, fname, 0,
3878 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3879 FILE_ATTRIBUTE_NORMAL,
3880 FILE_SHARE_READ|FILE_SHARE_WRITE,
3881 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3882 if (!NT_STATUS_IS_OK(status)) {
3883 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
3888 /* This should succeed. */
3889 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3890 FILE_ATTRIBUTE_NORMAL,
3891 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3892 FILE_OPEN, 0, 0, &fnum2);
3893 if (!NT_STATUS_IS_OK(status)) {
3894 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3899 status = cli_close(cli1, fnum2);
3900 if (!NT_STATUS_IS_OK(status)) {
3901 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
3906 status = cli_nt_delete_on_close(cli1, fnum1, true);
3907 if (!NT_STATUS_IS_OK(status)) {
3908 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
3913 /* This should fail - no more opens once delete on close set. */
3914 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3915 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3916 FILE_OPEN, 0, 0, &fnum2))) {
3917 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3921 printf("fourth delete on close test succeeded.\n");
3923 status = cli_close(cli1, fnum1);
3924 if (!NT_STATUS_IS_OK(status)) {
3925 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
3931 cli_setatr(cli1, fname, 0, 0);
3932 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3934 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
3935 if (!NT_STATUS_IS_OK(status)) {
3936 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
3941 /* This should fail - only allowed on NT opens with DELETE access. */
3943 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3944 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3949 status = cli_close(cli1, fnum1);
3950 if (!NT_STATUS_IS_OK(status)) {
3951 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
3956 printf("fifth delete on close test succeeded.\n");
3959 cli_setatr(cli1, fname, 0, 0);
3960 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3962 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3963 FILE_ATTRIBUTE_NORMAL,
3964 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3965 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3966 if (!NT_STATUS_IS_OK(status)) {
3967 printf("[6] open of %s failed (%s)\n", fname,
3973 /* This should fail - only allowed on NT opens with DELETE access. */
3975 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3976 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3981 status = cli_close(cli1, fnum1);
3982 if (!NT_STATUS_IS_OK(status)) {
3983 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
3988 printf("sixth delete on close test succeeded.\n");
3991 cli_setatr(cli1, fname, 0, 0);
3992 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3994 status = cli_ntcreate(cli1, fname, 0,
3995 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3996 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3998 if (!NT_STATUS_IS_OK(status)) {
3999 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4004 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4005 printf("[7] setting delete_on_close on file failed !\n");
4010 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4011 printf("[7] unsetting delete_on_close on file failed !\n");
4016 status = cli_close(cli1, fnum1);
4017 if (!NT_STATUS_IS_OK(status)) {
4018 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4023 /* This next open should succeed - we reset the flag. */
4024 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4025 if (!NT_STATUS_IS_OK(status)) {
4026 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4031 status = cli_close(cli1, fnum1);
4032 if (!NT_STATUS_IS_OK(status)) {
4033 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4038 printf("seventh delete on close test succeeded.\n");
4041 cli_setatr(cli1, fname, 0, 0);
4042 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4044 if (!torture_open_connection(&cli2, 1)) {
4045 printf("[8] failed to open second connection.\n");
4050 cli_sockopt(cli1, sockops);
4052 status = cli_ntcreate(cli1, fname, 0,
4053 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4054 FILE_ATTRIBUTE_NORMAL,
4055 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4056 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4063 status = cli_ntcreate(cli2, fname, 0,
4064 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4065 FILE_ATTRIBUTE_NORMAL,
4066 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4067 FILE_OPEN, 0, 0, &fnum2);
4068 if (!NT_STATUS_IS_OK(status)) {
4069 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4074 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4075 printf("[8] setting delete_on_close on file failed !\n");
4080 status = cli_close(cli1, fnum1);
4081 if (!NT_STATUS_IS_OK(status)) {
4082 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4087 status = cli_close(cli2, fnum2);
4088 if (!NT_STATUS_IS_OK(status)) {
4089 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4094 /* This should fail.. */
4095 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4096 if (NT_STATUS_IS_OK(status)) {
4097 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4101 printf("eighth delete on close test succeeded.\n");
4103 /* This should fail - we need to set DELETE_ACCESS. */
4104 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4105 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4106 printf("[9] open of %s succeeded should have failed!\n", fname);
4111 printf("ninth delete on close test succeeded.\n");
4113 status = cli_ntcreate(cli1, fname, 0,
4114 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4115 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4116 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4118 if (!NT_STATUS_IS_OK(status)) {
4119 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4124 /* This should delete the file. */
4125 status = cli_close(cli1, fnum1);
4126 if (!NT_STATUS_IS_OK(status)) {
4127 printf("[10] close failed (%s)\n", nt_errstr(status));
4132 /* This should fail.. */
4133 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4134 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4138 printf("tenth delete on close test succeeded.\n");
4140 cli_setatr(cli1, fname, 0, 0);
4141 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4143 /* What error do we get when attempting to open a read-only file with
4146 /* Create a readonly file. */
4147 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4148 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4149 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4150 if (!NT_STATUS_IS_OK(status)) {
4151 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4156 status = cli_close(cli1, fnum1);
4157 if (!NT_STATUS_IS_OK(status)) {
4158 printf("[11] close failed (%s)\n", nt_errstr(status));
4163 /* Now try open for delete access. */
4164 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4165 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4166 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4167 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4168 cli_close(cli1, fnum1);
4172 NTSTATUS nterr = cli_nt_error(cli1);
4173 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4174 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4178 printf("eleventh delete on close test succeeded.\n");
4182 printf("finished delete test\n");
4185 /* FIXME: This will crash if we aborted before cli2 got
4186 * intialized, because these functions don't handle
4187 * uninitialized connections. */
4189 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4190 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4191 cli_setatr(cli1, fname, 0, 0);
4192 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4194 if (cli1 && !torture_close_connection(cli1)) {
4197 if (cli2 && !torture_close_connection(cli2)) {
4203 static bool run_deletetest_ln(int dummy)
4205 struct cli_state *cli;
4206 const char *fname = "\\delete1";
4207 const char *fname_ln = "\\delete1_ln";
4211 bool correct = true;
4214 printf("starting deletetest-ln\n");
4216 if (!torture_open_connection(&cli, 0)) {
4220 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4221 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4223 cli_sockopt(cli, sockops);
4225 /* Create the file. */
4226 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4227 if (!NT_STATUS_IS_OK(status)) {
4228 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4232 status = cli_close(cli, fnum);
4233 if (!NT_STATUS_IS_OK(status)) {
4234 printf("close1 failed (%s)\n", nt_errstr(status));
4238 /* Now create a hardlink. */
4239 status = cli_nt_hardlink(cli, fname, fname_ln);
4240 if (!NT_STATUS_IS_OK(status)) {
4241 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4245 /* Open the original file. */
4246 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4247 FILE_ATTRIBUTE_NORMAL,
4248 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4249 FILE_OPEN_IF, 0, 0, &fnum);
4250 if (!NT_STATUS_IS_OK(status)) {
4251 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4255 /* Unlink the hard link path. */
4256 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4257 FILE_ATTRIBUTE_NORMAL,
4258 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4259 FILE_OPEN_IF, 0, 0, &fnum1);
4260 if (!NT_STATUS_IS_OK(status)) {
4261 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4264 status = cli_nt_delete_on_close(cli, fnum1, true);
4265 if (!NT_STATUS_IS_OK(status)) {
4266 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4267 __location__, fname_ln, nt_errstr(status));
4271 status = cli_close(cli, fnum1);
4272 if (!NT_STATUS_IS_OK(status)) {
4273 printf("close %s failed (%s)\n",
4274 fname_ln, nt_errstr(status));
4278 status = cli_close(cli, fnum);
4279 if (!NT_STATUS_IS_OK(status)) {
4280 printf("close %s failed (%s)\n",
4281 fname, nt_errstr(status));
4285 /* Ensure the original file is still there. */
4286 status = cli_getatr(cli, fname, NULL, NULL, &t);
4287 if (!NT_STATUS_IS_OK(status)) {
4288 printf("%s getatr on file %s failed (%s)\n",
4295 /* Ensure the link path is gone. */
4296 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4297 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4298 printf("%s, getatr for file %s returned wrong error code %s "
4299 "- should have been deleted\n",
4301 fname_ln, nt_errstr(status));
4305 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4306 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4308 if (!torture_close_connection(cli)) {
4312 printf("finished deletetest-ln\n");
4318 print out server properties
4320 static bool run_properties(int dummy)
4322 struct cli_state *cli;
4323 bool correct = True;
4325 printf("starting properties test\n");
4329 if (!torture_open_connection(&cli, 0)) {
4333 cli_sockopt(cli, sockops);
4335 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4337 if (!torture_close_connection(cli)) {
4346 /* FIRST_DESIRED_ACCESS 0xf019f */
4347 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4348 FILE_READ_EA| /* 0xf */ \
4349 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4350 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4351 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4352 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4353 /* SECOND_DESIRED_ACCESS 0xe0080 */
4354 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4355 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4356 WRITE_OWNER_ACCESS /* 0xe0000 */
4359 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4360 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4362 WRITE_OWNER_ACCESS /* */
4366 Test ntcreate calls made by xcopy
4368 static bool run_xcopy(int dummy)
4370 static struct cli_state *cli1;
4371 const char *fname = "\\test.txt";
4372 bool correct = True;
4373 uint16_t fnum1, fnum2;
4376 printf("starting xcopy test\n");
4378 if (!torture_open_connection(&cli1, 0)) {
4382 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4383 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4384 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4385 if (!NT_STATUS_IS_OK(status)) {
4386 printf("First open failed - %s\n", nt_errstr(status));
4390 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4391 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4392 FILE_OPEN, 0x200000, 0, &fnum2);
4393 if (!NT_STATUS_IS_OK(status)) {
4394 printf("second open failed - %s\n", nt_errstr(status));
4398 if (!torture_close_connection(cli1)) {
4406 Test rename on files open with share delete and no share delete.
4408 static bool run_rename(int dummy)
4410 static struct cli_state *cli1;
4411 const char *fname = "\\test.txt";
4412 const char *fname1 = "\\test1.txt";
4413 bool correct = True;
4418 printf("starting rename test\n");
4420 if (!torture_open_connection(&cli1, 0)) {
4424 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4425 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4427 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4428 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4429 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4430 if (!NT_STATUS_IS_OK(status)) {
4431 printf("First open failed - %s\n", nt_errstr(status));
4435 status = cli_rename(cli1, fname, fname1);
4436 if (!NT_STATUS_IS_OK(status)) {
4437 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4439 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4443 status = cli_close(cli1, fnum1);
4444 if (!NT_STATUS_IS_OK(status)) {
4445 printf("close - 1 failed (%s)\n", nt_errstr(status));
4449 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4450 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4451 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4453 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4455 FILE_SHARE_DELETE|FILE_SHARE_READ,
4457 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4458 if (!NT_STATUS_IS_OK(status)) {
4459 printf("Second open failed - %s\n", nt_errstr(status));
4463 status = cli_rename(cli1, fname, fname1);
4464 if (!NT_STATUS_IS_OK(status)) {
4465 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4468 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4471 status = cli_close(cli1, fnum1);
4472 if (!NT_STATUS_IS_OK(status)) {
4473 printf("close - 2 failed (%s)\n", nt_errstr(status));
4477 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4478 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4480 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4481 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4482 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4483 if (!NT_STATUS_IS_OK(status)) {
4484 printf("Third open failed - %s\n", nt_errstr(status));
4493 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4494 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4495 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4498 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4499 printf("[8] setting delete_on_close on file failed !\n");
4503 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4504 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4510 status = cli_rename(cli1, fname, fname1);
4511 if (!NT_STATUS_IS_OK(status)) {
4512 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4515 printf("Third rename succeeded (SHARE_NONE)\n");
4518 status = cli_close(cli1, fnum1);
4519 if (!NT_STATUS_IS_OK(status)) {
4520 printf("close - 3 failed (%s)\n", nt_errstr(status));
4524 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4525 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4529 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4530 FILE_ATTRIBUTE_NORMAL,
4531 FILE_SHARE_READ | FILE_SHARE_WRITE,
4532 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4533 if (!NT_STATUS_IS_OK(status)) {
4534 printf("Fourth open failed - %s\n", nt_errstr(status));
4538 status = cli_rename(cli1, fname, fname1);
4539 if (!NT_STATUS_IS_OK(status)) {
4540 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4542 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4546 status = cli_close(cli1, fnum1);
4547 if (!NT_STATUS_IS_OK(status)) {
4548 printf("close - 4 failed (%s)\n", nt_errstr(status));
4552 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4553 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4557 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4558 FILE_ATTRIBUTE_NORMAL,
4559 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4560 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4561 if (!NT_STATUS_IS_OK(status)) {
4562 printf("Fifth open failed - %s\n", nt_errstr(status));
4566 status = cli_rename(cli1, fname, fname1);
4567 if (!NT_STATUS_IS_OK(status)) {
4568 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4571 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4575 * Now check if the first name still exists ...
4578 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4579 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4580 printf("Opening original file after rename of open file fails: %s\n",
4584 printf("Opening original file after rename of open file works ...\n");
4585 (void)cli_close(cli1, fnum2);
4589 status = cli_close(cli1, fnum1);
4590 if (!NT_STATUS_IS_OK(status)) {
4591 printf("close - 5 failed (%s)\n", nt_errstr(status));
4595 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4596 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4597 if (!NT_STATUS_IS_OK(status)) {
4598 printf("getatr on file %s failed - %s ! \n",
4599 fname1, nt_errstr(status));
4602 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4603 printf("Renamed file %s has wrong attr 0x%x "
4604 "(should be 0x%x)\n",
4607 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4610 printf("Renamed file %s has archive bit set\n", fname1);
4614 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4615 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4617 if (!torture_close_connection(cli1)) {
4624 static bool run_pipe_number(int dummy)
4626 struct cli_state *cli1;
4627 const char *pipe_name = "\\SPOOLSS";
4632 printf("starting pipenumber test\n");
4633 if (!torture_open_connection(&cli1, 0)) {
4637 cli_sockopt(cli1, sockops);
4639 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4640 FILE_ATTRIBUTE_NORMAL,
4641 FILE_SHARE_READ|FILE_SHARE_WRITE,
4642 FILE_OPEN_IF, 0, 0, &fnum);
4643 if (!NT_STATUS_IS_OK(status)) {
4644 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4648 printf("\r%6d", num_pipes);
4651 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4652 torture_close_connection(cli1);
4657 Test open mode returns on read-only files.
4659 static bool run_opentest(int dummy)
4661 static struct cli_state *cli1;
4662 static struct cli_state *cli2;
4663 const char *fname = "\\readonly.file";
4664 uint16_t fnum1, fnum2;
4667 bool correct = True;
4671 printf("starting open test\n");
4673 if (!torture_open_connection(&cli1, 0)) {
4677 cli_setatr(cli1, fname, 0, 0);
4678 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4680 cli_sockopt(cli1, sockops);
4682 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4683 if (!NT_STATUS_IS_OK(status)) {
4684 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4688 status = cli_close(cli1, fnum1);
4689 if (!NT_STATUS_IS_OK(status)) {
4690 printf("close2 failed (%s)\n", nt_errstr(status));
4694 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4695 if (!NT_STATUS_IS_OK(status)) {
4696 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4700 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4701 if (!NT_STATUS_IS_OK(status)) {
4702 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4706 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4707 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4709 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4710 NT_STATUS_ACCESS_DENIED)) {
4711 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4714 printf("finished open test 1\n");
4716 cli_close(cli1, fnum1);
4718 /* Now try not readonly and ensure ERRbadshare is returned. */
4720 cli_setatr(cli1, fname, 0, 0);
4722 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4723 if (!NT_STATUS_IS_OK(status)) {
4724 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4728 /* This will fail - but the error should be ERRshare. */
4729 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4731 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4732 NT_STATUS_SHARING_VIOLATION)) {
4733 printf("correct error code ERRDOS/ERRbadshare returned\n");
4736 status = cli_close(cli1, fnum1);
4737 if (!NT_STATUS_IS_OK(status)) {
4738 printf("close2 failed (%s)\n", nt_errstr(status));
4742 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4744 printf("finished open test 2\n");
4746 /* Test truncate open disposition on file opened for read. */
4747 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4748 if (!NT_STATUS_IS_OK(status)) {
4749 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4753 /* write 20 bytes. */
4755 memset(buf, '\0', 20);
4757 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4758 if (!NT_STATUS_IS_OK(status)) {
4759 printf("write failed (%s)\n", nt_errstr(status));
4763 status = cli_close(cli1, fnum1);
4764 if (!NT_STATUS_IS_OK(status)) {
4765 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4769 /* Ensure size == 20. */
4770 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4771 if (!NT_STATUS_IS_OK(status)) {
4772 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4777 printf("(3) file size != 20\n");
4781 /* Now test if we can truncate a file opened for readonly. */
4782 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4783 if (!NT_STATUS_IS_OK(status)) {
4784 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4788 status = cli_close(cli1, fnum1);
4789 if (!NT_STATUS_IS_OK(status)) {
4790 printf("close2 failed (%s)\n", nt_errstr(status));
4794 /* Ensure size == 0. */
4795 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4796 if (!NT_STATUS_IS_OK(status)) {
4797 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4802 printf("(3) file size != 0\n");
4805 printf("finished open test 3\n");
4807 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4809 printf("Do ctemp tests\n");
4810 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4811 if (!NT_STATUS_IS_OK(status)) {
4812 printf("ctemp failed (%s)\n", nt_errstr(status));
4816 printf("ctemp gave path %s\n", tmp_path);
4817 status = cli_close(cli1, fnum1);
4818 if (!NT_STATUS_IS_OK(status)) {
4819 printf("close of temp failed (%s)\n", nt_errstr(status));
4822 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4823 if (!NT_STATUS_IS_OK(status)) {
4824 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4827 /* Test the non-io opens... */
4829 if (!torture_open_connection(&cli2, 1)) {
4833 cli_setatr(cli2, fname, 0, 0);
4834 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4836 cli_sockopt(cli2, sockops);
4838 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4839 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4840 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4841 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4842 if (!NT_STATUS_IS_OK(status)) {
4843 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4847 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4848 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4849 FILE_OPEN_IF, 0, 0, &fnum2);
4850 if (!NT_STATUS_IS_OK(status)) {
4851 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4855 status = cli_close(cli1, fnum1);
4856 if (!NT_STATUS_IS_OK(status)) {
4857 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4861 status = cli_close(cli2, fnum2);
4862 if (!NT_STATUS_IS_OK(status)) {
4863 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4867 printf("non-io open test #1 passed.\n");
4869 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4871 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4873 status = cli_ntcreate(cli1, fname, 0,
4874 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4875 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4876 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4877 if (!NT_STATUS_IS_OK(status)) {
4878 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4882 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4883 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4884 FILE_OPEN_IF, 0, 0, &fnum2);
4885 if (!NT_STATUS_IS_OK(status)) {
4886 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4890 status = cli_close(cli1, fnum1);
4891 if (!NT_STATUS_IS_OK(status)) {
4892 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4896 status = cli_close(cli2, fnum2);
4897 if (!NT_STATUS_IS_OK(status)) {
4898 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4902 printf("non-io open test #2 passed.\n");
4904 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4906 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4908 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4909 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4910 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4911 if (!NT_STATUS_IS_OK(status)) {
4912 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4916 status = cli_ntcreate(cli2, fname, 0,
4917 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4918 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4919 FILE_OPEN_IF, 0, 0, &fnum2);
4920 if (!NT_STATUS_IS_OK(status)) {
4921 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4925 status = cli_close(cli1, fnum1);
4926 if (!NT_STATUS_IS_OK(status)) {
4927 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4931 status = cli_close(cli2, fnum2);
4932 if (!NT_STATUS_IS_OK(status)) {
4933 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4937 printf("non-io open test #3 passed.\n");
4939 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4941 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4943 status = cli_ntcreate(cli1, fname, 0,
4944 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4945 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4946 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4947 if (!NT_STATUS_IS_OK(status)) {
4948 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4952 status = cli_ntcreate(cli2, fname, 0,
4953 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4954 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4955 FILE_OPEN_IF, 0, 0, &fnum2);
4956 if (NT_STATUS_IS_OK(status)) {
4957 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
4961 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
4963 status = cli_close(cli1, fnum1);
4964 if (!NT_STATUS_IS_OK(status)) {
4965 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4969 printf("non-io open test #4 passed.\n");
4971 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4973 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4975 status = cli_ntcreate(cli1, fname, 0,
4976 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4977 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
4978 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4979 if (!NT_STATUS_IS_OK(status)) {
4980 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4984 status = cli_ntcreate(cli2, fname, 0,
4985 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4986 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
4987 FILE_OPEN_IF, 0, 0, &fnum2);
4988 if (!NT_STATUS_IS_OK(status)) {
4989 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4993 status = cli_close(cli1, fnum1);
4994 if (!NT_STATUS_IS_OK(status)) {
4995 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4999 status = cli_close(cli2, fnum2);
5000 if (!NT_STATUS_IS_OK(status)) {
5001 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5005 printf("non-io open test #5 passed.\n");
5007 printf("TEST #6 testing 1 non-io open, one io open\n");
5009 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5011 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5012 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5013 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5014 if (!NT_STATUS_IS_OK(status)) {
5015 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5019 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5020 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5021 FILE_OPEN_IF, 0, 0, &fnum2);
5022 if (!NT_STATUS_IS_OK(status)) {
5023 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5027 status = cli_close(cli1, fnum1);
5028 if (!NT_STATUS_IS_OK(status)) {
5029 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5033 status = cli_close(cli2, fnum2);
5034 if (!NT_STATUS_IS_OK(status)) {
5035 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5039 printf("non-io open test #6 passed.\n");
5041 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5043 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5045 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5046 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5047 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5048 if (!NT_STATUS_IS_OK(status)) {
5049 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5053 status = cli_ntcreate(cli2, fname, 0,
5054 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5055 FILE_ATTRIBUTE_NORMAL,
5056 FILE_SHARE_READ|FILE_SHARE_DELETE,
5057 FILE_OPEN_IF, 0, 0, &fnum2);
5058 if (NT_STATUS_IS_OK(status)) {
5059 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5063 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5065 status = cli_close(cli1, fnum1);
5066 if (!NT_STATUS_IS_OK(status)) {
5067 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5071 printf("non-io open test #7 passed.\n");
5073 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5075 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5076 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5077 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5078 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5079 if (!NT_STATUS_IS_OK(status)) {
5080 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5085 /* Write to ensure we have to update the file time. */
5086 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5088 if (!NT_STATUS_IS_OK(status)) {
5089 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5094 status = cli_close(cli1, fnum1);
5095 if (!NT_STATUS_IS_OK(status)) {
5096 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5102 if (!torture_close_connection(cli1)) {
5105 if (!torture_close_connection(cli2)) {
5112 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5114 uint16 major, minor;
5115 uint32 caplow, caphigh;
5118 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5119 printf("Server doesn't support UNIX CIFS extensions.\n");
5120 return NT_STATUS_NOT_SUPPORTED;
5123 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5125 if (!NT_STATUS_IS_OK(status)) {
5126 printf("Server didn't return UNIX CIFS extensions: %s\n",
5131 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5133 if (!NT_STATUS_IS_OK(status)) {
5134 printf("Server doesn't support setting UNIX CIFS extensions: "
5135 "%s.\n", nt_errstr(status));
5139 return NT_STATUS_OK;
5143 Test POSIX open /mkdir calls.
5145 static bool run_simple_posix_open_test(int dummy)
5147 static struct cli_state *cli1;
5148 const char *fname = "posix:file";
5149 const char *hname = "posix:hlink";
5150 const char *sname = "posix:symlink";
5151 const char *dname = "posix:dir";
5154 uint16_t fnum1 = (uint16_t)-1;
5155 SMB_STRUCT_STAT sbuf;
5156 bool correct = false;
5159 printf("Starting simple POSIX open test\n");
5161 if (!torture_open_connection(&cli1, 0)) {
5165 cli_sockopt(cli1, sockops);
5167 status = torture_setup_unix_extensions(cli1);
5168 if (!NT_STATUS_IS_OK(status)) {
5172 cli_setatr(cli1, fname, 0, 0);
5173 cli_posix_unlink(cli1, fname);
5174 cli_setatr(cli1, dname, 0, 0);
5175 cli_posix_rmdir(cli1, dname);
5176 cli_setatr(cli1, hname, 0, 0);
5177 cli_posix_unlink(cli1, hname);
5178 cli_setatr(cli1, sname, 0, 0);
5179 cli_posix_unlink(cli1, sname);
5181 /* Create a directory. */
5182 status = cli_posix_mkdir(cli1, dname, 0777);
5183 if (!NT_STATUS_IS_OK(status)) {
5184 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5188 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5190 if (!NT_STATUS_IS_OK(status)) {
5191 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5195 /* Test ftruncate - set file size. */
5196 status = cli_ftruncate(cli1, fnum1, 1000);
5197 if (!NT_STATUS_IS_OK(status)) {
5198 printf("ftruncate failed (%s)\n", nt_errstr(status));
5202 /* Ensure st_size == 1000 */
5203 status = cli_posix_stat(cli1, fname, &sbuf);
5204 if (!NT_STATUS_IS_OK(status)) {
5205 printf("stat failed (%s)\n", nt_errstr(status));
5209 if (sbuf.st_ex_size != 1000) {
5210 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5214 /* Test ftruncate - set file size back to zero. */
5215 status = cli_ftruncate(cli1, fnum1, 0);
5216 if (!NT_STATUS_IS_OK(status)) {
5217 printf("ftruncate failed (%s)\n", nt_errstr(status));
5221 status = cli_close(cli1, fnum1);
5222 if (!NT_STATUS_IS_OK(status)) {
5223 printf("close failed (%s)\n", nt_errstr(status));
5227 /* Now open the file again for read only. */
5228 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5229 if (!NT_STATUS_IS_OK(status)) {
5230 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5234 /* Now unlink while open. */
5235 status = cli_posix_unlink(cli1, fname);
5236 if (!NT_STATUS_IS_OK(status)) {
5237 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5241 status = cli_close(cli1, fnum1);
5242 if (!NT_STATUS_IS_OK(status)) {
5243 printf("close(2) failed (%s)\n", nt_errstr(status));
5247 /* Ensure the file has gone. */
5248 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5249 if (NT_STATUS_IS_OK(status)) {
5250 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5254 /* Create again to test open with O_TRUNC. */
5255 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5256 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5260 /* Test ftruncate - set file size. */
5261 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5262 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5266 /* Ensure st_size == 1000 */
5267 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5268 printf("stat failed (%s)\n", cli_errstr(cli1));
5272 if (sbuf.st_ex_size != 1000) {
5273 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5277 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5278 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5282 /* Re-open with O_TRUNC. */
5283 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5284 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5288 /* Ensure st_size == 0 */
5289 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5290 printf("stat failed (%s)\n", cli_errstr(cli1));
5294 if (sbuf.st_ex_size != 0) {
5295 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5299 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5300 printf("close failed (%s)\n", cli_errstr(cli1));
5304 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5305 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5309 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5310 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5311 dname, cli_errstr(cli1));
5315 cli_close(cli1, fnum1);
5317 /* What happens when we try and POSIX open a directory for write ? */
5318 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5319 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5322 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5323 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5328 /* Create the file. */
5329 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5331 if (!NT_STATUS_IS_OK(status)) {
5332 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5336 /* Write some data into it. */
5337 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5339 if (!NT_STATUS_IS_OK(status)) {
5340 printf("cli_write failed: %s\n", nt_errstr(status));
5344 cli_close(cli1, fnum1);
5346 /* Now create a hardlink. */
5347 status = cli_posix_hardlink(cli1, fname, hname);
5348 if (!NT_STATUS_IS_OK(status)) {
5349 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5353 /* Now create a symlink. */
5354 status = cli_posix_symlink(cli1, fname, sname);
5355 if (!NT_STATUS_IS_OK(status)) {
5356 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5360 /* Open the hardlink for read. */
5361 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5362 if (!NT_STATUS_IS_OK(status)) {
5363 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5367 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5368 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5372 if (memcmp(buf, "TEST DATA\n", 10)) {
5373 printf("invalid data read from hardlink\n");
5377 /* Do a POSIX lock/unlock. */
5378 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5379 if (!NT_STATUS_IS_OK(status)) {
5380 printf("POSIX lock failed %s\n", nt_errstr(status));
5384 /* Punch a hole in the locked area. */
5385 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5386 if (!NT_STATUS_IS_OK(status)) {
5387 printf("POSIX unlock failed %s\n", nt_errstr(status));
5391 cli_close(cli1, fnum1);
5393 /* Open the symlink for read - this should fail. A POSIX
5394 client should not be doing opens on a symlink. */
5395 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5396 if (NT_STATUS_IS_OK(status)) {
5397 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5400 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5401 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5402 printf("POSIX open of %s should have failed "
5403 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5404 "failed with %s instead.\n",
5405 sname, nt_errstr(status));
5410 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5411 if (!NT_STATUS_IS_OK(status)) {
5412 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5416 if (strcmp(namebuf, fname) != 0) {
5417 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5418 sname, fname, namebuf);
5422 status = cli_posix_rmdir(cli1, dname);
5423 if (!NT_STATUS_IS_OK(status)) {
5424 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5428 printf("Simple POSIX open test passed\n");
5433 if (fnum1 != (uint16_t)-1) {
5434 cli_close(cli1, fnum1);
5435 fnum1 = (uint16_t)-1;
5438 cli_setatr(cli1, sname, 0, 0);
5439 cli_posix_unlink(cli1, sname);
5440 cli_setatr(cli1, hname, 0, 0);
5441 cli_posix_unlink(cli1, hname);
5442 cli_setatr(cli1, fname, 0, 0);
5443 cli_posix_unlink(cli1, fname);
5444 cli_setatr(cli1, dname, 0, 0);
5445 cli_posix_rmdir(cli1, dname);
5447 if (!torture_close_connection(cli1)) {
5455 static uint32 open_attrs_table[] = {
5456 FILE_ATTRIBUTE_NORMAL,
5457 FILE_ATTRIBUTE_ARCHIVE,
5458 FILE_ATTRIBUTE_READONLY,
5459 FILE_ATTRIBUTE_HIDDEN,
5460 FILE_ATTRIBUTE_SYSTEM,
5462 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5463 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5464 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5465 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5466 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5467 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5469 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5470 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5471 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5472 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5475 struct trunc_open_results {
5482 static struct trunc_open_results attr_results[] = {
5483 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5484 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5485 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5486 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5487 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5488 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5489 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5490 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5491 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5492 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5493 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5494 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5495 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5496 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5497 { 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 },
5498 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5499 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5500 { 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 },
5501 { 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 },
5502 { 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 },
5503 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5504 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5505 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5506 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5507 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5508 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5511 static bool run_openattrtest(int dummy)
5513 static struct cli_state *cli1;
5514 const char *fname = "\\openattr.file";
5516 bool correct = True;
5518 unsigned int i, j, k, l;
5521 printf("starting open attr test\n");
5523 if (!torture_open_connection(&cli1, 0)) {
5527 cli_sockopt(cli1, sockops);
5529 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5530 cli_setatr(cli1, fname, 0, 0);
5531 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5533 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5534 open_attrs_table[i], FILE_SHARE_NONE,
5535 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5536 if (!NT_STATUS_IS_OK(status)) {
5537 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5541 status = cli_close(cli1, fnum1);
5542 if (!NT_STATUS_IS_OK(status)) {
5543 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5547 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5548 status = cli_ntcreate(cli1, fname, 0,
5549 FILE_READ_DATA|FILE_WRITE_DATA,
5550 open_attrs_table[j],
5551 FILE_SHARE_NONE, FILE_OVERWRITE,
5553 if (!NT_STATUS_IS_OK(status)) {
5554 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5555 if (attr_results[l].num == k) {
5556 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5557 k, open_attrs_table[i],
5558 open_attrs_table[j],
5559 fname, NT_STATUS_V(status), nt_errstr(status));
5564 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5565 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5566 k, open_attrs_table[i], open_attrs_table[j],
5571 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5577 status = cli_close(cli1, fnum1);
5578 if (!NT_STATUS_IS_OK(status)) {
5579 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5583 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5584 if (!NT_STATUS_IS_OK(status)) {
5585 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5590 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5591 k, open_attrs_table[i], open_attrs_table[j], attr );
5594 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5595 if (attr_results[l].num == k) {
5596 if (attr != attr_results[l].result_attr ||
5597 open_attrs_table[i] != attr_results[l].init_attr ||
5598 open_attrs_table[j] != attr_results[l].trunc_attr) {
5599 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5600 open_attrs_table[i],
5601 open_attrs_table[j],
5603 attr_results[l].result_attr);
5613 cli_setatr(cli1, fname, 0, 0);
5614 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5616 printf("open attr test %s.\n", correct ? "passed" : "failed");
5618 if (!torture_close_connection(cli1)) {
5624 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5625 const char *name, void *state)
5627 int *matched = (int *)state;
5628 if (matched != NULL) {
5631 return NT_STATUS_OK;
5635 test directory listing speed
5637 static bool run_dirtest(int dummy)
5640 static struct cli_state *cli;
5642 struct timeval core_start;
5643 bool correct = True;
5646 printf("starting directory test\n");
5648 if (!torture_open_connection(&cli, 0)) {
5652 cli_sockopt(cli, sockops);
5655 for (i=0;i<torture_numops;i++) {
5657 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5658 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5659 fprintf(stderr,"Failed to open %s\n", fname);
5662 cli_close(cli, fnum);
5665 core_start = timeval_current();
5668 cli_list(cli, "a*.*", 0, list_fn, &matched);
5669 printf("Matched %d\n", matched);
5672 cli_list(cli, "b*.*", 0, list_fn, &matched);
5673 printf("Matched %d\n", matched);
5676 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5677 printf("Matched %d\n", matched);
5679 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5682 for (i=0;i<torture_numops;i++) {
5684 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5685 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5688 if (!torture_close_connection(cli)) {
5692 printf("finished dirtest\n");
5697 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5700 struct cli_state *pcli = (struct cli_state *)state;
5702 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5704 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5705 return NT_STATUS_OK;
5707 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5708 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5709 printf("del_fn: failed to rmdir %s\n,", fname );
5711 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5712 printf("del_fn: failed to unlink %s\n,", fname );
5714 return NT_STATUS_OK;
5719 sees what IOCTLs are supported
5721 bool torture_ioctl_test(int dummy)
5723 static struct cli_state *cli;
5724 uint16_t device, function;
5726 const char *fname = "\\ioctl.dat";
5730 if (!torture_open_connection(&cli, 0)) {
5734 printf("starting ioctl test\n");
5736 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5738 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5739 if (!NT_STATUS_IS_OK(status)) {
5740 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5744 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5745 printf("ioctl device info: %s\n", nt_errstr(status));
5747 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5748 printf("ioctl job info: %s\n", nt_errstr(status));
5750 for (device=0;device<0x100;device++) {
5751 printf("ioctl test with device = 0x%x\n", device);
5752 for (function=0;function<0x100;function++) {
5753 uint32 code = (device<<16) | function;
5755 status = cli_raw_ioctl(cli, fnum, code, &blob);
5757 if (NT_STATUS_IS_OK(status)) {
5758 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5760 data_blob_free(&blob);
5765 if (!torture_close_connection(cli)) {
5774 tries varients of chkpath
5776 bool torture_chkpath_test(int dummy)
5778 static struct cli_state *cli;
5783 if (!torture_open_connection(&cli, 0)) {
5787 printf("starting chkpath test\n");
5789 /* cleanup from an old run */
5790 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5791 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5792 cli_rmdir(cli, "\\chkpath.dir");
5794 status = cli_mkdir(cli, "\\chkpath.dir");
5795 if (!NT_STATUS_IS_OK(status)) {
5796 printf("mkdir1 failed : %s\n", nt_errstr(status));
5800 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5801 if (!NT_STATUS_IS_OK(status)) {
5802 printf("mkdir2 failed : %s\n", nt_errstr(status));
5806 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5808 if (!NT_STATUS_IS_OK(status)) {
5809 printf("open1 failed (%s)\n", nt_errstr(status));
5812 cli_close(cli, fnum);
5814 status = cli_chkpath(cli, "\\chkpath.dir");
5815 if (!NT_STATUS_IS_OK(status)) {
5816 printf("chkpath1 failed: %s\n", nt_errstr(status));
5820 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5821 if (!NT_STATUS_IS_OK(status)) {
5822 printf("chkpath2 failed: %s\n", nt_errstr(status));
5826 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5827 if (!NT_STATUS_IS_OK(status)) {
5828 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5829 NT_STATUS_NOT_A_DIRECTORY);
5831 printf("* chkpath on a file should fail\n");
5835 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5836 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5837 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5839 printf("* chkpath on a non existant file should fail\n");
5843 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5844 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5845 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5847 printf("* chkpath on a non existent component should fail\n");
5851 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5852 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5853 cli_rmdir(cli, "\\chkpath.dir");
5855 if (!torture_close_connection(cli)) {
5862 static bool run_eatest(int dummy)
5864 static struct cli_state *cli;
5865 const char *fname = "\\eatest.txt";
5866 bool correct = True;
5870 struct ea_struct *ea_list = NULL;
5871 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5874 printf("starting eatest\n");
5876 if (!torture_open_connection(&cli, 0)) {
5877 talloc_destroy(mem_ctx);
5881 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5883 status = cli_ntcreate(cli, fname, 0,
5884 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5885 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5887 if (!NT_STATUS_IS_OK(status)) {
5888 printf("open failed - %s\n", nt_errstr(status));
5889 talloc_destroy(mem_ctx);
5893 for (i = 0; i < 10; i++) {
5894 fstring ea_name, ea_val;
5896 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5897 memset(ea_val, (char)i+1, i+1);
5898 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5899 if (!NT_STATUS_IS_OK(status)) {
5900 printf("ea_set of name %s failed - %s\n", ea_name,
5902 talloc_destroy(mem_ctx);
5907 cli_close(cli, fnum);
5908 for (i = 0; i < 10; i++) {
5909 fstring ea_name, ea_val;
5911 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5912 memset(ea_val, (char)i+1, i+1);
5913 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5914 if (!NT_STATUS_IS_OK(status)) {
5915 printf("ea_set of name %s failed - %s\n", ea_name,
5917 talloc_destroy(mem_ctx);
5922 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5923 if (!NT_STATUS_IS_OK(status)) {
5924 printf("ea_get list failed - %s\n", nt_errstr(status));
5928 printf("num_eas = %d\n", (int)num_eas);
5930 if (num_eas != 20) {
5931 printf("Should be 20 EA's stored... failing.\n");
5935 for (i = 0; i < num_eas; i++) {
5936 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5937 dump_data(0, ea_list[i].value.data,
5938 ea_list[i].value.length);
5941 /* Setting EA's to zero length deletes them. Test this */
5942 printf("Now deleting all EA's - case indepenent....\n");
5945 cli_set_ea_path(cli, fname, "", "", 0);
5947 for (i = 0; i < 20; i++) {
5949 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5950 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5951 if (!NT_STATUS_IS_OK(status)) {
5952 printf("ea_set of name %s failed - %s\n", ea_name,
5954 talloc_destroy(mem_ctx);
5960 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5961 if (!NT_STATUS_IS_OK(status)) {
5962 printf("ea_get list failed - %s\n", nt_errstr(status));
5966 printf("num_eas = %d\n", (int)num_eas);
5967 for (i = 0; i < num_eas; i++) {
5968 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5969 dump_data(0, ea_list[i].value.data,
5970 ea_list[i].value.length);
5974 printf("deleting EA's failed.\n");
5978 /* Try and delete a non existant EA. */
5979 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5980 if (!NT_STATUS_IS_OK(status)) {
5981 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5986 talloc_destroy(mem_ctx);
5987 if (!torture_close_connection(cli)) {
5994 static bool run_dirtest1(int dummy)
5997 static struct cli_state *cli;
6000 bool correct = True;
6002 printf("starting directory test\n");
6004 if (!torture_open_connection(&cli, 0)) {
6008 cli_sockopt(cli, sockops);
6010 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6011 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6012 cli_rmdir(cli, "\\LISTDIR");
6013 cli_mkdir(cli, "\\LISTDIR");
6015 /* Create 1000 files and 1000 directories. */
6016 for (i=0;i<1000;i++) {
6018 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6019 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6020 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6021 fprintf(stderr,"Failed to open %s\n", fname);
6024 cli_close(cli, fnum);
6026 for (i=0;i<1000;i++) {
6028 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6029 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6030 fprintf(stderr,"Failed to open %s\n", fname);
6035 /* Now ensure that doing an old list sees both files and directories. */
6037 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6038 printf("num_seen = %d\n", num_seen );
6039 /* We should see 100 files + 1000 directories + . and .. */
6040 if (num_seen != 2002)
6043 /* Ensure if we have the "must have" bits we only see the
6047 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6048 printf("num_seen = %d\n", num_seen );
6049 if (num_seen != 1002)
6053 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6054 printf("num_seen = %d\n", num_seen );
6055 if (num_seen != 1000)
6058 /* Delete everything. */
6059 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6060 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6061 cli_rmdir(cli, "\\LISTDIR");
6064 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6065 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6066 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6069 if (!torture_close_connection(cli)) {
6073 printf("finished dirtest1\n");
6078 static bool run_error_map_extract(int dummy) {
6080 static struct cli_state *c_dos;
6081 static struct cli_state *c_nt;
6086 uint32 flgs2, errnum;
6093 /* NT-Error connection */
6095 if (!(c_nt = open_nbt_connection())) {
6099 c_nt->use_spnego = False;
6101 status = cli_negprot(c_nt);
6103 if (!NT_STATUS_IS_OK(status)) {
6104 printf("%s rejected the NT-error negprot (%s)\n", host,
6110 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6111 if (!NT_STATUS_IS_OK(status)) {
6112 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6116 /* DOS-Error connection */
6118 if (!(c_dos = open_nbt_connection())) {
6122 c_dos->use_spnego = False;
6123 c_dos->force_dos_errors = True;
6125 status = cli_negprot(c_dos);
6126 if (!NT_STATUS_IS_OK(status)) {
6127 printf("%s rejected the DOS-error negprot (%s)\n", host,
6129 cli_shutdown(c_dos);
6133 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6134 if (!NT_STATUS_IS_OK(status)) {
6135 printf("%s rejected the DOS-error initial session setup (%s)\n",
6136 host, nt_errstr(status));
6140 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6141 fstr_sprintf(user, "%X", error);
6143 status = cli_session_setup(c_nt, user,
6144 password, strlen(password),
6145 password, strlen(password),
6147 if (NT_STATUS_IS_OK(status)) {
6148 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6151 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
6153 /* Case #1: 32-bit NT errors */
6154 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6155 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
6157 printf("/** Dos error on NT connection! (%s) */\n",
6159 nt_status = NT_STATUS(0xc0000000);
6162 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
6163 password, strlen(password),
6164 password, strlen(password),
6166 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6168 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
6170 /* Case #1: 32-bit NT errors */
6171 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6172 printf("/** NT error on DOS connection! (%s) */\n",
6174 errnum = errclass = 0;
6176 cli_dos_error(c_dos, &errclass, &errnum);
6179 if (NT_STATUS_V(nt_status) != error) {
6180 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6181 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6182 get_nt_error_c_code(talloc_tos(), nt_status));
6185 printf("\t{%s,\t%s,\t%s},\n",
6186 smb_dos_err_class(errclass),
6187 smb_dos_err_name(errclass, errnum),
6188 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6193 static bool run_sesssetup_bench(int dummy)
6195 static struct cli_state *c;
6196 const char *fname = "\\file.dat";
6201 if (!torture_open_connection(&c, 0)) {
6205 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6206 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6207 FILE_DELETE_ON_CLOSE, 0, &fnum);
6208 if (!NT_STATUS_IS_OK(status)) {
6209 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6213 for (i=0; i<torture_numops; i++) {
6214 status = cli_session_setup(
6216 password, strlen(password),
6217 password, strlen(password),
6219 if (!NT_STATUS_IS_OK(status)) {
6220 d_printf("(%s) cli_session_setup failed: %s\n",
6221 __location__, nt_errstr(status));
6225 d_printf("\r%d ", (int)c->vuid);
6227 status = cli_ulogoff(c);
6228 if (!NT_STATUS_IS_OK(status)) {
6229 d_printf("(%s) cli_ulogoff failed: %s\n",
6230 __location__, nt_errstr(status));
6239 static bool subst_test(const char *str, const char *user, const char *domain,
6240 uid_t uid, gid_t gid, const char *expected)
6245 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6247 if (strcmp(subst, expected) != 0) {
6248 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6249 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6258 static void chain1_open_completion(struct tevent_req *req)
6262 status = cli_open_recv(req, &fnum);
6265 d_printf("cli_open_recv returned %s: %d\n",
6267 NT_STATUS_IS_OK(status) ? fnum : -1);
6270 static void chain1_write_completion(struct tevent_req *req)
6274 status = cli_write_andx_recv(req, &written);
6277 d_printf("cli_write_andx_recv returned %s: %d\n",
6279 NT_STATUS_IS_OK(status) ? (int)written : -1);
6282 static void chain1_close_completion(struct tevent_req *req)
6285 bool *done = (bool *)tevent_req_callback_data_void(req);
6287 status = cli_close_recv(req);
6292 d_printf("cli_close returned %s\n", nt_errstr(status));
6295 static bool run_chain1(int dummy)
6297 struct cli_state *cli1;
6298 struct event_context *evt = event_context_init(NULL);
6299 struct tevent_req *reqs[3], *smbreqs[3];
6301 const char *str = "foobar";
6304 printf("starting chain1 test\n");
6305 if (!torture_open_connection(&cli1, 0)) {
6309 cli_sockopt(cli1, sockops);
6311 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6312 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6313 if (reqs[0] == NULL) return false;
6314 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6317 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6318 (const uint8_t *)str, 0, strlen(str)+1,
6319 smbreqs, 1, &smbreqs[1]);
6320 if (reqs[1] == NULL) return false;
6321 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6323 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6324 if (reqs[2] == NULL) return false;
6325 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6327 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6328 if (!NT_STATUS_IS_OK(status)) {
6333 event_loop_once(evt);
6336 torture_close_connection(cli1);
6340 static void chain2_sesssetup_completion(struct tevent_req *req)
6343 status = cli_session_setup_guest_recv(req);
6344 d_printf("sesssetup returned %s\n", nt_errstr(status));
6347 static void chain2_tcon_completion(struct tevent_req *req)
6349 bool *done = (bool *)tevent_req_callback_data_void(req);
6351 status = cli_tcon_andx_recv(req);
6352 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6356 static bool run_chain2(int dummy)
6358 struct cli_state *cli1;
6359 struct event_context *evt = event_context_init(NULL);
6360 struct tevent_req *reqs[2], *smbreqs[2];
6364 printf("starting chain2 test\n");
6365 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6366 port_to_use, Undefined, 0);
6367 if (!NT_STATUS_IS_OK(status)) {
6371 cli_sockopt(cli1, sockops);
6373 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6375 if (reqs[0] == NULL) return false;
6376 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6378 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6379 "?????", NULL, 0, &smbreqs[1]);
6380 if (reqs[1] == NULL) return false;
6381 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6383 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6384 if (!NT_STATUS_IS_OK(status)) {
6389 event_loop_once(evt);
6392 torture_close_connection(cli1);
6397 struct torture_createdel_state {
6398 struct tevent_context *ev;
6399 struct cli_state *cli;
6402 static void torture_createdel_created(struct tevent_req *subreq);
6403 static void torture_createdel_closed(struct tevent_req *subreq);
6405 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6406 struct tevent_context *ev,
6407 struct cli_state *cli,
6410 struct tevent_req *req, *subreq;
6411 struct torture_createdel_state *state;
6413 req = tevent_req_create(mem_ctx, &state,
6414 struct torture_createdel_state);
6421 subreq = cli_ntcreate_send(
6422 state, ev, cli, name, 0,
6423 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6424 FILE_ATTRIBUTE_NORMAL,
6425 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6426 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6428 if (tevent_req_nomem(subreq, req)) {
6429 return tevent_req_post(req, ev);
6431 tevent_req_set_callback(subreq, torture_createdel_created, req);
6435 static void torture_createdel_created(struct tevent_req *subreq)
6437 struct tevent_req *req = tevent_req_callback_data(
6438 subreq, struct tevent_req);
6439 struct torture_createdel_state *state = tevent_req_data(
6440 req, struct torture_createdel_state);
6444 status = cli_ntcreate_recv(subreq, &fnum);
6445 TALLOC_FREE(subreq);
6446 if (!NT_STATUS_IS_OK(status)) {
6447 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6448 nt_errstr(status)));
6449 tevent_req_nterror(req, status);
6453 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6454 if (tevent_req_nomem(subreq, req)) {
6457 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6460 static void torture_createdel_closed(struct tevent_req *subreq)
6462 struct tevent_req *req = tevent_req_callback_data(
6463 subreq, struct tevent_req);
6466 status = cli_close_recv(subreq);
6467 if (!NT_STATUS_IS_OK(status)) {
6468 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6469 tevent_req_nterror(req, status);
6472 tevent_req_done(req);
6475 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6477 return tevent_req_simple_recv_ntstatus(req);
6480 struct torture_createdels_state {
6481 struct tevent_context *ev;
6482 struct cli_state *cli;
6483 const char *base_name;
6487 struct tevent_req **reqs;
6490 static void torture_createdels_done(struct tevent_req *subreq);
6492 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6493 struct tevent_context *ev,
6494 struct cli_state *cli,
6495 const char *base_name,
6499 struct tevent_req *req;
6500 struct torture_createdels_state *state;
6503 req = tevent_req_create(mem_ctx, &state,
6504 struct torture_createdels_state);
6510 state->base_name = talloc_strdup(state, base_name);
6511 if (tevent_req_nomem(state->base_name, req)) {
6512 return tevent_req_post(req, ev);
6514 state->num_files = MAX(num_parallel, num_files);
6516 state->received = 0;
6518 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6519 if (tevent_req_nomem(state->reqs, req)) {
6520 return tevent_req_post(req, ev);
6523 for (i=0; i<num_parallel; i++) {
6526 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6528 if (tevent_req_nomem(name, req)) {
6529 return tevent_req_post(req, ev);
6531 state->reqs[i] = torture_createdel_send(
6532 state->reqs, state->ev, state->cli, name);
6533 if (tevent_req_nomem(state->reqs[i], req)) {
6534 return tevent_req_post(req, ev);
6536 name = talloc_move(state->reqs[i], &name);
6537 tevent_req_set_callback(state->reqs[i],
6538 torture_createdels_done, req);
6544 static void torture_createdels_done(struct tevent_req *subreq)
6546 struct tevent_req *req = tevent_req_callback_data(
6547 subreq, struct tevent_req);
6548 struct torture_createdels_state *state = tevent_req_data(
6549 req, struct torture_createdels_state);
6550 size_t num_parallel = talloc_array_length(state->reqs);
6555 status = torture_createdel_recv(subreq);
6556 if (!NT_STATUS_IS_OK(status)){
6557 DEBUG(10, ("torture_createdel_recv returned %s\n",
6558 nt_errstr(status)));
6559 TALLOC_FREE(subreq);
6560 tevent_req_nterror(req, status);
6564 for (i=0; i<num_parallel; i++) {
6565 if (subreq == state->reqs[i]) {
6569 if (i == num_parallel) {
6570 DEBUG(10, ("received something we did not send\n"));
6571 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6574 TALLOC_FREE(state->reqs[i]);
6576 if (state->sent >= state->num_files) {
6577 tevent_req_done(req);
6581 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6583 if (tevent_req_nomem(name, req)) {
6586 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6588 if (tevent_req_nomem(state->reqs[i], req)) {
6591 name = talloc_move(state->reqs[i], &name);
6592 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6596 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6598 return tevent_req_simple_recv_ntstatus(req);
6601 struct swallow_notify_state {
6602 struct tevent_context *ev;
6603 struct cli_state *cli;
6605 uint32_t completion_filter;
6607 bool (*fn)(uint32_t action, const char *name, void *priv);
6611 static void swallow_notify_done(struct tevent_req *subreq);
6613 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6614 struct tevent_context *ev,
6615 struct cli_state *cli,
6617 uint32_t completion_filter,
6619 bool (*fn)(uint32_t action,
6624 struct tevent_req *req, *subreq;
6625 struct swallow_notify_state *state;
6627 req = tevent_req_create(mem_ctx, &state,
6628 struct swallow_notify_state);
6635 state->completion_filter = completion_filter;
6636 state->recursive = recursive;
6640 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6641 0xffff, state->completion_filter,
6643 if (tevent_req_nomem(subreq, req)) {
6644 return tevent_req_post(req, ev);
6646 tevent_req_set_callback(subreq, swallow_notify_done, req);
6650 static void swallow_notify_done(struct tevent_req *subreq)
6652 struct tevent_req *req = tevent_req_callback_data(
6653 subreq, struct tevent_req);
6654 struct swallow_notify_state *state = tevent_req_data(
6655 req, struct swallow_notify_state);
6657 uint32_t i, num_changes;
6658 struct notify_change *changes;
6660 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6661 TALLOC_FREE(subreq);
6662 if (!NT_STATUS_IS_OK(status)) {
6663 DEBUG(10, ("cli_notify_recv returned %s\n",
6664 nt_errstr(status)));
6665 tevent_req_nterror(req, status);
6669 for (i=0; i<num_changes; i++) {
6670 state->fn(changes[i].action, changes[i].name, state->priv);
6672 TALLOC_FREE(changes);
6674 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6675 0xffff, state->completion_filter,
6677 if (tevent_req_nomem(subreq, req)) {
6680 tevent_req_set_callback(subreq, swallow_notify_done, req);
6683 static bool print_notifies(uint32_t action, const char *name, void *priv)
6685 if (DEBUGLEVEL > 5) {
6686 d_printf("%d %s\n", (int)action, name);
6691 static void notify_bench_done(struct tevent_req *req)
6693 int *num_finished = (int *)tevent_req_callback_data_void(req);
6697 static bool run_notify_bench(int dummy)
6699 const char *dname = "\\notify-bench";
6700 struct tevent_context *ev;
6703 struct tevent_req *req1;
6704 struct tevent_req *req2 = NULL;
6705 int i, num_unc_names;
6706 int num_finished = 0;
6708 printf("starting notify-bench test\n");
6710 if (use_multishare_conn) {
6712 unc_list = file_lines_load(multishare_conn_fname,
6713 &num_unc_names, 0, NULL);
6714 if (!unc_list || num_unc_names <= 0) {
6715 d_printf("Failed to load unc names list from '%s'\n",
6716 multishare_conn_fname);
6719 TALLOC_FREE(unc_list);
6724 ev = tevent_context_init(talloc_tos());
6726 d_printf("tevent_context_init failed\n");
6730 for (i=0; i<num_unc_names; i++) {
6731 struct cli_state *cli;
6734 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6736 if (base_fname == NULL) {
6740 if (!torture_open_connection(&cli, i)) {
6744 status = cli_ntcreate(cli, dname, 0,
6745 MAXIMUM_ALLOWED_ACCESS,
6746 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6748 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6751 if (!NT_STATUS_IS_OK(status)) {
6752 d_printf("Could not create %s: %s\n", dname,
6757 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6758 FILE_NOTIFY_CHANGE_FILE_NAME |
6759 FILE_NOTIFY_CHANGE_DIR_NAME |
6760 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6761 FILE_NOTIFY_CHANGE_LAST_WRITE,
6762 false, print_notifies, NULL);
6764 d_printf("Could not create notify request\n");
6768 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6769 base_fname, 10, torture_numops);
6771 d_printf("Could not create createdels request\n");
6774 TALLOC_FREE(base_fname);
6776 tevent_req_set_callback(req2, notify_bench_done,
6780 while (num_finished < num_unc_names) {
6782 ret = tevent_loop_once(ev);
6784 d_printf("tevent_loop_once failed\n");
6789 if (!tevent_req_poll(req2, ev)) {
6790 d_printf("tevent_req_poll failed\n");
6793 status = torture_createdels_recv(req2);
6794 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6799 static bool run_mangle1(int dummy)
6801 struct cli_state *cli;
6802 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6806 time_t change_time, access_time, write_time;
6810 printf("starting mangle1 test\n");
6811 if (!torture_open_connection(&cli, 0)) {
6815 cli_sockopt(cli, sockops);
6817 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6818 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6820 if (!NT_STATUS_IS_OK(status)) {
6821 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6824 cli_close(cli, fnum);
6826 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6827 if (!NT_STATUS_IS_OK(status)) {
6828 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6832 d_printf("alt_name: %s\n", alt_name);
6834 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6835 if (!NT_STATUS_IS_OK(status)) {
6836 d_printf("cli_open(%s) failed: %s\n", alt_name,
6840 cli_close(cli, fnum);
6842 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6843 &write_time, &size, &mode);
6844 if (!NT_STATUS_IS_OK(status)) {
6845 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6853 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6855 size_t *to_pull = (size_t *)priv;
6856 size_t thistime = *to_pull;
6858 thistime = MIN(thistime, n);
6859 if (thistime == 0) {
6863 memset(buf, 0, thistime);
6864 *to_pull -= thistime;
6868 static bool run_windows_write(int dummy)
6870 struct cli_state *cli1;
6874 const char *fname = "\\writetest.txt";
6875 struct timeval start_time;
6880 printf("starting windows_write test\n");
6881 if (!torture_open_connection(&cli1, 0)) {
6885 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6886 if (!NT_STATUS_IS_OK(status)) {
6887 printf("open failed (%s)\n", nt_errstr(status));
6891 cli_sockopt(cli1, sockops);
6893 start_time = timeval_current();
6895 for (i=0; i<torture_numops; i++) {
6897 off_t start = i * torture_blocksize;
6898 size_t to_pull = torture_blocksize - 1;
6900 status = cli_writeall(cli1, fnum, 0, &c,
6901 start + torture_blocksize - 1, 1, NULL);
6902 if (!NT_STATUS_IS_OK(status)) {
6903 printf("cli_write failed: %s\n", nt_errstr(status));
6907 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6908 null_source, &to_pull);
6909 if (!NT_STATUS_IS_OK(status)) {
6910 printf("cli_push returned: %s\n", nt_errstr(status));
6915 seconds = timeval_elapsed(&start_time);
6916 kbytes = (double)torture_blocksize * torture_numops;
6919 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6920 (double)seconds, (int)(kbytes/seconds));
6924 cli_close(cli1, fnum);
6925 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6926 torture_close_connection(cli1);
6930 static bool run_cli_echo(int dummy)
6932 struct cli_state *cli;
6935 printf("starting cli_echo test\n");
6936 if (!torture_open_connection(&cli, 0)) {
6939 cli_sockopt(cli, sockops);
6941 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6943 d_printf("cli_echo returned %s\n", nt_errstr(status));
6945 torture_close_connection(cli);
6946 return NT_STATUS_IS_OK(status);
6949 static bool run_uid_regression_test(int dummy)
6951 static struct cli_state *cli;
6954 bool correct = True;
6957 printf("starting uid regression test\n");
6959 if (!torture_open_connection(&cli, 0)) {
6963 cli_sockopt(cli, sockops);
6965 /* Ok - now save then logoff our current user. */
6966 old_vuid = cli->vuid;
6968 status = cli_ulogoff(cli);
6969 if (!NT_STATUS_IS_OK(status)) {
6970 d_printf("(%s) cli_ulogoff failed: %s\n",
6971 __location__, nt_errstr(status));
6976 cli->vuid = old_vuid;
6978 /* Try an operation. */
6979 status = cli_mkdir(cli, "\\uid_reg_test");
6980 if (NT_STATUS_IS_OK(status)) {
6981 d_printf("(%s) cli_mkdir succeeded\n",
6986 /* Should be bad uid. */
6987 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6988 NT_STATUS_USER_SESSION_DELETED)) {
6994 old_cnum = cli->cnum;
6996 /* Now try a SMBtdis with the invald vuid set to zero. */
6999 /* This should succeed. */
7000 status = cli_tdis(cli);
7002 if (NT_STATUS_IS_OK(status)) {
7003 d_printf("First tdis with invalid vuid should succeed.\n");
7005 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7010 cli->vuid = old_vuid;
7011 cli->cnum = old_cnum;
7013 /* This should fail. */
7014 status = cli_tdis(cli);
7015 if (NT_STATUS_IS_OK(status)) {
7016 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7020 /* Should be bad tid. */
7021 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7022 NT_STATUS_NETWORK_NAME_DELETED)) {
7028 cli_rmdir(cli, "\\uid_reg_test");
7037 static const char *illegal_chars = "*\\/?<>|\":";
7038 static char force_shortname_chars[] = " +,.[];=\177";
7040 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7041 const char *mask, void *state)
7043 struct cli_state *pcli = (struct cli_state *)state;
7045 NTSTATUS status = NT_STATUS_OK;
7047 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7049 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7050 return NT_STATUS_OK;
7052 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7053 status = cli_rmdir(pcli, fname);
7054 if (!NT_STATUS_IS_OK(status)) {
7055 printf("del_fn: failed to rmdir %s\n,", fname );
7058 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7059 if (!NT_STATUS_IS_OK(status)) {
7060 printf("del_fn: failed to unlink %s\n,", fname );
7072 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7073 const char *name, void *state)
7075 struct sn_state *s = (struct sn_state *)state;
7079 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7080 i, finfo->name, finfo->short_name);
7083 if (strchr(force_shortname_chars, i)) {
7084 if (!finfo->short_name[0]) {
7085 /* Shortname not created when it should be. */
7086 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7087 __location__, finfo->name, i);
7090 } else if (finfo->short_name[0]){
7091 /* Shortname created when it should not be. */
7092 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7093 __location__, finfo->short_name, finfo->name);
7097 return NT_STATUS_OK;
7100 static bool run_shortname_test(int dummy)
7102 static struct cli_state *cli;
7103 bool correct = True;
7109 printf("starting shortname test\n");
7111 if (!torture_open_connection(&cli, 0)) {
7115 cli_sockopt(cli, sockops);
7117 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7118 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7119 cli_rmdir(cli, "\\shortname");
7121 status = cli_mkdir(cli, "\\shortname");
7122 if (!NT_STATUS_IS_OK(status)) {
7123 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7124 __location__, nt_errstr(status));
7129 strlcpy(fname, "\\shortname\\", sizeof(fname));
7130 strlcat(fname, "test .txt", sizeof(fname));
7134 for (i = 32; i < 128; i++) {
7135 uint16_t fnum = (uint16_t)-1;
7139 if (strchr(illegal_chars, i)) {
7144 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7145 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7146 if (!NT_STATUS_IS_OK(status)) {
7147 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7148 __location__, fname, nt_errstr(status));
7152 cli_close(cli, fnum);
7155 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
7157 if (s.matched != 1) {
7158 d_printf("(%s) failed to list %s: %s\n",
7159 __location__, fname, cli_errstr(cli));
7164 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7165 if (!NT_STATUS_IS_OK(status)) {
7166 d_printf("(%s) failed to delete %s: %s\n",
7167 __location__, fname, nt_errstr(status));
7180 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7181 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7182 cli_rmdir(cli, "\\shortname");
7183 torture_close_connection(cli);
7187 static void pagedsearch_cb(struct tevent_req *req)
7190 struct tldap_message *msg;
7193 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7194 if (rc != TLDAP_SUCCESS) {
7195 d_printf("tldap_search_paged_recv failed: %s\n",
7196 tldap_err2string(rc));
7199 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7203 if (!tldap_entry_dn(msg, &dn)) {
7204 d_printf("tldap_entry_dn failed\n");
7207 d_printf("%s\n", dn);
7211 static bool run_tldap(int dummy)
7213 struct tldap_context *ld;
7216 struct sockaddr_storage addr;
7217 struct tevent_context *ev;
7218 struct tevent_req *req;
7222 if (!resolve_name(host, &addr, 0, false)) {
7223 d_printf("could not find host %s\n", host);
7226 status = open_socket_out(&addr, 389, 9999, &fd);
7227 if (!NT_STATUS_IS_OK(status)) {
7228 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7232 ld = tldap_context_create(talloc_tos(), fd);
7235 d_printf("tldap_context_create failed\n");
7239 rc = tldap_fetch_rootdse(ld);
7240 if (rc != TLDAP_SUCCESS) {
7241 d_printf("tldap_fetch_rootdse failed: %s\n",
7242 tldap_errstr(talloc_tos(), ld, rc));
7246 basedn = tldap_talloc_single_attribute(
7247 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7248 if (basedn == NULL) {
7249 d_printf("no defaultNamingContext\n");
7252 d_printf("defaultNamingContext: %s\n", basedn);
7254 ev = tevent_context_init(talloc_tos());
7256 d_printf("tevent_context_init failed\n");
7260 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7261 TLDAP_SCOPE_SUB, "(objectclass=*)",
7263 NULL, 0, NULL, 0, 0, 0, 0, 5);
7265 d_printf("tldap_search_paged_send failed\n");
7268 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7270 tevent_req_poll(req, ev);
7274 /* test search filters against rootDSE */
7275 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7276 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7278 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7279 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7280 talloc_tos(), NULL, NULL);
7281 if (rc != TLDAP_SUCCESS) {
7282 d_printf("tldap_search with complex filter failed: %s\n",
7283 tldap_errstr(talloc_tos(), ld, rc));
7291 /* Torture test to ensure no regression of :
7292 https://bugzilla.samba.org/show_bug.cgi?id=7084
7295 static bool run_dir_createtime(int dummy)
7297 struct cli_state *cli;
7298 const char *dname = "\\testdir";
7299 const char *fname = "\\testdir\\testfile";
7301 struct timespec create_time;
7302 struct timespec create_time1;
7306 if (!torture_open_connection(&cli, 0)) {
7310 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7311 cli_rmdir(cli, dname);
7313 status = cli_mkdir(cli, dname);
7314 if (!NT_STATUS_IS_OK(status)) {
7315 printf("mkdir failed: %s\n", nt_errstr(status));
7319 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7321 if (!NT_STATUS_IS_OK(status)) {
7322 printf("cli_qpathinfo2 returned %s\n",
7327 /* Sleep 3 seconds, then create a file. */
7330 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7332 if (!NT_STATUS_IS_OK(status)) {
7333 printf("cli_open failed: %s\n", nt_errstr(status));
7337 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7339 if (!NT_STATUS_IS_OK(status)) {
7340 printf("cli_qpathinfo2 (2) returned %s\n",
7345 if (timespec_compare(&create_time1, &create_time)) {
7346 printf("run_dir_createtime: create time was updated (error)\n");
7348 printf("run_dir_createtime: create time was not updated (correct)\n");
7354 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7355 cli_rmdir(cli, dname);
7356 if (!torture_close_connection(cli)) {
7363 static bool run_streamerror(int dummy)
7365 struct cli_state *cli;
7366 const char *dname = "\\testdir";
7367 const char *streamname =
7368 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7370 time_t change_time, access_time, write_time;
7372 uint16_t mode, fnum;
7375 if (!torture_open_connection(&cli, 0)) {
7379 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7380 cli_rmdir(cli, dname);
7382 status = cli_mkdir(cli, dname);
7383 if (!NT_STATUS_IS_OK(status)) {
7384 printf("mkdir failed: %s\n", nt_errstr(status));
7388 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7390 status = cli_nt_error(cli);
7392 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7393 printf("pathinfo returned %s, expected "
7394 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7399 status = cli_ntcreate(cli, streamname, 0x16,
7400 FILE_READ_DATA|FILE_READ_EA|
7401 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7402 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7403 FILE_OPEN, 0, 0, &fnum);
7405 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7406 printf("ntcreate returned %s, expected "
7407 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7413 cli_rmdir(cli, dname);
7417 static bool run_local_substitute(int dummy)
7421 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7422 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7423 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7424 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7425 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7426 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7427 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7428 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7430 /* Different captialization rules in sub_basic... */
7432 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7438 static bool run_local_base64(int dummy)
7443 for (i=1; i<2000; i++) {
7444 DATA_BLOB blob1, blob2;
7447 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7449 generate_random_buffer(blob1.data, blob1.length);
7451 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7453 d_fprintf(stderr, "base64_encode_data_blob failed "
7454 "for %d bytes\n", i);
7457 blob2 = base64_decode_data_blob(b64);
7460 if (data_blob_cmp(&blob1, &blob2)) {
7461 d_fprintf(stderr, "data_blob_cmp failed for %d "
7465 TALLOC_FREE(blob1.data);
7466 data_blob_free(&blob2);
7471 static bool run_local_gencache(int dummy)
7477 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7478 d_printf("%s: gencache_set() failed\n", __location__);
7482 if (!gencache_get("foo", NULL, NULL)) {
7483 d_printf("%s: gencache_get() failed\n", __location__);
7487 if (!gencache_get("foo", &val, &tm)) {
7488 d_printf("%s: gencache_get() failed\n", __location__);
7492 if (strcmp(val, "bar") != 0) {
7493 d_printf("%s: gencache_get() returned %s, expected %s\n",
7494 __location__, val, "bar");
7501 if (!gencache_del("foo")) {
7502 d_printf("%s: gencache_del() failed\n", __location__);
7505 if (gencache_del("foo")) {
7506 d_printf("%s: second gencache_del() succeeded\n",
7511 if (gencache_get("foo", &val, &tm)) {
7512 d_printf("%s: gencache_get() on deleted entry "
7513 "succeeded\n", __location__);
7517 blob = data_blob_string_const_null("bar");
7518 tm = time(NULL) + 60;
7520 if (!gencache_set_data_blob("foo", &blob, tm)) {
7521 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7525 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7526 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7530 if (strcmp((const char *)blob.data, "bar") != 0) {
7531 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7532 __location__, (const char *)blob.data, "bar");
7533 data_blob_free(&blob);
7537 data_blob_free(&blob);
7539 if (!gencache_del("foo")) {
7540 d_printf("%s: gencache_del() failed\n", __location__);
7543 if (gencache_del("foo")) {
7544 d_printf("%s: second gencache_del() succeeded\n",
7549 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7550 d_printf("%s: gencache_get_data_blob() on deleted entry "
7551 "succeeded\n", __location__);
7558 static bool rbt_testval(struct db_context *db, const char *key,
7561 struct db_record *rec;
7562 TDB_DATA data = string_tdb_data(value);
7566 rec = db->fetch_locked(db, db, string_tdb_data(key));
7568 d_fprintf(stderr, "fetch_locked failed\n");
7571 status = rec->store(rec, data, 0);
7572 if (!NT_STATUS_IS_OK(status)) {
7573 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7578 rec = db->fetch_locked(db, db, string_tdb_data(key));
7580 d_fprintf(stderr, "second fetch_locked failed\n");
7583 if ((rec->value.dsize != data.dsize)
7584 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7585 d_fprintf(stderr, "Got wrong data back\n");
7595 static bool run_local_rbtree(int dummy)
7597 struct db_context *db;
7601 db = db_open_rbt(NULL);
7604 d_fprintf(stderr, "db_open_rbt failed\n");
7608 for (i=0; i<1000; i++) {
7611 if (asprintf(&key, "key%ld", random()) == -1) {
7614 if (asprintf(&value, "value%ld", random()) == -1) {
7619 if (!rbt_testval(db, key, value)) {
7626 if (asprintf(&value, "value%ld", random()) == -1) {
7631 if (!rbt_testval(db, key, value)) {
7650 local test for character set functions
7652 This is a very simple test for the functionality in convert_string_error()
7654 static bool run_local_convert_string(int dummy)
7656 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7657 const char *test_strings[2] = { "March", "M\303\244rz" };
7661 for (i=0; i<2; i++) {
7662 const char *str = test_strings[i];
7663 int len = strlen(str);
7664 size_t converted_size;
7667 memset(dst, 'X', sizeof(dst));
7669 /* first try with real source length */
7670 ret = convert_string_error(CH_UNIX, CH_UTF8,
7675 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7679 if (converted_size != len) {
7680 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7681 str, len, (int)converted_size);
7685 if (strncmp(str, dst, converted_size) != 0) {
7686 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7690 if (strlen(str) != converted_size) {
7691 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7692 (int)strlen(str), (int)converted_size);
7696 if (dst[converted_size] != 'X') {
7697 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7701 /* now with srclen==-1, this causes the nul to be
7703 ret = convert_string_error(CH_UNIX, CH_UTF8,
7708 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7712 if (converted_size != len+1) {
7713 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7714 str, len, (int)converted_size);
7718 if (strncmp(str, dst, converted_size) != 0) {
7719 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7723 if (len+1 != converted_size) {
7724 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7725 len+1, (int)converted_size);
7729 if (dst[converted_size] != 'X') {
7730 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7737 TALLOC_FREE(tmp_ctx);
7740 TALLOC_FREE(tmp_ctx);
7745 struct talloc_dict_test {
7749 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7751 int *count = (int *)priv;
7756 static bool run_local_talloc_dict(int dummy)
7758 struct talloc_dict *dict;
7759 struct talloc_dict_test *t;
7762 dict = talloc_dict_init(talloc_tos());
7767 t = talloc(talloc_tos(), struct talloc_dict_test);
7774 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7779 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7792 static bool run_local_string_to_sid(int dummy) {
7795 if (string_to_sid(&sid, "S--1-5-32-545")) {
7796 printf("allowing S--1-5-32-545\n");
7799 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7800 printf("allowing S-1-5-32-+545\n");
7803 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")) {
7804 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7807 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7808 printf("allowing S-1-5-32-545-abc\n");
7811 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7812 printf("could not parse S-1-5-32-545\n");
7815 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7816 printf("mis-parsed S-1-5-32-545 as %s\n",
7817 sid_string_tos(&sid));
7823 static bool run_local_binary_to_sid(int dummy) {
7824 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7825 static const char good_binary_sid[] = {
7826 0x1, /* revision number */
7828 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7829 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7830 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7831 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7832 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7833 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7834 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7835 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7836 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7837 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7838 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7839 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7840 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7841 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7842 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7843 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7846 static const char long_binary_sid[] = {
7847 0x1, /* revision number */
7849 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7850 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7851 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7852 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7853 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7854 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7855 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7856 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7857 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7858 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7859 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7860 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7861 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7862 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7863 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7864 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7865 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7866 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7867 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7870 static const char long_binary_sid2[] = {
7871 0x1, /* revision number */
7873 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7874 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7875 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7876 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7877 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7878 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7879 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7880 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7881 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7882 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7883 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7884 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7885 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7886 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7887 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7888 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7889 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7890 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7891 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7892 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7893 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7894 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7895 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7896 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7897 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7898 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7899 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7900 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7901 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7902 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7903 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7904 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7905 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7908 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7911 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7914 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7920 /* Split a path name into filename and stream name components. Canonicalise
7921 * such that an implicit $DATA token is always explicit.
7923 * The "specification" of this function can be found in the
7924 * run_local_stream_name() function in torture.c, I've tried those
7925 * combinations against a W2k3 server.
7928 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7929 char **pbase, char **pstream)
7932 char *stream = NULL;
7933 char *sname; /* stream name */
7934 const char *stype; /* stream type */
7936 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7938 sname = strchr_m(fname, ':');
7940 if (lp_posix_pathnames() || (sname == NULL)) {
7941 if (pbase != NULL) {
7942 base = talloc_strdup(mem_ctx, fname);
7943 NT_STATUS_HAVE_NO_MEMORY(base);
7948 if (pbase != NULL) {
7949 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7950 NT_STATUS_HAVE_NO_MEMORY(base);
7955 stype = strchr_m(sname, ':');
7957 if (stype == NULL) {
7958 sname = talloc_strdup(mem_ctx, sname);
7962 if (strcasecmp_m(stype, ":$DATA") != 0) {
7964 * If there is an explicit stream type, so far we only
7965 * allow $DATA. Is there anything else allowed? -- vl
7967 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7969 return NT_STATUS_OBJECT_NAME_INVALID;
7971 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7975 if (sname == NULL) {
7977 return NT_STATUS_NO_MEMORY;
7980 if (sname[0] == '\0') {
7982 * no stream name, so no stream
7987 if (pstream != NULL) {
7988 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7989 if (stream == NULL) {
7992 return NT_STATUS_NO_MEMORY;
7995 * upper-case the type field
7997 strupper_m(strchr_m(stream, ':')+1);
8001 if (pbase != NULL) {
8004 if (pstream != NULL) {
8007 return NT_STATUS_OK;
8010 static bool test_stream_name(const char *fname, const char *expected_base,
8011 const char *expected_stream,
8012 NTSTATUS expected_status)
8016 char *stream = NULL;
8018 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8019 if (!NT_STATUS_EQUAL(status, expected_status)) {
8023 if (!NT_STATUS_IS_OK(status)) {
8027 if (base == NULL) goto error;
8029 if (strcmp(expected_base, base) != 0) goto error;
8031 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8032 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8034 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8038 TALLOC_FREE(stream);
8042 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8043 fname, expected_base ? expected_base : "<NULL>",
8044 expected_stream ? expected_stream : "<NULL>",
8045 nt_errstr(expected_status));
8046 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8047 base ? base : "<NULL>", stream ? stream : "<NULL>",
8050 TALLOC_FREE(stream);
8054 static bool run_local_stream_name(int dummy)
8058 ret &= test_stream_name(
8059 "bla", "bla", NULL, NT_STATUS_OK);
8060 ret &= test_stream_name(
8061 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8062 ret &= test_stream_name(
8063 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8064 ret &= test_stream_name(
8065 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8066 ret &= test_stream_name(
8067 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8068 ret &= test_stream_name(
8069 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8070 ret &= test_stream_name(
8071 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8072 ret &= test_stream_name(
8073 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8078 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8080 if (a.length != b.length) {
8081 printf("a.length=%d != b.length=%d\n",
8082 (int)a.length, (int)b.length);
8085 if (memcmp(a.data, b.data, a.length) != 0) {
8086 printf("a.data and b.data differ\n");
8092 static bool run_local_memcache(int dummy)
8094 struct memcache *cache;
8096 DATA_BLOB d1, d2, d3;
8097 DATA_BLOB v1, v2, v3;
8099 TALLOC_CTX *mem_ctx;
8101 size_t size1, size2;
8104 cache = memcache_init(NULL, 100);
8106 if (cache == NULL) {
8107 printf("memcache_init failed\n");
8111 d1 = data_blob_const("d1", 2);
8112 d2 = data_blob_const("d2", 2);
8113 d3 = data_blob_const("d3", 2);
8115 k1 = data_blob_const("d1", 2);
8116 k2 = data_blob_const("d2", 2);
8118 memcache_add(cache, STAT_CACHE, k1, d1);
8119 memcache_add(cache, GETWD_CACHE, k2, d2);
8121 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8122 printf("could not find k1\n");
8125 if (!data_blob_equal(d1, v1)) {
8129 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8130 printf("could not find k2\n");
8133 if (!data_blob_equal(d2, v2)) {
8137 memcache_add(cache, STAT_CACHE, k1, d3);
8139 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8140 printf("could not find replaced k1\n");
8143 if (!data_blob_equal(d3, v3)) {
8147 memcache_add(cache, GETWD_CACHE, k1, d1);
8149 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8150 printf("Did find k2, should have been purged\n");
8156 cache = memcache_init(NULL, 0);
8158 mem_ctx = talloc_init("foo");
8160 str1 = talloc_strdup(mem_ctx, "string1");
8161 str2 = talloc_strdup(mem_ctx, "string2");
8163 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8164 data_blob_string_const("torture"), &str1);
8165 size1 = talloc_total_size(cache);
8167 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8168 data_blob_string_const("torture"), &str2);
8169 size2 = talloc_total_size(cache);
8171 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8173 if (size2 > size1) {
8174 printf("memcache leaks memory!\n");
8184 static void wbclient_done(struct tevent_req *req)
8187 struct winbindd_response *wb_resp;
8188 int *i = (int *)tevent_req_callback_data_void(req);
8190 wbc_err = wb_trans_recv(req, req, &wb_resp);
8193 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8196 static bool run_local_wbclient(int dummy)
8198 struct event_context *ev;
8199 struct wb_context **wb_ctx;
8200 struct winbindd_request wb_req;
8201 bool result = false;
8204 BlockSignals(True, SIGPIPE);
8206 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8211 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8212 if (wb_ctx == NULL) {
8216 ZERO_STRUCT(wb_req);
8217 wb_req.cmd = WINBINDD_PING;
8219 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8221 for (i=0; i<nprocs; i++) {
8222 wb_ctx[i] = wb_context_init(ev, NULL);
8223 if (wb_ctx[i] == NULL) {
8226 for (j=0; j<torture_numops; j++) {
8227 struct tevent_req *req;
8228 req = wb_trans_send(ev, ev, wb_ctx[i],
8229 (j % 2) == 0, &wb_req);
8233 tevent_req_set_callback(req, wbclient_done, &i);
8239 while (i < nprocs * torture_numops) {
8240 event_loop_once(ev);
8249 static void getaddrinfo_finished(struct tevent_req *req)
8251 char *name = (char *)tevent_req_callback_data_void(req);
8252 struct addrinfo *ainfo;
8255 res = getaddrinfo_recv(req, &ainfo);
8257 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8260 d_printf("gai(%s) succeeded\n", name);
8261 freeaddrinfo(ainfo);
8264 static bool run_getaddrinfo_send(int dummy)
8266 TALLOC_CTX *frame = talloc_stackframe();
8267 struct fncall_context *ctx;
8268 struct tevent_context *ev;
8269 bool result = false;
8270 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8271 "www.slashdot.org", "heise.de" };
8272 struct tevent_req *reqs[4];
8275 ev = event_context_init(frame);
8280 ctx = fncall_context_init(frame, 4);
8282 for (i=0; i<ARRAY_SIZE(names); i++) {
8283 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8285 if (reqs[i] == NULL) {
8288 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8289 discard_const_p(void, names[i]));
8292 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8293 tevent_loop_once(ev);
8302 static bool dbtrans_inc(struct db_context *db)
8304 struct db_record *rec;
8309 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8311 printf(__location__ "fetch_lock failed\n");
8315 if (rec->value.dsize != sizeof(uint32_t)) {
8316 printf(__location__ "value.dsize = %d\n",
8317 (int)rec->value.dsize);
8321 val = (uint32_t *)rec->value.dptr;
8324 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8327 if (!NT_STATUS_IS_OK(status)) {
8328 printf(__location__ "store failed: %s\n",
8339 static bool run_local_dbtrans(int dummy)
8341 struct db_context *db;
8342 struct db_record *rec;
8347 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8348 O_RDWR|O_CREAT, 0600);
8350 printf("Could not open transtest.db\n");
8354 res = db->transaction_start(db);
8356 printf(__location__ "transaction_start failed\n");
8360 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8362 printf(__location__ "fetch_lock failed\n");
8366 if (rec->value.dptr == NULL) {
8368 status = rec->store(
8369 rec, make_tdb_data((uint8_t *)&initial,
8372 if (!NT_STATUS_IS_OK(status)) {
8373 printf(__location__ "store returned %s\n",
8381 res = db->transaction_commit(db);
8383 printf(__location__ "transaction_commit failed\n");
8391 res = db->transaction_start(db);
8393 printf(__location__ "transaction_start failed\n");
8397 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8398 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8402 for (i=0; i<10; i++) {
8403 if (!dbtrans_inc(db)) {
8408 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8409 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8413 if (val2 != val + 10) {
8414 printf(__location__ "val=%d, val2=%d\n",
8415 (int)val, (int)val2);
8419 printf("val2=%d\r", val2);
8421 res = db->transaction_commit(db);
8423 printf(__location__ "transaction_commit failed\n");
8433 * Just a dummy test to be run under a debugger. There's no real way
8434 * to inspect the tevent_select specific function from outside of
8438 static bool run_local_tevent_select(int dummy)
8440 struct tevent_context *ev;
8441 struct tevent_fd *fd1, *fd2;
8442 bool result = false;
8444 ev = tevent_context_init_byname(NULL, "select");
8446 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8450 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8452 d_fprintf(stderr, "tevent_add_fd failed\n");
8455 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8457 d_fprintf(stderr, "tevent_add_fd failed\n");
8462 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8464 d_fprintf(stderr, "tevent_add_fd failed\n");
8474 static double create_procs(bool (*fn)(int), bool *result)
8477 volatile pid_t *child_status;
8478 volatile bool *child_status_out;
8481 struct timeval start;
8485 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8486 if (!child_status) {
8487 printf("Failed to setup shared memory\n");
8491 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8492 if (!child_status_out) {
8493 printf("Failed to setup result status shared memory\n");
8497 for (i = 0; i < nprocs; i++) {
8498 child_status[i] = 0;
8499 child_status_out[i] = True;
8502 start = timeval_current();
8504 for (i=0;i<nprocs;i++) {
8507 pid_t mypid = getpid();
8508 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8510 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8513 if (torture_open_connection(¤t_cli, i)) break;
8515 printf("pid %d failed to start\n", (int)getpid());
8521 child_status[i] = getpid();
8523 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8525 child_status_out[i] = fn(i);
8532 for (i=0;i<nprocs;i++) {
8533 if (child_status[i]) synccount++;
8535 if (synccount == nprocs) break;
8537 } while (timeval_elapsed(&start) < 30);
8539 if (synccount != nprocs) {
8540 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8542 return timeval_elapsed(&start);
8545 /* start the client load */
8546 start = timeval_current();
8548 for (i=0;i<nprocs;i++) {
8549 child_status[i] = 0;
8552 printf("%d clients started\n", nprocs);
8554 for (i=0;i<nprocs;i++) {
8555 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8560 for (i=0;i<nprocs;i++) {
8561 if (!child_status_out[i]) {
8565 return timeval_elapsed(&start);
8568 #define FLAG_MULTIPROC 1
8575 {"FDPASS", run_fdpasstest, 0},
8576 {"LOCK1", run_locktest1, 0},
8577 {"LOCK2", run_locktest2, 0},
8578 {"LOCK3", run_locktest3, 0},
8579 {"LOCK4", run_locktest4, 0},
8580 {"LOCK5", run_locktest5, 0},
8581 {"LOCK6", run_locktest6, 0},
8582 {"LOCK7", run_locktest7, 0},
8583 {"LOCK8", run_locktest8, 0},
8584 {"LOCK9", run_locktest9, 0},
8585 {"UNLINK", run_unlinktest, 0},
8586 {"BROWSE", run_browsetest, 0},
8587 {"ATTR", run_attrtest, 0},
8588 {"TRANS2", run_trans2test, 0},
8589 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8590 {"TORTURE",run_torture, FLAG_MULTIPROC},
8591 {"RANDOMIPC", run_randomipc, 0},
8592 {"NEGNOWAIT", run_negprot_nowait, 0},
8593 {"NBENCH", run_nbench, 0},
8594 {"NBENCH2", run_nbench2, 0},
8595 {"OPLOCK1", run_oplock1, 0},
8596 {"OPLOCK2", run_oplock2, 0},
8597 {"OPLOCK4", run_oplock4, 0},
8598 {"DIR", run_dirtest, 0},
8599 {"DIR1", run_dirtest1, 0},
8600 {"DIR-CREATETIME", run_dir_createtime, 0},
8601 {"DENY1", torture_denytest1, 0},
8602 {"DENY2", torture_denytest2, 0},
8603 {"TCON", run_tcon_test, 0},
8604 {"TCONDEV", run_tcon_devtype_test, 0},
8605 {"RW1", run_readwritetest, 0},
8606 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8607 {"RW3", run_readwritelarge, 0},
8608 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8609 {"OPEN", run_opentest, 0},
8610 {"POSIX", run_simple_posix_open_test, 0},
8611 {"POSIX-APPEND", run_posix_append, 0},
8612 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8613 {"ASYNC-ECHO", run_async_echo, 0},
8614 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8615 { "SHORTNAME-TEST", run_shortname_test, 0},
8616 { "ADDRCHANGE", run_addrchange, 0},
8618 {"OPENATTR", run_openattrtest, 0},
8620 {"XCOPY", run_xcopy, 0},
8621 {"RENAME", run_rename, 0},
8622 {"DELETE", run_deletetest, 0},
8623 {"DELETE-LN", run_deletetest_ln, 0},
8624 {"PROPERTIES", run_properties, 0},
8625 {"MANGLE", torture_mangle, 0},
8626 {"MANGLE1", run_mangle1, 0},
8627 {"W2K", run_w2ktest, 0},
8628 {"TRANS2SCAN", torture_trans2_scan, 0},
8629 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8630 {"UTABLE", torture_utable, 0},
8631 {"CASETABLE", torture_casetable, 0},
8632 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8633 {"PIPE_NUMBER", run_pipe_number, 0},
8634 {"TCON2", run_tcon2_test, 0},
8635 {"IOCTL", torture_ioctl_test, 0},
8636 {"CHKPATH", torture_chkpath_test, 0},
8637 {"FDSESS", run_fdsesstest, 0},
8638 { "EATEST", run_eatest, 0},
8639 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8640 { "CHAIN1", run_chain1, 0},
8641 { "CHAIN2", run_chain2, 0},
8642 { "WINDOWS-WRITE", run_windows_write, 0},
8643 { "NTTRANS-CREATE", run_nttrans_create, 0},
8644 { "CLI_ECHO", run_cli_echo, 0},
8645 { "GETADDRINFO", run_getaddrinfo_send, 0},
8646 { "TLDAP", run_tldap },
8647 { "STREAMERROR", run_streamerror },
8648 { "NOTIFY-BENCH", run_notify_bench },
8649 { "BAD-NBT-SESSION", run_bad_nbt_session },
8650 { "SMB-ANY-CONNECT", run_smb_any_connect },
8651 { "NOTIFY-ONLINE", run_notify_online },
8652 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8653 { "LOCAL-GENCACHE", run_local_gencache, 0},
8654 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8655 { "LOCAL-BASE64", run_local_base64, 0},
8656 { "LOCAL-RBTREE", run_local_rbtree, 0},
8657 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8658 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8659 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8660 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8661 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8662 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8663 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8664 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8669 /****************************************************************************
8670 run a specified test or "ALL"
8671 ****************************************************************************/
8672 static bool run_test(const char *name)
8679 if (strequal(name,"ALL")) {
8680 for (i=0;torture_ops[i].name;i++) {
8681 run_test(torture_ops[i].name);
8686 for (i=0;torture_ops[i].name;i++) {
8687 fstr_sprintf(randomfname, "\\XX%x",
8688 (unsigned)random());
8690 if (strequal(name, torture_ops[i].name)) {
8692 printf("Running %s\n", name);
8693 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8694 t = create_procs(torture_ops[i].fn, &result);
8697 printf("TEST %s FAILED!\n", name);
8700 struct timeval start;
8701 start = timeval_current();
8702 if (!torture_ops[i].fn(0)) {
8704 printf("TEST %s FAILED!\n", name);
8706 t = timeval_elapsed(&start);
8708 printf("%s took %g secs\n\n", name, t);
8713 printf("Did not find a test named %s\n", name);
8721 static void usage(void)
8725 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8726 printf("Please use samba4 torture.\n\n");
8728 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8730 printf("\t-d debuglevel\n");
8731 printf("\t-U user%%pass\n");
8732 printf("\t-k use kerberos\n");
8733 printf("\t-N numprocs\n");
8734 printf("\t-n my_netbios_name\n");
8735 printf("\t-W workgroup\n");
8736 printf("\t-o num_operations\n");
8737 printf("\t-O socket_options\n");
8738 printf("\t-m maximum protocol\n");
8739 printf("\t-L use oplocks\n");
8740 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8741 printf("\t-A showall\n");
8742 printf("\t-p port\n");
8743 printf("\t-s seed\n");
8744 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8745 printf("\t-f filename filename to test\n");
8748 printf("tests are:");
8749 for (i=0;torture_ops[i].name;i++) {
8750 printf(" %s", torture_ops[i].name);
8754 printf("default test is ALL\n");
8759 /****************************************************************************
8761 ****************************************************************************/
8762 int main(int argc,char *argv[])
8768 bool correct = True;
8769 TALLOC_CTX *frame = talloc_stackframe();
8770 int seed = time(NULL);
8772 #ifdef HAVE_SETBUFFER
8773 setbuffer(stdout, NULL, 0);
8776 setup_logging("smbtorture", DEBUG_STDOUT);
8780 if (is_default_dyn_CONFIGFILE()) {
8781 if(getenv("SMB_CONF_PATH")) {
8782 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8785 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8792 for(p = argv[1]; *p; p++)
8796 if (strncmp(argv[1], "//", 2)) {
8800 fstrcpy(host, &argv[1][2]);
8801 p = strchr_m(&host[2],'/');
8806 fstrcpy(share, p+1);
8808 fstrcpy(myname, get_myname(talloc_tos()));
8810 fprintf(stderr, "Failed to get my hostname.\n");
8814 if (*username == 0 && getenv("LOGNAME")) {
8815 fstrcpy(username,getenv("LOGNAME"));
8821 fstrcpy(workgroup, lp_workgroup());
8823 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8827 port_to_use = atoi(optarg);
8830 seed = atoi(optarg);
8833 fstrcpy(workgroup,optarg);
8836 max_protocol = interpret_protocol(optarg, max_protocol);
8839 nprocs = atoi(optarg);
8842 torture_numops = atoi(optarg);
8845 lp_set_cmdline("log level", optarg);
8854 local_path = optarg;
8857 torture_showall = True;
8860 fstrcpy(myname, optarg);
8863 client_txt = optarg;
8870 use_kerberos = True;
8872 d_printf("No kerberos support compiled in\n");
8878 fstrcpy(username,optarg);
8879 p = strchr_m(username,'%');
8882 fstrcpy(password, p+1);
8887 fstrcpy(multishare_conn_fname, optarg);
8888 use_multishare_conn = True;
8891 torture_blocksize = atoi(optarg);
8894 test_filename = SMB_STRDUP(optarg);
8897 printf("Unknown option %c (%d)\n", (char)opt, opt);
8902 d_printf("using seed %d\n", seed);
8906 if(use_kerberos && !gotuser) gotpass = True;
8909 p = getpass("Password:");
8911 fstrcpy(password, p);
8916 printf("host=%s share=%s user=%s myname=%s\n",
8917 host, share, username, myname);
8919 if (argc == optind) {
8920 correct = run_test("ALL");
8922 for (i=optind;i<argc;i++) {
8923 if (!run_test(argv[i])) {