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)
215 frame = talloc_stackframe();
217 iov[0].iov_base = len_buf;
218 iov[0].iov_len = sizeof(len_buf);
220 /* put in the destination name */
222 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
224 if (iov[1].iov_base == NULL) {
227 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
228 talloc_get_size(iov[1].iov_base));
232 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
234 if (iov[2].iov_base == NULL) {
237 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
238 talloc_get_size(iov[2].iov_base));
240 /* Deliberately corrupt the name len (first byte) */
241 *((uint8_t *)iov[2].iov_base) = 100;
243 /* send a session request (RFC 1002) */
244 /* setup the packet length
245 * Remove four bytes from the length count, since the length
246 * field in the NBT Session Service header counts the number
247 * of bytes which follow. The cli_send_smb() function knows
248 * about this and accounts for those four bytes.
252 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
253 SCVAL(len_buf,0,0x81);
255 len = write_data_iov(fd, iov, 3);
259 len = read_smb(fd, talloc_tos(), &inbuf, &err);
265 if (CVAL(inbuf,0) != 0x82) {
266 /* This is the wrong place to put the error... JRA. */
276 /* Insert a NULL at the first separator of the given path and return a pointer
277 * to the remainder of the string.
280 terminate_path_at_separator(char * path)
288 if ((p = strchr_m(path, '/'))) {
293 if ((p = strchr_m(path, '\\'))) {
303 parse a //server/share type UNC name
305 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
306 char **hostname, char **sharename)
310 *hostname = *sharename = NULL;
312 if (strncmp(unc_name, "\\\\", 2) &&
313 strncmp(unc_name, "//", 2)) {
317 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
318 p = terminate_path_at_separator(*hostname);
321 *sharename = talloc_strdup(mem_ctx, p);
322 terminate_path_at_separator(*sharename);
325 if (*hostname && *sharename) {
329 TALLOC_FREE(*hostname);
330 TALLOC_FREE(*sharename);
334 static bool torture_open_connection_share(struct cli_state **c,
335 const char *hostname,
336 const char *sharename)
342 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
344 flags |= CLI_FULL_CONNECTION_OPLOCKS;
345 if (use_level_II_oplocks)
346 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
348 status = cli_full_connection(c, myname,
349 hostname, NULL, port_to_use,
352 password, flags, signing_state);
353 if (!NT_STATUS_IS_OK(status)) {
354 printf("failed to open share connection: //%s/%s port:%d - %s\n",
355 hostname, sharename, port_to_use, nt_errstr(status));
359 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
362 return force_cli_encryption(*c,
368 bool torture_open_connection(struct cli_state **c, int conn_index)
370 char **unc_list = NULL;
371 int num_unc_names = 0;
374 if (use_multishare_conn==True) {
376 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
377 if (!unc_list || num_unc_names <= 0) {
378 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
382 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
384 printf("Failed to parse UNC name %s\n",
385 unc_list[conn_index % num_unc_names]);
386 TALLOC_FREE(unc_list);
390 result = torture_open_connection_share(c, h, s);
392 /* h, s were copied earlier */
393 TALLOC_FREE(unc_list);
397 return torture_open_connection_share(c, host, share);
400 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
402 uint16 old_vuid = cli->vuid;
403 fstring old_user_name;
404 size_t passlen = strlen(password);
408 fstrcpy(old_user_name, cli->user_name);
410 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
414 *new_vuid = cli->vuid;
415 cli->vuid = old_vuid;
416 status = cli_set_username(cli, old_user_name);
417 if (!NT_STATUS_IS_OK(status)) {
424 bool torture_close_connection(struct cli_state *c)
429 status = cli_tdis(c);
430 if (!NT_STATUS_IS_OK(status)) {
431 printf("tdis failed (%s)\n", nt_errstr(status));
441 /* check if the server produced the expected error code */
442 static bool check_error(int line, struct cli_state *c,
443 uint8 eclass, uint32 ecode, NTSTATUS nterr)
445 if (cli_is_dos_error(c)) {
449 /* Check DOS error */
451 cli_dos_error(c, &cclass, &num);
453 if (eclass != cclass || ecode != num) {
454 printf("unexpected error code class=%d code=%d\n",
455 (int)cclass, (int)num);
456 printf(" expected %d/%d %s (line=%d)\n",
457 (int)eclass, (int)ecode, nt_errstr(nterr), line);
466 status = cli_nt_error(c);
468 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
469 printf("unexpected error code %s\n", nt_errstr(status));
470 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
479 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
481 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
482 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
488 static bool rw_torture(struct cli_state *c)
490 const char *lockfname = "\\torture.lck";
494 pid_t pid2, pid = getpid();
500 memset(buf, '\0', sizeof(buf));
502 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
504 if (!NT_STATUS_IS_OK(status)) {
505 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
507 if (!NT_STATUS_IS_OK(status)) {
508 printf("open of %s failed (%s)\n",
509 lockfname, nt_errstr(status));
513 for (i=0;i<torture_numops;i++) {
514 unsigned n = (unsigned)sys_random()%10;
517 printf("%d\r", i); fflush(stdout);
519 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
521 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
525 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
527 if (!NT_STATUS_IS_OK(status)) {
528 printf("open failed (%s)\n", nt_errstr(status));
533 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
535 if (!NT_STATUS_IS_OK(status)) {
536 printf("write failed (%s)\n", nt_errstr(status));
541 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
542 sizeof(pid)+(j*sizeof(buf)),
544 if (!NT_STATUS_IS_OK(status)) {
545 printf("write failed (%s)\n",
553 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
554 printf("read failed (%s)\n", cli_errstr(c));
559 printf("data corruption!\n");
563 status = cli_close(c, fnum);
564 if (!NT_STATUS_IS_OK(status)) {
565 printf("close failed (%s)\n", nt_errstr(status));
569 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
570 if (!NT_STATUS_IS_OK(status)) {
571 printf("unlink failed (%s)\n", nt_errstr(status));
575 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
576 if (!NT_STATUS_IS_OK(status)) {
577 printf("unlock failed (%s)\n", nt_errstr(status));
583 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
590 static bool run_torture(int dummy)
592 struct cli_state *cli;
597 cli_sockopt(cli, sockops);
599 ret = rw_torture(cli);
601 if (!torture_close_connection(cli)) {
608 static bool rw_torture3(struct cli_state *c, char *lockfname)
610 uint16_t fnum = (uint16_t)-1;
615 unsigned countprev = 0;
618 NTSTATUS status = NT_STATUS_OK;
621 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
623 SIVAL(buf, i, sys_random());
628 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
629 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
632 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
634 if (!NT_STATUS_IS_OK(status)) {
635 printf("first open read/write of %s failed (%s)\n",
636 lockfname, nt_errstr(status));
642 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
644 status = cli_open(c, lockfname, O_RDONLY,
646 if (!NT_STATUS_IS_OK(status)) {
651 if (!NT_STATUS_IS_OK(status)) {
652 printf("second open read-only of %s failed (%s)\n",
653 lockfname, nt_errstr(status));
659 for (count = 0; count < sizeof(buf); count += sent)
661 if (count >= countprev) {
662 printf("%d %8d\r", i, count);
665 countprev += (sizeof(buf) / 20);
670 sent = ((unsigned)sys_random()%(20))+ 1;
671 if (sent > sizeof(buf) - count)
673 sent = sizeof(buf) - count;
676 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
677 count, (size_t)sent, NULL);
678 if (!NT_STATUS_IS_OK(status)) {
679 printf("write failed (%s)\n",
686 sent = cli_read(c, fnum, buf_rd+count, count,
690 printf("read failed offset:%d size:%ld (%s)\n",
691 count, (unsigned long)sizeof(buf)-count,
698 if (memcmp(buf_rd+count, buf+count, sent) != 0)
700 printf("read/write compare failed\n");
701 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
710 status = cli_close(c, fnum);
711 if (!NT_STATUS_IS_OK(status)) {
712 printf("close failed (%s)\n", nt_errstr(status));
719 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
721 const char *lockfname = "\\torture2.lck";
731 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
732 if (!NT_STATUS_IS_OK(status)) {
733 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
736 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
738 if (!NT_STATUS_IS_OK(status)) {
739 printf("first open read/write of %s failed (%s)\n",
740 lockfname, nt_errstr(status));
744 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
745 if (!NT_STATUS_IS_OK(status)) {
746 printf("second open read-only of %s failed (%s)\n",
747 lockfname, nt_errstr(status));
748 cli_close(c1, fnum1);
752 for (i = 0; i < torture_numops; i++)
754 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
756 printf("%d\r", i); fflush(stdout);
759 generate_random_buffer((unsigned char *)buf, buf_size);
761 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
763 if (!NT_STATUS_IS_OK(status)) {
764 printf("write failed (%s)\n", nt_errstr(status));
769 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
770 printf("read failed (%s)\n", cli_errstr(c2));
771 printf("read %d, expected %ld\n", (int)bytes_read,
772 (unsigned long)buf_size);
777 if (memcmp(buf_rd, buf, buf_size) != 0)
779 printf("read/write compare failed\n");
785 status = cli_close(c2, fnum2);
786 if (!NT_STATUS_IS_OK(status)) {
787 printf("close failed (%s)\n", nt_errstr(status));
791 status = cli_close(c1, fnum1);
792 if (!NT_STATUS_IS_OK(status)) {
793 printf("close failed (%s)\n", nt_errstr(status));
797 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
798 if (!NT_STATUS_IS_OK(status)) {
799 printf("unlink failed (%s)\n", nt_errstr(status));
806 static bool run_readwritetest(int dummy)
808 struct cli_state *cli1, *cli2;
809 bool test1, test2 = False;
811 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
814 cli_sockopt(cli1, sockops);
815 cli_sockopt(cli2, sockops);
817 printf("starting readwritetest\n");
819 test1 = rw_torture2(cli1, cli2);
820 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
823 test2 = rw_torture2(cli1, cli1);
824 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
827 if (!torture_close_connection(cli1)) {
831 if (!torture_close_connection(cli2)) {
835 return (test1 && test2);
838 static bool run_readwritemulti(int dummy)
840 struct cli_state *cli;
845 cli_sockopt(cli, sockops);
847 printf("run_readwritemulti: fname %s\n", randomfname);
848 test = rw_torture3(cli, randomfname);
850 if (!torture_close_connection(cli)) {
857 static bool run_readwritelarge_internal(int max_xmit_k)
859 static struct cli_state *cli1;
861 const char *lockfname = "\\large.dat";
867 if (!torture_open_connection(&cli1, 0)) {
870 cli_sockopt(cli1, sockops);
871 memset(buf,'\0',sizeof(buf));
873 cli1->max_xmit = max_xmit_k*1024;
875 if (signing_state == Required) {
876 /* Horrible cheat to force
877 multiple signed outstanding
878 packets against a Samba server.
880 cli1->is_samba = false;
883 printf("starting readwritelarge_internal\n");
885 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
887 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
889 if (!NT_STATUS_IS_OK(status)) {
890 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
894 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
896 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
898 if (!NT_STATUS_IS_OK(status)) {
899 printf("qfileinfo failed (%s)\n", nt_errstr(status));
903 if (fsize == sizeof(buf))
904 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
905 (unsigned long)fsize);
907 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
908 (unsigned long)fsize);
912 status = cli_close(cli1, fnum1);
913 if (!NT_STATUS_IS_OK(status)) {
914 printf("close failed (%s)\n", nt_errstr(status));
918 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
919 if (!NT_STATUS_IS_OK(status)) {
920 printf("unlink failed (%s)\n", nt_errstr(status));
924 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
926 if (!NT_STATUS_IS_OK(status)) {
927 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
931 cli1->max_xmit = 4*1024;
933 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
935 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
937 if (!NT_STATUS_IS_OK(status)) {
938 printf("qfileinfo failed (%s)\n", nt_errstr(status));
942 if (fsize == sizeof(buf))
943 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
944 (unsigned long)fsize);
946 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
947 (unsigned long)fsize);
952 /* ToDo - set allocation. JRA */
953 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
954 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
957 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
959 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
963 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
966 status = cli_close(cli1, fnum1);
967 if (!NT_STATUS_IS_OK(status)) {
968 printf("close failed (%s)\n", nt_errstr(status));
972 if (!torture_close_connection(cli1)) {
978 static bool run_readwritelarge(int dummy)
980 return run_readwritelarge_internal(128);
983 static bool run_readwritelarge_signtest(int dummy)
986 signing_state = Required;
987 ret = run_readwritelarge_internal(2);
988 signing_state = Undefined;
995 #define ival(s) strtol(s, NULL, 0)
997 /* run a test that simulates an approximate netbench client load */
998 static bool run_netbench(int client)
1000 struct cli_state *cli;
1005 const char *params[20];
1006 bool correct = True;
1012 cli_sockopt(cli, sockops);
1016 slprintf(cname,sizeof(cname)-1, "client%d", client);
1018 f = fopen(client_txt, "r");
1025 while (fgets(line, sizeof(line)-1, f)) {
1029 line[strlen(line)-1] = 0;
1031 /* printf("[%d] %s\n", line_count, line); */
1033 all_string_sub(line,"client1", cname, sizeof(line));
1035 /* parse the command parameters */
1036 params[0] = strtok_r(line, " ", &saveptr);
1038 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1042 if (i < 2) continue;
1044 if (!strncmp(params[0],"SMB", 3)) {
1045 printf("ERROR: You are using a dbench 1 load file\n");
1049 if (!strcmp(params[0],"NTCreateX")) {
1050 nb_createx(params[1], ival(params[2]), ival(params[3]),
1052 } else if (!strcmp(params[0],"Close")) {
1053 nb_close(ival(params[1]));
1054 } else if (!strcmp(params[0],"Rename")) {
1055 nb_rename(params[1], params[2]);
1056 } else if (!strcmp(params[0],"Unlink")) {
1057 nb_unlink(params[1]);
1058 } else if (!strcmp(params[0],"Deltree")) {
1059 nb_deltree(params[1]);
1060 } else if (!strcmp(params[0],"Rmdir")) {
1061 nb_rmdir(params[1]);
1062 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1063 nb_qpathinfo(params[1]);
1064 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1065 nb_qfileinfo(ival(params[1]));
1066 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1067 nb_qfsinfo(ival(params[1]));
1068 } else if (!strcmp(params[0],"FIND_FIRST")) {
1069 nb_findfirst(params[1]);
1070 } else if (!strcmp(params[0],"WriteX")) {
1071 nb_writex(ival(params[1]),
1072 ival(params[2]), ival(params[3]), ival(params[4]));
1073 } else if (!strcmp(params[0],"ReadX")) {
1074 nb_readx(ival(params[1]),
1075 ival(params[2]), ival(params[3]), ival(params[4]));
1076 } else if (!strcmp(params[0],"Flush")) {
1077 nb_flush(ival(params[1]));
1079 printf("Unknown operation %s\n", params[0]);
1087 if (!torture_close_connection(cli)) {
1095 /* run a test that simulates an approximate netbench client load */
1096 static bool run_nbench(int dummy)
1099 bool correct = True;
1105 signal(SIGALRM, nb_alarm);
1107 t = create_procs(run_netbench, &correct);
1110 printf("\nThroughput %g MB/sec\n",
1111 1.0e-6 * nbio_total() / t);
1117 This test checks for two things:
1119 1) correct support for retaining locks over a close (ie. the server
1120 must not use posix semantics)
1121 2) support for lock timeouts
1123 static bool run_locktest1(int dummy)
1125 struct cli_state *cli1, *cli2;
1126 const char *fname = "\\lockt1.lck";
1127 uint16_t fnum1, fnum2, fnum3;
1129 unsigned lock_timeout;
1132 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1135 cli_sockopt(cli1, sockops);
1136 cli_sockopt(cli2, sockops);
1138 printf("starting locktest1\n");
1140 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1142 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1144 if (!NT_STATUS_IS_OK(status)) {
1145 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1149 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1150 if (!NT_STATUS_IS_OK(status)) {
1151 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1155 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1156 if (!NT_STATUS_IS_OK(status)) {
1157 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1161 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1162 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1167 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1168 printf("lock2 succeeded! This is a locking bug\n");
1171 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1172 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1176 lock_timeout = (1 + (random() % 20));
1177 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1179 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1180 printf("lock3 succeeded! This is a locking bug\n");
1183 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1184 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1188 if (ABS(t2 - t1) < lock_timeout-1) {
1189 printf("error: This server appears not to support timed lock requests\n");
1192 printf("server slept for %u seconds for a %u second timeout\n",
1193 (unsigned int)(t2-t1), lock_timeout);
1195 status = cli_close(cli1, fnum2);
1196 if (!NT_STATUS_IS_OK(status)) {
1197 printf("close1 failed (%s)\n", nt_errstr(status));
1201 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1202 printf("lock4 succeeded! This is a locking bug\n");
1205 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1206 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1209 status = cli_close(cli1, fnum1);
1210 if (!NT_STATUS_IS_OK(status)) {
1211 printf("close2 failed (%s)\n", nt_errstr(status));
1215 status = cli_close(cli2, fnum3);
1216 if (!NT_STATUS_IS_OK(status)) {
1217 printf("close3 failed (%s)\n", nt_errstr(status));
1221 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 printf("unlink failed (%s)\n", nt_errstr(status));
1228 if (!torture_close_connection(cli1)) {
1232 if (!torture_close_connection(cli2)) {
1236 printf("Passed locktest1\n");
1241 this checks to see if a secondary tconx can use open files from an
1244 static bool run_tcon_test(int dummy)
1246 static struct cli_state *cli;
1247 const char *fname = "\\tcontest.tmp";
1249 uint16 cnum1, cnum2, cnum3;
1250 uint16 vuid1, vuid2;
1255 memset(buf, '\0', sizeof(buf));
1257 if (!torture_open_connection(&cli, 0)) {
1260 cli_sockopt(cli, sockops);
1262 printf("starting tcontest\n");
1264 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1266 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1267 if (!NT_STATUS_IS_OK(status)) {
1268 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1275 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1276 if (!NT_STATUS_IS_OK(status)) {
1277 printf("initial write failed (%s)", nt_errstr(status));
1281 status = cli_tcon_andx(cli, share, "?????",
1282 password, strlen(password)+1);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 printf("%s refused 2nd tree connect (%s)\n", host,
1291 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1292 vuid2 = cli->vuid + 1;
1294 /* try a write with the wrong tid */
1297 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1298 if (NT_STATUS_IS_OK(status)) {
1299 printf("* server allows write with wrong TID\n");
1302 printf("server fails write with wrong TID : %s\n",
1307 /* try a write with an invalid tid */
1310 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1311 if (NT_STATUS_IS_OK(status)) {
1312 printf("* server allows write with invalid TID\n");
1315 printf("server fails write with invalid TID : %s\n",
1319 /* try a write with an invalid vuid */
1323 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1324 if (NT_STATUS_IS_OK(status)) {
1325 printf("* server allows write with invalid VUID\n");
1328 printf("server fails write with invalid VUID : %s\n",
1335 status = cli_close(cli, fnum1);
1336 if (!NT_STATUS_IS_OK(status)) {
1337 printf("close failed (%s)\n", nt_errstr(status));
1343 status = cli_tdis(cli);
1344 if (!NT_STATUS_IS_OK(status)) {
1345 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1351 if (!torture_close_connection(cli)) {
1360 checks for old style tcon support
1362 static bool run_tcon2_test(int dummy)
1364 static struct cli_state *cli;
1365 uint16 cnum, max_xmit;
1369 if (!torture_open_connection(&cli, 0)) {
1372 cli_sockopt(cli, sockops);
1374 printf("starting tcon2 test\n");
1376 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1380 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1384 if (!NT_STATUS_IS_OK(status)) {
1385 printf("tcon2 failed : %s\n", nt_errstr(status));
1387 printf("tcon OK : max_xmit=%d cnum=%d\n",
1388 (int)max_xmit, (int)cnum);
1391 if (!torture_close_connection(cli)) {
1395 printf("Passed tcon2 test\n");
1399 static bool tcon_devtest(struct cli_state *cli,
1400 const char *myshare, const char *devtype,
1401 const char *return_devtype,
1402 NTSTATUS expected_error)
1407 status = cli_tcon_andx(cli, myshare, devtype,
1408 password, strlen(password)+1);
1410 if (NT_STATUS_IS_OK(expected_error)) {
1411 if (NT_STATUS_IS_OK(status)) {
1412 if (strcmp(cli->dev, return_devtype) == 0) {
1415 printf("tconX to share %s with type %s "
1416 "succeeded but returned the wrong "
1417 "device type (got [%s] but should have got [%s])\n",
1418 myshare, devtype, cli->dev, return_devtype);
1422 printf("tconX to share %s with type %s "
1423 "should have succeeded but failed\n",
1429 if (NT_STATUS_IS_OK(status)) {
1430 printf("tconx to share %s with type %s "
1431 "should have failed but succeeded\n",
1435 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1439 printf("Returned unexpected error\n");
1448 checks for correct tconX support
1450 static bool run_tcon_devtype_test(int dummy)
1452 static struct cli_state *cli1 = NULL;
1457 status = cli_full_connection(&cli1, myname,
1458 host, NULL, port_to_use,
1460 username, workgroup,
1461 password, flags, signing_state);
1463 if (!NT_STATUS_IS_OK(status)) {
1464 printf("could not open connection\n");
1468 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1471 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1474 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1477 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1480 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1483 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1486 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1489 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1492 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1495 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1501 printf("Passed tcondevtest\n");
1508 This test checks that
1510 1) the server supports multiple locking contexts on the one SMB
1511 connection, distinguished by PID.
1513 2) the server correctly fails overlapping locks made by the same PID (this
1514 goes against POSIX behaviour, which is why it is tricky to implement)
1516 3) the server denies unlock requests by an incorrect client PID
1518 static bool run_locktest2(int dummy)
1520 static struct cli_state *cli;
1521 const char *fname = "\\lockt2.lck";
1522 uint16_t fnum1, fnum2, fnum3;
1523 bool correct = True;
1526 if (!torture_open_connection(&cli, 0)) {
1530 cli_sockopt(cli, sockops);
1532 printf("starting locktest2\n");
1534 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1538 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1539 if (!NT_STATUS_IS_OK(status)) {
1540 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1544 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1545 if (!NT_STATUS_IS_OK(status)) {
1546 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1552 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1553 if (!NT_STATUS_IS_OK(status)) {
1554 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1560 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1561 printf("lock1 failed (%s)\n", cli_errstr(cli));
1565 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1566 printf("WRITE lock1 succeeded! This is a locking bug\n");
1569 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1570 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1573 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1574 printf("WRITE lock2 succeeded! This is a locking bug\n");
1577 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1578 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1581 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1582 printf("READ lock2 succeeded! This is a locking bug\n");
1585 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1586 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1589 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1590 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1593 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1594 printf("unlock at 100 succeeded! This is a locking bug\n");
1598 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1599 printf("unlock1 succeeded! This is a locking bug\n");
1602 if (!check_error(__LINE__, cli,
1604 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1607 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1608 printf("unlock2 succeeded! This is a locking bug\n");
1611 if (!check_error(__LINE__, cli,
1613 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1616 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1617 printf("lock3 succeeded! This is a locking bug\n");
1620 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1625 status = cli_close(cli, fnum1);
1626 if (!NT_STATUS_IS_OK(status)) {
1627 printf("close1 failed (%s)\n", nt_errstr(status));
1631 status = cli_close(cli, fnum2);
1632 if (!NT_STATUS_IS_OK(status)) {
1633 printf("close2 failed (%s)\n", nt_errstr(status));
1637 status = cli_close(cli, fnum3);
1638 if (!NT_STATUS_IS_OK(status)) {
1639 printf("close3 failed (%s)\n", nt_errstr(status));
1643 if (!torture_close_connection(cli)) {
1647 printf("locktest2 finished\n");
1654 This test checks that
1656 1) the server supports the full offset range in lock requests
1658 static bool run_locktest3(int dummy)
1660 static struct cli_state *cli1, *cli2;
1661 const char *fname = "\\lockt3.lck";
1662 uint16_t fnum1, fnum2;
1665 bool correct = True;
1668 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1670 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1673 cli_sockopt(cli1, sockops);
1674 cli_sockopt(cli2, sockops);
1676 printf("starting locktest3\n");
1678 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1680 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1682 if (!NT_STATUS_IS_OK(status)) {
1683 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1687 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1688 if (!NT_STATUS_IS_OK(status)) {
1689 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1693 for (offset=i=0;i<torture_numops;i++) {
1695 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1696 printf("lock1 %d failed (%s)\n",
1702 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1703 printf("lock2 %d failed (%s)\n",
1710 for (offset=i=0;i<torture_numops;i++) {
1713 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1714 printf("error: lock1 %d succeeded!\n", i);
1718 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1719 printf("error: lock2 %d succeeded!\n", i);
1723 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1724 printf("error: lock3 %d succeeded!\n", i);
1728 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1729 printf("error: lock4 %d succeeded!\n", i);
1734 for (offset=i=0;i<torture_numops;i++) {
1737 status = cli_unlock(cli1, fnum1, offset-1, 1);
1738 if (!NT_STATUS_IS_OK(status)) {
1739 printf("unlock1 %d failed (%s)\n",
1745 status = cli_unlock(cli2, fnum2, offset-2, 1);
1746 if (!NT_STATUS_IS_OK(status)) {
1747 printf("unlock2 %d failed (%s)\n",
1754 status = cli_close(cli1, fnum1);
1755 if (!NT_STATUS_IS_OK(status)) {
1756 printf("close1 failed (%s)\n", nt_errstr(status));
1760 status = cli_close(cli2, fnum2);
1761 if (!NT_STATUS_IS_OK(status)) {
1762 printf("close2 failed (%s)\n", nt_errstr(status));
1766 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1767 if (!NT_STATUS_IS_OK(status)) {
1768 printf("unlink failed (%s)\n", nt_errstr(status));
1772 if (!torture_close_connection(cli1)) {
1776 if (!torture_close_connection(cli2)) {
1780 printf("finished locktest3\n");
1785 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1786 printf("** "); correct = False; \
1790 looks at overlapping locks
1792 static bool run_locktest4(int dummy)
1794 static struct cli_state *cli1, *cli2;
1795 const char *fname = "\\lockt4.lck";
1796 uint16_t fnum1, fnum2, f;
1799 bool correct = True;
1802 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1806 cli_sockopt(cli1, sockops);
1807 cli_sockopt(cli2, sockops);
1809 printf("starting locktest4\n");
1811 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1813 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1814 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1816 memset(buf, 0, sizeof(buf));
1818 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1820 if (!NT_STATUS_IS_OK(status)) {
1821 printf("Failed to create file: %s\n", nt_errstr(status));
1826 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1827 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1828 EXPECTED(ret, False);
1829 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1831 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1832 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1833 EXPECTED(ret, True);
1834 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1836 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1837 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1838 EXPECTED(ret, False);
1839 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1841 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1842 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1843 EXPECTED(ret, True);
1844 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1846 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1847 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1848 EXPECTED(ret, False);
1849 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1851 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1852 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1853 EXPECTED(ret, True);
1854 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1856 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1857 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1858 EXPECTED(ret, True);
1859 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1861 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1862 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1863 EXPECTED(ret, False);
1864 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1866 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1867 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1868 EXPECTED(ret, False);
1869 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1871 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1872 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1873 EXPECTED(ret, True);
1874 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1876 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1877 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1878 EXPECTED(ret, False);
1879 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1881 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1882 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1883 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1884 EXPECTED(ret, False);
1885 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1888 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1889 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1890 EXPECTED(ret, False);
1891 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1893 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1895 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1897 ret = NT_STATUS_IS_OK(status);
1899 EXPECTED(ret, False);
1900 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1903 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1904 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1905 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1906 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1907 EXPECTED(ret, True);
1908 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1911 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1912 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1913 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1914 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1915 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1917 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1918 EXPECTED(ret, True);
1919 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1921 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1922 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1923 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1925 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1926 EXPECTED(ret, True);
1927 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1929 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1930 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1931 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1933 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1934 EXPECTED(ret, True);
1935 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1937 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1938 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1939 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1940 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1942 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1943 EXPECTED(ret, True);
1944 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1946 cli_close(cli1, fnum1);
1947 cli_close(cli2, fnum2);
1948 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1949 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1950 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1951 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1952 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1953 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1954 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1956 cli_close(cli1, fnum1);
1957 EXPECTED(ret, True);
1958 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1961 cli_close(cli1, fnum1);
1962 cli_close(cli2, fnum2);
1963 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1964 torture_close_connection(cli1);
1965 torture_close_connection(cli2);
1967 printf("finished locktest4\n");
1972 looks at lock upgrade/downgrade.
1974 static bool run_locktest5(int dummy)
1976 static struct cli_state *cli1, *cli2;
1977 const char *fname = "\\lockt5.lck";
1978 uint16_t fnum1, fnum2, fnum3;
1981 bool correct = True;
1984 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1988 cli_sockopt(cli1, sockops);
1989 cli_sockopt(cli2, sockops);
1991 printf("starting locktest5\n");
1993 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1995 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1996 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1997 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1999 memset(buf, 0, sizeof(buf));
2001 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2003 if (!NT_STATUS_IS_OK(status)) {
2004 printf("Failed to create file: %s\n", nt_errstr(status));
2009 /* Check for NT bug... */
2010 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2011 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2012 cli_close(cli1, fnum1);
2013 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2014 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2015 EXPECTED(ret, True);
2016 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2017 cli_close(cli1, fnum1);
2018 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2019 cli_unlock(cli1, fnum3, 0, 1);
2021 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2022 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2023 EXPECTED(ret, True);
2024 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2026 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2027 EXPECTED(ret, False);
2029 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2031 /* Unlock the process 2 lock. */
2032 cli_unlock(cli2, fnum2, 0, 4);
2034 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2035 EXPECTED(ret, False);
2037 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2039 /* Unlock the process 1 fnum3 lock. */
2040 cli_unlock(cli1, fnum3, 0, 4);
2042 /* Stack 2 more locks here. */
2043 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2044 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2046 EXPECTED(ret, True);
2047 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2049 /* Unlock the first process lock, then check this was the WRITE lock that was
2052 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2053 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2055 EXPECTED(ret, True);
2056 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2058 /* Unlock the process 2 lock. */
2059 cli_unlock(cli2, fnum2, 0, 4);
2061 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2063 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2064 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2065 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2067 EXPECTED(ret, True);
2068 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2070 /* Ensure the next unlock fails. */
2071 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2072 EXPECTED(ret, False);
2073 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2075 /* Ensure connection 2 can get a write lock. */
2076 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2077 EXPECTED(ret, True);
2079 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2083 cli_close(cli1, fnum1);
2084 cli_close(cli2, fnum2);
2085 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2086 if (!torture_close_connection(cli1)) {
2089 if (!torture_close_connection(cli2)) {
2093 printf("finished locktest5\n");
2099 tries the unusual lockingX locktype bits
2101 static bool run_locktest6(int dummy)
2103 static struct cli_state *cli;
2104 const char *fname[1] = { "\\lock6.txt" };
2109 if (!torture_open_connection(&cli, 0)) {
2113 cli_sockopt(cli, sockops);
2115 printf("starting locktest6\n");
2118 printf("Testing %s\n", fname[i]);
2120 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2122 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2123 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2124 cli_close(cli, fnum);
2125 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2127 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2128 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2129 cli_close(cli, fnum);
2130 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2132 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2135 torture_close_connection(cli);
2137 printf("finished locktest6\n");
2141 static bool run_locktest7(int dummy)
2143 struct cli_state *cli1;
2144 const char *fname = "\\lockt7.lck";
2147 bool correct = False;
2150 if (!torture_open_connection(&cli1, 0)) {
2154 cli_sockopt(cli1, sockops);
2156 printf("starting locktest7\n");
2158 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2160 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2162 memset(buf, 0, sizeof(buf));
2164 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2166 if (!NT_STATUS_IS_OK(status)) {
2167 printf("Failed to create file: %s\n", nt_errstr(status));
2171 cli_setpid(cli1, 1);
2173 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2174 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2177 printf("pid1 successfully locked range 130:4 for READ\n");
2180 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2181 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2184 printf("pid1 successfully read the range 130:4\n");
2187 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2188 if (!NT_STATUS_IS_OK(status)) {
2189 printf("pid1 unable to write to the range 130:4, error was "
2190 "%s\n", nt_errstr(status));
2191 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2192 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2196 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2200 cli_setpid(cli1, 2);
2202 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2203 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2205 printf("pid2 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("pid2 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("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2221 cli_setpid(cli1, 1);
2222 cli_unlock(cli1, fnum1, 130, 4);
2224 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2225 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2228 printf("pid1 successfully locked range 130:4 for WRITE\n");
2231 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2232 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2235 printf("pid1 successfully read the range 130:4\n");
2238 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2239 if (!NT_STATUS_IS_OK(status)) {
2240 printf("pid1 unable to write to the range 130:4, error was "
2241 "%s\n", nt_errstr(status));
2244 printf("pid1 successfully wrote to the range 130:4\n");
2247 cli_setpid(cli1, 2);
2249 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2250 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2251 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2252 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2256 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2260 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2261 if (!NT_STATUS_IS_OK(status)) {
2262 printf("pid2 unable to write to the range 130:4, error was "
2263 "%s\n", nt_errstr(status));
2264 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2265 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2269 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2273 cli_unlock(cli1, fnum1, 130, 0);
2277 cli_close(cli1, fnum1);
2278 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2279 torture_close_connection(cli1);
2281 printf("finished locktest7\n");
2286 * This demonstrates a problem with our use of GPFS share modes: A file
2287 * descriptor sitting in the pending close queue holding a GPFS share mode
2288 * blocks opening a file another time. Happens with Word 2007 temp files.
2289 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2290 * open is denied with NT_STATUS_SHARING_VIOLATION.
2293 static bool run_locktest8(int dummy)
2295 struct cli_state *cli1;
2296 const char *fname = "\\lockt8.lck";
2297 uint16_t fnum1, fnum2;
2299 bool correct = False;
2302 if (!torture_open_connection(&cli1, 0)) {
2306 cli_sockopt(cli1, sockops);
2308 printf("starting locktest8\n");
2310 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2312 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2314 if (!NT_STATUS_IS_OK(status)) {
2315 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2319 memset(buf, 0, sizeof(buf));
2321 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2322 if (!NT_STATUS_IS_OK(status)) {
2323 d_fprintf(stderr, "cli_open second time returned %s\n",
2328 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2329 printf("Unable to apply read lock on range 1:1, error was "
2330 "%s\n", cli_errstr(cli1));
2334 status = cli_close(cli1, fnum1);
2335 if (!NT_STATUS_IS_OK(status)) {
2336 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2340 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 d_fprintf(stderr, "cli_open third time returned %s\n",
2350 cli_close(cli1, fnum1);
2351 cli_close(cli1, fnum2);
2352 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2353 torture_close_connection(cli1);
2355 printf("finished locktest8\n");
2360 * This test is designed to be run in conjunction with
2361 * external NFS or POSIX locks taken in the filesystem.
2362 * It checks that the smbd server will block until the
2363 * lock is released and then acquire it. JRA.
2366 static bool got_alarm;
2367 static int alarm_fd;
2369 static void alarm_handler(int dummy)
2374 static void alarm_handler_parent(int dummy)
2379 static void do_local_lock(int read_fd, int write_fd)
2384 const char *local_pathname = NULL;
2387 local_pathname = talloc_asprintf(talloc_tos(),
2388 "%s/lockt9.lck", local_path);
2389 if (!local_pathname) {
2390 printf("child: alloc fail\n");
2394 unlink(local_pathname);
2395 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2397 printf("child: open of %s failed %s.\n",
2398 local_pathname, strerror(errno));
2402 /* Now take a fcntl lock. */
2403 lock.l_type = F_WRLCK;
2404 lock.l_whence = SEEK_SET;
2407 lock.l_pid = getpid();
2409 ret = fcntl(fd,F_SETLK,&lock);
2411 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2412 local_pathname, strerror(errno));
2415 printf("child: got lock 0:4 on file %s.\n",
2420 CatchSignal(SIGALRM, alarm_handler);
2422 /* Signal the parent. */
2423 if (write(write_fd, &c, 1) != 1) {
2424 printf("child: start signal fail %s.\n",
2431 /* Wait for the parent to be ready. */
2432 if (read(read_fd, &c, 1) != 1) {
2433 printf("child: reply signal fail %s.\n",
2441 printf("child: released lock 0:4 on file %s.\n",
2447 static bool run_locktest9(int dummy)
2449 struct cli_state *cli1;
2450 const char *fname = "\\lockt9.lck";
2452 bool correct = False;
2453 int pipe_in[2], pipe_out[2];
2457 struct timeval start;
2461 printf("starting locktest9\n");
2463 if (local_path == NULL) {
2464 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2468 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2473 if (child_pid == -1) {
2477 if (child_pid == 0) {
2479 do_local_lock(pipe_out[0], pipe_in[1]);
2489 ret = read(pipe_in[0], &c, 1);
2491 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2496 if (!torture_open_connection(&cli1, 0)) {
2500 cli_sockopt(cli1, sockops);
2502 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2504 if (!NT_STATUS_IS_OK(status)) {
2505 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2509 /* Ensure the child has the lock. */
2510 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2511 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2514 d_printf("Child has the lock.\n");
2517 /* Tell the child to wait 5 seconds then exit. */
2518 ret = write(pipe_out[1], &c, 1);
2520 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2525 /* Wait 20 seconds for the lock. */
2526 alarm_fd = cli1->fd;
2527 CatchSignal(SIGALRM, alarm_handler_parent);
2530 start = timeval_current();
2532 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2533 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2534 "%s\n", cli_errstr(cli1));
2539 seconds = timeval_elapsed(&start);
2541 printf("Parent got the lock after %.2f seconds.\n",
2544 status = cli_close(cli1, fnum);
2545 if (!NT_STATUS_IS_OK(status)) {
2546 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2553 cli_close(cli1, fnum);
2554 torture_close_connection(cli1);
2558 printf("finished locktest9\n");
2563 test whether fnums and tids open on one VC are available on another (a major
2566 static bool run_fdpasstest(int dummy)
2568 struct cli_state *cli1, *cli2;
2569 const char *fname = "\\fdpass.tst";
2574 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2577 cli_sockopt(cli1, sockops);
2578 cli_sockopt(cli2, sockops);
2580 printf("starting fdpasstest\n");
2582 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2584 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2586 if (!NT_STATUS_IS_OK(status)) {
2587 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2591 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2593 if (!NT_STATUS_IS_OK(status)) {
2594 printf("write failed (%s)\n", nt_errstr(status));
2598 cli2->vuid = cli1->vuid;
2599 cli2->cnum = cli1->cnum;
2600 cli2->pid = cli1->pid;
2602 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2603 printf("read succeeded! nasty security hole [%s]\n",
2608 cli_close(cli1, fnum1);
2609 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2611 torture_close_connection(cli1);
2612 torture_close_connection(cli2);
2614 printf("finished fdpasstest\n");
2618 static bool run_fdsesstest(int dummy)
2620 struct cli_state *cli;
2625 const char *fname = "\\fdsess.tst";
2626 const char *fname1 = "\\fdsess1.tst";
2633 if (!torture_open_connection(&cli, 0))
2635 cli_sockopt(cli, sockops);
2637 if (!torture_cli_session_setup2(cli, &new_vuid))
2640 saved_cnum = cli->cnum;
2641 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2643 new_cnum = cli->cnum;
2644 cli->cnum = saved_cnum;
2646 printf("starting fdsesstest\n");
2648 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2649 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2651 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2652 if (!NT_STATUS_IS_OK(status)) {
2653 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2657 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2659 if (!NT_STATUS_IS_OK(status)) {
2660 printf("write failed (%s)\n", nt_errstr(status));
2664 saved_vuid = cli->vuid;
2665 cli->vuid = new_vuid;
2667 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2668 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2672 /* Try to open a file with different vuid, samba cnum. */
2673 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2674 printf("create with different vuid, same cnum succeeded.\n");
2675 cli_close(cli, fnum2);
2676 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2678 printf("create with different vuid, same cnum failed.\n");
2679 printf("This will cause problems with service clients.\n");
2683 cli->vuid = saved_vuid;
2685 /* Try with same vuid, different cnum. */
2686 cli->cnum = new_cnum;
2688 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2689 printf("read succeeded with different cnum![%s]\n",
2694 cli->cnum = saved_cnum;
2695 cli_close(cli, fnum1);
2696 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2698 torture_close_connection(cli);
2700 printf("finished fdsesstest\n");
2705 This test checks that
2707 1) the server does not allow an unlink on a file that is open
2709 static bool run_unlinktest(int dummy)
2711 struct cli_state *cli;
2712 const char *fname = "\\unlink.tst";
2714 bool correct = True;
2717 if (!torture_open_connection(&cli, 0)) {
2721 cli_sockopt(cli, sockops);
2723 printf("starting unlink test\n");
2725 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2729 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2730 if (!NT_STATUS_IS_OK(status)) {
2731 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2735 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2736 printf("error: server allowed unlink on an open file\n");
2739 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2740 NT_STATUS_SHARING_VIOLATION);
2743 cli_close(cli, fnum);
2744 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2746 if (!torture_close_connection(cli)) {
2750 printf("unlink test finished\n");
2757 test how many open files this server supports on the one socket
2759 static bool run_maxfidtest(int dummy)
2761 struct cli_state *cli;
2763 uint16_t fnums[0x11000];
2766 bool correct = True;
2772 printf("failed to connect\n");
2776 cli_sockopt(cli, sockops);
2778 for (i=0; i<0x11000; i++) {
2779 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2780 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2782 if (!NT_STATUS_IS_OK(status)) {
2783 printf("open of %s failed (%s)\n",
2784 fname, nt_errstr(status));
2785 printf("maximum fnum is %d\n", i);
2793 printf("cleaning up\n");
2795 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2796 cli_close(cli, fnums[i]);
2798 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2799 if (!NT_STATUS_IS_OK(status)) {
2800 printf("unlink of %s failed (%s)\n",
2801 fname, nt_errstr(status));
2808 printf("maxfid test finished\n");
2809 if (!torture_close_connection(cli)) {
2815 /* generate a random buffer */
2816 static void rand_buf(char *buf, int len)
2819 *buf = (char)sys_random();
2824 /* send smb negprot commands, not reading the response */
2825 static bool run_negprot_nowait(int dummy)
2827 struct tevent_context *ev;
2829 struct cli_state *cli;
2830 bool correct = True;
2832 printf("starting negprot nowait test\n");
2834 ev = tevent_context_init(talloc_tos());
2839 if (!(cli = open_nbt_connection())) {
2844 for (i=0;i<50000;i++) {
2845 struct tevent_req *req;
2847 req = cli_negprot_send(ev, ev, cli);
2852 if (!tevent_req_poll(req, ev)) {
2853 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2861 if (torture_close_connection(cli)) {
2865 printf("finished negprot nowait test\n");
2870 /* send smb negprot commands, not reading the response */
2871 static bool run_bad_nbt_session(int dummy)
2873 struct nmb_name called, calling;
2874 struct sockaddr_storage ss;
2879 printf("starting bad nbt session test\n");
2881 make_nmb_name(&calling, myname, 0x0);
2882 make_nmb_name(&called , host, 0x20);
2884 if (!resolve_name(host, &ss, 0x20, true)) {
2885 d_fprintf(stderr, "Could not resolve name %s\n", host);
2889 status = open_socket_out(&ss, 139, 10000, &fd);
2890 if (!NT_STATUS_IS_OK(status)) {
2891 d_fprintf(stderr, "open_socket_out failed: %s\n",
2896 ret = cli_bad_session_request(fd, &calling, &called);
2899 d_fprintf(stderr, "open_socket_out failed: %s\n",
2904 printf("finished bad nbt session test\n");
2908 /* send random IPC commands */
2909 static bool run_randomipc(int dummy)
2911 char *rparam = NULL;
2913 unsigned int rdrcnt,rprcnt;
2915 int api, param_len, i;
2916 struct cli_state *cli;
2917 bool correct = True;
2920 printf("starting random ipc test\n");
2922 if (!torture_open_connection(&cli, 0)) {
2926 for (i=0;i<count;i++) {
2927 api = sys_random() % 500;
2928 param_len = (sys_random() % 64);
2930 rand_buf(param, param_len);
2935 param, param_len, 8,
2936 NULL, 0, BUFFER_SIZE,
2940 printf("%d/%d\r", i,count);
2943 printf("%d/%d\n", i, count);
2945 if (!torture_close_connection(cli)) {
2949 printf("finished random ipc test\n");
2956 static void browse_callback(const char *sname, uint32 stype,
2957 const char *comment, void *state)
2959 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2965 This test checks the browse list code
2968 static bool run_browsetest(int dummy)
2970 static struct cli_state *cli;
2971 bool correct = True;
2973 printf("starting browse test\n");
2975 if (!torture_open_connection(&cli, 0)) {
2979 printf("domain list:\n");
2980 cli_NetServerEnum(cli, cli->server_domain,
2981 SV_TYPE_DOMAIN_ENUM,
2982 browse_callback, NULL);
2984 printf("machine list:\n");
2985 cli_NetServerEnum(cli, cli->server_domain,
2987 browse_callback, NULL);
2989 if (!torture_close_connection(cli)) {
2993 printf("browse test finished\n");
3001 This checks how the getatr calls works
3003 static bool run_attrtest(int dummy)
3005 struct cli_state *cli;
3008 const char *fname = "\\attrib123456789.tst";
3009 bool correct = True;
3012 printf("starting attrib test\n");
3014 if (!torture_open_connection(&cli, 0)) {
3018 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3019 cli_open(cli, fname,
3020 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3021 cli_close(cli, fnum);
3023 status = cli_getatr(cli, fname, NULL, NULL, &t);
3024 if (!NT_STATUS_IS_OK(status)) {
3025 printf("getatr failed (%s)\n", nt_errstr(status));
3029 if (abs(t - time(NULL)) > 60*60*24*10) {
3030 printf("ERROR: SMBgetatr bug. time is %s",
3036 t2 = t-60*60*24; /* 1 day ago */
3038 status = cli_setatr(cli, fname, 0, t2);
3039 if (!NT_STATUS_IS_OK(status)) {
3040 printf("setatr failed (%s)\n", nt_errstr(status));
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));
3051 printf("ERROR: getatr/setatr bug. times are\n%s",
3053 printf("%s", ctime(&t2));
3057 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3059 if (!torture_close_connection(cli)) {
3063 printf("attrib test finished\n");
3070 This checks a couple of trans2 calls
3072 static bool run_trans2test(int dummy)
3074 struct cli_state *cli;
3077 time_t c_time, a_time, m_time;
3078 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3079 const char *fname = "\\trans2.tst";
3080 const char *dname = "\\trans2";
3081 const char *fname2 = "\\trans2\\trans2.tst";
3083 bool correct = True;
3087 printf("starting trans2 test\n");
3089 if (!torture_open_connection(&cli, 0)) {
3093 status = cli_get_fs_attr_info(cli, &fs_attr);
3094 if (!NT_STATUS_IS_OK(status)) {
3095 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3100 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3101 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3102 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3103 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3104 if (!NT_STATUS_IS_OK(status)) {
3105 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3109 status = cli_qfilename(cli, fnum, pname, sizeof(pname));
3110 if (!NT_STATUS_IS_OK(status)) {
3111 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3115 if (strcmp(pname, fname)) {
3116 printf("qfilename gave different name? [%s] [%s]\n",
3121 cli_close(cli, fnum);
3125 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3126 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3128 if (!NT_STATUS_IS_OK(status)) {
3129 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3132 cli_close(cli, fnum);
3134 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3136 if (!NT_STATUS_IS_OK(status)) {
3137 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3140 if (c_time != m_time) {
3141 printf("create time=%s", ctime(&c_time));
3142 printf("modify time=%s", ctime(&m_time));
3143 printf("This system appears to have sticky create times\n");
3145 if (a_time % (60*60) == 0) {
3146 printf("access time=%s", ctime(&a_time));
3147 printf("This system appears to set a midnight access time\n");
3151 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3152 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3158 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3159 cli_open(cli, fname,
3160 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3161 cli_close(cli, fnum);
3162 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3163 &m_time_ts, &size, NULL, NULL);
3164 if (!NT_STATUS_IS_OK(status)) {
3165 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3168 if (w_time_ts.tv_sec < 60*60*24*2) {
3169 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3170 printf("This system appears to set a initial 0 write time\n");
3175 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3178 /* check if the server updates the directory modification time
3179 when creating a new file */
3180 status = cli_mkdir(cli, dname);
3181 if (!NT_STATUS_IS_OK(status)) {
3182 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3186 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3187 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3188 if (!NT_STATUS_IS_OK(status)) {
3189 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3193 cli_open(cli, fname2,
3194 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3195 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3196 cli_close(cli, fnum);
3197 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3198 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3199 if (!NT_STATUS_IS_OK(status)) {
3200 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3203 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3205 printf("This system does not update directory modification times\n");
3209 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3210 cli_rmdir(cli, dname);
3212 if (!torture_close_connection(cli)) {
3216 printf("trans2 test finished\n");
3222 This checks new W2K calls.
3225 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3227 uint8_t *buf = NULL;
3231 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3232 pcli->max_xmit, &buf, &len);
3233 if (!NT_STATUS_IS_OK(status)) {
3234 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3237 printf("qfileinfo: level %d, len = %u\n", level, len);
3238 dump_data(0, (uint8 *)buf, len);
3245 static bool run_w2ktest(int dummy)
3247 struct cli_state *cli;
3249 const char *fname = "\\w2ktest\\w2k.tst";
3251 bool correct = True;
3253 printf("starting w2k test\n");
3255 if (!torture_open_connection(&cli, 0)) {
3259 cli_open(cli, fname,
3260 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3262 for (level = 1004; level < 1040; level++) {
3263 new_trans(cli, fnum, level);
3266 cli_close(cli, fnum);
3268 if (!torture_close_connection(cli)) {
3272 printf("w2k test finished\n");
3279 this is a harness for some oplock tests
3281 static bool run_oplock1(int dummy)
3283 struct cli_state *cli1;
3284 const char *fname = "\\lockt1.lck";
3286 bool correct = True;
3289 printf("starting oplock test 1\n");
3291 if (!torture_open_connection(&cli1, 0)) {
3295 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3297 cli_sockopt(cli1, sockops);
3299 cli1->use_oplocks = True;
3301 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3303 if (!NT_STATUS_IS_OK(status)) {
3304 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3308 cli1->use_oplocks = False;
3310 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3311 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3313 status = cli_close(cli1, fnum1);
3314 if (!NT_STATUS_IS_OK(status)) {
3315 printf("close2 failed (%s)\n", nt_errstr(status));
3319 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3320 if (!NT_STATUS_IS_OK(status)) {
3321 printf("unlink failed (%s)\n", nt_errstr(status));
3325 if (!torture_close_connection(cli1)) {
3329 printf("finished oplock test 1\n");
3334 static bool run_oplock2(int dummy)
3336 struct cli_state *cli1, *cli2;
3337 const char *fname = "\\lockt2.lck";
3338 uint16_t fnum1, fnum2;
3339 int saved_use_oplocks = use_oplocks;
3341 bool correct = True;
3342 volatile bool *shared_correct;
3345 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3346 *shared_correct = True;
3348 use_level_II_oplocks = True;
3351 printf("starting oplock test 2\n");
3353 if (!torture_open_connection(&cli1, 0)) {
3354 use_level_II_oplocks = False;
3355 use_oplocks = saved_use_oplocks;
3359 cli1->use_oplocks = True;
3360 cli1->use_level_II_oplocks = True;
3362 if (!torture_open_connection(&cli2, 1)) {
3363 use_level_II_oplocks = False;
3364 use_oplocks = saved_use_oplocks;
3368 cli2->use_oplocks = True;
3369 cli2->use_level_II_oplocks = True;
3371 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3373 cli_sockopt(cli1, sockops);
3374 cli_sockopt(cli2, sockops);
3376 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3378 if (!NT_STATUS_IS_OK(status)) {
3379 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3383 /* Don't need the globals any more. */
3384 use_level_II_oplocks = False;
3385 use_oplocks = saved_use_oplocks;
3389 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3390 if (!NT_STATUS_IS_OK(status)) {
3391 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3392 *shared_correct = False;
3398 status = cli_close(cli2, fnum2);
3399 if (!NT_STATUS_IS_OK(status)) {
3400 printf("close2 failed (%s)\n", nt_errstr(status));
3401 *shared_correct = False;
3409 /* Ensure cli1 processes the break. Empty file should always return 0
3412 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3413 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3417 /* Should now be at level II. */
3418 /* Test if sending a write locks causes a break to none. */
3420 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3421 printf("lock failed (%s)\n", cli_errstr(cli1));
3425 cli_unlock(cli1, fnum1, 0, 4);
3429 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3430 printf("lock failed (%s)\n", cli_errstr(cli1));
3434 cli_unlock(cli1, fnum1, 0, 4);
3438 cli_read(cli1, fnum1, buf, 0, 4);
3440 status = cli_close(cli1, fnum1);
3441 if (!NT_STATUS_IS_OK(status)) {
3442 printf("close1 failed (%s)\n", nt_errstr(status));
3448 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3449 if (!NT_STATUS_IS_OK(status)) {
3450 printf("unlink failed (%s)\n", nt_errstr(status));
3454 if (!torture_close_connection(cli1)) {
3458 if (!*shared_correct) {
3462 printf("finished oplock test 2\n");
3467 struct oplock4_state {
3468 struct tevent_context *ev;
3469 struct cli_state *cli;
3474 static void oplock4_got_break(struct tevent_req *req);
3475 static void oplock4_got_open(struct tevent_req *req);
3477 static bool run_oplock4(int dummy)
3479 struct tevent_context *ev;
3480 struct cli_state *cli1, *cli2;
3481 struct tevent_req *oplock_req, *open_req;
3482 const char *fname = "\\lockt4.lck";
3483 const char *fname_ln = "\\lockt4_ln.lck";
3484 uint16_t fnum1, fnum2;
3485 int saved_use_oplocks = use_oplocks;
3487 bool correct = true;
3491 struct oplock4_state *state;
3493 printf("starting oplock test 4\n");
3495 if (!torture_open_connection(&cli1, 0)) {
3496 use_level_II_oplocks = false;
3497 use_oplocks = saved_use_oplocks;
3501 if (!torture_open_connection(&cli2, 1)) {
3502 use_level_II_oplocks = false;
3503 use_oplocks = saved_use_oplocks;
3507 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3508 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3510 cli_sockopt(cli1, sockops);
3511 cli_sockopt(cli2, sockops);
3513 /* Create the file. */
3514 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3516 if (!NT_STATUS_IS_OK(status)) {
3517 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3521 status = cli_close(cli1, fnum1);
3522 if (!NT_STATUS_IS_OK(status)) {
3523 printf("close1 failed (%s)\n", nt_errstr(status));
3527 /* Now create a hardlink. */
3528 status = cli_nt_hardlink(cli1, fname, fname_ln);
3529 if (!NT_STATUS_IS_OK(status)) {
3530 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3534 /* Prove that opening hardlinks cause deny modes to conflict. */
3535 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3536 if (!NT_STATUS_IS_OK(status)) {
3537 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3541 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3542 if (NT_STATUS_IS_OK(status)) {
3543 printf("open of %s succeeded - should fail with sharing violation.\n",
3548 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3549 printf("open of %s should fail with sharing violation. Got %s\n",
3550 fname_ln, nt_errstr(status));
3554 status = cli_close(cli1, fnum1);
3555 if (!NT_STATUS_IS_OK(status)) {
3556 printf("close1 failed (%s)\n", nt_errstr(status));
3560 cli1->use_oplocks = true;
3561 cli1->use_level_II_oplocks = true;
3563 cli2->use_oplocks = true;
3564 cli2->use_level_II_oplocks = true;
3566 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3567 if (!NT_STATUS_IS_OK(status)) {
3568 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3572 ev = tevent_context_init(talloc_tos());
3574 printf("tevent_req_create failed\n");
3578 state = talloc(ev, struct oplock4_state);
3579 if (state == NULL) {
3580 printf("talloc failed\n");
3585 state->got_break = &got_break;
3586 state->fnum2 = &fnum2;
3588 oplock_req = cli_smb_oplock_break_waiter_send(
3589 talloc_tos(), ev, cli1);
3590 if (oplock_req == NULL) {
3591 printf("cli_smb_oplock_break_waiter_send failed\n");
3594 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3596 open_req = cli_open_send(
3597 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3598 if (oplock_req == NULL) {
3599 printf("cli_open_send failed\n");
3602 tevent_req_set_callback(open_req, oplock4_got_open, state);
3607 while (!got_break || fnum2 == 0xffff) {
3609 ret = tevent_loop_once(ev);
3611 printf("tevent_loop_once failed: %s\n",
3617 status = cli_close(cli2, fnum2);
3618 if (!NT_STATUS_IS_OK(status)) {
3619 printf("close2 failed (%s)\n", nt_errstr(status));
3623 status = cli_close(cli1, fnum1);
3624 if (!NT_STATUS_IS_OK(status)) {
3625 printf("close1 failed (%s)\n", nt_errstr(status));
3629 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3630 if (!NT_STATUS_IS_OK(status)) {
3631 printf("unlink failed (%s)\n", nt_errstr(status));
3635 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3636 if (!NT_STATUS_IS_OK(status)) {
3637 printf("unlink failed (%s)\n", nt_errstr(status));
3641 if (!torture_close_connection(cli1)) {
3649 printf("finished oplock test 4\n");
3654 static void oplock4_got_break(struct tevent_req *req)
3656 struct oplock4_state *state = tevent_req_callback_data(
3657 req, struct oplock4_state);
3662 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3664 if (!NT_STATUS_IS_OK(status)) {
3665 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3669 *state->got_break = true;
3671 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3674 printf("cli_oplock_ack_send failed\n");
3679 static void oplock4_got_open(struct tevent_req *req)
3681 struct oplock4_state *state = tevent_req_callback_data(
3682 req, struct oplock4_state);
3685 status = cli_open_recv(req, state->fnum2);
3686 if (!NT_STATUS_IS_OK(status)) {
3687 printf("cli_open_recv returned %s\n", nt_errstr(status));
3688 *state->fnum2 = 0xffff;
3693 Test delete on close semantics.
3695 static bool run_deletetest(int dummy)
3697 struct cli_state *cli1 = NULL;
3698 struct cli_state *cli2 = NULL;
3699 const char *fname = "\\delete.file";
3700 uint16_t fnum1 = (uint16_t)-1;
3701 uint16_t fnum2 = (uint16_t)-1;
3702 bool correct = True;
3705 printf("starting delete test\n");
3707 if (!torture_open_connection(&cli1, 0)) {
3711 cli_sockopt(cli1, sockops);
3713 /* Test 1 - this should delete the file on close. */
3715 cli_setatr(cli1, fname, 0, 0);
3716 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3718 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3719 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3720 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3721 if (!NT_STATUS_IS_OK(status)) {
3722 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3727 status = cli_close(cli1, fnum1);
3728 if (!NT_STATUS_IS_OK(status)) {
3729 printf("[1] close failed (%s)\n", nt_errstr(status));
3734 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3735 printf("[1] open of %s succeeded (should fail)\n", fname);
3740 printf("first delete on close test succeeded.\n");
3742 /* Test 2 - this should delete the file on close. */
3744 cli_setatr(cli1, fname, 0, 0);
3745 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3747 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3748 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3749 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3750 if (!NT_STATUS_IS_OK(status)) {
3751 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3756 status = cli_nt_delete_on_close(cli1, fnum1, true);
3757 if (!NT_STATUS_IS_OK(status)) {
3758 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3763 status = cli_close(cli1, fnum1);
3764 if (!NT_STATUS_IS_OK(status)) {
3765 printf("[2] close failed (%s)\n", nt_errstr(status));
3770 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3771 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3772 status = cli_close(cli1, fnum1);
3773 if (!NT_STATUS_IS_OK(status)) {
3774 printf("[2] close failed (%s)\n", nt_errstr(status));
3778 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3780 printf("second delete on close test succeeded.\n");
3783 cli_setatr(cli1, fname, 0, 0);
3784 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3786 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3787 FILE_ATTRIBUTE_NORMAL,
3788 FILE_SHARE_READ|FILE_SHARE_WRITE,
3789 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3790 if (!NT_STATUS_IS_OK(status)) {
3791 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3796 /* This should fail with a sharing violation - open for delete is only compatible
3797 with SHARE_DELETE. */
3799 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3800 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3801 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3806 /* This should succeed. */
3807 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3808 FILE_ATTRIBUTE_NORMAL,
3809 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3810 FILE_OPEN, 0, 0, &fnum2);
3811 if (!NT_STATUS_IS_OK(status)) {
3812 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3817 status = cli_nt_delete_on_close(cli1, fnum1, true);
3818 if (!NT_STATUS_IS_OK(status)) {
3819 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3824 status = cli_close(cli1, fnum1);
3825 if (!NT_STATUS_IS_OK(status)) {
3826 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3831 status = cli_close(cli1, fnum2);
3832 if (!NT_STATUS_IS_OK(status)) {
3833 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3838 /* This should fail - file should no longer be there. */
3840 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3841 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3842 status = cli_close(cli1, fnum1);
3843 if (!NT_STATUS_IS_OK(status)) {
3844 printf("[3] close failed (%s)\n", nt_errstr(status));
3846 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3850 printf("third delete on close test succeeded.\n");
3853 cli_setatr(cli1, fname, 0, 0);
3854 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3856 status = cli_ntcreate(cli1, fname, 0,
3857 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3858 FILE_ATTRIBUTE_NORMAL,
3859 FILE_SHARE_READ|FILE_SHARE_WRITE,
3860 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3861 if (!NT_STATUS_IS_OK(status)) {
3862 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
3867 /* This should succeed. */
3868 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3869 FILE_ATTRIBUTE_NORMAL,
3870 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3871 FILE_OPEN, 0, 0, &fnum2);
3872 if (!NT_STATUS_IS_OK(status)) {
3873 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3878 status = cli_close(cli1, fnum2);
3879 if (!NT_STATUS_IS_OK(status)) {
3880 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
3885 status = cli_nt_delete_on_close(cli1, fnum1, true);
3886 if (!NT_STATUS_IS_OK(status)) {
3887 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
3892 /* This should fail - no more opens once delete on close set. */
3893 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3894 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3895 FILE_OPEN, 0, 0, &fnum2))) {
3896 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3900 printf("fourth delete on close test succeeded.\n");
3902 status = cli_close(cli1, fnum1);
3903 if (!NT_STATUS_IS_OK(status)) {
3904 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
3910 cli_setatr(cli1, fname, 0, 0);
3911 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3913 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
3914 if (!NT_STATUS_IS_OK(status)) {
3915 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
3920 /* This should fail - only allowed on NT opens with DELETE access. */
3922 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3923 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3928 status = cli_close(cli1, fnum1);
3929 if (!NT_STATUS_IS_OK(status)) {
3930 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
3935 printf("fifth delete on close test succeeded.\n");
3938 cli_setatr(cli1, fname, 0, 0);
3939 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3941 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3942 FILE_ATTRIBUTE_NORMAL,
3943 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3944 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3945 if (!NT_STATUS_IS_OK(status)) {
3946 printf("[6] open of %s failed (%s)\n", fname,
3952 /* This should fail - only allowed on NT opens with DELETE access. */
3954 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3955 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3960 status = cli_close(cli1, fnum1);
3961 if (!NT_STATUS_IS_OK(status)) {
3962 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
3967 printf("sixth delete on close test succeeded.\n");
3970 cli_setatr(cli1, fname, 0, 0);
3971 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3973 status = cli_ntcreate(cli1, fname, 0,
3974 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3975 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3977 if (!NT_STATUS_IS_OK(status)) {
3978 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
3983 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3984 printf("[7] setting delete_on_close on file failed !\n");
3989 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3990 printf("[7] unsetting delete_on_close on file failed !\n");
3995 status = cli_close(cli1, fnum1);
3996 if (!NT_STATUS_IS_OK(status)) {
3997 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4002 /* This next open should succeed - we reset the flag. */
4003 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4004 if (!NT_STATUS_IS_OK(status)) {
4005 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4010 status = cli_close(cli1, fnum1);
4011 if (!NT_STATUS_IS_OK(status)) {
4012 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4017 printf("seventh delete on close test succeeded.\n");
4020 cli_setatr(cli1, fname, 0, 0);
4021 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4023 if (!torture_open_connection(&cli2, 1)) {
4024 printf("[8] failed to open second connection.\n");
4029 cli_sockopt(cli1, sockops);
4031 status = cli_ntcreate(cli1, fname, 0,
4032 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4033 FILE_ATTRIBUTE_NORMAL,
4034 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4035 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4036 if (!NT_STATUS_IS_OK(status)) {
4037 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4042 status = cli_ntcreate(cli2, fname, 0,
4043 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4044 FILE_ATTRIBUTE_NORMAL,
4045 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4046 FILE_OPEN, 0, 0, &fnum2);
4047 if (!NT_STATUS_IS_OK(status)) {
4048 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4053 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4054 printf("[8] setting delete_on_close on file failed !\n");
4059 status = cli_close(cli1, fnum1);
4060 if (!NT_STATUS_IS_OK(status)) {
4061 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4066 status = cli_close(cli2, fnum2);
4067 if (!NT_STATUS_IS_OK(status)) {
4068 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4073 /* This should fail.. */
4074 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4075 if (NT_STATUS_IS_OK(status)) {
4076 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4080 printf("eighth delete on close test succeeded.\n");
4082 /* This should fail - we need to set DELETE_ACCESS. */
4083 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4084 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4085 printf("[9] open of %s succeeded should have failed!\n", fname);
4090 printf("ninth delete on close test succeeded.\n");
4092 status = cli_ntcreate(cli1, fname, 0,
4093 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4094 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4095 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4097 if (!NT_STATUS_IS_OK(status)) {
4098 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4103 /* This should delete the file. */
4104 status = cli_close(cli1, fnum1);
4105 if (!NT_STATUS_IS_OK(status)) {
4106 printf("[10] close failed (%s)\n", nt_errstr(status));
4111 /* This should fail.. */
4112 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4113 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4117 printf("tenth delete on close test succeeded.\n");
4119 cli_setatr(cli1, fname, 0, 0);
4120 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4122 /* What error do we get when attempting to open a read-only file with
4125 /* Create a readonly file. */
4126 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4127 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4128 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4129 if (!NT_STATUS_IS_OK(status)) {
4130 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4135 status = cli_close(cli1, fnum1);
4136 if (!NT_STATUS_IS_OK(status)) {
4137 printf("[11] close failed (%s)\n", nt_errstr(status));
4142 /* Now try open for delete access. */
4143 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4144 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4145 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4146 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4147 cli_close(cli1, fnum1);
4151 NTSTATUS nterr = cli_nt_error(cli1);
4152 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4153 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4157 printf("eleventh delete on close test succeeded.\n");
4161 printf("finished delete test\n");
4164 /* FIXME: This will crash if we aborted before cli2 got
4165 * intialized, because these functions don't handle
4166 * uninitialized connections. */
4168 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4169 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4170 cli_setatr(cli1, fname, 0, 0);
4171 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4173 if (cli1 && !torture_close_connection(cli1)) {
4176 if (cli2 && !torture_close_connection(cli2)) {
4182 static bool run_deletetest_ln(int dummy)
4184 struct cli_state *cli;
4185 const char *fname = "\\delete1";
4186 const char *fname_ln = "\\delete1_ln";
4190 bool correct = true;
4193 printf("starting deletetest-ln\n");
4195 if (!torture_open_connection(&cli, 0)) {
4199 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4200 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4202 cli_sockopt(cli, sockops);
4204 /* Create the file. */
4205 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4206 if (!NT_STATUS_IS_OK(status)) {
4207 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4211 status = cli_close(cli, fnum);
4212 if (!NT_STATUS_IS_OK(status)) {
4213 printf("close1 failed (%s)\n", nt_errstr(status));
4217 /* Now create a hardlink. */
4218 status = cli_nt_hardlink(cli, fname, fname_ln);
4219 if (!NT_STATUS_IS_OK(status)) {
4220 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4224 /* Open the original file. */
4225 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4226 FILE_ATTRIBUTE_NORMAL,
4227 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4228 FILE_OPEN_IF, 0, 0, &fnum);
4229 if (!NT_STATUS_IS_OK(status)) {
4230 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4234 /* Unlink the hard link path. */
4235 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4236 FILE_ATTRIBUTE_NORMAL,
4237 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4238 FILE_OPEN_IF, 0, 0, &fnum1);
4239 if (!NT_STATUS_IS_OK(status)) {
4240 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4243 status = cli_nt_delete_on_close(cli, fnum1, true);
4244 if (!NT_STATUS_IS_OK(status)) {
4245 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4246 __location__, fname_ln, nt_errstr(status));
4250 status = cli_close(cli, fnum1);
4251 if (!NT_STATUS_IS_OK(status)) {
4252 printf("close %s failed (%s)\n",
4253 fname_ln, nt_errstr(status));
4257 status = cli_close(cli, fnum);
4258 if (!NT_STATUS_IS_OK(status)) {
4259 printf("close %s failed (%s)\n",
4260 fname, nt_errstr(status));
4264 /* Ensure the original file is still there. */
4265 status = cli_getatr(cli, fname, NULL, NULL, &t);
4266 if (!NT_STATUS_IS_OK(status)) {
4267 printf("%s getatr on file %s failed (%s)\n",
4274 /* Ensure the link path is gone. */
4275 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4276 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4277 printf("%s, getatr for file %s returned wrong error code %s "
4278 "- should have been deleted\n",
4280 fname_ln, nt_errstr(status));
4284 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4285 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4287 if (!torture_close_connection(cli)) {
4291 printf("finished deletetest-ln\n");
4297 print out server properties
4299 static bool run_properties(int dummy)
4301 struct cli_state *cli;
4302 bool correct = True;
4304 printf("starting properties test\n");
4308 if (!torture_open_connection(&cli, 0)) {
4312 cli_sockopt(cli, sockops);
4314 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4316 if (!torture_close_connection(cli)) {
4325 /* FIRST_DESIRED_ACCESS 0xf019f */
4326 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4327 FILE_READ_EA| /* 0xf */ \
4328 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4329 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4330 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4331 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4332 /* SECOND_DESIRED_ACCESS 0xe0080 */
4333 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4334 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4335 WRITE_OWNER_ACCESS /* 0xe0000 */
4338 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4339 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4341 WRITE_OWNER_ACCESS /* */
4345 Test ntcreate calls made by xcopy
4347 static bool run_xcopy(int dummy)
4349 static struct cli_state *cli1;
4350 const char *fname = "\\test.txt";
4351 bool correct = True;
4352 uint16_t fnum1, fnum2;
4355 printf("starting xcopy test\n");
4357 if (!torture_open_connection(&cli1, 0)) {
4361 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4362 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4363 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4364 if (!NT_STATUS_IS_OK(status)) {
4365 printf("First open failed - %s\n", nt_errstr(status));
4369 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4370 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4371 FILE_OPEN, 0x200000, 0, &fnum2);
4372 if (!NT_STATUS_IS_OK(status)) {
4373 printf("second open failed - %s\n", nt_errstr(status));
4377 if (!torture_close_connection(cli1)) {
4385 Test rename on files open with share delete and no share delete.
4387 static bool run_rename(int dummy)
4389 static struct cli_state *cli1;
4390 const char *fname = "\\test.txt";
4391 const char *fname1 = "\\test1.txt";
4392 bool correct = True;
4397 printf("starting rename test\n");
4399 if (!torture_open_connection(&cli1, 0)) {
4403 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4404 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4406 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4407 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4408 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4409 if (!NT_STATUS_IS_OK(status)) {
4410 printf("First open failed - %s\n", nt_errstr(status));
4414 status = cli_rename(cli1, fname, fname1);
4415 if (!NT_STATUS_IS_OK(status)) {
4416 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4418 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4422 status = cli_close(cli1, fnum1);
4423 if (!NT_STATUS_IS_OK(status)) {
4424 printf("close - 1 failed (%s)\n", nt_errstr(status));
4428 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4429 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4430 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4432 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4434 FILE_SHARE_DELETE|FILE_SHARE_READ,
4436 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4437 if (!NT_STATUS_IS_OK(status)) {
4438 printf("Second open failed - %s\n", nt_errstr(status));
4442 status = cli_rename(cli1, fname, fname1);
4443 if (!NT_STATUS_IS_OK(status)) {
4444 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4447 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4450 status = cli_close(cli1, fnum1);
4451 if (!NT_STATUS_IS_OK(status)) {
4452 printf("close - 2 failed (%s)\n", nt_errstr(status));
4456 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4457 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4459 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4460 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4461 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4462 if (!NT_STATUS_IS_OK(status)) {
4463 printf("Third open failed - %s\n", nt_errstr(status));
4472 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4473 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4474 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4477 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4478 printf("[8] setting delete_on_close on file failed !\n");
4482 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4483 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4489 status = cli_rename(cli1, fname, fname1);
4490 if (!NT_STATUS_IS_OK(status)) {
4491 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4494 printf("Third rename succeeded (SHARE_NONE)\n");
4497 status = cli_close(cli1, fnum1);
4498 if (!NT_STATUS_IS_OK(status)) {
4499 printf("close - 3 failed (%s)\n", nt_errstr(status));
4503 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4504 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4508 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4509 FILE_ATTRIBUTE_NORMAL,
4510 FILE_SHARE_READ | FILE_SHARE_WRITE,
4511 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4512 if (!NT_STATUS_IS_OK(status)) {
4513 printf("Fourth open failed - %s\n", nt_errstr(status));
4517 status = cli_rename(cli1, fname, fname1);
4518 if (!NT_STATUS_IS_OK(status)) {
4519 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4521 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4525 status = cli_close(cli1, fnum1);
4526 if (!NT_STATUS_IS_OK(status)) {
4527 printf("close - 4 failed (%s)\n", nt_errstr(status));
4531 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4532 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4536 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4537 FILE_ATTRIBUTE_NORMAL,
4538 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4539 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4540 if (!NT_STATUS_IS_OK(status)) {
4541 printf("Fifth open failed - %s\n", nt_errstr(status));
4545 status = cli_rename(cli1, fname, fname1);
4546 if (!NT_STATUS_IS_OK(status)) {
4547 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4550 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4554 * Now check if the first name still exists ...
4557 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4558 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4559 printf("Opening original file after rename of open file fails: %s\n",
4563 printf("Opening original file after rename of open file works ...\n");
4564 (void)cli_close(cli1, fnum2);
4568 status = cli_close(cli1, fnum1);
4569 if (!NT_STATUS_IS_OK(status)) {
4570 printf("close - 5 failed (%s)\n", nt_errstr(status));
4574 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4575 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4576 if (!NT_STATUS_IS_OK(status)) {
4577 printf("getatr on file %s failed - %s ! \n",
4578 fname1, nt_errstr(status));
4581 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4582 printf("Renamed file %s has wrong attr 0x%x "
4583 "(should be 0x%x)\n",
4586 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4589 printf("Renamed file %s has archive bit set\n", fname1);
4593 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4594 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4596 if (!torture_close_connection(cli1)) {
4603 static bool run_pipe_number(int dummy)
4605 struct cli_state *cli1;
4606 const char *pipe_name = "\\SPOOLSS";
4611 printf("starting pipenumber test\n");
4612 if (!torture_open_connection(&cli1, 0)) {
4616 cli_sockopt(cli1, sockops);
4618 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4619 FILE_ATTRIBUTE_NORMAL,
4620 FILE_SHARE_READ|FILE_SHARE_WRITE,
4621 FILE_OPEN_IF, 0, 0, &fnum);
4622 if (!NT_STATUS_IS_OK(status)) {
4623 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4627 printf("\r%6d", num_pipes);
4630 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4631 torture_close_connection(cli1);
4636 Test open mode returns on read-only files.
4638 static bool run_opentest(int dummy)
4640 static struct cli_state *cli1;
4641 static struct cli_state *cli2;
4642 const char *fname = "\\readonly.file";
4643 uint16_t fnum1, fnum2;
4646 bool correct = True;
4650 printf("starting open test\n");
4652 if (!torture_open_connection(&cli1, 0)) {
4656 cli_setatr(cli1, fname, 0, 0);
4657 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4659 cli_sockopt(cli1, sockops);
4661 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4662 if (!NT_STATUS_IS_OK(status)) {
4663 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4667 status = cli_close(cli1, fnum1);
4668 if (!NT_STATUS_IS_OK(status)) {
4669 printf("close2 failed (%s)\n", nt_errstr(status));
4673 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4674 if (!NT_STATUS_IS_OK(status)) {
4675 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4679 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4680 if (!NT_STATUS_IS_OK(status)) {
4681 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4685 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4686 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4688 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4689 NT_STATUS_ACCESS_DENIED)) {
4690 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4693 printf("finished open test 1\n");
4695 cli_close(cli1, fnum1);
4697 /* Now try not readonly and ensure ERRbadshare is returned. */
4699 cli_setatr(cli1, fname, 0, 0);
4701 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4702 if (!NT_STATUS_IS_OK(status)) {
4703 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4707 /* This will fail - but the error should be ERRshare. */
4708 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4710 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4711 NT_STATUS_SHARING_VIOLATION)) {
4712 printf("correct error code ERRDOS/ERRbadshare returned\n");
4715 status = cli_close(cli1, fnum1);
4716 if (!NT_STATUS_IS_OK(status)) {
4717 printf("close2 failed (%s)\n", nt_errstr(status));
4721 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4723 printf("finished open test 2\n");
4725 /* Test truncate open disposition on file opened for read. */
4726 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4727 if (!NT_STATUS_IS_OK(status)) {
4728 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4732 /* write 20 bytes. */
4734 memset(buf, '\0', 20);
4736 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4737 if (!NT_STATUS_IS_OK(status)) {
4738 printf("write failed (%s)\n", nt_errstr(status));
4742 status = cli_close(cli1, fnum1);
4743 if (!NT_STATUS_IS_OK(status)) {
4744 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4748 /* Ensure size == 20. */
4749 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4750 if (!NT_STATUS_IS_OK(status)) {
4751 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4756 printf("(3) file size != 20\n");
4760 /* Now test if we can truncate a file opened for readonly. */
4761 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4762 if (!NT_STATUS_IS_OK(status)) {
4763 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4767 status = cli_close(cli1, fnum1);
4768 if (!NT_STATUS_IS_OK(status)) {
4769 printf("close2 failed (%s)\n", nt_errstr(status));
4773 /* Ensure size == 0. */
4774 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4775 if (!NT_STATUS_IS_OK(status)) {
4776 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4781 printf("(3) file size != 0\n");
4784 printf("finished open test 3\n");
4786 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4788 printf("Do ctemp tests\n");
4789 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4790 if (!NT_STATUS_IS_OK(status)) {
4791 printf("ctemp failed (%s)\n", nt_errstr(status));
4795 printf("ctemp gave path %s\n", tmp_path);
4796 status = cli_close(cli1, fnum1);
4797 if (!NT_STATUS_IS_OK(status)) {
4798 printf("close of temp failed (%s)\n", nt_errstr(status));
4801 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4802 if (!NT_STATUS_IS_OK(status)) {
4803 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4806 /* Test the non-io opens... */
4808 if (!torture_open_connection(&cli2, 1)) {
4812 cli_setatr(cli2, fname, 0, 0);
4813 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4815 cli_sockopt(cli2, sockops);
4817 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4818 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4819 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4820 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4821 if (!NT_STATUS_IS_OK(status)) {
4822 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4826 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4827 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4828 FILE_OPEN_IF, 0, 0, &fnum2);
4829 if (!NT_STATUS_IS_OK(status)) {
4830 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4834 status = cli_close(cli1, fnum1);
4835 if (!NT_STATUS_IS_OK(status)) {
4836 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4840 status = cli_close(cli2, fnum2);
4841 if (!NT_STATUS_IS_OK(status)) {
4842 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4846 printf("non-io open test #1 passed.\n");
4848 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4850 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4852 status = cli_ntcreate(cli1, fname, 0,
4853 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4854 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4855 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4856 if (!NT_STATUS_IS_OK(status)) {
4857 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4861 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4862 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4863 FILE_OPEN_IF, 0, 0, &fnum2);
4864 if (!NT_STATUS_IS_OK(status)) {
4865 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4869 status = cli_close(cli1, fnum1);
4870 if (!NT_STATUS_IS_OK(status)) {
4871 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4875 status = cli_close(cli2, fnum2);
4876 if (!NT_STATUS_IS_OK(status)) {
4877 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4881 printf("non-io open test #2 passed.\n");
4883 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4885 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4887 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4888 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4889 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4890 if (!NT_STATUS_IS_OK(status)) {
4891 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4895 status = cli_ntcreate(cli2, fname, 0,
4896 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4897 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4898 FILE_OPEN_IF, 0, 0, &fnum2);
4899 if (!NT_STATUS_IS_OK(status)) {
4900 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4904 status = cli_close(cli1, fnum1);
4905 if (!NT_STATUS_IS_OK(status)) {
4906 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4910 status = cli_close(cli2, fnum2);
4911 if (!NT_STATUS_IS_OK(status)) {
4912 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4916 printf("non-io open test #3 passed.\n");
4918 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4920 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4922 status = cli_ntcreate(cli1, fname, 0,
4923 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4924 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4925 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4926 if (!NT_STATUS_IS_OK(status)) {
4927 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4931 status = cli_ntcreate(cli2, fname, 0,
4932 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4933 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4934 FILE_OPEN_IF, 0, 0, &fnum2);
4935 if (NT_STATUS_IS_OK(status)) {
4936 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
4940 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
4942 status = cli_close(cli1, fnum1);
4943 if (!NT_STATUS_IS_OK(status)) {
4944 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4948 printf("non-io open test #4 passed.\n");
4950 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4952 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4954 status = cli_ntcreate(cli1, fname, 0,
4955 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4956 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
4957 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4958 if (!NT_STATUS_IS_OK(status)) {
4959 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4963 status = cli_ntcreate(cli2, fname, 0,
4964 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4965 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
4966 FILE_OPEN_IF, 0, 0, &fnum2);
4967 if (!NT_STATUS_IS_OK(status)) {
4968 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4972 status = cli_close(cli1, fnum1);
4973 if (!NT_STATUS_IS_OK(status)) {
4974 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4978 status = cli_close(cli2, fnum2);
4979 if (!NT_STATUS_IS_OK(status)) {
4980 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4984 printf("non-io open test #5 passed.\n");
4986 printf("TEST #6 testing 1 non-io open, one io open\n");
4988 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4990 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
4991 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4992 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4993 if (!NT_STATUS_IS_OK(status)) {
4994 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4998 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4999 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5000 FILE_OPEN_IF, 0, 0, &fnum2);
5001 if (!NT_STATUS_IS_OK(status)) {
5002 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5006 status = cli_close(cli1, fnum1);
5007 if (!NT_STATUS_IS_OK(status)) {
5008 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5012 status = cli_close(cli2, fnum2);
5013 if (!NT_STATUS_IS_OK(status)) {
5014 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5018 printf("non-io open test #6 passed.\n");
5020 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5022 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5024 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5025 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5026 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5027 if (!NT_STATUS_IS_OK(status)) {
5028 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5032 status = cli_ntcreate(cli2, fname, 0,
5033 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5034 FILE_ATTRIBUTE_NORMAL,
5035 FILE_SHARE_READ|FILE_SHARE_DELETE,
5036 FILE_OPEN_IF, 0, 0, &fnum2);
5037 if (NT_STATUS_IS_OK(status)) {
5038 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5042 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5044 status = cli_close(cli1, fnum1);
5045 if (!NT_STATUS_IS_OK(status)) {
5046 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5050 printf("non-io open test #7 passed.\n");
5052 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5054 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5055 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5056 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5057 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5058 if (!NT_STATUS_IS_OK(status)) {
5059 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5064 /* Write to ensure we have to update the file time. */
5065 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5067 if (!NT_STATUS_IS_OK(status)) {
5068 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5073 status = cli_close(cli1, fnum1);
5074 if (!NT_STATUS_IS_OK(status)) {
5075 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5081 if (!torture_close_connection(cli1)) {
5084 if (!torture_close_connection(cli2)) {
5091 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5093 uint16 major, minor;
5094 uint32 caplow, caphigh;
5097 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5098 printf("Server doesn't support UNIX CIFS extensions.\n");
5099 return NT_STATUS_NOT_SUPPORTED;
5102 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5104 if (!NT_STATUS_IS_OK(status)) {
5105 printf("Server didn't return UNIX CIFS extensions: %s\n",
5110 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5112 if (!NT_STATUS_IS_OK(status)) {
5113 printf("Server doesn't support setting UNIX CIFS extensions: "
5114 "%s.\n", nt_errstr(status));
5118 return NT_STATUS_OK;
5122 Test POSIX open /mkdir calls.
5124 static bool run_simple_posix_open_test(int dummy)
5126 static struct cli_state *cli1;
5127 const char *fname = "posix:file";
5128 const char *hname = "posix:hlink";
5129 const char *sname = "posix:symlink";
5130 const char *dname = "posix:dir";
5133 uint16_t fnum1 = (uint16_t)-1;
5134 SMB_STRUCT_STAT sbuf;
5135 bool correct = false;
5138 printf("Starting simple POSIX open test\n");
5140 if (!torture_open_connection(&cli1, 0)) {
5144 cli_sockopt(cli1, sockops);
5146 status = torture_setup_unix_extensions(cli1);
5147 if (!NT_STATUS_IS_OK(status)) {
5151 cli_setatr(cli1, fname, 0, 0);
5152 cli_posix_unlink(cli1, fname);
5153 cli_setatr(cli1, dname, 0, 0);
5154 cli_posix_rmdir(cli1, dname);
5155 cli_setatr(cli1, hname, 0, 0);
5156 cli_posix_unlink(cli1, hname);
5157 cli_setatr(cli1, sname, 0, 0);
5158 cli_posix_unlink(cli1, sname);
5160 /* Create a directory. */
5161 status = cli_posix_mkdir(cli1, dname, 0777);
5162 if (!NT_STATUS_IS_OK(status)) {
5163 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5167 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5169 if (!NT_STATUS_IS_OK(status)) {
5170 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5174 /* Test ftruncate - set file size. */
5175 status = cli_ftruncate(cli1, fnum1, 1000);
5176 if (!NT_STATUS_IS_OK(status)) {
5177 printf("ftruncate failed (%s)\n", nt_errstr(status));
5181 /* Ensure st_size == 1000 */
5182 status = cli_posix_stat(cli1, fname, &sbuf);
5183 if (!NT_STATUS_IS_OK(status)) {
5184 printf("stat failed (%s)\n", nt_errstr(status));
5188 if (sbuf.st_ex_size != 1000) {
5189 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5193 /* Test ftruncate - set file size back to zero. */
5194 status = cli_ftruncate(cli1, fnum1, 0);
5195 if (!NT_STATUS_IS_OK(status)) {
5196 printf("ftruncate failed (%s)\n", nt_errstr(status));
5200 status = cli_close(cli1, fnum1);
5201 if (!NT_STATUS_IS_OK(status)) {
5202 printf("close failed (%s)\n", nt_errstr(status));
5206 /* Now open the file again for read only. */
5207 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5208 if (!NT_STATUS_IS_OK(status)) {
5209 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5213 /* Now unlink while open. */
5214 status = cli_posix_unlink(cli1, fname);
5215 if (!NT_STATUS_IS_OK(status)) {
5216 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5220 status = cli_close(cli1, fnum1);
5221 if (!NT_STATUS_IS_OK(status)) {
5222 printf("close(2) failed (%s)\n", nt_errstr(status));
5226 /* Ensure the file has gone. */
5227 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5228 if (NT_STATUS_IS_OK(status)) {
5229 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5233 /* Create again to test open with O_TRUNC. */
5234 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5235 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5239 /* Test ftruncate - set file size. */
5240 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5241 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5245 /* Ensure st_size == 1000 */
5246 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5247 printf("stat failed (%s)\n", cli_errstr(cli1));
5251 if (sbuf.st_ex_size != 1000) {
5252 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5256 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5257 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5261 /* Re-open with O_TRUNC. */
5262 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5263 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5267 /* Ensure st_size == 0 */
5268 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5269 printf("stat failed (%s)\n", cli_errstr(cli1));
5273 if (sbuf.st_ex_size != 0) {
5274 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5278 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5279 printf("close failed (%s)\n", cli_errstr(cli1));
5283 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5284 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5288 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5289 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5290 dname, cli_errstr(cli1));
5294 cli_close(cli1, fnum1);
5296 /* What happens when we try and POSIX open a directory for write ? */
5297 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5298 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5301 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5302 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5307 /* Create the file. */
5308 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5310 if (!NT_STATUS_IS_OK(status)) {
5311 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5315 /* Write some data into it. */
5316 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5318 if (!NT_STATUS_IS_OK(status)) {
5319 printf("cli_write failed: %s\n", nt_errstr(status));
5323 cli_close(cli1, fnum1);
5325 /* Now create a hardlink. */
5326 status = cli_posix_hardlink(cli1, fname, hname);
5327 if (!NT_STATUS_IS_OK(status)) {
5328 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5332 /* Now create a symlink. */
5333 status = cli_posix_symlink(cli1, fname, sname);
5334 if (!NT_STATUS_IS_OK(status)) {
5335 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5339 /* Open the hardlink for read. */
5340 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5341 if (!NT_STATUS_IS_OK(status)) {
5342 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5346 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5347 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5351 if (memcmp(buf, "TEST DATA\n", 10)) {
5352 printf("invalid data read from hardlink\n");
5356 /* Do a POSIX lock/unlock. */
5357 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5358 if (!NT_STATUS_IS_OK(status)) {
5359 printf("POSIX lock failed %s\n", nt_errstr(status));
5363 /* Punch a hole in the locked area. */
5364 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5365 if (!NT_STATUS_IS_OK(status)) {
5366 printf("POSIX unlock failed %s\n", nt_errstr(status));
5370 cli_close(cli1, fnum1);
5372 /* Open the symlink for read - this should fail. A POSIX
5373 client should not be doing opens on a symlink. */
5374 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5375 if (NT_STATUS_IS_OK(status)) {
5376 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5379 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5380 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5381 printf("POSIX open of %s should have failed "
5382 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5383 "failed with %s instead.\n",
5384 sname, nt_errstr(status));
5389 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5390 if (!NT_STATUS_IS_OK(status)) {
5391 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5395 if (strcmp(namebuf, fname) != 0) {
5396 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5397 sname, fname, namebuf);
5401 status = cli_posix_rmdir(cli1, dname);
5402 if (!NT_STATUS_IS_OK(status)) {
5403 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5407 printf("Simple POSIX open test passed\n");
5412 if (fnum1 != (uint16_t)-1) {
5413 cli_close(cli1, fnum1);
5414 fnum1 = (uint16_t)-1;
5417 cli_setatr(cli1, sname, 0, 0);
5418 cli_posix_unlink(cli1, sname);
5419 cli_setatr(cli1, hname, 0, 0);
5420 cli_posix_unlink(cli1, hname);
5421 cli_setatr(cli1, fname, 0, 0);
5422 cli_posix_unlink(cli1, fname);
5423 cli_setatr(cli1, dname, 0, 0);
5424 cli_posix_rmdir(cli1, dname);
5426 if (!torture_close_connection(cli1)) {
5434 static uint32 open_attrs_table[] = {
5435 FILE_ATTRIBUTE_NORMAL,
5436 FILE_ATTRIBUTE_ARCHIVE,
5437 FILE_ATTRIBUTE_READONLY,
5438 FILE_ATTRIBUTE_HIDDEN,
5439 FILE_ATTRIBUTE_SYSTEM,
5441 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5442 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5443 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5444 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5445 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5446 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5448 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5449 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5450 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5451 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5454 struct trunc_open_results {
5461 static struct trunc_open_results attr_results[] = {
5462 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5463 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5464 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5465 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5466 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5467 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5468 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5469 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5470 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5471 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5472 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5473 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5474 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5475 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5476 { 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 },
5477 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5478 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5479 { 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 },
5480 { 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 },
5481 { 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 },
5482 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5483 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5484 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5485 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5486 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5487 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5490 static bool run_openattrtest(int dummy)
5492 static struct cli_state *cli1;
5493 const char *fname = "\\openattr.file";
5495 bool correct = True;
5497 unsigned int i, j, k, l;
5500 printf("starting open attr test\n");
5502 if (!torture_open_connection(&cli1, 0)) {
5506 cli_sockopt(cli1, sockops);
5508 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5509 cli_setatr(cli1, fname, 0, 0);
5510 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5512 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5513 open_attrs_table[i], FILE_SHARE_NONE,
5514 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5515 if (!NT_STATUS_IS_OK(status)) {
5516 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5520 status = cli_close(cli1, fnum1);
5521 if (!NT_STATUS_IS_OK(status)) {
5522 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5526 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5527 status = cli_ntcreate(cli1, fname, 0,
5528 FILE_READ_DATA|FILE_WRITE_DATA,
5529 open_attrs_table[j],
5530 FILE_SHARE_NONE, FILE_OVERWRITE,
5532 if (!NT_STATUS_IS_OK(status)) {
5533 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5534 if (attr_results[l].num == k) {
5535 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5536 k, open_attrs_table[i],
5537 open_attrs_table[j],
5538 fname, NT_STATUS_V(status), nt_errstr(status));
5543 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5544 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5545 k, open_attrs_table[i], open_attrs_table[j],
5550 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5556 status = cli_close(cli1, fnum1);
5557 if (!NT_STATUS_IS_OK(status)) {
5558 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5562 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5563 if (!NT_STATUS_IS_OK(status)) {
5564 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5569 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5570 k, open_attrs_table[i], open_attrs_table[j], attr );
5573 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5574 if (attr_results[l].num == k) {
5575 if (attr != attr_results[l].result_attr ||
5576 open_attrs_table[i] != attr_results[l].init_attr ||
5577 open_attrs_table[j] != attr_results[l].trunc_attr) {
5578 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5579 open_attrs_table[i],
5580 open_attrs_table[j],
5582 attr_results[l].result_attr);
5592 cli_setatr(cli1, fname, 0, 0);
5593 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5595 printf("open attr test %s.\n", correct ? "passed" : "failed");
5597 if (!torture_close_connection(cli1)) {
5603 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5604 const char *name, void *state)
5606 int *matched = (int *)state;
5607 if (matched != NULL) {
5610 return NT_STATUS_OK;
5614 test directory listing speed
5616 static bool run_dirtest(int dummy)
5619 static struct cli_state *cli;
5621 struct timeval core_start;
5622 bool correct = True;
5625 printf("starting directory test\n");
5627 if (!torture_open_connection(&cli, 0)) {
5631 cli_sockopt(cli, sockops);
5634 for (i=0;i<torture_numops;i++) {
5636 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5637 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5638 fprintf(stderr,"Failed to open %s\n", fname);
5641 cli_close(cli, fnum);
5644 core_start = timeval_current();
5647 cli_list(cli, "a*.*", 0, list_fn, &matched);
5648 printf("Matched %d\n", matched);
5651 cli_list(cli, "b*.*", 0, list_fn, &matched);
5652 printf("Matched %d\n", matched);
5655 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5656 printf("Matched %d\n", matched);
5658 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5661 for (i=0;i<torture_numops;i++) {
5663 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5664 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5667 if (!torture_close_connection(cli)) {
5671 printf("finished dirtest\n");
5676 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5679 struct cli_state *pcli = (struct cli_state *)state;
5681 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5683 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5684 return NT_STATUS_OK;
5686 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5687 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5688 printf("del_fn: failed to rmdir %s\n,", fname );
5690 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5691 printf("del_fn: failed to unlink %s\n,", fname );
5693 return NT_STATUS_OK;
5698 sees what IOCTLs are supported
5700 bool torture_ioctl_test(int dummy)
5702 static struct cli_state *cli;
5703 uint16_t device, function;
5705 const char *fname = "\\ioctl.dat";
5709 if (!torture_open_connection(&cli, 0)) {
5713 printf("starting ioctl test\n");
5715 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5717 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5718 if (!NT_STATUS_IS_OK(status)) {
5719 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5723 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5724 printf("ioctl device info: %s\n", nt_errstr(status));
5726 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5727 printf("ioctl job info: %s\n", nt_errstr(status));
5729 for (device=0;device<0x100;device++) {
5730 printf("ioctl test with device = 0x%x\n", device);
5731 for (function=0;function<0x100;function++) {
5732 uint32 code = (device<<16) | function;
5734 status = cli_raw_ioctl(cli, fnum, code, &blob);
5736 if (NT_STATUS_IS_OK(status)) {
5737 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5739 data_blob_free(&blob);
5744 if (!torture_close_connection(cli)) {
5753 tries varients of chkpath
5755 bool torture_chkpath_test(int dummy)
5757 static struct cli_state *cli;
5762 if (!torture_open_connection(&cli, 0)) {
5766 printf("starting chkpath test\n");
5768 /* cleanup from an old run */
5769 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5770 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5771 cli_rmdir(cli, "\\chkpath.dir");
5773 status = cli_mkdir(cli, "\\chkpath.dir");
5774 if (!NT_STATUS_IS_OK(status)) {
5775 printf("mkdir1 failed : %s\n", nt_errstr(status));
5779 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5780 if (!NT_STATUS_IS_OK(status)) {
5781 printf("mkdir2 failed : %s\n", nt_errstr(status));
5785 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5787 if (!NT_STATUS_IS_OK(status)) {
5788 printf("open1 failed (%s)\n", nt_errstr(status));
5791 cli_close(cli, fnum);
5793 status = cli_chkpath(cli, "\\chkpath.dir");
5794 if (!NT_STATUS_IS_OK(status)) {
5795 printf("chkpath1 failed: %s\n", nt_errstr(status));
5799 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5800 if (!NT_STATUS_IS_OK(status)) {
5801 printf("chkpath2 failed: %s\n", nt_errstr(status));
5805 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5806 if (!NT_STATUS_IS_OK(status)) {
5807 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5808 NT_STATUS_NOT_A_DIRECTORY);
5810 printf("* chkpath on a file should fail\n");
5814 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5815 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5816 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5818 printf("* chkpath on a non existant file should fail\n");
5822 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5823 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5824 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5826 printf("* chkpath on a non existent component should fail\n");
5830 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5831 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5832 cli_rmdir(cli, "\\chkpath.dir");
5834 if (!torture_close_connection(cli)) {
5841 static bool run_eatest(int dummy)
5843 static struct cli_state *cli;
5844 const char *fname = "\\eatest.txt";
5845 bool correct = True;
5849 struct ea_struct *ea_list = NULL;
5850 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5853 printf("starting eatest\n");
5855 if (!torture_open_connection(&cli, 0)) {
5856 talloc_destroy(mem_ctx);
5860 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5862 status = cli_ntcreate(cli, fname, 0,
5863 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5864 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5866 if (!NT_STATUS_IS_OK(status)) {
5867 printf("open failed - %s\n", nt_errstr(status));
5868 talloc_destroy(mem_ctx);
5872 for (i = 0; i < 10; i++) {
5873 fstring ea_name, ea_val;
5875 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5876 memset(ea_val, (char)i+1, i+1);
5877 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5878 if (!NT_STATUS_IS_OK(status)) {
5879 printf("ea_set of name %s failed - %s\n", ea_name,
5881 talloc_destroy(mem_ctx);
5886 cli_close(cli, fnum);
5887 for (i = 0; i < 10; i++) {
5888 fstring ea_name, ea_val;
5890 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5891 memset(ea_val, (char)i+1, i+1);
5892 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5893 if (!NT_STATUS_IS_OK(status)) {
5894 printf("ea_set of name %s failed - %s\n", ea_name,
5896 talloc_destroy(mem_ctx);
5901 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5902 if (!NT_STATUS_IS_OK(status)) {
5903 printf("ea_get list failed - %s\n", nt_errstr(status));
5907 printf("num_eas = %d\n", (int)num_eas);
5909 if (num_eas != 20) {
5910 printf("Should be 20 EA's stored... failing.\n");
5914 for (i = 0; i < num_eas; i++) {
5915 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5916 dump_data(0, ea_list[i].value.data,
5917 ea_list[i].value.length);
5920 /* Setting EA's to zero length deletes them. Test this */
5921 printf("Now deleting all EA's - case indepenent....\n");
5924 cli_set_ea_path(cli, fname, "", "", 0);
5926 for (i = 0; i < 20; i++) {
5928 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5929 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5930 if (!NT_STATUS_IS_OK(status)) {
5931 printf("ea_set of name %s failed - %s\n", ea_name,
5933 talloc_destroy(mem_ctx);
5939 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5940 if (!NT_STATUS_IS_OK(status)) {
5941 printf("ea_get list failed - %s\n", nt_errstr(status));
5945 printf("num_eas = %d\n", (int)num_eas);
5946 for (i = 0; i < num_eas; i++) {
5947 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5948 dump_data(0, ea_list[i].value.data,
5949 ea_list[i].value.length);
5953 printf("deleting EA's failed.\n");
5957 /* Try and delete a non existant EA. */
5958 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5959 if (!NT_STATUS_IS_OK(status)) {
5960 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5965 talloc_destroy(mem_ctx);
5966 if (!torture_close_connection(cli)) {
5973 static bool run_dirtest1(int dummy)
5976 static struct cli_state *cli;
5979 bool correct = True;
5981 printf("starting directory test\n");
5983 if (!torture_open_connection(&cli, 0)) {
5987 cli_sockopt(cli, sockops);
5989 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5990 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5991 cli_rmdir(cli, "\\LISTDIR");
5992 cli_mkdir(cli, "\\LISTDIR");
5994 /* Create 1000 files and 1000 directories. */
5995 for (i=0;i<1000;i++) {
5997 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5998 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5999 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6000 fprintf(stderr,"Failed to open %s\n", fname);
6003 cli_close(cli, fnum);
6005 for (i=0;i<1000;i++) {
6007 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6008 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6009 fprintf(stderr,"Failed to open %s\n", fname);
6014 /* Now ensure that doing an old list sees both files and directories. */
6016 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6017 printf("num_seen = %d\n", num_seen );
6018 /* We should see 100 files + 1000 directories + . and .. */
6019 if (num_seen != 2002)
6022 /* Ensure if we have the "must have" bits we only see the
6026 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6027 printf("num_seen = %d\n", num_seen );
6028 if (num_seen != 1002)
6032 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6033 printf("num_seen = %d\n", num_seen );
6034 if (num_seen != 1000)
6037 /* Delete everything. */
6038 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6039 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6040 cli_rmdir(cli, "\\LISTDIR");
6043 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6044 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6045 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6048 if (!torture_close_connection(cli)) {
6052 printf("finished dirtest1\n");
6057 static bool run_error_map_extract(int dummy) {
6059 static struct cli_state *c_dos;
6060 static struct cli_state *c_nt;
6065 uint32 flgs2, errnum;
6072 /* NT-Error connection */
6074 if (!(c_nt = open_nbt_connection())) {
6078 c_nt->use_spnego = False;
6080 status = cli_negprot(c_nt);
6082 if (!NT_STATUS_IS_OK(status)) {
6083 printf("%s rejected the NT-error negprot (%s)\n", host,
6089 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6090 if (!NT_STATUS_IS_OK(status)) {
6091 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6095 /* DOS-Error connection */
6097 if (!(c_dos = open_nbt_connection())) {
6101 c_dos->use_spnego = False;
6102 c_dos->force_dos_errors = True;
6104 status = cli_negprot(c_dos);
6105 if (!NT_STATUS_IS_OK(status)) {
6106 printf("%s rejected the DOS-error negprot (%s)\n", host,
6108 cli_shutdown(c_dos);
6112 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6113 if (!NT_STATUS_IS_OK(status)) {
6114 printf("%s rejected the DOS-error initial session setup (%s)\n",
6115 host, nt_errstr(status));
6119 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6120 fstr_sprintf(user, "%X", error);
6122 status = cli_session_setup(c_nt, user,
6123 password, strlen(password),
6124 password, strlen(password),
6126 if (NT_STATUS_IS_OK(status)) {
6127 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6130 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
6132 /* Case #1: 32-bit NT errors */
6133 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6134 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
6136 printf("/** Dos error on NT connection! (%s) */\n",
6138 nt_status = NT_STATUS(0xc0000000);
6141 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
6142 password, strlen(password),
6143 password, strlen(password),
6145 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6147 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
6149 /* Case #1: 32-bit NT errors */
6150 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6151 printf("/** NT error on DOS connection! (%s) */\n",
6153 errnum = errclass = 0;
6155 cli_dos_error(c_dos, &errclass, &errnum);
6158 if (NT_STATUS_V(nt_status) != error) {
6159 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6160 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6161 get_nt_error_c_code(talloc_tos(), nt_status));
6164 printf("\t{%s,\t%s,\t%s},\n",
6165 smb_dos_err_class(errclass),
6166 smb_dos_err_name(errclass, errnum),
6167 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6172 static bool run_sesssetup_bench(int dummy)
6174 static struct cli_state *c;
6175 const char *fname = "\\file.dat";
6180 if (!torture_open_connection(&c, 0)) {
6184 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6185 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6186 FILE_DELETE_ON_CLOSE, 0, &fnum);
6187 if (!NT_STATUS_IS_OK(status)) {
6188 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6192 for (i=0; i<torture_numops; i++) {
6193 status = cli_session_setup(
6195 password, strlen(password),
6196 password, strlen(password),
6198 if (!NT_STATUS_IS_OK(status)) {
6199 d_printf("(%s) cli_session_setup failed: %s\n",
6200 __location__, nt_errstr(status));
6204 d_printf("\r%d ", (int)c->vuid);
6206 status = cli_ulogoff(c);
6207 if (!NT_STATUS_IS_OK(status)) {
6208 d_printf("(%s) cli_ulogoff failed: %s\n",
6209 __location__, nt_errstr(status));
6218 static bool subst_test(const char *str, const char *user, const char *domain,
6219 uid_t uid, gid_t gid, const char *expected)
6224 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6226 if (strcmp(subst, expected) != 0) {
6227 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6228 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6237 static void chain1_open_completion(struct tevent_req *req)
6241 status = cli_open_recv(req, &fnum);
6244 d_printf("cli_open_recv returned %s: %d\n",
6246 NT_STATUS_IS_OK(status) ? fnum : -1);
6249 static void chain1_write_completion(struct tevent_req *req)
6253 status = cli_write_andx_recv(req, &written);
6256 d_printf("cli_write_andx_recv returned %s: %d\n",
6258 NT_STATUS_IS_OK(status) ? (int)written : -1);
6261 static void chain1_close_completion(struct tevent_req *req)
6264 bool *done = (bool *)tevent_req_callback_data_void(req);
6266 status = cli_close_recv(req);
6271 d_printf("cli_close returned %s\n", nt_errstr(status));
6274 static bool run_chain1(int dummy)
6276 struct cli_state *cli1;
6277 struct event_context *evt = event_context_init(NULL);
6278 struct tevent_req *reqs[3], *smbreqs[3];
6280 const char *str = "foobar";
6283 printf("starting chain1 test\n");
6284 if (!torture_open_connection(&cli1, 0)) {
6288 cli_sockopt(cli1, sockops);
6290 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6291 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6292 if (reqs[0] == NULL) return false;
6293 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6296 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6297 (const uint8_t *)str, 0, strlen(str)+1,
6298 smbreqs, 1, &smbreqs[1]);
6299 if (reqs[1] == NULL) return false;
6300 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6302 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6303 if (reqs[2] == NULL) return false;
6304 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6306 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6307 if (!NT_STATUS_IS_OK(status)) {
6312 event_loop_once(evt);
6315 torture_close_connection(cli1);
6319 static void chain2_sesssetup_completion(struct tevent_req *req)
6322 status = cli_session_setup_guest_recv(req);
6323 d_printf("sesssetup returned %s\n", nt_errstr(status));
6326 static void chain2_tcon_completion(struct tevent_req *req)
6328 bool *done = (bool *)tevent_req_callback_data_void(req);
6330 status = cli_tcon_andx_recv(req);
6331 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6335 static bool run_chain2(int dummy)
6337 struct cli_state *cli1;
6338 struct event_context *evt = event_context_init(NULL);
6339 struct tevent_req *reqs[2], *smbreqs[2];
6343 printf("starting chain2 test\n");
6344 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6345 port_to_use, Undefined, 0);
6346 if (!NT_STATUS_IS_OK(status)) {
6350 cli_sockopt(cli1, sockops);
6352 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6354 if (reqs[0] == NULL) return false;
6355 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6357 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6358 "?????", NULL, 0, &smbreqs[1]);
6359 if (reqs[1] == NULL) return false;
6360 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6362 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6363 if (!NT_STATUS_IS_OK(status)) {
6368 event_loop_once(evt);
6371 torture_close_connection(cli1);
6376 struct torture_createdel_state {
6377 struct tevent_context *ev;
6378 struct cli_state *cli;
6381 static void torture_createdel_created(struct tevent_req *subreq);
6382 static void torture_createdel_closed(struct tevent_req *subreq);
6384 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6385 struct tevent_context *ev,
6386 struct cli_state *cli,
6389 struct tevent_req *req, *subreq;
6390 struct torture_createdel_state *state;
6392 req = tevent_req_create(mem_ctx, &state,
6393 struct torture_createdel_state);
6400 subreq = cli_ntcreate_send(
6401 state, ev, cli, name, 0,
6402 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6403 FILE_ATTRIBUTE_NORMAL,
6404 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6405 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6407 if (tevent_req_nomem(subreq, req)) {
6408 return tevent_req_post(req, ev);
6410 tevent_req_set_callback(subreq, torture_createdel_created, req);
6414 static void torture_createdel_created(struct tevent_req *subreq)
6416 struct tevent_req *req = tevent_req_callback_data(
6417 subreq, struct tevent_req);
6418 struct torture_createdel_state *state = tevent_req_data(
6419 req, struct torture_createdel_state);
6423 status = cli_ntcreate_recv(subreq, &fnum);
6424 TALLOC_FREE(subreq);
6425 if (!NT_STATUS_IS_OK(status)) {
6426 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6427 nt_errstr(status)));
6428 tevent_req_nterror(req, status);
6432 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6433 if (tevent_req_nomem(subreq, req)) {
6436 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6439 static void torture_createdel_closed(struct tevent_req *subreq)
6441 struct tevent_req *req = tevent_req_callback_data(
6442 subreq, struct tevent_req);
6445 status = cli_close_recv(subreq);
6446 if (!NT_STATUS_IS_OK(status)) {
6447 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6448 tevent_req_nterror(req, status);
6451 tevent_req_done(req);
6454 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6456 return tevent_req_simple_recv_ntstatus(req);
6459 struct torture_createdels_state {
6460 struct tevent_context *ev;
6461 struct cli_state *cli;
6462 const char *base_name;
6466 struct tevent_req **reqs;
6469 static void torture_createdels_done(struct tevent_req *subreq);
6471 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6472 struct tevent_context *ev,
6473 struct cli_state *cli,
6474 const char *base_name,
6478 struct tevent_req *req;
6479 struct torture_createdels_state *state;
6482 req = tevent_req_create(mem_ctx, &state,
6483 struct torture_createdels_state);
6489 state->base_name = talloc_strdup(state, base_name);
6490 if (tevent_req_nomem(state->base_name, req)) {
6491 return tevent_req_post(req, ev);
6493 state->num_files = MAX(num_parallel, num_files);
6495 state->received = 0;
6497 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6498 if (tevent_req_nomem(state->reqs, req)) {
6499 return tevent_req_post(req, ev);
6502 for (i=0; i<num_parallel; i++) {
6505 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6507 if (tevent_req_nomem(name, req)) {
6508 return tevent_req_post(req, ev);
6510 state->reqs[i] = torture_createdel_send(
6511 state->reqs, state->ev, state->cli, name);
6512 if (tevent_req_nomem(state->reqs[i], req)) {
6513 return tevent_req_post(req, ev);
6515 name = talloc_move(state->reqs[i], &name);
6516 tevent_req_set_callback(state->reqs[i],
6517 torture_createdels_done, req);
6523 static void torture_createdels_done(struct tevent_req *subreq)
6525 struct tevent_req *req = tevent_req_callback_data(
6526 subreq, struct tevent_req);
6527 struct torture_createdels_state *state = tevent_req_data(
6528 req, struct torture_createdels_state);
6529 size_t num_parallel = talloc_array_length(state->reqs);
6534 status = torture_createdel_recv(subreq);
6535 if (!NT_STATUS_IS_OK(status)){
6536 DEBUG(10, ("torture_createdel_recv returned %s\n",
6537 nt_errstr(status)));
6538 TALLOC_FREE(subreq);
6539 tevent_req_nterror(req, status);
6543 for (i=0; i<num_parallel; i++) {
6544 if (subreq == state->reqs[i]) {
6548 if (i == num_parallel) {
6549 DEBUG(10, ("received something we did not send\n"));
6550 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6553 TALLOC_FREE(state->reqs[i]);
6555 if (state->sent >= state->num_files) {
6556 tevent_req_done(req);
6560 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6562 if (tevent_req_nomem(name, req)) {
6565 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6567 if (tevent_req_nomem(state->reqs[i], req)) {
6570 name = talloc_move(state->reqs[i], &name);
6571 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6575 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6577 return tevent_req_simple_recv_ntstatus(req);
6580 struct swallow_notify_state {
6581 struct tevent_context *ev;
6582 struct cli_state *cli;
6584 uint32_t completion_filter;
6586 bool (*fn)(uint32_t action, const char *name, void *priv);
6590 static void swallow_notify_done(struct tevent_req *subreq);
6592 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6593 struct tevent_context *ev,
6594 struct cli_state *cli,
6596 uint32_t completion_filter,
6598 bool (*fn)(uint32_t action,
6603 struct tevent_req *req, *subreq;
6604 struct swallow_notify_state *state;
6606 req = tevent_req_create(mem_ctx, &state,
6607 struct swallow_notify_state);
6614 state->completion_filter = completion_filter;
6615 state->recursive = recursive;
6619 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6620 0xffff, state->completion_filter,
6622 if (tevent_req_nomem(subreq, req)) {
6623 return tevent_req_post(req, ev);
6625 tevent_req_set_callback(subreq, swallow_notify_done, req);
6629 static void swallow_notify_done(struct tevent_req *subreq)
6631 struct tevent_req *req = tevent_req_callback_data(
6632 subreq, struct tevent_req);
6633 struct swallow_notify_state *state = tevent_req_data(
6634 req, struct swallow_notify_state);
6636 uint32_t i, num_changes;
6637 struct notify_change *changes;
6639 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6640 TALLOC_FREE(subreq);
6641 if (!NT_STATUS_IS_OK(status)) {
6642 DEBUG(10, ("cli_notify_recv returned %s\n",
6643 nt_errstr(status)));
6644 tevent_req_nterror(req, status);
6648 for (i=0; i<num_changes; i++) {
6649 state->fn(changes[i].action, changes[i].name, state->priv);
6651 TALLOC_FREE(changes);
6653 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6654 0xffff, state->completion_filter,
6656 if (tevent_req_nomem(subreq, req)) {
6659 tevent_req_set_callback(subreq, swallow_notify_done, req);
6662 static bool print_notifies(uint32_t action, const char *name, void *priv)
6664 if (DEBUGLEVEL > 5) {
6665 d_printf("%d %s\n", (int)action, name);
6670 static void notify_bench_done(struct tevent_req *req)
6672 int *num_finished = (int *)tevent_req_callback_data_void(req);
6676 static bool run_notify_bench(int dummy)
6678 const char *dname = "\\notify-bench";
6679 struct tevent_context *ev;
6682 struct tevent_req *req1;
6683 struct tevent_req *req2 = NULL;
6684 int i, num_unc_names;
6685 int num_finished = 0;
6687 printf("starting notify-bench test\n");
6689 if (use_multishare_conn) {
6691 unc_list = file_lines_load(multishare_conn_fname,
6692 &num_unc_names, 0, NULL);
6693 if (!unc_list || num_unc_names <= 0) {
6694 d_printf("Failed to load unc names list from '%s'\n",
6695 multishare_conn_fname);
6698 TALLOC_FREE(unc_list);
6703 ev = tevent_context_init(talloc_tos());
6705 d_printf("tevent_context_init failed\n");
6709 for (i=0; i<num_unc_names; i++) {
6710 struct cli_state *cli;
6713 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6715 if (base_fname == NULL) {
6719 if (!torture_open_connection(&cli, i)) {
6723 status = cli_ntcreate(cli, dname, 0,
6724 MAXIMUM_ALLOWED_ACCESS,
6725 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6727 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6730 if (!NT_STATUS_IS_OK(status)) {
6731 d_printf("Could not create %s: %s\n", dname,
6736 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6737 FILE_NOTIFY_CHANGE_FILE_NAME |
6738 FILE_NOTIFY_CHANGE_DIR_NAME |
6739 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6740 FILE_NOTIFY_CHANGE_LAST_WRITE,
6741 false, print_notifies, NULL);
6743 d_printf("Could not create notify request\n");
6747 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6748 base_fname, 10, torture_numops);
6750 d_printf("Could not create createdels request\n");
6753 TALLOC_FREE(base_fname);
6755 tevent_req_set_callback(req2, notify_bench_done,
6759 while (num_finished < num_unc_names) {
6761 ret = tevent_loop_once(ev);
6763 d_printf("tevent_loop_once failed\n");
6768 if (!tevent_req_poll(req2, ev)) {
6769 d_printf("tevent_req_poll failed\n");
6772 status = torture_createdels_recv(req2);
6773 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6778 static bool run_mangle1(int dummy)
6780 struct cli_state *cli;
6781 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6785 time_t change_time, access_time, write_time;
6789 printf("starting mangle1 test\n");
6790 if (!torture_open_connection(&cli, 0)) {
6794 cli_sockopt(cli, sockops);
6796 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6797 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6799 if (!NT_STATUS_IS_OK(status)) {
6800 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6803 cli_close(cli, fnum);
6805 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6806 if (!NT_STATUS_IS_OK(status)) {
6807 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6811 d_printf("alt_name: %s\n", alt_name);
6813 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6814 if (!NT_STATUS_IS_OK(status)) {
6815 d_printf("cli_open(%s) failed: %s\n", alt_name,
6819 cli_close(cli, fnum);
6821 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6822 &write_time, &size, &mode);
6823 if (!NT_STATUS_IS_OK(status)) {
6824 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6832 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6834 size_t *to_pull = (size_t *)priv;
6835 size_t thistime = *to_pull;
6837 thistime = MIN(thistime, n);
6838 if (thistime == 0) {
6842 memset(buf, 0, thistime);
6843 *to_pull -= thistime;
6847 static bool run_windows_write(int dummy)
6849 struct cli_state *cli1;
6853 const char *fname = "\\writetest.txt";
6854 struct timeval start_time;
6859 printf("starting windows_write test\n");
6860 if (!torture_open_connection(&cli1, 0)) {
6864 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6865 if (!NT_STATUS_IS_OK(status)) {
6866 printf("open failed (%s)\n", nt_errstr(status));
6870 cli_sockopt(cli1, sockops);
6872 start_time = timeval_current();
6874 for (i=0; i<torture_numops; i++) {
6876 off_t start = i * torture_blocksize;
6877 size_t to_pull = torture_blocksize - 1;
6879 status = cli_writeall(cli1, fnum, 0, &c,
6880 start + torture_blocksize - 1, 1, NULL);
6881 if (!NT_STATUS_IS_OK(status)) {
6882 printf("cli_write failed: %s\n", nt_errstr(status));
6886 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6887 null_source, &to_pull);
6888 if (!NT_STATUS_IS_OK(status)) {
6889 printf("cli_push returned: %s\n", nt_errstr(status));
6894 seconds = timeval_elapsed(&start_time);
6895 kbytes = (double)torture_blocksize * torture_numops;
6898 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6899 (double)seconds, (int)(kbytes/seconds));
6903 cli_close(cli1, fnum);
6904 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6905 torture_close_connection(cli1);
6909 static bool run_cli_echo(int dummy)
6911 struct cli_state *cli;
6914 printf("starting cli_echo test\n");
6915 if (!torture_open_connection(&cli, 0)) {
6918 cli_sockopt(cli, sockops);
6920 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6922 d_printf("cli_echo returned %s\n", nt_errstr(status));
6924 torture_close_connection(cli);
6925 return NT_STATUS_IS_OK(status);
6928 static bool run_uid_regression_test(int dummy)
6930 static struct cli_state *cli;
6933 bool correct = True;
6936 printf("starting uid regression test\n");
6938 if (!torture_open_connection(&cli, 0)) {
6942 cli_sockopt(cli, sockops);
6944 /* Ok - now save then logoff our current user. */
6945 old_vuid = cli->vuid;
6947 status = cli_ulogoff(cli);
6948 if (!NT_STATUS_IS_OK(status)) {
6949 d_printf("(%s) cli_ulogoff failed: %s\n",
6950 __location__, nt_errstr(status));
6955 cli->vuid = old_vuid;
6957 /* Try an operation. */
6958 status = cli_mkdir(cli, "\\uid_reg_test");
6959 if (NT_STATUS_IS_OK(status)) {
6960 d_printf("(%s) cli_mkdir succeeded\n",
6965 /* Should be bad uid. */
6966 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6967 NT_STATUS_USER_SESSION_DELETED)) {
6973 old_cnum = cli->cnum;
6975 /* Now try a SMBtdis with the invald vuid set to zero. */
6978 /* This should succeed. */
6979 status = cli_tdis(cli);
6981 if (NT_STATUS_IS_OK(status)) {
6982 d_printf("First tdis with invalid vuid should succeed.\n");
6984 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6989 cli->vuid = old_vuid;
6990 cli->cnum = old_cnum;
6992 /* This should fail. */
6993 status = cli_tdis(cli);
6994 if (NT_STATUS_IS_OK(status)) {
6995 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6999 /* Should be bad tid. */
7000 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7001 NT_STATUS_NETWORK_NAME_DELETED)) {
7007 cli_rmdir(cli, "\\uid_reg_test");
7016 static const char *illegal_chars = "*\\/?<>|\":";
7017 static char force_shortname_chars[] = " +,.[];=\177";
7019 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7020 const char *mask, void *state)
7022 struct cli_state *pcli = (struct cli_state *)state;
7024 NTSTATUS status = NT_STATUS_OK;
7026 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7028 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7029 return NT_STATUS_OK;
7031 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7032 status = cli_rmdir(pcli, fname);
7033 if (!NT_STATUS_IS_OK(status)) {
7034 printf("del_fn: failed to rmdir %s\n,", fname );
7037 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7038 if (!NT_STATUS_IS_OK(status)) {
7039 printf("del_fn: failed to unlink %s\n,", fname );
7051 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7052 const char *name, void *state)
7054 struct sn_state *s = (struct sn_state *)state;
7058 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7059 i, finfo->name, finfo->short_name);
7062 if (strchr(force_shortname_chars, i)) {
7063 if (!finfo->short_name[0]) {
7064 /* Shortname not created when it should be. */
7065 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7066 __location__, finfo->name, i);
7069 } else if (finfo->short_name[0]){
7070 /* Shortname created when it should not be. */
7071 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7072 __location__, finfo->short_name, finfo->name);
7076 return NT_STATUS_OK;
7079 static bool run_shortname_test(int dummy)
7081 static struct cli_state *cli;
7082 bool correct = True;
7088 printf("starting shortname test\n");
7090 if (!torture_open_connection(&cli, 0)) {
7094 cli_sockopt(cli, sockops);
7096 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7097 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7098 cli_rmdir(cli, "\\shortname");
7100 status = cli_mkdir(cli, "\\shortname");
7101 if (!NT_STATUS_IS_OK(status)) {
7102 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7103 __location__, nt_errstr(status));
7108 strlcpy(fname, "\\shortname\\", sizeof(fname));
7109 strlcat(fname, "test .txt", sizeof(fname));
7113 for (i = 32; i < 128; i++) {
7114 uint16_t fnum = (uint16_t)-1;
7118 if (strchr(illegal_chars, i)) {
7123 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7124 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7125 if (!NT_STATUS_IS_OK(status)) {
7126 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7127 __location__, fname, nt_errstr(status));
7131 cli_close(cli, fnum);
7134 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
7136 if (s.matched != 1) {
7137 d_printf("(%s) failed to list %s: %s\n",
7138 __location__, fname, cli_errstr(cli));
7143 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7144 if (!NT_STATUS_IS_OK(status)) {
7145 d_printf("(%s) failed to delete %s: %s\n",
7146 __location__, fname, nt_errstr(status));
7159 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7160 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7161 cli_rmdir(cli, "\\shortname");
7162 torture_close_connection(cli);
7166 static void pagedsearch_cb(struct tevent_req *req)
7169 struct tldap_message *msg;
7172 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7173 if (rc != TLDAP_SUCCESS) {
7174 d_printf("tldap_search_paged_recv failed: %s\n",
7175 tldap_err2string(rc));
7178 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7182 if (!tldap_entry_dn(msg, &dn)) {
7183 d_printf("tldap_entry_dn failed\n");
7186 d_printf("%s\n", dn);
7190 static bool run_tldap(int dummy)
7192 struct tldap_context *ld;
7195 struct sockaddr_storage addr;
7196 struct tevent_context *ev;
7197 struct tevent_req *req;
7201 if (!resolve_name(host, &addr, 0, false)) {
7202 d_printf("could not find host %s\n", host);
7205 status = open_socket_out(&addr, 389, 9999, &fd);
7206 if (!NT_STATUS_IS_OK(status)) {
7207 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7211 ld = tldap_context_create(talloc_tos(), fd);
7214 d_printf("tldap_context_create failed\n");
7218 rc = tldap_fetch_rootdse(ld);
7219 if (rc != TLDAP_SUCCESS) {
7220 d_printf("tldap_fetch_rootdse failed: %s\n",
7221 tldap_errstr(talloc_tos(), ld, rc));
7225 basedn = tldap_talloc_single_attribute(
7226 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7227 if (basedn == NULL) {
7228 d_printf("no defaultNamingContext\n");
7231 d_printf("defaultNamingContext: %s\n", basedn);
7233 ev = tevent_context_init(talloc_tos());
7235 d_printf("tevent_context_init failed\n");
7239 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7240 TLDAP_SCOPE_SUB, "(objectclass=*)",
7242 NULL, 0, NULL, 0, 0, 0, 0, 5);
7244 d_printf("tldap_search_paged_send failed\n");
7247 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7249 tevent_req_poll(req, ev);
7253 /* test search filters against rootDSE */
7254 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7255 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7257 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7258 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7259 talloc_tos(), NULL, NULL);
7260 if (rc != TLDAP_SUCCESS) {
7261 d_printf("tldap_search with complex filter failed: %s\n",
7262 tldap_errstr(talloc_tos(), ld, rc));
7270 /* Torture test to ensure no regression of :
7271 https://bugzilla.samba.org/show_bug.cgi?id=7084
7274 static bool run_dir_createtime(int dummy)
7276 struct cli_state *cli;
7277 const char *dname = "\\testdir";
7278 const char *fname = "\\testdir\\testfile";
7280 struct timespec create_time;
7281 struct timespec create_time1;
7285 if (!torture_open_connection(&cli, 0)) {
7289 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7290 cli_rmdir(cli, dname);
7292 status = cli_mkdir(cli, dname);
7293 if (!NT_STATUS_IS_OK(status)) {
7294 printf("mkdir failed: %s\n", nt_errstr(status));
7298 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7300 if (!NT_STATUS_IS_OK(status)) {
7301 printf("cli_qpathinfo2 returned %s\n",
7306 /* Sleep 3 seconds, then create a file. */
7309 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7311 if (!NT_STATUS_IS_OK(status)) {
7312 printf("cli_open failed: %s\n", nt_errstr(status));
7316 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7318 if (!NT_STATUS_IS_OK(status)) {
7319 printf("cli_qpathinfo2 (2) returned %s\n",
7324 if (timespec_compare(&create_time1, &create_time)) {
7325 printf("run_dir_createtime: create time was updated (error)\n");
7327 printf("run_dir_createtime: create time was not updated (correct)\n");
7333 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7334 cli_rmdir(cli, dname);
7335 if (!torture_close_connection(cli)) {
7342 static bool run_streamerror(int dummy)
7344 struct cli_state *cli;
7345 const char *dname = "\\testdir";
7346 const char *streamname =
7347 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7349 time_t change_time, access_time, write_time;
7351 uint16_t mode, fnum;
7354 if (!torture_open_connection(&cli, 0)) {
7358 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7359 cli_rmdir(cli, dname);
7361 status = cli_mkdir(cli, dname);
7362 if (!NT_STATUS_IS_OK(status)) {
7363 printf("mkdir failed: %s\n", nt_errstr(status));
7367 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7369 status = cli_nt_error(cli);
7371 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7372 printf("pathinfo returned %s, expected "
7373 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7378 status = cli_ntcreate(cli, streamname, 0x16,
7379 FILE_READ_DATA|FILE_READ_EA|
7380 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7381 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7382 FILE_OPEN, 0, 0, &fnum);
7384 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7385 printf("ntcreate returned %s, expected "
7386 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7392 cli_rmdir(cli, dname);
7396 static bool run_local_substitute(int dummy)
7400 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7401 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7402 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7403 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7404 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7405 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7406 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7407 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7409 /* Different captialization rules in sub_basic... */
7411 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7417 static bool run_local_base64(int dummy)
7422 for (i=1; i<2000; i++) {
7423 DATA_BLOB blob1, blob2;
7426 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7428 generate_random_buffer(blob1.data, blob1.length);
7430 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7432 d_fprintf(stderr, "base64_encode_data_blob failed "
7433 "for %d bytes\n", i);
7436 blob2 = base64_decode_data_blob(b64);
7439 if (data_blob_cmp(&blob1, &blob2)) {
7440 d_fprintf(stderr, "data_blob_cmp failed for %d "
7444 TALLOC_FREE(blob1.data);
7445 data_blob_free(&blob2);
7450 static bool run_local_gencache(int dummy)
7456 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7457 d_printf("%s: gencache_set() failed\n", __location__);
7461 if (!gencache_get("foo", NULL, NULL)) {
7462 d_printf("%s: gencache_get() failed\n", __location__);
7466 if (!gencache_get("foo", &val, &tm)) {
7467 d_printf("%s: gencache_get() failed\n", __location__);
7471 if (strcmp(val, "bar") != 0) {
7472 d_printf("%s: gencache_get() returned %s, expected %s\n",
7473 __location__, val, "bar");
7480 if (!gencache_del("foo")) {
7481 d_printf("%s: gencache_del() failed\n", __location__);
7484 if (gencache_del("foo")) {
7485 d_printf("%s: second gencache_del() succeeded\n",
7490 if (gencache_get("foo", &val, &tm)) {
7491 d_printf("%s: gencache_get() on deleted entry "
7492 "succeeded\n", __location__);
7496 blob = data_blob_string_const_null("bar");
7497 tm = time(NULL) + 60;
7499 if (!gencache_set_data_blob("foo", &blob, tm)) {
7500 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7504 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7505 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7509 if (strcmp((const char *)blob.data, "bar") != 0) {
7510 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7511 __location__, (const char *)blob.data, "bar");
7512 data_blob_free(&blob);
7516 data_blob_free(&blob);
7518 if (!gencache_del("foo")) {
7519 d_printf("%s: gencache_del() failed\n", __location__);
7522 if (gencache_del("foo")) {
7523 d_printf("%s: second gencache_del() succeeded\n",
7528 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7529 d_printf("%s: gencache_get_data_blob() on deleted entry "
7530 "succeeded\n", __location__);
7537 static bool rbt_testval(struct db_context *db, const char *key,
7540 struct db_record *rec;
7541 TDB_DATA data = string_tdb_data(value);
7545 rec = db->fetch_locked(db, db, string_tdb_data(key));
7547 d_fprintf(stderr, "fetch_locked failed\n");
7550 status = rec->store(rec, data, 0);
7551 if (!NT_STATUS_IS_OK(status)) {
7552 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7557 rec = db->fetch_locked(db, db, string_tdb_data(key));
7559 d_fprintf(stderr, "second fetch_locked failed\n");
7562 if ((rec->value.dsize != data.dsize)
7563 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7564 d_fprintf(stderr, "Got wrong data back\n");
7574 static bool run_local_rbtree(int dummy)
7576 struct db_context *db;
7580 db = db_open_rbt(NULL);
7583 d_fprintf(stderr, "db_open_rbt failed\n");
7587 for (i=0; i<1000; i++) {
7590 if (asprintf(&key, "key%ld", random()) == -1) {
7593 if (asprintf(&value, "value%ld", random()) == -1) {
7598 if (!rbt_testval(db, key, value)) {
7605 if (asprintf(&value, "value%ld", random()) == -1) {
7610 if (!rbt_testval(db, key, value)) {
7629 local test for character set functions
7631 This is a very simple test for the functionality in convert_string_error()
7633 static bool run_local_convert_string(int dummy)
7635 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7636 const char *test_strings[2] = { "March", "M\303\244rz" };
7640 for (i=0; i<2; i++) {
7641 const char *str = test_strings[i];
7642 int len = strlen(str);
7643 size_t converted_size;
7646 memset(dst, 'X', sizeof(dst));
7648 /* first try with real source length */
7649 ret = convert_string_error(CH_UNIX, CH_UTF8,
7654 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7658 if (converted_size != len) {
7659 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7660 str, len, (int)converted_size);
7664 if (strncmp(str, dst, converted_size) != 0) {
7665 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7669 if (strlen(str) != converted_size) {
7670 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7671 (int)strlen(str), (int)converted_size);
7675 if (dst[converted_size] != 'X') {
7676 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7680 /* now with srclen==-1, this causes the nul to be
7682 ret = convert_string_error(CH_UNIX, CH_UTF8,
7687 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7691 if (converted_size != len+1) {
7692 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7693 str, len, (int)converted_size);
7697 if (strncmp(str, dst, converted_size) != 0) {
7698 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7702 if (len+1 != converted_size) {
7703 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7704 len+1, (int)converted_size);
7708 if (dst[converted_size] != 'X') {
7709 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7716 TALLOC_FREE(tmp_ctx);
7719 TALLOC_FREE(tmp_ctx);
7724 struct talloc_dict_test {
7728 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7730 int *count = (int *)priv;
7735 static bool run_local_talloc_dict(int dummy)
7737 struct talloc_dict *dict;
7738 struct talloc_dict_test *t;
7741 dict = talloc_dict_init(talloc_tos());
7746 t = talloc(talloc_tos(), struct talloc_dict_test);
7753 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7758 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7771 static bool run_local_string_to_sid(int dummy) {
7774 if (string_to_sid(&sid, "S--1-5-32-545")) {
7775 printf("allowing S--1-5-32-545\n");
7778 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7779 printf("allowing S-1-5-32-+545\n");
7782 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")) {
7783 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7786 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7787 printf("allowing S-1-5-32-545-abc\n");
7790 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7791 printf("could not parse S-1-5-32-545\n");
7794 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7795 printf("mis-parsed S-1-5-32-545 as %s\n",
7796 sid_string_tos(&sid));
7802 static bool run_local_binary_to_sid(int dummy) {
7803 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7804 static const char good_binary_sid[] = {
7805 0x1, /* revision number */
7807 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7808 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7809 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7810 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7811 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7812 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7813 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7814 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7815 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7816 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7817 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7818 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7819 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7820 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7821 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7822 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7825 static const char long_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] */
7844 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7845 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7846 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7849 static const char long_binary_sid2[] = {
7850 0x1, /* revision number */
7852 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7853 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7854 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7855 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7856 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7857 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7858 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7859 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7860 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7861 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7862 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7863 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7864 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7865 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7866 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7867 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7868 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7869 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7870 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7871 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7872 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7873 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7874 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7875 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7876 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7877 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7878 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7879 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7880 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7881 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7882 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7883 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7884 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7887 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7890 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7893 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7899 /* Split a path name into filename and stream name components. Canonicalise
7900 * such that an implicit $DATA token is always explicit.
7902 * The "specification" of this function can be found in the
7903 * run_local_stream_name() function in torture.c, I've tried those
7904 * combinations against a W2k3 server.
7907 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7908 char **pbase, char **pstream)
7911 char *stream = NULL;
7912 char *sname; /* stream name */
7913 const char *stype; /* stream type */
7915 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7917 sname = strchr_m(fname, ':');
7919 if (lp_posix_pathnames() || (sname == NULL)) {
7920 if (pbase != NULL) {
7921 base = talloc_strdup(mem_ctx, fname);
7922 NT_STATUS_HAVE_NO_MEMORY(base);
7927 if (pbase != NULL) {
7928 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7929 NT_STATUS_HAVE_NO_MEMORY(base);
7934 stype = strchr_m(sname, ':');
7936 if (stype == NULL) {
7937 sname = talloc_strdup(mem_ctx, sname);
7941 if (strcasecmp_m(stype, ":$DATA") != 0) {
7943 * If there is an explicit stream type, so far we only
7944 * allow $DATA. Is there anything else allowed? -- vl
7946 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7948 return NT_STATUS_OBJECT_NAME_INVALID;
7950 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7954 if (sname == NULL) {
7956 return NT_STATUS_NO_MEMORY;
7959 if (sname[0] == '\0') {
7961 * no stream name, so no stream
7966 if (pstream != NULL) {
7967 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7968 if (stream == NULL) {
7971 return NT_STATUS_NO_MEMORY;
7974 * upper-case the type field
7976 strupper_m(strchr_m(stream, ':')+1);
7980 if (pbase != NULL) {
7983 if (pstream != NULL) {
7986 return NT_STATUS_OK;
7989 static bool test_stream_name(const char *fname, const char *expected_base,
7990 const char *expected_stream,
7991 NTSTATUS expected_status)
7995 char *stream = NULL;
7997 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7998 if (!NT_STATUS_EQUAL(status, expected_status)) {
8002 if (!NT_STATUS_IS_OK(status)) {
8006 if (base == NULL) goto error;
8008 if (strcmp(expected_base, base) != 0) goto error;
8010 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8011 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8013 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8017 TALLOC_FREE(stream);
8021 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8022 fname, expected_base ? expected_base : "<NULL>",
8023 expected_stream ? expected_stream : "<NULL>",
8024 nt_errstr(expected_status));
8025 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8026 base ? base : "<NULL>", stream ? stream : "<NULL>",
8029 TALLOC_FREE(stream);
8033 static bool run_local_stream_name(int dummy)
8037 ret &= test_stream_name(
8038 "bla", "bla", NULL, NT_STATUS_OK);
8039 ret &= test_stream_name(
8040 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8041 ret &= test_stream_name(
8042 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8043 ret &= test_stream_name(
8044 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8045 ret &= test_stream_name(
8046 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8047 ret &= test_stream_name(
8048 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8049 ret &= test_stream_name(
8050 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8051 ret &= test_stream_name(
8052 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8057 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8059 if (a.length != b.length) {
8060 printf("a.length=%d != b.length=%d\n",
8061 (int)a.length, (int)b.length);
8064 if (memcmp(a.data, b.data, a.length) != 0) {
8065 printf("a.data and b.data differ\n");
8071 static bool run_local_memcache(int dummy)
8073 struct memcache *cache;
8075 DATA_BLOB d1, d2, d3;
8076 DATA_BLOB v1, v2, v3;
8078 TALLOC_CTX *mem_ctx;
8080 size_t size1, size2;
8083 cache = memcache_init(NULL, 100);
8085 if (cache == NULL) {
8086 printf("memcache_init failed\n");
8090 d1 = data_blob_const("d1", 2);
8091 d2 = data_blob_const("d2", 2);
8092 d3 = data_blob_const("d3", 2);
8094 k1 = data_blob_const("d1", 2);
8095 k2 = data_blob_const("d2", 2);
8097 memcache_add(cache, STAT_CACHE, k1, d1);
8098 memcache_add(cache, GETWD_CACHE, k2, d2);
8100 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8101 printf("could not find k1\n");
8104 if (!data_blob_equal(d1, v1)) {
8108 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8109 printf("could not find k2\n");
8112 if (!data_blob_equal(d2, v2)) {
8116 memcache_add(cache, STAT_CACHE, k1, d3);
8118 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8119 printf("could not find replaced k1\n");
8122 if (!data_blob_equal(d3, v3)) {
8126 memcache_add(cache, GETWD_CACHE, k1, d1);
8128 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8129 printf("Did find k2, should have been purged\n");
8135 cache = memcache_init(NULL, 0);
8137 mem_ctx = talloc_init("foo");
8139 str1 = talloc_strdup(mem_ctx, "string1");
8140 str2 = talloc_strdup(mem_ctx, "string2");
8142 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8143 data_blob_string_const("torture"), &str1);
8144 size1 = talloc_total_size(cache);
8146 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8147 data_blob_string_const("torture"), &str2);
8148 size2 = talloc_total_size(cache);
8150 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8152 if (size2 > size1) {
8153 printf("memcache leaks memory!\n");
8163 static void wbclient_done(struct tevent_req *req)
8166 struct winbindd_response *wb_resp;
8167 int *i = (int *)tevent_req_callback_data_void(req);
8169 wbc_err = wb_trans_recv(req, req, &wb_resp);
8172 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8175 static bool run_local_wbclient(int dummy)
8177 struct event_context *ev;
8178 struct wb_context **wb_ctx;
8179 struct winbindd_request wb_req;
8180 bool result = false;
8183 BlockSignals(True, SIGPIPE);
8185 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8190 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
8191 if (wb_ctx == NULL) {
8195 ZERO_STRUCT(wb_req);
8196 wb_req.cmd = WINBINDD_PING;
8198 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8200 for (i=0; i<nprocs; i++) {
8201 wb_ctx[i] = wb_context_init(ev, NULL);
8202 if (wb_ctx[i] == NULL) {
8205 for (j=0; j<torture_numops; j++) {
8206 struct tevent_req *req;
8207 req = wb_trans_send(ev, ev, wb_ctx[i],
8208 (j % 2) == 0, &wb_req);
8212 tevent_req_set_callback(req, wbclient_done, &i);
8218 while (i < nprocs * torture_numops) {
8219 event_loop_once(ev);
8228 static void getaddrinfo_finished(struct tevent_req *req)
8230 char *name = (char *)tevent_req_callback_data_void(req);
8231 struct addrinfo *ainfo;
8234 res = getaddrinfo_recv(req, &ainfo);
8236 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8239 d_printf("gai(%s) succeeded\n", name);
8240 freeaddrinfo(ainfo);
8243 static bool run_getaddrinfo_send(int dummy)
8245 TALLOC_CTX *frame = talloc_stackframe();
8246 struct fncall_context *ctx;
8247 struct tevent_context *ev;
8248 bool result = false;
8249 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8250 "www.slashdot.org", "heise.de" };
8251 struct tevent_req *reqs[4];
8254 ev = event_context_init(frame);
8259 ctx = fncall_context_init(frame, 4);
8261 for (i=0; i<ARRAY_SIZE(names); i++) {
8262 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8264 if (reqs[i] == NULL) {
8267 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8268 discard_const_p(void, names[i]));
8271 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8272 tevent_loop_once(ev);
8281 static bool dbtrans_inc(struct db_context *db)
8283 struct db_record *rec;
8288 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8290 printf(__location__ "fetch_lock failed\n");
8294 if (rec->value.dsize != sizeof(uint32_t)) {
8295 printf(__location__ "value.dsize = %d\n",
8296 (int)rec->value.dsize);
8300 val = (uint32_t *)rec->value.dptr;
8303 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8306 if (!NT_STATUS_IS_OK(status)) {
8307 printf(__location__ "store failed: %s\n",
8318 static bool run_local_dbtrans(int dummy)
8320 struct db_context *db;
8321 struct db_record *rec;
8326 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8327 O_RDWR|O_CREAT, 0600);
8329 printf("Could not open transtest.db\n");
8333 res = db->transaction_start(db);
8335 printf(__location__ "transaction_start failed\n");
8339 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8341 printf(__location__ "fetch_lock failed\n");
8345 if (rec->value.dptr == NULL) {
8347 status = rec->store(
8348 rec, make_tdb_data((uint8_t *)&initial,
8351 if (!NT_STATUS_IS_OK(status)) {
8352 printf(__location__ "store returned %s\n",
8360 res = db->transaction_commit(db);
8362 printf(__location__ "transaction_commit failed\n");
8370 res = db->transaction_start(db);
8372 printf(__location__ "transaction_start failed\n");
8376 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8377 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8381 for (i=0; i<10; i++) {
8382 if (!dbtrans_inc(db)) {
8387 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8388 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8392 if (val2 != val + 10) {
8393 printf(__location__ "val=%d, val2=%d\n",
8394 (int)val, (int)val2);
8398 printf("val2=%d\r", val2);
8400 res = db->transaction_commit(db);
8402 printf(__location__ "transaction_commit failed\n");
8412 * Just a dummy test to be run under a debugger. There's no real way
8413 * to inspect the tevent_select specific function from outside of
8417 static bool run_local_tevent_select(int dummy)
8419 struct tevent_context *ev;
8420 struct tevent_fd *fd1, *fd2;
8421 bool result = false;
8423 ev = tevent_context_init_byname(NULL, "select");
8425 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8429 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8431 d_fprintf(stderr, "tevent_add_fd failed\n");
8434 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8436 d_fprintf(stderr, "tevent_add_fd failed\n");
8441 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8443 d_fprintf(stderr, "tevent_add_fd failed\n");
8453 static double create_procs(bool (*fn)(int), bool *result)
8456 volatile pid_t *child_status;
8457 volatile bool *child_status_out;
8460 struct timeval start;
8464 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8465 if (!child_status) {
8466 printf("Failed to setup shared memory\n");
8470 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8471 if (!child_status_out) {
8472 printf("Failed to setup result status shared memory\n");
8476 for (i = 0; i < nprocs; i++) {
8477 child_status[i] = 0;
8478 child_status_out[i] = True;
8481 start = timeval_current();
8483 for (i=0;i<nprocs;i++) {
8486 pid_t mypid = getpid();
8487 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8489 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8492 if (torture_open_connection(¤t_cli, i)) break;
8494 printf("pid %d failed to start\n", (int)getpid());
8500 child_status[i] = getpid();
8502 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8504 child_status_out[i] = fn(i);
8511 for (i=0;i<nprocs;i++) {
8512 if (child_status[i]) synccount++;
8514 if (synccount == nprocs) break;
8516 } while (timeval_elapsed(&start) < 30);
8518 if (synccount != nprocs) {
8519 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8521 return timeval_elapsed(&start);
8524 /* start the client load */
8525 start = timeval_current();
8527 for (i=0;i<nprocs;i++) {
8528 child_status[i] = 0;
8531 printf("%d clients started\n", nprocs);
8533 for (i=0;i<nprocs;i++) {
8534 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8539 for (i=0;i<nprocs;i++) {
8540 if (!child_status_out[i]) {
8544 return timeval_elapsed(&start);
8547 #define FLAG_MULTIPROC 1
8554 {"FDPASS", run_fdpasstest, 0},
8555 {"LOCK1", run_locktest1, 0},
8556 {"LOCK2", run_locktest2, 0},
8557 {"LOCK3", run_locktest3, 0},
8558 {"LOCK4", run_locktest4, 0},
8559 {"LOCK5", run_locktest5, 0},
8560 {"LOCK6", run_locktest6, 0},
8561 {"LOCK7", run_locktest7, 0},
8562 {"LOCK8", run_locktest8, 0},
8563 {"LOCK9", run_locktest9, 0},
8564 {"UNLINK", run_unlinktest, 0},
8565 {"BROWSE", run_browsetest, 0},
8566 {"ATTR", run_attrtest, 0},
8567 {"TRANS2", run_trans2test, 0},
8568 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8569 {"TORTURE",run_torture, FLAG_MULTIPROC},
8570 {"RANDOMIPC", run_randomipc, 0},
8571 {"NEGNOWAIT", run_negprot_nowait, 0},
8572 {"NBENCH", run_nbench, 0},
8573 {"NBENCH2", run_nbench2, 0},
8574 {"OPLOCK1", run_oplock1, 0},
8575 {"OPLOCK2", run_oplock2, 0},
8576 {"OPLOCK4", run_oplock4, 0},
8577 {"DIR", run_dirtest, 0},
8578 {"DIR1", run_dirtest1, 0},
8579 {"DIR-CREATETIME", run_dir_createtime, 0},
8580 {"DENY1", torture_denytest1, 0},
8581 {"DENY2", torture_denytest2, 0},
8582 {"TCON", run_tcon_test, 0},
8583 {"TCONDEV", run_tcon_devtype_test, 0},
8584 {"RW1", run_readwritetest, 0},
8585 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8586 {"RW3", run_readwritelarge, 0},
8587 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8588 {"OPEN", run_opentest, 0},
8589 {"POSIX", run_simple_posix_open_test, 0},
8590 {"POSIX-APPEND", run_posix_append, 0},
8591 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8592 {"ASYNC-ECHO", run_async_echo, 0},
8593 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8594 { "SHORTNAME-TEST", run_shortname_test, 0},
8595 { "ADDRCHANGE", run_addrchange, 0},
8597 {"OPENATTR", run_openattrtest, 0},
8599 {"XCOPY", run_xcopy, 0},
8600 {"RENAME", run_rename, 0},
8601 {"DELETE", run_deletetest, 0},
8602 {"DELETE-LN", run_deletetest_ln, 0},
8603 {"PROPERTIES", run_properties, 0},
8604 {"MANGLE", torture_mangle, 0},
8605 {"MANGLE1", run_mangle1, 0},
8606 {"W2K", run_w2ktest, 0},
8607 {"TRANS2SCAN", torture_trans2_scan, 0},
8608 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8609 {"UTABLE", torture_utable, 0},
8610 {"CASETABLE", torture_casetable, 0},
8611 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8612 {"PIPE_NUMBER", run_pipe_number, 0},
8613 {"TCON2", run_tcon2_test, 0},
8614 {"IOCTL", torture_ioctl_test, 0},
8615 {"CHKPATH", torture_chkpath_test, 0},
8616 {"FDSESS", run_fdsesstest, 0},
8617 { "EATEST", run_eatest, 0},
8618 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8619 { "CHAIN1", run_chain1, 0},
8620 { "CHAIN2", run_chain2, 0},
8621 { "WINDOWS-WRITE", run_windows_write, 0},
8622 { "CLI_ECHO", run_cli_echo, 0},
8623 { "GETADDRINFO", run_getaddrinfo_send, 0},
8624 { "TLDAP", run_tldap },
8625 { "STREAMERROR", run_streamerror },
8626 { "NOTIFY-BENCH", run_notify_bench },
8627 { "BAD-NBT-SESSION", run_bad_nbt_session },
8628 { "SMB-ANY-CONNECT", run_smb_any_connect },
8629 { "NOTIFY-ONLINE", run_notify_online },
8630 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8631 { "LOCAL-GENCACHE", run_local_gencache, 0},
8632 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8633 { "LOCAL-BASE64", run_local_base64, 0},
8634 { "LOCAL-RBTREE", run_local_rbtree, 0},
8635 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8636 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8637 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8638 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8639 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8640 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8641 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8642 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8647 /****************************************************************************
8648 run a specified test or "ALL"
8649 ****************************************************************************/
8650 static bool run_test(const char *name)
8657 if (strequal(name,"ALL")) {
8658 for (i=0;torture_ops[i].name;i++) {
8659 run_test(torture_ops[i].name);
8664 for (i=0;torture_ops[i].name;i++) {
8665 fstr_sprintf(randomfname, "\\XX%x",
8666 (unsigned)random());
8668 if (strequal(name, torture_ops[i].name)) {
8670 printf("Running %s\n", name);
8671 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8672 t = create_procs(torture_ops[i].fn, &result);
8675 printf("TEST %s FAILED!\n", name);
8678 struct timeval start;
8679 start = timeval_current();
8680 if (!torture_ops[i].fn(0)) {
8682 printf("TEST %s FAILED!\n", name);
8684 t = timeval_elapsed(&start);
8686 printf("%s took %g secs\n\n", name, t);
8691 printf("Did not find a test named %s\n", name);
8699 static void usage(void)
8703 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8704 printf("Please use samba4 torture.\n\n");
8706 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8708 printf("\t-d debuglevel\n");
8709 printf("\t-U user%%pass\n");
8710 printf("\t-k use kerberos\n");
8711 printf("\t-N numprocs\n");
8712 printf("\t-n my_netbios_name\n");
8713 printf("\t-W workgroup\n");
8714 printf("\t-o num_operations\n");
8715 printf("\t-O socket_options\n");
8716 printf("\t-m maximum protocol\n");
8717 printf("\t-L use oplocks\n");
8718 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8719 printf("\t-A showall\n");
8720 printf("\t-p port\n");
8721 printf("\t-s seed\n");
8722 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8723 printf("\t-f filename filename to test\n");
8726 printf("tests are:");
8727 for (i=0;torture_ops[i].name;i++) {
8728 printf(" %s", torture_ops[i].name);
8732 printf("default test is ALL\n");
8737 /****************************************************************************
8739 ****************************************************************************/
8740 int main(int argc,char *argv[])
8746 bool correct = True;
8747 TALLOC_CTX *frame = talloc_stackframe();
8748 int seed = time(NULL);
8750 #ifdef HAVE_SETBUFFER
8751 setbuffer(stdout, NULL, 0);
8754 setup_logging("smbtorture", DEBUG_STDOUT);
8758 if (is_default_dyn_CONFIGFILE()) {
8759 if(getenv("SMB_CONF_PATH")) {
8760 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8763 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8770 for(p = argv[1]; *p; p++)
8774 if (strncmp(argv[1], "//", 2)) {
8778 fstrcpy(host, &argv[1][2]);
8779 p = strchr_m(&host[2],'/');
8784 fstrcpy(share, p+1);
8786 fstrcpy(myname, get_myname(talloc_tos()));
8788 fprintf(stderr, "Failed to get my hostname.\n");
8792 if (*username == 0 && getenv("LOGNAME")) {
8793 fstrcpy(username,getenv("LOGNAME"));
8799 fstrcpy(workgroup, lp_workgroup());
8801 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8805 port_to_use = atoi(optarg);
8808 seed = atoi(optarg);
8811 fstrcpy(workgroup,optarg);
8814 max_protocol = interpret_protocol(optarg, max_protocol);
8817 nprocs = atoi(optarg);
8820 torture_numops = atoi(optarg);
8823 lp_set_cmdline("log level", optarg);
8832 local_path = optarg;
8835 torture_showall = True;
8838 fstrcpy(myname, optarg);
8841 client_txt = optarg;
8848 use_kerberos = True;
8850 d_printf("No kerberos support compiled in\n");
8856 fstrcpy(username,optarg);
8857 p = strchr_m(username,'%');
8860 fstrcpy(password, p+1);
8865 fstrcpy(multishare_conn_fname, optarg);
8866 use_multishare_conn = True;
8869 torture_blocksize = atoi(optarg);
8872 test_filename = SMB_STRDUP(optarg);
8875 printf("Unknown option %c (%d)\n", (char)opt, opt);
8880 d_printf("using seed %d\n", seed);
8884 if(use_kerberos && !gotuser) gotpass = True;
8887 p = getpass("Password:");
8889 fstrcpy(password, p);
8894 printf("host=%s share=%s user=%s myname=%s\n",
8895 host, share, username, myname);
8897 if (argc == optind) {
8898 correct = run_test("ALL");
8900 for (i=optind;i<argc;i++) {
8901 if (!run_test(argv[i])) {