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"
29 #include "../lib/util/memcache.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap/dbwrap.h"
32 #include "dbwrap/dbwrap_open.h"
33 #include "dbwrap/dbwrap_rbt.h"
34 #include "talloc_dict.h"
35 #include "async_smb.h"
36 #include "libsmb/libsmb.h"
37 #include "libsmb/clirap.h"
39 #include "libsmb/nmblib.h"
40 #include "../lib/util/tevent_ntstatus.h"
42 #include "../libcli/smb/read_smb.h"
43 #include "../libcli/smb/smbXcli_base.h"
44 #include "lib/util/sys_rw_data.h"
45 #include "lib/util/base64.h"
50 fstring host, workgroup, share, password, username, myname;
51 static const char *sockops="TCP_NODELAY";
53 static int port_to_use=0;
54 int torture_numops=100;
55 int torture_blocksize=1024*1024;
56 static int procnum; /* records process count number when forking */
57 static struct cli_state *current_cli;
58 static fstring randomfname;
59 static bool use_oplocks;
60 static bool use_level_II_oplocks;
61 static const char *client_txt = "client_oplocks.txt";
62 static bool disable_spnego;
63 static bool use_kerberos;
64 static bool force_dos_errors;
65 static fstring multishare_conn_fname;
66 static bool use_multishare_conn = False;
67 static bool do_encrypt;
68 static const char *local_path = NULL;
69 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
72 bool torture_showall = False;
74 static double create_procs(bool (*fn)(int), bool *result);
76 /********************************************************************
77 Ensure a connection is encrypted.
78 ********************************************************************/
80 static bool force_cli_encryption(struct cli_state *c,
81 const char *sharename)
83 uint16_t major, minor;
84 uint32_t caplow, caphigh;
87 if (!SERVER_HAS_UNIX_CIFS(c)) {
88 d_printf("Encryption required and "
89 "server that doesn't support "
90 "UNIX extensions - failing connect\n");
94 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
96 if (!NT_STATUS_IS_OK(status)) {
97 d_printf("Encryption required and "
98 "can't get UNIX CIFS extensions "
99 "version from server: %s\n", nt_errstr(status));
103 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
104 d_printf("Encryption required and "
105 "share %s doesn't support "
106 "encryption.\n", sharename);
110 if (c->use_kerberos) {
111 status = cli_gss_smb_encryption_start(c);
113 status = cli_raw_ntlm_smb_encryption_start(c,
119 if (!NT_STATUS_IS_OK(status)) {
120 d_printf("Encryption required and "
121 "setup failed with error %s.\n",
130 static struct cli_state *open_nbt_connection(void)
136 if (disable_spnego) {
137 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
141 flags |= CLI_FULL_CONNECTION_OPLOCKS;
144 if (use_level_II_oplocks) {
145 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
149 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
152 if (force_dos_errors) {
153 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
156 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
157 signing_state, flags, &c);
158 if (!NT_STATUS_IS_OK(status)) {
159 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
163 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
168 /****************************************************************************
169 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
170 ****************************************************************************/
172 static bool cli_bad_session_request(int fd,
173 struct nmb_name *calling, struct nmb_name *called)
182 uint8_t message_type;
184 struct tevent_context *ev;
185 struct tevent_req *req;
187 frame = talloc_stackframe();
189 iov[0].iov_base = len_buf;
190 iov[0].iov_len = sizeof(len_buf);
192 /* put in the destination name */
194 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
196 if (iov[1].iov_base == NULL) {
199 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
200 talloc_get_size(iov[1].iov_base));
204 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
206 if (iov[2].iov_base == NULL) {
209 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
210 talloc_get_size(iov[2].iov_base));
212 /* Deliberately corrupt the name len (first byte) */
213 *((uint8_t *)iov[2].iov_base) = 100;
215 /* send a session request (RFC 1002) */
216 /* setup the packet length
217 * Remove four bytes from the length count, since the length
218 * field in the NBT Session Service header counts the number
219 * of bytes which follow. The cli_send_smb() function knows
220 * about this and accounts for those four bytes.
224 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
225 SCVAL(len_buf,0,0x81);
227 len = write_data_iov(fd, iov, 3);
232 ev = samba_tevent_context_init(frame);
236 req = read_smb_send(frame, ev, fd);
240 if (!tevent_req_poll(req, ev)) {
243 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
250 message_type = CVAL(inbuf, 0);
251 if (message_type != 0x83) {
252 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
257 if (smb_len(inbuf) != 1) {
258 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
259 (int)smb_len(inbuf));
263 error = CVAL(inbuf, 4);
265 d_fprintf(stderr, "Expected error 0x82, got %d\n",
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 cli_set_timeout(*c, 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_init_connection(struct cli_state **pcli)
402 struct cli_state *cli;
404 cli = open_nbt_connection();
413 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
415 uint16_t old_vuid = cli_state_get_uid(cli);
419 cli_state_set_uid(cli, 0);
420 status = cli_session_setup(cli, username,
423 ret = NT_STATUS_IS_OK(status);
424 *new_vuid = cli_state_get_uid(cli);
425 cli_state_set_uid(cli, old_vuid);
430 bool torture_close_connection(struct cli_state *c)
435 status = cli_tdis(c);
436 if (!NT_STATUS_IS_OK(status)) {
437 printf("tdis failed (%s)\n", nt_errstr(status));
447 /* check if the server produced the expected dos or nt error code */
448 static bool check_both_error(int line, NTSTATUS status,
449 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
451 if (NT_STATUS_IS_DOS(status)) {
455 /* Check DOS error */
456 cclass = NT_STATUS_DOS_CLASS(status);
457 num = NT_STATUS_DOS_CODE(status);
459 if (eclass != cclass || ecode != num) {
460 printf("unexpected error code class=%d code=%d\n",
461 (int)cclass, (int)num);
462 printf(" expected %d/%d %s (line=%d)\n",
463 (int)eclass, (int)ecode, nt_errstr(nterr), line);
468 if (!NT_STATUS_EQUAL(nterr, status)) {
469 printf("unexpected error code %s\n",
471 printf(" expected %s (line=%d)\n",
472 nt_errstr(nterr), line);
481 /* check if the server produced the expected error code */
482 static bool check_error(int line, NTSTATUS status,
483 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
485 if (NT_STATUS_IS_DOS(status)) {
489 /* Check DOS error */
491 cclass = NT_STATUS_DOS_CLASS(status);
492 num = NT_STATUS_DOS_CODE(status);
494 if (eclass != cclass || ecode != num) {
495 printf("unexpected error code class=%d code=%d\n",
496 (int)cclass, (int)num);
497 printf(" expected %d/%d %s (line=%d)\n",
498 (int)eclass, (int)ecode, nt_errstr(nterr),
506 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
507 printf("unexpected error code %s\n",
509 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
519 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
523 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
525 while (!NT_STATUS_IS_OK(status)) {
526 if (!check_both_error(__LINE__, status, ERRDOS,
527 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
531 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
538 static bool rw_torture(struct cli_state *c)
540 const char *lockfname = "\\torture.lck";
544 pid_t pid2, pid = getpid();
551 memset(buf, '\0', sizeof(buf));
553 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
555 if (!NT_STATUS_IS_OK(status)) {
556 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
558 if (!NT_STATUS_IS_OK(status)) {
559 printf("open of %s failed (%s)\n",
560 lockfname, nt_errstr(status));
564 for (i=0;i<torture_numops;i++) {
565 unsigned n = (unsigned)sys_random()%10;
568 printf("%d\r", i); fflush(stdout);
570 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
572 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
576 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
578 if (!NT_STATUS_IS_OK(status)) {
579 printf("open failed (%s)\n", nt_errstr(status));
584 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
586 if (!NT_STATUS_IS_OK(status)) {
587 printf("write failed (%s)\n", nt_errstr(status));
592 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
593 sizeof(pid)+(j*sizeof(buf)),
595 if (!NT_STATUS_IS_OK(status)) {
596 printf("write failed (%s)\n",
604 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
606 if (!NT_STATUS_IS_OK(status)) {
607 printf("read failed (%s)\n", nt_errstr(status));
609 } else if (nread != sizeof(pid)) {
610 printf("read/write compare failed: "
611 "recv %ld req %ld\n", (unsigned long)nread,
612 (unsigned long)sizeof(pid));
617 printf("data corruption!\n");
621 status = cli_close(c, fnum);
622 if (!NT_STATUS_IS_OK(status)) {
623 printf("close failed (%s)\n", nt_errstr(status));
627 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
628 if (!NT_STATUS_IS_OK(status)) {
629 printf("unlink failed (%s)\n", nt_errstr(status));
633 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
634 if (!NT_STATUS_IS_OK(status)) {
635 printf("unlock failed (%s)\n", nt_errstr(status));
641 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
648 static bool run_torture(int dummy)
650 struct cli_state *cli;
655 smbXcli_conn_set_sockopt(cli->conn, sockops);
657 ret = rw_torture(cli);
659 if (!torture_close_connection(cli)) {
666 static bool rw_torture3(struct cli_state *c, char *lockfname)
668 uint16_t fnum = (uint16_t)-1;
673 unsigned countprev = 0;
676 NTSTATUS status = NT_STATUS_OK;
679 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
681 SIVAL(buf, i, sys_random());
688 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
689 if (!NT_STATUS_IS_OK(status)) {
690 printf("unlink failed (%s) (normal, this file should "
691 "not exist)\n", nt_errstr(status));
694 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
696 if (!NT_STATUS_IS_OK(status)) {
697 printf("first open read/write of %s failed (%s)\n",
698 lockfname, nt_errstr(status));
704 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
706 status = cli_openx(c, lockfname, O_RDONLY,
708 if (NT_STATUS_IS_OK(status)) {
713 if (!NT_STATUS_IS_OK(status)) {
714 printf("second open read-only of %s failed (%s)\n",
715 lockfname, nt_errstr(status));
721 for (count = 0; count < sizeof(buf); count += sent)
723 if (count >= countprev) {
724 printf("%d %8d\r", i, count);
727 countprev += (sizeof(buf) / 20);
732 sent = ((unsigned)sys_random()%(20))+ 1;
733 if (sent > sizeof(buf) - count)
735 sent = sizeof(buf) - count;
738 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("write failed (%s)\n",
748 status = cli_read(c, fnum, buf_rd+count, count,
749 sizeof(buf)-count, &sent);
750 if(!NT_STATUS_IS_OK(status)) {
751 printf("read failed offset:%d size:%ld (%s)\n",
752 count, (unsigned long)sizeof(buf)-count,
756 } else if (sent > 0) {
757 if (memcmp(buf_rd+count, buf+count, sent) != 0)
759 printf("read/write compare failed\n");
760 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
769 status = cli_close(c, fnum);
770 if (!NT_STATUS_IS_OK(status)) {
771 printf("close failed (%s)\n", nt_errstr(status));
778 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
780 const char *lockfname = "\\torture2.lck";
790 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
791 if (!NT_STATUS_IS_OK(status)) {
792 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
795 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
797 if (!NT_STATUS_IS_OK(status)) {
798 printf("first open read/write of %s failed (%s)\n",
799 lockfname, nt_errstr(status));
803 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
804 if (!NT_STATUS_IS_OK(status)) {
805 printf("second open read-only of %s failed (%s)\n",
806 lockfname, nt_errstr(status));
807 cli_close(c1, fnum1);
811 for (i = 0; i < torture_numops; i++)
813 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
815 printf("%d\r", i); fflush(stdout);
818 generate_random_buffer((unsigned char *)buf, buf_size);
820 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
822 if (!NT_STATUS_IS_OK(status)) {
823 printf("write failed (%s)\n", nt_errstr(status));
828 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
829 if(!NT_STATUS_IS_OK(status)) {
830 printf("read failed (%s)\n", nt_errstr(status));
833 } else if (bytes_read != buf_size) {
834 printf("read failed\n");
835 printf("read %ld, expected %ld\n",
836 (unsigned long)bytes_read,
837 (unsigned long)buf_size);
842 if (memcmp(buf_rd, buf, buf_size) != 0)
844 printf("read/write compare failed\n");
850 status = cli_close(c2, fnum2);
851 if (!NT_STATUS_IS_OK(status)) {
852 printf("close failed (%s)\n", nt_errstr(status));
856 status = cli_close(c1, fnum1);
857 if (!NT_STATUS_IS_OK(status)) {
858 printf("close failed (%s)\n", nt_errstr(status));
862 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
863 if (!NT_STATUS_IS_OK(status)) {
864 printf("unlink failed (%s)\n", nt_errstr(status));
871 static bool run_readwritetest(int dummy)
873 struct cli_state *cli1, *cli2;
874 bool test1, test2 = False;
876 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
879 smbXcli_conn_set_sockopt(cli1->conn, sockops);
880 smbXcli_conn_set_sockopt(cli2->conn, sockops);
882 printf("starting readwritetest\n");
884 test1 = rw_torture2(cli1, cli2);
885 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
888 test2 = rw_torture2(cli1, cli1);
889 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
892 if (!torture_close_connection(cli1)) {
896 if (!torture_close_connection(cli2)) {
900 return (test1 && test2);
903 static bool run_readwritemulti(int dummy)
905 struct cli_state *cli;
910 smbXcli_conn_set_sockopt(cli->conn, sockops);
912 printf("run_readwritemulti: fname %s\n", randomfname);
913 test = rw_torture3(cli, randomfname);
915 if (!torture_close_connection(cli)) {
922 static bool run_readwritelarge_internal(void)
924 static struct cli_state *cli1;
926 const char *lockfname = "\\large.dat";
932 if (!torture_open_connection(&cli1, 0)) {
935 smbXcli_conn_set_sockopt(cli1->conn, sockops);
936 memset(buf,'\0',sizeof(buf));
938 printf("starting readwritelarge_internal\n");
940 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
942 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
944 if (!NT_STATUS_IS_OK(status)) {
945 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
949 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
951 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
953 if (!NT_STATUS_IS_OK(status)) {
954 printf("qfileinfo failed (%s)\n", nt_errstr(status));
958 if (fsize == sizeof(buf))
959 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
960 (unsigned long)fsize);
962 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
963 (unsigned long)fsize);
967 status = cli_close(cli1, fnum1);
968 if (!NT_STATUS_IS_OK(status)) {
969 printf("close failed (%s)\n", nt_errstr(status));
973 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
974 if (!NT_STATUS_IS_OK(status)) {
975 printf("unlink failed (%s)\n", nt_errstr(status));
979 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
981 if (!NT_STATUS_IS_OK(status)) {
982 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
986 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
988 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
990 if (!NT_STATUS_IS_OK(status)) {
991 printf("qfileinfo failed (%s)\n", nt_errstr(status));
995 if (fsize == sizeof(buf))
996 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
997 (unsigned long)fsize);
999 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1000 (unsigned long)fsize);
1005 /* ToDo - set allocation. JRA */
1006 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1007 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1010 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1012 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1016 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1019 status = cli_close(cli1, fnum1);
1020 if (!NT_STATUS_IS_OK(status)) {
1021 printf("close failed (%s)\n", nt_errstr(status));
1025 if (!torture_close_connection(cli1)) {
1031 static bool run_readwritelarge(int dummy)
1033 return run_readwritelarge_internal();
1036 static bool run_readwritelarge_signtest(int dummy)
1039 signing_state = SMB_SIGNING_REQUIRED;
1040 ret = run_readwritelarge_internal();
1041 signing_state = SMB_SIGNING_DEFAULT;
1048 #define ival(s) strtol(s, NULL, 0)
1050 /* run a test that simulates an approximate netbench client load */
1051 static bool run_netbench(int client)
1053 struct cli_state *cli;
1058 const char *params[20];
1059 bool correct = True;
1065 smbXcli_conn_set_sockopt(cli->conn, sockops);
1069 slprintf(cname,sizeof(cname)-1, "client%d", client);
1071 f = fopen(client_txt, "r");
1078 while (fgets(line, sizeof(line)-1, f)) {
1082 line[strlen(line)-1] = 0;
1084 /* printf("[%d] %s\n", line_count, line); */
1086 all_string_sub(line,"client1", cname, sizeof(line));
1088 /* parse the command parameters */
1089 params[0] = strtok_r(line, " ", &saveptr);
1091 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1095 if (i < 2) continue;
1097 if (!strncmp(params[0],"SMB", 3)) {
1098 printf("ERROR: You are using a dbench 1 load file\n");
1102 if (!strcmp(params[0],"NTCreateX")) {
1103 nb_createx(params[1], ival(params[2]), ival(params[3]),
1105 } else if (!strcmp(params[0],"Close")) {
1106 nb_close(ival(params[1]));
1107 } else if (!strcmp(params[0],"Rename")) {
1108 nb_rename(params[1], params[2]);
1109 } else if (!strcmp(params[0],"Unlink")) {
1110 nb_unlink(params[1]);
1111 } else if (!strcmp(params[0],"Deltree")) {
1112 nb_deltree(params[1]);
1113 } else if (!strcmp(params[0],"Rmdir")) {
1114 nb_rmdir(params[1]);
1115 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1116 nb_qpathinfo(params[1]);
1117 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1118 nb_qfileinfo(ival(params[1]));
1119 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1120 nb_qfsinfo(ival(params[1]));
1121 } else if (!strcmp(params[0],"FIND_FIRST")) {
1122 nb_findfirst(params[1]);
1123 } else if (!strcmp(params[0],"WriteX")) {
1124 nb_writex(ival(params[1]),
1125 ival(params[2]), ival(params[3]), ival(params[4]));
1126 } else if (!strcmp(params[0],"ReadX")) {
1127 nb_readx(ival(params[1]),
1128 ival(params[2]), ival(params[3]), ival(params[4]));
1129 } else if (!strcmp(params[0],"Flush")) {
1130 nb_flush(ival(params[1]));
1132 printf("Unknown operation %s\n", params[0]);
1140 if (!torture_close_connection(cli)) {
1148 /* run a test that simulates an approximate netbench client load */
1149 static bool run_nbench(int dummy)
1152 bool correct = True;
1154 nbio_shmem(torture_nprocs);
1158 signal(SIGALRM, nb_alarm);
1160 t = create_procs(run_netbench, &correct);
1163 printf("\nThroughput %g MB/sec\n",
1164 1.0e-6 * nbio_total() / t);
1170 This test checks for two things:
1172 1) correct support for retaining locks over a close (ie. the server
1173 must not use posix semantics)
1174 2) support for lock timeouts
1176 static bool run_locktest1(int dummy)
1178 struct cli_state *cli1, *cli2;
1179 const char *fname = "\\lockt1.lck";
1180 uint16_t fnum1, fnum2, fnum3;
1182 unsigned lock_timeout;
1185 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1188 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1189 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1191 printf("starting locktest1\n");
1193 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1195 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1197 if (!NT_STATUS_IS_OK(status)) {
1198 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1202 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1203 if (!NT_STATUS_IS_OK(status)) {
1204 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1208 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1209 if (!NT_STATUS_IS_OK(status)) {
1210 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1214 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1215 if (!NT_STATUS_IS_OK(status)) {
1216 printf("lock1 failed (%s)\n", nt_errstr(status));
1220 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1221 if (NT_STATUS_IS_OK(status)) {
1222 printf("lock2 succeeded! This is a locking bug\n");
1225 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1226 NT_STATUS_LOCK_NOT_GRANTED)) {
1231 lock_timeout = (1 + (random() % 20));
1232 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1234 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1235 if (NT_STATUS_IS_OK(status)) {
1236 printf("lock3 succeeded! This is a locking bug\n");
1239 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1240 NT_STATUS_FILE_LOCK_CONFLICT)) {
1246 if (ABS(t2 - t1) < lock_timeout-1) {
1247 printf("error: This server appears not to support timed lock requests\n");
1250 printf("server slept for %u seconds for a %u second timeout\n",
1251 (unsigned int)(t2-t1), lock_timeout);
1253 status = cli_close(cli1, fnum2);
1254 if (!NT_STATUS_IS_OK(status)) {
1255 printf("close1 failed (%s)\n", nt_errstr(status));
1259 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1260 if (NT_STATUS_IS_OK(status)) {
1261 printf("lock4 succeeded! This is a locking bug\n");
1264 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1265 NT_STATUS_FILE_LOCK_CONFLICT)) {
1270 status = cli_close(cli1, fnum1);
1271 if (!NT_STATUS_IS_OK(status)) {
1272 printf("close2 failed (%s)\n", nt_errstr(status));
1276 status = cli_close(cli2, fnum3);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 printf("close3 failed (%s)\n", nt_errstr(status));
1282 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 printf("unlink failed (%s)\n", nt_errstr(status));
1289 if (!torture_close_connection(cli1)) {
1293 if (!torture_close_connection(cli2)) {
1297 printf("Passed locktest1\n");
1302 this checks to see if a secondary tconx can use open files from an
1305 static bool run_tcon_test(int dummy)
1307 static struct cli_state *cli;
1308 const char *fname = "\\tcontest.tmp";
1310 uint16_t cnum1, cnum2, cnum3;
1311 uint16_t vuid1, vuid2;
1316 memset(buf, '\0', sizeof(buf));
1318 if (!torture_open_connection(&cli, 0)) {
1321 smbXcli_conn_set_sockopt(cli->conn, sockops);
1323 printf("starting tcontest\n");
1325 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1327 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1328 if (!NT_STATUS_IS_OK(status)) {
1329 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1333 cnum1 = cli_state_get_tid(cli);
1334 vuid1 = cli_state_get_uid(cli);
1336 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1337 if (!NT_STATUS_IS_OK(status)) {
1338 printf("initial write failed (%s)", nt_errstr(status));
1342 status = cli_tree_connect(cli, share, "?????",
1343 password, strlen(password)+1);
1344 if (!NT_STATUS_IS_OK(status)) {
1345 printf("%s refused 2nd tree connect (%s)\n", host,
1351 cnum2 = cli_state_get_tid(cli);
1352 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1353 vuid2 = cli_state_get_uid(cli) + 1;
1355 /* try a write with the wrong tid */
1356 cli_state_set_tid(cli, cnum2);
1358 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1359 if (NT_STATUS_IS_OK(status)) {
1360 printf("* server allows write with wrong TID\n");
1363 printf("server fails write with wrong TID : %s\n",
1368 /* try a write with an invalid tid */
1369 cli_state_set_tid(cli, cnum3);
1371 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1372 if (NT_STATUS_IS_OK(status)) {
1373 printf("* server allows write with invalid TID\n");
1376 printf("server fails write with invalid TID : %s\n",
1380 /* try a write with an invalid vuid */
1381 cli_state_set_uid(cli, vuid2);
1382 cli_state_set_tid(cli, cnum1);
1384 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1385 if (NT_STATUS_IS_OK(status)) {
1386 printf("* server allows write with invalid VUID\n");
1389 printf("server fails write with invalid VUID : %s\n",
1393 cli_state_set_tid(cli, cnum1);
1394 cli_state_set_uid(cli, vuid1);
1396 status = cli_close(cli, fnum1);
1397 if (!NT_STATUS_IS_OK(status)) {
1398 printf("close failed (%s)\n", nt_errstr(status));
1402 cli_state_set_tid(cli, cnum2);
1404 status = cli_tdis(cli);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1410 cli_state_set_tid(cli, cnum1);
1412 if (!torture_close_connection(cli)) {
1421 checks for old style tcon support
1423 static bool run_tcon2_test(int dummy)
1425 static struct cli_state *cli;
1426 uint16_t cnum, max_xmit;
1430 if (!torture_open_connection(&cli, 0)) {
1433 smbXcli_conn_set_sockopt(cli->conn, sockops);
1435 printf("starting tcon2 test\n");
1437 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1441 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1445 if (!NT_STATUS_IS_OK(status)) {
1446 printf("tcon2 failed : %s\n", nt_errstr(status));
1448 printf("tcon OK : max_xmit=%d cnum=%d\n",
1449 (int)max_xmit, (int)cnum);
1452 if (!torture_close_connection(cli)) {
1456 printf("Passed tcon2 test\n");
1460 static bool tcon_devtest(struct cli_state *cli,
1461 const char *myshare, const char *devtype,
1462 const char *return_devtype,
1463 NTSTATUS expected_error)
1468 status = cli_tree_connect(cli, myshare, devtype,
1469 password, strlen(password)+1);
1471 if (NT_STATUS_IS_OK(expected_error)) {
1472 if (NT_STATUS_IS_OK(status)) {
1473 if (strcmp(cli->dev, return_devtype) == 0) {
1476 printf("tconX to share %s with type %s "
1477 "succeeded but returned the wrong "
1478 "device type (got [%s] but should have got [%s])\n",
1479 myshare, devtype, cli->dev, return_devtype);
1483 printf("tconX to share %s with type %s "
1484 "should have succeeded but failed\n",
1490 if (NT_STATUS_IS_OK(status)) {
1491 printf("tconx to share %s with type %s "
1492 "should have failed but succeeded\n",
1496 if (NT_STATUS_EQUAL(status, expected_error)) {
1499 printf("Returned unexpected error\n");
1508 checks for correct tconX support
1510 static bool run_tcon_devtype_test(int dummy)
1512 static struct cli_state *cli1 = NULL;
1517 status = cli_full_connection(&cli1, myname,
1518 host, NULL, port_to_use,
1520 username, workgroup,
1521 password, flags, signing_state);
1523 if (!NT_STATUS_IS_OK(status)) {
1524 printf("could not open connection\n");
1528 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1531 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1534 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1537 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1540 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1543 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1546 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1549 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1552 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1555 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1561 printf("Passed tcondevtest\n");
1568 This test checks that
1570 1) the server supports multiple locking contexts on the one SMB
1571 connection, distinguished by PID.
1573 2) the server correctly fails overlapping locks made by the same PID (this
1574 goes against POSIX behaviour, which is why it is tricky to implement)
1576 3) the server denies unlock requests by an incorrect client PID
1578 static bool run_locktest2(int dummy)
1580 static struct cli_state *cli;
1581 const char *fname = "\\lockt2.lck";
1582 uint16_t fnum1, fnum2, fnum3;
1583 bool correct = True;
1586 if (!torture_open_connection(&cli, 0)) {
1590 smbXcli_conn_set_sockopt(cli->conn, sockops);
1592 printf("starting locktest2\n");
1594 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1598 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1599 if (!NT_STATUS_IS_OK(status)) {
1600 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1604 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1605 if (!NT_STATUS_IS_OK(status)) {
1606 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1612 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1613 if (!NT_STATUS_IS_OK(status)) {
1614 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1620 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1621 if (!NT_STATUS_IS_OK(status)) {
1622 printf("lock1 failed (%s)\n", nt_errstr(status));
1626 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1627 if (NT_STATUS_IS_OK(status)) {
1628 printf("WRITE lock1 succeeded! This is a locking bug\n");
1631 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1632 NT_STATUS_LOCK_NOT_GRANTED)) {
1637 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1638 if (NT_STATUS_IS_OK(status)) {
1639 printf("WRITE lock2 succeeded! This is a locking bug\n");
1642 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1643 NT_STATUS_LOCK_NOT_GRANTED)) {
1648 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1649 if (NT_STATUS_IS_OK(status)) {
1650 printf("READ lock2 succeeded! This is a locking bug\n");
1653 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1654 NT_STATUS_FILE_LOCK_CONFLICT)) {
1659 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1660 if (!NT_STATUS_IS_OK(status)) {
1661 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1664 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1665 printf("unlock at 100 succeeded! This is a locking bug\n");
1669 status = cli_unlock(cli, fnum1, 0, 4);
1670 if (NT_STATUS_IS_OK(status)) {
1671 printf("unlock1 succeeded! This is a locking bug\n");
1674 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1675 NT_STATUS_RANGE_NOT_LOCKED)) {
1680 status = cli_unlock(cli, fnum1, 0, 8);
1681 if (NT_STATUS_IS_OK(status)) {
1682 printf("unlock2 succeeded! This is a locking bug\n");
1685 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1686 NT_STATUS_RANGE_NOT_LOCKED)) {
1691 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1692 if (NT_STATUS_IS_OK(status)) {
1693 printf("lock3 succeeded! This is a locking bug\n");
1696 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1697 NT_STATUS_LOCK_NOT_GRANTED)) {
1704 status = cli_close(cli, fnum1);
1705 if (!NT_STATUS_IS_OK(status)) {
1706 printf("close1 failed (%s)\n", nt_errstr(status));
1710 status = cli_close(cli, fnum2);
1711 if (!NT_STATUS_IS_OK(status)) {
1712 printf("close2 failed (%s)\n", nt_errstr(status));
1716 status = cli_close(cli, fnum3);
1717 if (!NT_STATUS_IS_OK(status)) {
1718 printf("close3 failed (%s)\n", nt_errstr(status));
1722 if (!torture_close_connection(cli)) {
1726 printf("locktest2 finished\n");
1733 This test checks that
1735 1) the server supports the full offset range in lock requests
1737 static bool run_locktest3(int dummy)
1739 static struct cli_state *cli1, *cli2;
1740 const char *fname = "\\lockt3.lck";
1741 uint16_t fnum1, fnum2;
1744 bool correct = True;
1747 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1749 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1752 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1753 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1755 printf("starting locktest3\n");
1757 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1759 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1761 if (!NT_STATUS_IS_OK(status)) {
1762 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1766 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1767 if (!NT_STATUS_IS_OK(status)) {
1768 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1772 for (offset=i=0;i<torture_numops;i++) {
1775 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1776 if (!NT_STATUS_IS_OK(status)) {
1777 printf("lock1 %d failed (%s)\n",
1783 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1784 if (!NT_STATUS_IS_OK(status)) {
1785 printf("lock2 %d failed (%s)\n",
1792 for (offset=i=0;i<torture_numops;i++) {
1795 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1796 if (NT_STATUS_IS_OK(status)) {
1797 printf("error: lock1 %d succeeded!\n", i);
1801 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1802 if (NT_STATUS_IS_OK(status)) {
1803 printf("error: lock2 %d succeeded!\n", i);
1807 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1808 if (NT_STATUS_IS_OK(status)) {
1809 printf("error: lock3 %d succeeded!\n", i);
1813 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1814 if (NT_STATUS_IS_OK(status)) {
1815 printf("error: lock4 %d succeeded!\n", i);
1820 for (offset=i=0;i<torture_numops;i++) {
1823 status = cli_unlock(cli1, fnum1, offset-1, 1);
1824 if (!NT_STATUS_IS_OK(status)) {
1825 printf("unlock1 %d failed (%s)\n",
1831 status = cli_unlock(cli2, fnum2, offset-2, 1);
1832 if (!NT_STATUS_IS_OK(status)) {
1833 printf("unlock2 %d failed (%s)\n",
1840 status = cli_close(cli1, fnum1);
1841 if (!NT_STATUS_IS_OK(status)) {
1842 printf("close1 failed (%s)\n", nt_errstr(status));
1846 status = cli_close(cli2, fnum2);
1847 if (!NT_STATUS_IS_OK(status)) {
1848 printf("close2 failed (%s)\n", nt_errstr(status));
1852 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1853 if (!NT_STATUS_IS_OK(status)) {
1854 printf("unlink failed (%s)\n", nt_errstr(status));
1858 if (!torture_close_connection(cli1)) {
1862 if (!torture_close_connection(cli2)) {
1866 printf("finished locktest3\n");
1871 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1872 char *buf, off_t offset, size_t size,
1873 size_t *nread, size_t expect)
1878 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1880 if(!NT_STATUS_IS_OK(status)) {
1882 } else if (l_nread != expect) {
1893 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1894 printf("** "); correct = False; \
1898 looks at overlapping locks
1900 static bool run_locktest4(int dummy)
1902 static struct cli_state *cli1, *cli2;
1903 const char *fname = "\\lockt4.lck";
1904 uint16_t fnum1, fnum2, f;
1907 bool correct = True;
1910 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1914 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1915 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1917 printf("starting locktest4\n");
1919 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1921 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1922 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1924 memset(buf, 0, sizeof(buf));
1926 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1928 if (!NT_STATUS_IS_OK(status)) {
1929 printf("Failed to create file: %s\n", nt_errstr(status));
1934 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1935 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1936 EXPECTED(ret, False);
1937 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1939 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1940 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1941 EXPECTED(ret, True);
1942 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1944 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1945 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1946 EXPECTED(ret, False);
1947 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1949 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1950 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1951 EXPECTED(ret, True);
1952 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1954 ret = (cli_setpid(cli1, 1),
1955 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1956 (cli_setpid(cli1, 2),
1957 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1958 EXPECTED(ret, False);
1959 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1961 ret = (cli_setpid(cli1, 1),
1962 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1963 (cli_setpid(cli1, 2),
1964 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1965 EXPECTED(ret, True);
1966 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1968 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1969 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1970 EXPECTED(ret, True);
1971 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1973 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1974 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1975 EXPECTED(ret, False);
1976 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1978 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1979 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1980 EXPECTED(ret, False);
1981 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1983 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1984 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
1985 EXPECTED(ret, True);
1986 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1988 ret = (cli_setpid(cli1, 1),
1989 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1990 (cli_setpid(cli1, 2),
1991 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
1992 EXPECTED(ret, False);
1993 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1995 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
1996 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
1997 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1998 EXPECTED(ret, False);
1999 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2002 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2003 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2004 EXPECTED(ret, False);
2005 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2007 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2008 ret = NT_STATUS_IS_OK(status);
2010 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2012 ret = NT_STATUS_IS_OK(status);
2014 EXPECTED(ret, False);
2015 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2018 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2019 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2020 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2021 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2022 EXPECTED(ret, True);
2023 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2026 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2027 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2028 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2029 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2030 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2032 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2033 EXPECTED(ret, True);
2034 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2036 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2037 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2038 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2040 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2041 EXPECTED(ret, True);
2042 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2044 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2045 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2046 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2048 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2049 EXPECTED(ret, True);
2050 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2052 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2053 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2054 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2055 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2057 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2058 EXPECTED(ret, True);
2059 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2061 cli_close(cli1, fnum1);
2062 cli_close(cli2, fnum2);
2063 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2064 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2065 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2066 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2067 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2068 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2069 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2071 cli_close(cli1, fnum1);
2072 EXPECTED(ret, True);
2073 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2076 cli_close(cli1, fnum1);
2077 cli_close(cli2, fnum2);
2078 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2079 torture_close_connection(cli1);
2080 torture_close_connection(cli2);
2082 printf("finished locktest4\n");
2087 looks at lock upgrade/downgrade.
2089 static bool run_locktest5(int dummy)
2091 static struct cli_state *cli1, *cli2;
2092 const char *fname = "\\lockt5.lck";
2093 uint16_t fnum1, fnum2, fnum3;
2096 bool correct = True;
2099 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2103 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2104 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2106 printf("starting locktest5\n");
2108 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2110 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2111 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2112 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2114 memset(buf, 0, sizeof(buf));
2116 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2118 if (!NT_STATUS_IS_OK(status)) {
2119 printf("Failed to create file: %s\n", nt_errstr(status));
2124 /* Check for NT bug... */
2125 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2126 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2127 cli_close(cli1, fnum1);
2128 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2129 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2130 ret = NT_STATUS_IS_OK(status);
2131 EXPECTED(ret, True);
2132 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2133 cli_close(cli1, fnum1);
2134 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2135 cli_unlock(cli1, fnum3, 0, 1);
2137 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2138 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2139 EXPECTED(ret, True);
2140 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2142 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2143 ret = NT_STATUS_IS_OK(status);
2144 EXPECTED(ret, False);
2146 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2148 /* Unlock the process 2 lock. */
2149 cli_unlock(cli2, fnum2, 0, 4);
2151 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2152 ret = NT_STATUS_IS_OK(status);
2153 EXPECTED(ret, False);
2155 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2157 /* Unlock the process 1 fnum3 lock. */
2158 cli_unlock(cli1, fnum3, 0, 4);
2160 /* Stack 2 more locks here. */
2161 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2162 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2164 EXPECTED(ret, True);
2165 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2167 /* Unlock the first process lock, then check this was the WRITE lock that was
2170 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2171 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2173 EXPECTED(ret, True);
2174 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2176 /* Unlock the process 2 lock. */
2177 cli_unlock(cli2, fnum2, 0, 4);
2179 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2181 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2182 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2183 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2185 EXPECTED(ret, True);
2186 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2188 /* Ensure the next unlock fails. */
2189 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2190 EXPECTED(ret, False);
2191 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2193 /* Ensure connection 2 can get a write lock. */
2194 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2195 ret = NT_STATUS_IS_OK(status);
2196 EXPECTED(ret, True);
2198 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2202 cli_close(cli1, fnum1);
2203 cli_close(cli2, fnum2);
2204 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2205 if (!torture_close_connection(cli1)) {
2208 if (!torture_close_connection(cli2)) {
2212 printf("finished locktest5\n");
2218 tries the unusual lockingX locktype bits
2220 static bool run_locktest6(int dummy)
2222 static struct cli_state *cli;
2223 const char *fname[1] = { "\\lock6.txt" };
2228 if (!torture_open_connection(&cli, 0)) {
2232 smbXcli_conn_set_sockopt(cli->conn, sockops);
2234 printf("starting locktest6\n");
2237 printf("Testing %s\n", fname[i]);
2239 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2241 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2242 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2243 cli_close(cli, fnum);
2244 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2246 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2247 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2248 cli_close(cli, fnum);
2249 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2251 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2254 torture_close_connection(cli);
2256 printf("finished locktest6\n");
2260 static bool run_locktest7(int dummy)
2262 struct cli_state *cli1;
2263 const char *fname = "\\lockt7.lck";
2266 bool correct = False;
2270 if (!torture_open_connection(&cli1, 0)) {
2274 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2276 printf("starting locktest7\n");
2278 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2280 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2282 memset(buf, 0, sizeof(buf));
2284 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2286 if (!NT_STATUS_IS_OK(status)) {
2287 printf("Failed to create file: %s\n", nt_errstr(status));
2291 cli_setpid(cli1, 1);
2293 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2294 if (!NT_STATUS_IS_OK(status)) {
2295 printf("Unable to apply read lock on range 130:4, "
2296 "error was %s\n", nt_errstr(status));
2299 printf("pid1 successfully locked range 130:4 for READ\n");
2302 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2303 if (!NT_STATUS_IS_OK(status)) {
2304 printf("pid1 unable to read the range 130:4, error was %s\n",
2307 } else if (nread != 4) {
2308 printf("pid1 unable to read the range 130:4, "
2309 "recv %ld req %d\n", (unsigned long)nread, 4);
2312 printf("pid1 successfully read the range 130:4\n");
2315 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2316 if (!NT_STATUS_IS_OK(status)) {
2317 printf("pid1 unable to write to the range 130:4, error was "
2318 "%s\n", nt_errstr(status));
2319 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2320 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2324 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2328 cli_setpid(cli1, 2);
2330 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2331 if (!NT_STATUS_IS_OK(status)) {
2332 printf("pid2 unable to read the range 130:4, error was %s\n",
2335 } else if (nread != 4) {
2336 printf("pid2 unable to read the range 130:4, "
2337 "recv %ld req %d\n", (unsigned long)nread, 4);
2340 printf("pid2 successfully read the range 130:4\n");
2343 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2344 if (!NT_STATUS_IS_OK(status)) {
2345 printf("pid2 unable to write to the range 130:4, error was "
2346 "%s\n", nt_errstr(status));
2347 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2348 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2352 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2356 cli_setpid(cli1, 1);
2357 cli_unlock(cli1, fnum1, 130, 4);
2359 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2360 if (!NT_STATUS_IS_OK(status)) {
2361 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2364 printf("pid1 successfully locked range 130:4 for WRITE\n");
2367 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2368 if (!NT_STATUS_IS_OK(status)) {
2369 printf("pid1 unable to read the range 130:4, error was %s\n",
2372 } else if (nread != 4) {
2373 printf("pid1 unable to read the range 130:4, "
2374 "recv %ld req %d\n", (unsigned long)nread, 4);
2377 printf("pid1 successfully read the range 130:4\n");
2380 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2381 if (!NT_STATUS_IS_OK(status)) {
2382 printf("pid1 unable to write to the range 130:4, error was "
2383 "%s\n", nt_errstr(status));
2386 printf("pid1 successfully wrote to the range 130:4\n");
2389 cli_setpid(cli1, 2);
2391 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2392 if (!NT_STATUS_IS_OK(status)) {
2393 printf("pid2 unable to read the range 130:4, error was "
2394 "%s\n", nt_errstr(status));
2395 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2396 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2400 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2401 (unsigned long)nread);
2405 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2406 if (!NT_STATUS_IS_OK(status)) {
2407 printf("pid2 unable to write to the range 130:4, error was "
2408 "%s\n", nt_errstr(status));
2409 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2410 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2414 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2418 cli_unlock(cli1, fnum1, 130, 0);
2422 cli_close(cli1, fnum1);
2423 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2424 torture_close_connection(cli1);
2426 printf("finished locktest7\n");
2431 * This demonstrates a problem with our use of GPFS share modes: A file
2432 * descriptor sitting in the pending close queue holding a GPFS share mode
2433 * blocks opening a file another time. Happens with Word 2007 temp files.
2434 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2435 * open is denied with NT_STATUS_SHARING_VIOLATION.
2438 static bool run_locktest8(int dummy)
2440 struct cli_state *cli1;
2441 const char *fname = "\\lockt8.lck";
2442 uint16_t fnum1, fnum2;
2444 bool correct = False;
2447 if (!torture_open_connection(&cli1, 0)) {
2451 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2453 printf("starting locktest8\n");
2455 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2457 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2459 if (!NT_STATUS_IS_OK(status)) {
2460 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2464 memset(buf, 0, sizeof(buf));
2466 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2467 if (!NT_STATUS_IS_OK(status)) {
2468 d_fprintf(stderr, "cli_openx second time returned %s\n",
2473 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2474 if (!NT_STATUS_IS_OK(status)) {
2475 printf("Unable to apply read lock on range 1:1, error was "
2476 "%s\n", nt_errstr(status));
2480 status = cli_close(cli1, fnum1);
2481 if (!NT_STATUS_IS_OK(status)) {
2482 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2486 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2487 if (!NT_STATUS_IS_OK(status)) {
2488 d_fprintf(stderr, "cli_openx third time returned %s\n",
2496 cli_close(cli1, fnum1);
2497 cli_close(cli1, fnum2);
2498 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2499 torture_close_connection(cli1);
2501 printf("finished locktest8\n");
2506 * This test is designed to be run in conjunction with
2507 * external NFS or POSIX locks taken in the filesystem.
2508 * It checks that the smbd server will block until the
2509 * lock is released and then acquire it. JRA.
2512 static bool got_alarm;
2513 static struct cli_state *alarm_cli;
2515 static void alarm_handler(int dummy)
2520 static void alarm_handler_parent(int dummy)
2522 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2525 static void do_local_lock(int read_fd, int write_fd)
2530 const char *local_pathname = NULL;
2533 local_pathname = talloc_asprintf(talloc_tos(),
2534 "%s/lockt9.lck", local_path);
2535 if (!local_pathname) {
2536 printf("child: alloc fail\n");
2540 unlink(local_pathname);
2541 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2543 printf("child: open of %s failed %s.\n",
2544 local_pathname, strerror(errno));
2548 /* Now take a fcntl lock. */
2549 lock.l_type = F_WRLCK;
2550 lock.l_whence = SEEK_SET;
2553 lock.l_pid = getpid();
2555 ret = fcntl(fd,F_SETLK,&lock);
2557 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2558 local_pathname, strerror(errno));
2561 printf("child: got lock 0:4 on file %s.\n",
2566 CatchSignal(SIGALRM, alarm_handler);
2568 /* Signal the parent. */
2569 if (write(write_fd, &c, 1) != 1) {
2570 printf("child: start signal fail %s.\n",
2577 /* Wait for the parent to be ready. */
2578 if (read(read_fd, &c, 1) != 1) {
2579 printf("child: reply signal fail %s.\n",
2587 printf("child: released lock 0:4 on file %s.\n",
2593 static bool run_locktest9(int dummy)
2595 struct cli_state *cli1;
2596 const char *fname = "\\lockt9.lck";
2598 bool correct = False;
2599 int pipe_in[2], pipe_out[2];
2603 struct timeval start;
2607 printf("starting locktest9\n");
2609 if (local_path == NULL) {
2610 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2614 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2619 if (child_pid == -1) {
2623 if (child_pid == 0) {
2625 do_local_lock(pipe_out[0], pipe_in[1]);
2635 ret = read(pipe_in[0], &c, 1);
2637 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2642 if (!torture_open_connection(&cli1, 0)) {
2646 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2648 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2650 if (!NT_STATUS_IS_OK(status)) {
2651 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2655 /* Ensure the child has the lock. */
2656 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2657 if (NT_STATUS_IS_OK(status)) {
2658 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2661 d_printf("Child has the lock.\n");
2664 /* Tell the child to wait 5 seconds then exit. */
2665 ret = write(pipe_out[1], &c, 1);
2667 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2672 /* Wait 20 seconds for the lock. */
2674 CatchSignal(SIGALRM, alarm_handler_parent);
2677 start = timeval_current();
2679 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2680 if (!NT_STATUS_IS_OK(status)) {
2681 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2682 "%s\n", nt_errstr(status));
2687 seconds = timeval_elapsed(&start);
2689 printf("Parent got the lock after %.2f seconds.\n",
2692 status = cli_close(cli1, fnum);
2693 if (!NT_STATUS_IS_OK(status)) {
2694 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2701 cli_close(cli1, fnum);
2702 torture_close_connection(cli1);
2706 printf("finished locktest9\n");
2711 test whether fnums and tids open on one VC are available on another (a major
2714 static bool run_fdpasstest(int dummy)
2716 struct cli_state *cli1, *cli2;
2717 const char *fname = "\\fdpass.tst";
2722 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2725 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2726 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2728 printf("starting fdpasstest\n");
2730 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2732 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2734 if (!NT_STATUS_IS_OK(status)) {
2735 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2739 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2741 if (!NT_STATUS_IS_OK(status)) {
2742 printf("write failed (%s)\n", nt_errstr(status));
2746 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2747 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2748 cli_setpid(cli2, cli_getpid(cli1));
2750 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2751 printf("read succeeded! nasty security hole [%s]\n", buf);
2755 cli_close(cli1, fnum1);
2756 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2758 torture_close_connection(cli1);
2759 torture_close_connection(cli2);
2761 printf("finished fdpasstest\n");
2765 static bool run_fdsesstest(int dummy)
2767 struct cli_state *cli;
2769 uint16_t saved_vuid;
2771 uint16_t saved_cnum;
2772 const char *fname = "\\fdsess.tst";
2773 const char *fname1 = "\\fdsess1.tst";
2780 if (!torture_open_connection(&cli, 0))
2782 smbXcli_conn_set_sockopt(cli->conn, sockops);
2784 if (!torture_cli_session_setup2(cli, &new_vuid))
2787 saved_cnum = cli_state_get_tid(cli);
2788 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", "", 1)))
2790 new_cnum = cli_state_get_tid(cli);
2791 cli_state_set_tid(cli, saved_cnum);
2793 printf("starting fdsesstest\n");
2795 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2796 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2798 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2799 if (!NT_STATUS_IS_OK(status)) {
2800 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2804 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2806 if (!NT_STATUS_IS_OK(status)) {
2807 printf("write failed (%s)\n", nt_errstr(status));
2811 saved_vuid = cli_state_get_uid(cli);
2812 cli_state_set_uid(cli, new_vuid);
2814 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2815 printf("read succeeded with different vuid! "
2816 "nasty security hole [%s]\n", buf);
2819 /* Try to open a file with different vuid, samba cnum. */
2820 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2821 printf("create with different vuid, same cnum succeeded.\n");
2822 cli_close(cli, fnum2);
2823 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2825 printf("create with different vuid, same cnum failed.\n");
2826 printf("This will cause problems with service clients.\n");
2830 cli_state_set_uid(cli, saved_vuid);
2832 /* Try with same vuid, different cnum. */
2833 cli_state_set_tid(cli, new_cnum);
2835 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2836 printf("read succeeded with different cnum![%s]\n", buf);
2840 cli_state_set_tid(cli, saved_cnum);
2841 cli_close(cli, fnum1);
2842 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2844 torture_close_connection(cli);
2846 printf("finished fdsesstest\n");
2851 This test checks that
2853 1) the server does not allow an unlink on a file that is open
2855 static bool run_unlinktest(int dummy)
2857 struct cli_state *cli;
2858 const char *fname = "\\unlink.tst";
2860 bool correct = True;
2863 if (!torture_open_connection(&cli, 0)) {
2867 smbXcli_conn_set_sockopt(cli->conn, sockops);
2869 printf("starting unlink test\n");
2871 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2875 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2876 if (!NT_STATUS_IS_OK(status)) {
2877 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2881 status = cli_unlink(cli, fname,
2882 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2883 if (NT_STATUS_IS_OK(status)) {
2884 printf("error: server allowed unlink on an open file\n");
2887 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2888 NT_STATUS_SHARING_VIOLATION);
2891 cli_close(cli, fnum);
2892 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2894 if (!torture_close_connection(cli)) {
2898 printf("unlink test finished\n");
2905 test how many open files this server supports on the one socket
2907 static bool run_maxfidtest(int dummy)
2909 struct cli_state *cli;
2911 uint16_t fnums[0x11000];
2914 bool correct = True;
2920 printf("failed to connect\n");
2924 smbXcli_conn_set_sockopt(cli->conn, sockops);
2926 for (i=0; i<0x11000; i++) {
2927 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2928 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2930 if (!NT_STATUS_IS_OK(status)) {
2931 printf("open of %s failed (%s)\n",
2932 fname, nt_errstr(status));
2933 printf("maximum fnum is %d\n", i);
2941 printf("cleaning up\n");
2943 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2944 cli_close(cli, fnums[i]);
2946 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2947 if (!NT_STATUS_IS_OK(status)) {
2948 printf("unlink of %s failed (%s)\n",
2949 fname, nt_errstr(status));
2956 printf("maxfid test finished\n");
2957 if (!torture_close_connection(cli)) {
2963 /* generate a random buffer */
2964 static void rand_buf(char *buf, int len)
2967 *buf = (char)sys_random();
2972 /* send smb negprot commands, not reading the response */
2973 static bool run_negprot_nowait(int dummy)
2975 struct tevent_context *ev;
2977 struct cli_state *cli;
2978 bool correct = True;
2980 printf("starting negprot nowait test\n");
2982 ev = samba_tevent_context_init(talloc_tos());
2987 if (!(cli = open_nbt_connection())) {
2992 for (i=0;i<50000;i++) {
2993 struct tevent_req *req;
2995 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
2996 PROTOCOL_CORE, PROTOCOL_NT1);
3001 if (!tevent_req_poll(req, ev)) {
3002 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3010 if (torture_close_connection(cli)) {
3014 printf("finished negprot nowait test\n");
3019 /* send smb negprot commands, not reading the response */
3020 static bool run_bad_nbt_session(int dummy)
3022 struct nmb_name called, calling;
3023 struct sockaddr_storage ss;
3028 printf("starting bad nbt session test\n");
3030 make_nmb_name(&calling, myname, 0x0);
3031 make_nmb_name(&called , host, 0x20);
3033 if (!resolve_name(host, &ss, 0x20, true)) {
3034 d_fprintf(stderr, "Could not resolve name %s\n", host);
3038 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3039 if (!NT_STATUS_IS_OK(status)) {
3040 d_fprintf(stderr, "open_socket_out failed: %s\n",
3045 ret = cli_bad_session_request(fd, &calling, &called);
3048 d_fprintf(stderr, "open_socket_out failed: %s\n",
3053 printf("finished bad nbt session test\n");
3057 /* send random IPC commands */
3058 static bool run_randomipc(int dummy)
3060 char *rparam = NULL;
3062 unsigned int rdrcnt,rprcnt;
3064 int api, param_len, i;
3065 struct cli_state *cli;
3066 bool correct = True;
3069 printf("starting random ipc test\n");
3071 if (!torture_open_connection(&cli, 0)) {
3075 for (i=0;i<count;i++) {
3076 api = sys_random() % 500;
3077 param_len = (sys_random() % 64);
3079 rand_buf(param, param_len);
3084 param, param_len, 8,
3085 NULL, 0, CLI_BUFFER_SIZE,
3089 printf("%d/%d\r", i,count);
3092 printf("%d/%d\n", i, count);
3094 if (!torture_close_connection(cli)) {
3101 printf("finished random ipc test\n");
3108 static void browse_callback(const char *sname, uint32_t stype,
3109 const char *comment, void *state)
3111 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3117 This test checks the browse list code
3120 static bool run_browsetest(int dummy)
3122 static struct cli_state *cli;
3123 bool correct = True;
3125 printf("starting browse test\n");
3127 if (!torture_open_connection(&cli, 0)) {
3131 printf("domain list:\n");
3132 cli_NetServerEnum(cli, cli->server_domain,
3133 SV_TYPE_DOMAIN_ENUM,
3134 browse_callback, NULL);
3136 printf("machine list:\n");
3137 cli_NetServerEnum(cli, cli->server_domain,
3139 browse_callback, NULL);
3141 if (!torture_close_connection(cli)) {
3145 printf("browse test finished\n");
3153 This checks how the getatr calls works
3155 static bool run_attrtest(int dummy)
3157 struct cli_state *cli;
3160 const char *fname = "\\attrib123456789.tst";
3161 bool correct = True;
3164 printf("starting attrib test\n");
3166 if (!torture_open_connection(&cli, 0)) {
3170 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3171 cli_openx(cli, fname,
3172 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3173 cli_close(cli, fnum);
3175 status = cli_getatr(cli, fname, NULL, NULL, &t);
3176 if (!NT_STATUS_IS_OK(status)) {
3177 printf("getatr failed (%s)\n", nt_errstr(status));
3181 if (abs(t - time(NULL)) > 60*60*24*10) {
3182 printf("ERROR: SMBgetatr bug. time is %s",
3188 t2 = t-60*60*24; /* 1 day ago */
3190 status = cli_setatr(cli, fname, 0, t2);
3191 if (!NT_STATUS_IS_OK(status)) {
3192 printf("setatr failed (%s)\n", nt_errstr(status));
3196 status = cli_getatr(cli, fname, NULL, NULL, &t);
3197 if (!NT_STATUS_IS_OK(status)) {
3198 printf("getatr failed (%s)\n", nt_errstr(status));
3203 printf("ERROR: getatr/setatr bug. times are\n%s",
3205 printf("%s", ctime(&t2));
3209 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3211 if (!torture_close_connection(cli)) {
3215 printf("attrib test finished\n");
3222 This checks a couple of trans2 calls
3224 static bool run_trans2test(int dummy)
3226 struct cli_state *cli;
3229 time_t c_time, a_time, m_time;
3230 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3231 const char *fname = "\\trans2.tst";
3232 const char *dname = "\\trans2";
3233 const char *fname2 = "\\trans2\\trans2.tst";
3235 bool correct = True;
3239 printf("starting trans2 test\n");
3241 if (!torture_open_connection(&cli, 0)) {
3245 status = cli_get_fs_attr_info(cli, &fs_attr);
3246 if (!NT_STATUS_IS_OK(status)) {
3247 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3252 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3253 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3254 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3255 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3256 if (!NT_STATUS_IS_OK(status)) {
3257 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3261 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3262 if (!NT_STATUS_IS_OK(status)) {
3263 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3266 else if (strcmp(pname, fname)) {
3267 printf("qfilename gave different name? [%s] [%s]\n",
3272 cli_close(cli, fnum);
3276 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3277 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3279 if (!NT_STATUS_IS_OK(status)) {
3280 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3283 cli_close(cli, fnum);
3285 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3287 if (!NT_STATUS_IS_OK(status)) {
3288 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3291 time_t t = time(NULL);
3293 if (c_time != m_time) {
3294 printf("create time=%s", ctime(&c_time));
3295 printf("modify time=%s", ctime(&m_time));
3296 printf("This system appears to have sticky create times\n");
3298 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3299 printf("access time=%s", ctime(&a_time));
3300 printf("This system appears to set a midnight access time\n");
3304 if (abs(m_time - t) > 60*60*24*7) {
3305 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3311 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3312 cli_openx(cli, fname,
3313 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3314 cli_close(cli, fnum);
3315 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3316 &m_time_ts, &size, NULL, NULL);
3317 if (!NT_STATUS_IS_OK(status)) {
3318 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3321 if (w_time_ts.tv_sec < 60*60*24*2) {
3322 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3323 printf("This system appears to set a initial 0 write time\n");
3328 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3331 /* check if the server updates the directory modification time
3332 when creating a new file */
3333 status = cli_mkdir(cli, dname);
3334 if (!NT_STATUS_IS_OK(status)) {
3335 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3339 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3340 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3346 cli_openx(cli, fname2,
3347 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3348 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3349 cli_close(cli, fnum);
3350 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3351 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3352 if (!NT_STATUS_IS_OK(status)) {
3353 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3356 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3358 printf("This system does not update directory modification times\n");
3362 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3363 cli_rmdir(cli, dname);
3365 if (!torture_close_connection(cli)) {
3369 printf("trans2 test finished\n");
3375 This checks new W2K calls.
3378 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3380 uint8_t *buf = NULL;
3384 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3385 CLI_BUFFER_SIZE, NULL, &buf, &len);
3386 if (!NT_STATUS_IS_OK(status)) {
3387 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3390 printf("qfileinfo: level %d, len = %u\n", level, len);
3391 dump_data(0, (uint8_t *)buf, len);
3398 static bool run_w2ktest(int dummy)
3400 struct cli_state *cli;
3402 const char *fname = "\\w2ktest\\w2k.tst";
3404 bool correct = True;
3406 printf("starting w2k test\n");
3408 if (!torture_open_connection(&cli, 0)) {
3412 cli_openx(cli, fname,
3413 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3415 for (level = 1004; level < 1040; level++) {
3416 new_trans(cli, fnum, level);
3419 cli_close(cli, fnum);
3421 if (!torture_close_connection(cli)) {
3425 printf("w2k test finished\n");
3432 this is a harness for some oplock tests
3434 static bool run_oplock1(int dummy)
3436 struct cli_state *cli1;
3437 const char *fname = "\\lockt1.lck";
3439 bool correct = True;
3442 printf("starting oplock test 1\n");
3444 if (!torture_open_connection(&cli1, 0)) {
3448 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3450 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3452 cli1->use_oplocks = True;
3454 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3456 if (!NT_STATUS_IS_OK(status)) {
3457 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3461 cli1->use_oplocks = False;
3463 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3464 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3466 status = cli_close(cli1, fnum1);
3467 if (!NT_STATUS_IS_OK(status)) {
3468 printf("close2 failed (%s)\n", nt_errstr(status));
3472 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3473 if (!NT_STATUS_IS_OK(status)) {
3474 printf("unlink failed (%s)\n", nt_errstr(status));
3478 if (!torture_close_connection(cli1)) {
3482 printf("finished oplock test 1\n");
3487 static bool run_oplock2(int dummy)
3489 struct cli_state *cli1, *cli2;
3490 const char *fname = "\\lockt2.lck";
3491 uint16_t fnum1, fnum2;
3492 int saved_use_oplocks = use_oplocks;
3494 bool correct = True;
3495 volatile bool *shared_correct;
3499 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3500 *shared_correct = True;
3502 use_level_II_oplocks = True;
3505 printf("starting oplock test 2\n");
3507 if (!torture_open_connection(&cli1, 0)) {
3508 use_level_II_oplocks = False;
3509 use_oplocks = saved_use_oplocks;
3513 if (!torture_open_connection(&cli2, 1)) {
3514 use_level_II_oplocks = False;
3515 use_oplocks = saved_use_oplocks;
3519 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3521 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3522 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3524 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3526 if (!NT_STATUS_IS_OK(status)) {
3527 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3531 /* Don't need the globals any more. */
3532 use_level_II_oplocks = False;
3533 use_oplocks = saved_use_oplocks;
3537 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3538 if (!NT_STATUS_IS_OK(status)) {
3539 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3540 *shared_correct = False;
3546 status = cli_close(cli2, fnum2);
3547 if (!NT_STATUS_IS_OK(status)) {
3548 printf("close2 failed (%s)\n", nt_errstr(status));
3549 *shared_correct = False;
3557 /* Ensure cli1 processes the break. Empty file should always return 0
3559 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3560 if (!NT_STATUS_IS_OK(status)) {
3561 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3563 } else if (nread != 0) {
3564 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3565 (unsigned long)nread, 0);
3569 /* Should now be at level II. */
3570 /* Test if sending a write locks causes a break to none. */
3571 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3572 if (!NT_STATUS_IS_OK(status)) {
3573 printf("lock failed (%s)\n", nt_errstr(status));
3577 cli_unlock(cli1, fnum1, 0, 4);
3581 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3582 if (!NT_STATUS_IS_OK(status)) {
3583 printf("lock failed (%s)\n", nt_errstr(status));
3587 cli_unlock(cli1, fnum1, 0, 4);
3591 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3593 status = cli_close(cli1, fnum1);
3594 if (!NT_STATUS_IS_OK(status)) {
3595 printf("close1 failed (%s)\n", nt_errstr(status));
3601 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3602 if (!NT_STATUS_IS_OK(status)) {
3603 printf("unlink failed (%s)\n", nt_errstr(status));
3607 if (!torture_close_connection(cli1)) {
3611 if (!*shared_correct) {
3615 printf("finished oplock test 2\n");
3620 struct oplock4_state {
3621 struct tevent_context *ev;
3622 struct cli_state *cli;
3627 static void oplock4_got_break(struct tevent_req *req);
3628 static void oplock4_got_open(struct tevent_req *req);
3630 static bool run_oplock4(int dummy)
3632 struct tevent_context *ev;
3633 struct cli_state *cli1, *cli2;
3634 struct tevent_req *oplock_req, *open_req;
3635 const char *fname = "\\lockt4.lck";
3636 const char *fname_ln = "\\lockt4_ln.lck";
3637 uint16_t fnum1, fnum2;
3638 int saved_use_oplocks = use_oplocks;
3640 bool correct = true;
3644 struct oplock4_state *state;
3646 printf("starting oplock test 4\n");
3648 if (!torture_open_connection(&cli1, 0)) {
3649 use_level_II_oplocks = false;
3650 use_oplocks = saved_use_oplocks;
3654 if (!torture_open_connection(&cli2, 1)) {
3655 use_level_II_oplocks = false;
3656 use_oplocks = saved_use_oplocks;
3660 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3661 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3663 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3664 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3666 /* Create the file. */
3667 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3669 if (!NT_STATUS_IS_OK(status)) {
3670 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3674 status = cli_close(cli1, fnum1);
3675 if (!NT_STATUS_IS_OK(status)) {
3676 printf("close1 failed (%s)\n", nt_errstr(status));
3680 /* Now create a hardlink. */
3681 status = cli_nt_hardlink(cli1, fname, fname_ln);
3682 if (!NT_STATUS_IS_OK(status)) {
3683 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3687 /* Prove that opening hardlinks cause deny modes to conflict. */
3688 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3689 if (!NT_STATUS_IS_OK(status)) {
3690 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3694 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3695 if (NT_STATUS_IS_OK(status)) {
3696 printf("open of %s succeeded - should fail with sharing violation.\n",
3701 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3702 printf("open of %s should fail with sharing violation. Got %s\n",
3703 fname_ln, nt_errstr(status));
3707 status = cli_close(cli1, fnum1);
3708 if (!NT_STATUS_IS_OK(status)) {
3709 printf("close1 failed (%s)\n", nt_errstr(status));
3713 cli1->use_oplocks = true;
3714 cli2->use_oplocks = true;
3716 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3717 if (!NT_STATUS_IS_OK(status)) {
3718 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3722 ev = samba_tevent_context_init(talloc_tos());
3724 printf("tevent_context_init failed\n");
3728 state = talloc(ev, struct oplock4_state);
3729 if (state == NULL) {
3730 printf("talloc failed\n");
3735 state->got_break = &got_break;
3736 state->fnum2 = &fnum2;
3738 oplock_req = cli_smb_oplock_break_waiter_send(
3739 talloc_tos(), ev, cli1);
3740 if (oplock_req == NULL) {
3741 printf("cli_smb_oplock_break_waiter_send failed\n");
3744 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3746 open_req = cli_openx_send(
3747 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3748 if (open_req == NULL) {
3749 printf("cli_openx_send failed\n");
3752 tevent_req_set_callback(open_req, oplock4_got_open, state);
3757 while (!got_break || fnum2 == 0xffff) {
3759 ret = tevent_loop_once(ev);
3761 printf("tevent_loop_once failed: %s\n",
3767 status = cli_close(cli2, fnum2);
3768 if (!NT_STATUS_IS_OK(status)) {
3769 printf("close2 failed (%s)\n", nt_errstr(status));
3773 status = cli_close(cli1, fnum1);
3774 if (!NT_STATUS_IS_OK(status)) {
3775 printf("close1 failed (%s)\n", nt_errstr(status));
3779 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3780 if (!NT_STATUS_IS_OK(status)) {
3781 printf("unlink failed (%s)\n", nt_errstr(status));
3785 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3786 if (!NT_STATUS_IS_OK(status)) {
3787 printf("unlink failed (%s)\n", nt_errstr(status));
3791 if (!torture_close_connection(cli1)) {
3799 printf("finished oplock test 4\n");
3804 static void oplock4_got_break(struct tevent_req *req)
3806 struct oplock4_state *state = tevent_req_callback_data(
3807 req, struct oplock4_state);
3812 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3814 if (!NT_STATUS_IS_OK(status)) {
3815 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3819 *state->got_break = true;
3821 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3824 printf("cli_oplock_ack_send failed\n");
3829 static void oplock4_got_open(struct tevent_req *req)
3831 struct oplock4_state *state = tevent_req_callback_data(
3832 req, struct oplock4_state);
3835 status = cli_openx_recv(req, state->fnum2);
3836 if (!NT_STATUS_IS_OK(status)) {
3837 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3838 *state->fnum2 = 0xffff;
3843 Test delete on close semantics.
3845 static bool run_deletetest(int dummy)
3847 struct cli_state *cli1 = NULL;
3848 struct cli_state *cli2 = NULL;
3849 const char *fname = "\\delete.file";
3850 uint16_t fnum1 = (uint16_t)-1;
3851 uint16_t fnum2 = (uint16_t)-1;
3852 bool correct = false;
3855 printf("starting delete test\n");
3857 if (!torture_open_connection(&cli1, 0)) {
3861 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3863 /* Test 1 - this should delete the file on close. */
3865 cli_setatr(cli1, fname, 0, 0);
3866 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3868 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3869 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3870 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
3871 if (!NT_STATUS_IS_OK(status)) {
3872 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3876 status = cli_close(cli1, fnum1);
3877 if (!NT_STATUS_IS_OK(status)) {
3878 printf("[1] close failed (%s)\n", nt_errstr(status));
3882 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3883 if (NT_STATUS_IS_OK(status)) {
3884 printf("[1] open of %s succeeded (should fail)\n", fname);
3888 printf("first delete on close test succeeded.\n");
3890 /* Test 2 - this should delete the file on close. */
3892 cli_setatr(cli1, fname, 0, 0);
3893 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3895 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3896 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3897 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3898 if (!NT_STATUS_IS_OK(status)) {
3899 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3903 status = cli_nt_delete_on_close(cli1, fnum1, true);
3904 if (!NT_STATUS_IS_OK(status)) {
3905 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3909 status = cli_close(cli1, fnum1);
3910 if (!NT_STATUS_IS_OK(status)) {
3911 printf("[2] close failed (%s)\n", nt_errstr(status));
3915 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3916 if (NT_STATUS_IS_OK(status)) {
3917 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3918 status = cli_close(cli1, fnum1);
3919 if (!NT_STATUS_IS_OK(status)) {
3920 printf("[2] close failed (%s)\n", nt_errstr(status));
3922 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3926 printf("second delete on close test succeeded.\n");
3929 cli_setatr(cli1, fname, 0, 0);
3930 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3932 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3933 FILE_ATTRIBUTE_NORMAL,
3934 FILE_SHARE_READ|FILE_SHARE_WRITE,
3935 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3941 /* This should fail with a sharing violation - open for delete is only compatible
3942 with SHARE_DELETE. */
3944 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3945 FILE_ATTRIBUTE_NORMAL,
3946 FILE_SHARE_READ|FILE_SHARE_WRITE,
3947 FILE_OPEN, 0, 0, &fnum2, NULL);
3948 if (NT_STATUS_IS_OK(status)) {
3949 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3953 /* This should succeed. */
3954 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3955 FILE_ATTRIBUTE_NORMAL,
3956 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3957 FILE_OPEN, 0, 0, &fnum2, NULL);
3958 if (!NT_STATUS_IS_OK(status)) {
3959 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
3963 status = cli_nt_delete_on_close(cli1, fnum1, true);
3964 if (!NT_STATUS_IS_OK(status)) {
3965 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3969 status = cli_close(cli1, fnum1);
3970 if (!NT_STATUS_IS_OK(status)) {
3971 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3975 status = cli_close(cli1, fnum2);
3976 if (!NT_STATUS_IS_OK(status)) {
3977 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3981 /* This should fail - file should no longer be there. */
3983 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3984 if (NT_STATUS_IS_OK(status)) {
3985 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3986 status = cli_close(cli1, fnum1);
3987 if (!NT_STATUS_IS_OK(status)) {
3988 printf("[3] close failed (%s)\n", nt_errstr(status));
3990 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3994 printf("third delete on close test succeeded.\n");
3997 cli_setatr(cli1, fname, 0, 0);
3998 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4000 status = cli_ntcreate(cli1, fname, 0,
4001 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4002 FILE_ATTRIBUTE_NORMAL,
4003 FILE_SHARE_READ|FILE_SHARE_WRITE,
4004 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4005 if (!NT_STATUS_IS_OK(status)) {
4006 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4010 /* This should succeed. */
4011 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4012 FILE_ATTRIBUTE_NORMAL,
4013 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4014 FILE_OPEN, 0, 0, &fnum2, NULL);
4015 if (!NT_STATUS_IS_OK(status)) {
4016 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4020 status = cli_close(cli1, fnum2);
4021 if (!NT_STATUS_IS_OK(status)) {
4022 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4026 status = cli_nt_delete_on_close(cli1, fnum1, true);
4027 if (!NT_STATUS_IS_OK(status)) {
4028 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4032 /* This should fail - no more opens once delete on close set. */
4033 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4034 FILE_ATTRIBUTE_NORMAL,
4035 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4036 FILE_OPEN, 0, 0, &fnum2, NULL);
4037 if (NT_STATUS_IS_OK(status)) {
4038 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4042 status = cli_close(cli1, fnum1);
4043 if (!NT_STATUS_IS_OK(status)) {
4044 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4048 printf("fourth delete on close test succeeded.\n");
4051 cli_setatr(cli1, fname, 0, 0);
4052 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4054 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4055 if (!NT_STATUS_IS_OK(status)) {
4056 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4060 /* This should fail - only allowed on NT opens with DELETE access. */
4062 status = cli_nt_delete_on_close(cli1, fnum1, true);
4063 if (NT_STATUS_IS_OK(status)) {
4064 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4068 status = cli_close(cli1, fnum1);
4069 if (!NT_STATUS_IS_OK(status)) {
4070 printf("[5] close failed (%s)\n", nt_errstr(status));
4074 printf("fifth delete on close test succeeded.\n");
4077 cli_setatr(cli1, fname, 0, 0);
4078 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4080 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4081 FILE_ATTRIBUTE_NORMAL,
4082 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4083 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4084 if (!NT_STATUS_IS_OK(status)) {
4085 printf("[6] open of %s failed (%s)\n", fname,
4090 /* This should fail - only allowed on NT opens with DELETE access. */
4092 status = cli_nt_delete_on_close(cli1, fnum1, true);
4093 if (NT_STATUS_IS_OK(status)) {
4094 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4098 status = cli_close(cli1, fnum1);
4099 if (!NT_STATUS_IS_OK(status)) {
4100 printf("[6] close failed (%s)\n", nt_errstr(status));
4104 printf("sixth delete on close test succeeded.\n");
4107 cli_setatr(cli1, fname, 0, 0);
4108 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4110 status = cli_ntcreate(cli1, fname, 0,
4111 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4112 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4113 0, 0, &fnum1, NULL);
4114 if (!NT_STATUS_IS_OK(status)) {
4115 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4119 status = cli_nt_delete_on_close(cli1, fnum1, true);
4120 if (!NT_STATUS_IS_OK(status)) {
4121 printf("[7] setting delete_on_close on file failed !\n");
4125 status = cli_nt_delete_on_close(cli1, fnum1, false);
4126 if (!NT_STATUS_IS_OK(status)) {
4127 printf("[7] unsetting delete_on_close on file failed !\n");
4131 status = cli_close(cli1, fnum1);
4132 if (!NT_STATUS_IS_OK(status)) {
4133 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4137 /* This next open should succeed - we reset the flag. */
4138 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4139 if (!NT_STATUS_IS_OK(status)) {
4140 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4144 status = cli_close(cli1, fnum1);
4145 if (!NT_STATUS_IS_OK(status)) {
4146 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4150 printf("seventh delete on close test succeeded.\n");
4153 cli_setatr(cli1, fname, 0, 0);
4154 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4156 if (!torture_open_connection(&cli2, 1)) {
4157 printf("[8] failed to open second connection.\n");
4161 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4163 status = cli_ntcreate(cli1, fname, 0,
4164 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4165 FILE_ATTRIBUTE_NORMAL,
4166 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4167 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4168 if (!NT_STATUS_IS_OK(status)) {
4169 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4173 status = cli_ntcreate(cli2, fname, 0,
4174 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4175 FILE_ATTRIBUTE_NORMAL,
4176 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4177 FILE_OPEN, 0, 0, &fnum2, NULL);
4178 if (!NT_STATUS_IS_OK(status)) {
4179 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4183 status = cli_nt_delete_on_close(cli1, fnum1, true);
4184 if (!NT_STATUS_IS_OK(status)) {
4185 printf("[8] setting delete_on_close on file failed !\n");
4189 status = cli_close(cli1, fnum1);
4190 if (!NT_STATUS_IS_OK(status)) {
4191 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4195 status = cli_close(cli2, fnum2);
4196 if (!NT_STATUS_IS_OK(status)) {
4197 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4201 /* This should fail.. */
4202 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4203 if (NT_STATUS_IS_OK(status)) {
4204 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4208 printf("eighth delete on close test succeeded.\n");
4212 /* This should fail - we need to set DELETE_ACCESS. */
4213 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4214 FILE_ATTRIBUTE_NORMAL,
4217 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4218 if (NT_STATUS_IS_OK(status)) {
4219 printf("[9] open of %s succeeded should have failed!\n", fname);
4223 printf("ninth delete on close test succeeded.\n");
4227 status = cli_ntcreate(cli1, fname, 0,
4228 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4229 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4230 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4232 if (!NT_STATUS_IS_OK(status)) {
4233 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4237 /* This should delete the file. */
4238 status = cli_close(cli1, fnum1);
4239 if (!NT_STATUS_IS_OK(status)) {
4240 printf("[10] close failed (%s)\n", nt_errstr(status));
4244 /* This should fail.. */
4245 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4246 if (NT_STATUS_IS_OK(status)) {
4247 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4251 printf("tenth delete on close test succeeded.\n");
4255 cli_setatr(cli1, fname, 0, 0);
4256 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4258 /* Can we open a read-only file with delete access? */
4260 /* Create a readonly file. */
4261 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4262 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4263 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4264 if (!NT_STATUS_IS_OK(status)) {
4265 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4269 status = cli_close(cli1, fnum1);
4270 if (!NT_STATUS_IS_OK(status)) {
4271 printf("[11] close failed (%s)\n", nt_errstr(status));
4275 /* Now try open for delete access. */
4276 status = cli_ntcreate(cli1, fname, 0,
4277 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4279 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4280 FILE_OPEN, 0, 0, &fnum1, NULL);
4281 if (!NT_STATUS_IS_OK(status)) {
4282 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4286 cli_close(cli1, fnum1);
4288 printf("eleventh delete on close test succeeded.\n");
4292 * like test 4 but with initial delete on close
4295 cli_setatr(cli1, fname, 0, 0);
4296 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4298 status = cli_ntcreate(cli1, fname, 0,
4299 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4300 FILE_ATTRIBUTE_NORMAL,
4301 FILE_SHARE_READ|FILE_SHARE_WRITE,
4303 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4304 if (!NT_STATUS_IS_OK(status)) {
4305 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4309 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4310 FILE_ATTRIBUTE_NORMAL,
4311 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4312 FILE_OPEN, 0, 0, &fnum2, NULL);
4313 if (!NT_STATUS_IS_OK(status)) {
4314 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4318 status = cli_close(cli1, fnum2);
4319 if (!NT_STATUS_IS_OK(status)) {
4320 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4324 status = cli_nt_delete_on_close(cli1, fnum1, true);
4325 if (!NT_STATUS_IS_OK(status)) {
4326 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4330 /* This should fail - no more opens once delete on close set. */
4331 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4332 FILE_ATTRIBUTE_NORMAL,
4333 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4334 FILE_OPEN, 0, 0, &fnum2, NULL);
4335 if (NT_STATUS_IS_OK(status)) {
4336 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4340 status = cli_nt_delete_on_close(cli1, fnum1, false);
4341 if (!NT_STATUS_IS_OK(status)) {
4342 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4346 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4347 FILE_ATTRIBUTE_NORMAL,
4348 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4349 FILE_OPEN, 0, 0, &fnum2, NULL);
4350 if (!NT_STATUS_IS_OK(status)) {
4351 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4355 status = cli_close(cli1, fnum2);
4356 if (!NT_STATUS_IS_OK(status)) {
4357 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4361 status = cli_close(cli1, fnum1);
4362 if (!NT_STATUS_IS_OK(status)) {
4363 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4368 * setting delete on close on the handle does
4369 * not unset the initial delete on close...
4371 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4372 FILE_ATTRIBUTE_NORMAL,
4373 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4374 FILE_OPEN, 0, 0, &fnum2, NULL);
4375 if (NT_STATUS_IS_OK(status)) {
4376 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4378 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4379 printf("ntcreate returned %s, expected "
4380 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4385 printf("twelfth delete on close test succeeded.\n");
4388 printf("finished delete test\n");
4393 /* FIXME: This will crash if we aborted before cli2 got
4394 * intialized, because these functions don't handle
4395 * uninitialized connections. */
4397 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4398 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4399 cli_setatr(cli1, fname, 0, 0);
4400 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4402 if (cli1 && !torture_close_connection(cli1)) {
4405 if (cli2 && !torture_close_connection(cli2)) {
4413 Test wildcard delete.
4415 static bool run_wild_deletetest(int dummy)
4417 struct cli_state *cli = NULL;
4418 const char *dname = "\\WTEST";
4419 const char *fname = "\\WTEST\\A";
4420 const char *wunlink_name = "\\WTEST\\*";
4421 uint16_t fnum1 = (uint16_t)-1;
4422 bool correct = false;
4425 printf("starting wildcard delete test\n");
4427 if (!torture_open_connection(&cli, 0)) {
4431 smbXcli_conn_set_sockopt(cli->conn, sockops);
4433 cli_unlink(cli, fname, 0);
4434 cli_rmdir(cli, dname);
4435 status = cli_mkdir(cli, dname);
4436 if (!NT_STATUS_IS_OK(status)) {
4437 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4440 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4441 if (!NT_STATUS_IS_OK(status)) {
4442 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4445 status = cli_close(cli, fnum1);
4449 * Note the unlink attribute-type of zero. This should
4450 * map into FILE_ATTRIBUTE_NORMAL at the server even
4451 * on a wildcard delete.
4454 status = cli_unlink(cli, wunlink_name, 0);
4455 if (!NT_STATUS_IS_OK(status)) {
4456 printf("unlink of %s failed %s!\n",
4457 wunlink_name, nt_errstr(status));
4461 printf("finished wildcard delete test\n");
4467 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4468 cli_unlink(cli, fname, 0);
4469 cli_rmdir(cli, dname);
4471 if (cli && !torture_close_connection(cli)) {
4477 static bool run_deletetest_ln(int dummy)
4479 struct cli_state *cli;
4480 const char *fname = "\\delete1";
4481 const char *fname_ln = "\\delete1_ln";
4485 bool correct = true;
4488 printf("starting deletetest-ln\n");
4490 if (!torture_open_connection(&cli, 0)) {
4494 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4495 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4497 smbXcli_conn_set_sockopt(cli->conn, sockops);
4499 /* Create the file. */
4500 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4501 if (!NT_STATUS_IS_OK(status)) {
4502 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4506 status = cli_close(cli, fnum);
4507 if (!NT_STATUS_IS_OK(status)) {
4508 printf("close1 failed (%s)\n", nt_errstr(status));
4512 /* Now create a hardlink. */
4513 status = cli_nt_hardlink(cli, fname, fname_ln);
4514 if (!NT_STATUS_IS_OK(status)) {
4515 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4519 /* Open the original file. */
4520 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4521 FILE_ATTRIBUTE_NORMAL,
4522 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4523 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4524 if (!NT_STATUS_IS_OK(status)) {
4525 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4529 /* Unlink the hard link path. */
4530 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4531 FILE_ATTRIBUTE_NORMAL,
4532 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4533 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4534 if (!NT_STATUS_IS_OK(status)) {
4535 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4538 status = cli_nt_delete_on_close(cli, fnum1, true);
4539 if (!NT_STATUS_IS_OK(status)) {
4540 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4541 __location__, fname_ln, nt_errstr(status));
4545 status = cli_close(cli, fnum1);
4546 if (!NT_STATUS_IS_OK(status)) {
4547 printf("close %s failed (%s)\n",
4548 fname_ln, nt_errstr(status));
4552 status = cli_close(cli, fnum);
4553 if (!NT_STATUS_IS_OK(status)) {
4554 printf("close %s failed (%s)\n",
4555 fname, nt_errstr(status));
4559 /* Ensure the original file is still there. */
4560 status = cli_getatr(cli, fname, NULL, NULL, &t);
4561 if (!NT_STATUS_IS_OK(status)) {
4562 printf("%s getatr on file %s failed (%s)\n",
4569 /* Ensure the link path is gone. */
4570 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4571 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4572 printf("%s, getatr for file %s returned wrong error code %s "
4573 "- should have been deleted\n",
4575 fname_ln, nt_errstr(status));
4579 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4580 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4582 if (!torture_close_connection(cli)) {
4586 printf("finished deletetest-ln\n");
4592 print out server properties
4594 static bool run_properties(int dummy)
4596 struct cli_state *cli;
4597 bool correct = True;
4599 printf("starting properties test\n");
4603 if (!torture_open_connection(&cli, 0)) {
4607 smbXcli_conn_set_sockopt(cli->conn, sockops);
4609 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4611 if (!torture_close_connection(cli)) {
4620 /* FIRST_DESIRED_ACCESS 0xf019f */
4621 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4622 FILE_READ_EA| /* 0xf */ \
4623 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4624 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4625 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4626 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4627 /* SECOND_DESIRED_ACCESS 0xe0080 */
4628 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4629 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4630 WRITE_OWNER_ACCESS /* 0xe0000 */
4633 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4634 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4636 WRITE_OWNER_ACCESS /* */
4640 Test ntcreate calls made by xcopy
4642 static bool run_xcopy(int dummy)
4644 static struct cli_state *cli1;
4645 const char *fname = "\\test.txt";
4646 bool correct = True;
4647 uint16_t fnum1, fnum2;
4650 printf("starting xcopy test\n");
4652 if (!torture_open_connection(&cli1, 0)) {
4656 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4657 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4658 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4659 if (!NT_STATUS_IS_OK(status)) {
4660 printf("First open failed - %s\n", nt_errstr(status));
4664 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4665 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4666 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4667 if (!NT_STATUS_IS_OK(status)) {
4668 printf("second open failed - %s\n", nt_errstr(status));
4672 if (!torture_close_connection(cli1)) {
4680 Test rename on files open with share delete and no share delete.
4682 static bool run_rename(int dummy)
4684 static struct cli_state *cli1;
4685 const char *fname = "\\test.txt";
4686 const char *fname1 = "\\test1.txt";
4687 bool correct = True;
4692 printf("starting rename test\n");
4694 if (!torture_open_connection(&cli1, 0)) {
4698 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4699 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4701 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4702 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4703 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4704 if (!NT_STATUS_IS_OK(status)) {
4705 printf("First open failed - %s\n", nt_errstr(status));
4709 status = cli_rename(cli1, fname, fname1);
4710 if (!NT_STATUS_IS_OK(status)) {
4711 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4713 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4717 status = cli_close(cli1, fnum1);
4718 if (!NT_STATUS_IS_OK(status)) {
4719 printf("close - 1 failed (%s)\n", nt_errstr(status));
4723 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4724 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4725 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4727 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4729 FILE_SHARE_DELETE|FILE_SHARE_READ,
4731 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4732 if (!NT_STATUS_IS_OK(status)) {
4733 printf("Second open failed - %s\n", nt_errstr(status));
4737 status = cli_rename(cli1, fname, fname1);
4738 if (!NT_STATUS_IS_OK(status)) {
4739 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4742 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4745 status = cli_close(cli1, fnum1);
4746 if (!NT_STATUS_IS_OK(status)) {
4747 printf("close - 2 failed (%s)\n", nt_errstr(status));
4751 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4752 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4754 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4755 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4756 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4757 if (!NT_STATUS_IS_OK(status)) {
4758 printf("Third open failed - %s\n", nt_errstr(status));
4767 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4768 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4769 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4772 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4773 printf("[8] setting delete_on_close on file failed !\n");
4777 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4778 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4784 status = cli_rename(cli1, fname, fname1);
4785 if (!NT_STATUS_IS_OK(status)) {
4786 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4789 printf("Third rename succeeded (SHARE_NONE)\n");
4792 status = cli_close(cli1, fnum1);
4793 if (!NT_STATUS_IS_OK(status)) {
4794 printf("close - 3 failed (%s)\n", nt_errstr(status));
4798 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4799 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4803 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4804 FILE_ATTRIBUTE_NORMAL,
4805 FILE_SHARE_READ | FILE_SHARE_WRITE,
4806 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4807 if (!NT_STATUS_IS_OK(status)) {
4808 printf("Fourth open failed - %s\n", nt_errstr(status));
4812 status = cli_rename(cli1, fname, fname1);
4813 if (!NT_STATUS_IS_OK(status)) {
4814 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4816 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4820 status = cli_close(cli1, fnum1);
4821 if (!NT_STATUS_IS_OK(status)) {
4822 printf("close - 4 failed (%s)\n", nt_errstr(status));
4826 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4827 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4831 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4832 FILE_ATTRIBUTE_NORMAL,
4833 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4834 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4835 if (!NT_STATUS_IS_OK(status)) {
4836 printf("Fifth open failed - %s\n", nt_errstr(status));
4840 status = cli_rename(cli1, fname, fname1);
4841 if (!NT_STATUS_IS_OK(status)) {
4842 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4845 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4849 * Now check if the first name still exists ...
4852 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4853 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4854 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4855 printf("Opening original file after rename of open file fails: %s\n",
4859 printf("Opening original file after rename of open file works ...\n");
4860 (void)cli_close(cli1, fnum2);
4864 status = cli_close(cli1, fnum1);
4865 if (!NT_STATUS_IS_OK(status)) {
4866 printf("close - 5 failed (%s)\n", nt_errstr(status));
4870 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4871 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4872 if (!NT_STATUS_IS_OK(status)) {
4873 printf("getatr on file %s failed - %s ! \n",
4874 fname1, nt_errstr(status));
4877 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4878 printf("Renamed file %s has wrong attr 0x%x "
4879 "(should be 0x%x)\n",
4882 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4885 printf("Renamed file %s has archive bit set\n", fname1);
4889 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4890 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4892 if (!torture_close_connection(cli1)) {
4899 static bool run_pipe_number(int dummy)
4901 struct cli_state *cli1;
4902 const char *pipe_name = "\\SPOOLSS";
4907 printf("starting pipenumber test\n");
4908 if (!torture_open_connection(&cli1, 0)) {
4912 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4914 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4915 FILE_ATTRIBUTE_NORMAL,
4916 FILE_SHARE_READ|FILE_SHARE_WRITE,
4917 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4918 if (!NT_STATUS_IS_OK(status)) {
4919 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4923 printf("\r%6d", num_pipes);
4926 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4927 torture_close_connection(cli1);
4932 Test open mode returns on read-only files.
4934 static bool run_opentest(int dummy)
4936 static struct cli_state *cli1;
4937 static struct cli_state *cli2;
4938 const char *fname = "\\readonly.file";
4939 uint16_t fnum1, fnum2;
4942 bool correct = True;
4946 printf("starting open test\n");
4948 if (!torture_open_connection(&cli1, 0)) {
4952 cli_setatr(cli1, fname, 0, 0);
4953 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4955 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4957 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4958 if (!NT_STATUS_IS_OK(status)) {
4959 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4963 status = cli_close(cli1, fnum1);
4964 if (!NT_STATUS_IS_OK(status)) {
4965 printf("close2 failed (%s)\n", nt_errstr(status));
4969 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4970 if (!NT_STATUS_IS_OK(status)) {
4971 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4975 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4976 if (!NT_STATUS_IS_OK(status)) {
4977 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4981 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4982 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4984 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4985 NT_STATUS_ACCESS_DENIED)) {
4986 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4989 printf("finished open test 1\n");
4991 cli_close(cli1, fnum1);
4993 /* Now try not readonly and ensure ERRbadshare is returned. */
4995 cli_setatr(cli1, fname, 0, 0);
4997 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4998 if (!NT_STATUS_IS_OK(status)) {
4999 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5003 /* This will fail - but the error should be ERRshare. */
5004 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5006 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5007 NT_STATUS_SHARING_VIOLATION)) {
5008 printf("correct error code ERRDOS/ERRbadshare returned\n");
5011 status = cli_close(cli1, fnum1);
5012 if (!NT_STATUS_IS_OK(status)) {
5013 printf("close2 failed (%s)\n", nt_errstr(status));
5017 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5019 printf("finished open test 2\n");
5021 /* Test truncate open disposition on file opened for read. */
5022 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5023 if (!NT_STATUS_IS_OK(status)) {
5024 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5028 /* write 20 bytes. */
5030 memset(buf, '\0', 20);
5032 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5033 if (!NT_STATUS_IS_OK(status)) {
5034 printf("write failed (%s)\n", nt_errstr(status));
5038 status = cli_close(cli1, fnum1);
5039 if (!NT_STATUS_IS_OK(status)) {
5040 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5044 /* Ensure size == 20. */
5045 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5046 if (!NT_STATUS_IS_OK(status)) {
5047 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5052 printf("(3) file size != 20\n");
5056 /* Now test if we can truncate a file opened for readonly. */
5057 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5058 if (!NT_STATUS_IS_OK(status)) {
5059 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5063 status = cli_close(cli1, fnum1);
5064 if (!NT_STATUS_IS_OK(status)) {
5065 printf("close2 failed (%s)\n", nt_errstr(status));
5069 /* Ensure size == 0. */
5070 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5071 if (!NT_STATUS_IS_OK(status)) {
5072 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5077 printf("(3) file size != 0\n");
5080 printf("finished open test 3\n");
5082 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5084 printf("Do ctemp tests\n");
5085 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5086 if (!NT_STATUS_IS_OK(status)) {
5087 printf("ctemp failed (%s)\n", nt_errstr(status));
5091 printf("ctemp gave path %s\n", tmp_path);
5092 status = cli_close(cli1, fnum1);
5093 if (!NT_STATUS_IS_OK(status)) {
5094 printf("close of temp failed (%s)\n", nt_errstr(status));
5097 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5098 if (!NT_STATUS_IS_OK(status)) {
5099 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5102 /* Test the non-io opens... */
5104 if (!torture_open_connection(&cli2, 1)) {
5108 cli_setatr(cli2, fname, 0, 0);
5109 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5111 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5113 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5114 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5115 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5116 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5117 if (!NT_STATUS_IS_OK(status)) {
5118 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5122 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5123 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5124 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5125 if (!NT_STATUS_IS_OK(status)) {
5126 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5130 status = cli_close(cli1, fnum1);
5131 if (!NT_STATUS_IS_OK(status)) {
5132 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5136 status = cli_close(cli2, fnum2);
5137 if (!NT_STATUS_IS_OK(status)) {
5138 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5142 printf("non-io open test #1 passed.\n");
5144 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5146 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5148 status = cli_ntcreate(cli1, fname, 0,
5149 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5150 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5151 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5152 if (!NT_STATUS_IS_OK(status)) {
5153 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5157 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5158 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5159 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5160 if (!NT_STATUS_IS_OK(status)) {
5161 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5165 status = cli_close(cli1, fnum1);
5166 if (!NT_STATUS_IS_OK(status)) {
5167 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5171 status = cli_close(cli2, fnum2);
5172 if (!NT_STATUS_IS_OK(status)) {
5173 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5177 printf("non-io open test #2 passed.\n");
5179 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5181 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5183 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5184 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5185 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5186 if (!NT_STATUS_IS_OK(status)) {
5187 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5191 status = cli_ntcreate(cli2, fname, 0,
5192 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5193 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5194 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5195 if (!NT_STATUS_IS_OK(status)) {
5196 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5200 status = cli_close(cli1, fnum1);
5201 if (!NT_STATUS_IS_OK(status)) {
5202 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5206 status = cli_close(cli2, fnum2);
5207 if (!NT_STATUS_IS_OK(status)) {
5208 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5212 printf("non-io open test #3 passed.\n");
5214 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5216 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5218 status = cli_ntcreate(cli1, fname, 0,
5219 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5220 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5221 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5222 if (!NT_STATUS_IS_OK(status)) {
5223 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5227 status = cli_ntcreate(cli2, fname, 0,
5228 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5229 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5230 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5231 if (NT_STATUS_IS_OK(status)) {
5232 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5236 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5238 status = cli_close(cli1, fnum1);
5239 if (!NT_STATUS_IS_OK(status)) {
5240 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5244 printf("non-io open test #4 passed.\n");
5246 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5248 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5250 status = cli_ntcreate(cli1, fname, 0,
5251 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5252 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5253 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5254 if (!NT_STATUS_IS_OK(status)) {
5255 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5259 status = cli_ntcreate(cli2, fname, 0,
5260 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5261 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5262 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5263 if (!NT_STATUS_IS_OK(status)) {
5264 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5268 status = cli_close(cli1, fnum1);
5269 if (!NT_STATUS_IS_OK(status)) {
5270 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5274 status = cli_close(cli2, fnum2);
5275 if (!NT_STATUS_IS_OK(status)) {
5276 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5280 printf("non-io open test #5 passed.\n");
5282 printf("TEST #6 testing 1 non-io open, one io open\n");
5284 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5286 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5287 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5288 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5289 if (!NT_STATUS_IS_OK(status)) {
5290 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5294 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5295 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5296 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5297 if (!NT_STATUS_IS_OK(status)) {
5298 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5302 status = cli_close(cli1, fnum1);
5303 if (!NT_STATUS_IS_OK(status)) {
5304 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5308 status = cli_close(cli2, fnum2);
5309 if (!NT_STATUS_IS_OK(status)) {
5310 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5314 printf("non-io open test #6 passed.\n");
5316 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5318 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5320 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5321 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5322 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5323 if (!NT_STATUS_IS_OK(status)) {
5324 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5328 status = cli_ntcreate(cli2, fname, 0,
5329 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5330 FILE_ATTRIBUTE_NORMAL,
5331 FILE_SHARE_READ|FILE_SHARE_DELETE,
5332 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5333 if (NT_STATUS_IS_OK(status)) {
5334 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5338 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5340 status = cli_close(cli1, fnum1);
5341 if (!NT_STATUS_IS_OK(status)) {
5342 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5346 printf("non-io open test #7 passed.\n");
5348 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5350 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5351 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5352 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5353 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5354 if (!NT_STATUS_IS_OK(status)) {
5355 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5360 /* Write to ensure we have to update the file time. */
5361 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5363 if (!NT_STATUS_IS_OK(status)) {
5364 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5369 status = cli_close(cli1, fnum1);
5370 if (!NT_STATUS_IS_OK(status)) {
5371 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5377 if (!torture_close_connection(cli1)) {
5380 if (!torture_close_connection(cli2)) {
5387 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5389 uint16_t major, minor;
5390 uint32_t caplow, caphigh;
5393 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5394 printf("Server doesn't support UNIX CIFS extensions.\n");
5395 return NT_STATUS_NOT_SUPPORTED;
5398 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5400 if (!NT_STATUS_IS_OK(status)) {
5401 printf("Server didn't return UNIX CIFS extensions: %s\n",
5406 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5408 if (!NT_STATUS_IS_OK(status)) {
5409 printf("Server doesn't support setting UNIX CIFS extensions: "
5410 "%s.\n", nt_errstr(status));
5414 return NT_STATUS_OK;
5418 Test POSIX open /mkdir calls.
5420 static bool run_simple_posix_open_test(int dummy)
5422 static struct cli_state *cli1;
5423 const char *fname = "posix:file";
5424 const char *hname = "posix:hlink";
5425 const char *sname = "posix:symlink";
5426 const char *dname = "posix:dir";
5429 uint16_t fnum1 = (uint16_t)-1;
5430 SMB_STRUCT_STAT sbuf;
5431 bool correct = false;
5434 const char *fname_windows = "windows_file";
5435 uint16_t fnum2 = (uint16_t)-1;
5437 printf("Starting simple POSIX open test\n");
5439 if (!torture_open_connection(&cli1, 0)) {
5443 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5445 status = torture_setup_unix_extensions(cli1);
5446 if (!NT_STATUS_IS_OK(status)) {
5450 cli_setatr(cli1, fname, 0, 0);
5451 cli_posix_unlink(cli1, fname);
5452 cli_setatr(cli1, dname, 0, 0);
5453 cli_posix_rmdir(cli1, dname);
5454 cli_setatr(cli1, hname, 0, 0);
5455 cli_posix_unlink(cli1, hname);
5456 cli_setatr(cli1, sname, 0, 0);
5457 cli_posix_unlink(cli1, sname);
5458 cli_setatr(cli1, fname_windows, 0, 0);
5459 cli_posix_unlink(cli1, fname_windows);
5461 /* Create a directory. */
5462 status = cli_posix_mkdir(cli1, dname, 0777);
5463 if (!NT_STATUS_IS_OK(status)) {
5464 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5468 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5470 if (!NT_STATUS_IS_OK(status)) {
5471 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5475 /* Test ftruncate - set file size. */
5476 status = cli_ftruncate(cli1, fnum1, 1000);
5477 if (!NT_STATUS_IS_OK(status)) {
5478 printf("ftruncate failed (%s)\n", nt_errstr(status));
5482 /* Ensure st_size == 1000 */
5483 status = cli_posix_stat(cli1, fname, &sbuf);
5484 if (!NT_STATUS_IS_OK(status)) {
5485 printf("stat failed (%s)\n", nt_errstr(status));
5489 if (sbuf.st_ex_size != 1000) {
5490 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5494 /* Ensure st_mode == 0600 */
5495 if ((sbuf.st_ex_mode & 07777) != 0600) {
5496 printf("posix_open - bad permissions 0%o != 0600\n",
5497 (unsigned int)(sbuf.st_ex_mode & 07777));
5501 /* Test ftruncate - set file size back to zero. */
5502 status = cli_ftruncate(cli1, fnum1, 0);
5503 if (!NT_STATUS_IS_OK(status)) {
5504 printf("ftruncate failed (%s)\n", nt_errstr(status));
5508 status = cli_close(cli1, fnum1);
5509 if (!NT_STATUS_IS_OK(status)) {
5510 printf("close failed (%s)\n", nt_errstr(status));
5514 /* Now open the file again for read only. */
5515 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5516 if (!NT_STATUS_IS_OK(status)) {
5517 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5521 /* Now unlink while open. */
5522 status = cli_posix_unlink(cli1, fname);
5523 if (!NT_STATUS_IS_OK(status)) {
5524 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5528 status = cli_close(cli1, fnum1);
5529 if (!NT_STATUS_IS_OK(status)) {
5530 printf("close(2) failed (%s)\n", nt_errstr(status));
5534 /* Ensure the file has gone. */
5535 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5536 if (NT_STATUS_IS_OK(status)) {
5537 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5541 /* Create again to test open with O_TRUNC. */
5542 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5543 if (!NT_STATUS_IS_OK(status)) {
5544 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5548 /* Test ftruncate - set file size. */
5549 status = cli_ftruncate(cli1, fnum1, 1000);
5550 if (!NT_STATUS_IS_OK(status)) {
5551 printf("ftruncate failed (%s)\n", nt_errstr(status));
5555 /* Ensure st_size == 1000 */
5556 status = cli_posix_stat(cli1, fname, &sbuf);
5557 if (!NT_STATUS_IS_OK(status)) {
5558 printf("stat failed (%s)\n", nt_errstr(status));
5562 if (sbuf.st_ex_size != 1000) {
5563 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5567 status = cli_close(cli1, fnum1);
5568 if (!NT_STATUS_IS_OK(status)) {
5569 printf("close(2) failed (%s)\n", nt_errstr(status));
5573 /* Re-open with O_TRUNC. */
5574 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5575 if (!NT_STATUS_IS_OK(status)) {
5576 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5580 /* Ensure st_size == 0 */
5581 status = cli_posix_stat(cli1, fname, &sbuf);
5582 if (!NT_STATUS_IS_OK(status)) {
5583 printf("stat failed (%s)\n", nt_errstr(status));
5587 if (sbuf.st_ex_size != 0) {
5588 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5592 status = cli_close(cli1, fnum1);
5593 if (!NT_STATUS_IS_OK(status)) {
5594 printf("close failed (%s)\n", nt_errstr(status));
5598 status = cli_posix_unlink(cli1, fname);
5599 if (!NT_STATUS_IS_OK(status)) {
5600 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5604 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5605 if (!NT_STATUS_IS_OK(status)) {
5606 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5607 dname, nt_errstr(status));
5611 cli_close(cli1, fnum1);
5613 /* What happens when we try and POSIX open a directory for write ? */
5614 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5615 if (NT_STATUS_IS_OK(status)) {
5616 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5619 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5620 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5625 /* Create the file. */
5626 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5628 if (!NT_STATUS_IS_OK(status)) {
5629 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5633 /* Write some data into it. */
5634 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5636 if (!NT_STATUS_IS_OK(status)) {
5637 printf("cli_write failed: %s\n", nt_errstr(status));
5641 cli_close(cli1, fnum1);
5643 /* Now create a hardlink. */
5644 status = cli_posix_hardlink(cli1, fname, hname);
5645 if (!NT_STATUS_IS_OK(status)) {
5646 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5650 /* Now create a symlink. */
5651 status = cli_posix_symlink(cli1, fname, sname);
5652 if (!NT_STATUS_IS_OK(status)) {
5653 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5657 /* Open the hardlink for read. */
5658 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5659 if (!NT_STATUS_IS_OK(status)) {
5660 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5664 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5665 if (!NT_STATUS_IS_OK(status)) {
5666 printf("POSIX read of %s failed (%s)\n", hname,
5669 } else if (nread != 10) {
5670 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5671 hname, (unsigned long)nread, 10);
5675 if (memcmp(buf, "TEST DATA\n", 10)) {
5676 printf("invalid data read from hardlink\n");
5680 /* Do a POSIX lock/unlock. */
5681 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5682 if (!NT_STATUS_IS_OK(status)) {
5683 printf("POSIX lock failed %s\n", nt_errstr(status));
5687 /* Punch a hole in the locked area. */
5688 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5689 if (!NT_STATUS_IS_OK(status)) {
5690 printf("POSIX unlock failed %s\n", nt_errstr(status));
5694 cli_close(cli1, fnum1);
5696 /* Open the symlink for read - this should fail. A POSIX
5697 client should not be doing opens on a symlink. */
5698 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5699 if (NT_STATUS_IS_OK(status)) {
5700 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5703 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5704 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5705 printf("POSIX open of %s should have failed "
5706 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5707 "failed with %s instead.\n",
5708 sname, nt_errstr(status));
5713 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5714 if (!NT_STATUS_IS_OK(status)) {
5715 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5719 if (strcmp(namebuf, fname) != 0) {
5720 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5721 sname, fname, namebuf);
5725 status = cli_posix_rmdir(cli1, dname);
5726 if (!NT_STATUS_IS_OK(status)) {
5727 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5731 /* Check directory opens with a specific permission. */
5732 status = cli_posix_mkdir(cli1, dname, 0700);
5733 if (!NT_STATUS_IS_OK(status)) {
5734 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5738 /* Ensure st_mode == 0700 */
5739 status = cli_posix_stat(cli1, dname, &sbuf);
5740 if (!NT_STATUS_IS_OK(status)) {
5741 printf("stat failed (%s)\n", nt_errstr(status));
5745 if ((sbuf.st_ex_mode & 07777) != 0700) {
5746 printf("posix_mkdir - bad permissions 0%o != 0700\n",
5747 (unsigned int)(sbuf.st_ex_mode & 07777));
5752 * Now create a Windows file, and attempt a POSIX unlink.
5753 * This should fail with a sharing violation but due to:
5755 * [Bug 9571] Unlink after open causes smbd to panic
5757 * ensure we've fixed the lock ordering violation.
5760 status = cli_ntcreate(cli1, fname_windows, 0,
5761 FILE_READ_DATA|FILE_WRITE_DATA, 0,
5762 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5764 0x0, 0x0, &fnum2, NULL);
5765 if (!NT_STATUS_IS_OK(status)) {
5766 printf("Windows create of %s failed (%s)\n", fname_windows,
5771 /* Now try posix_unlink. */
5772 status = cli_posix_unlink(cli1, fname_windows);
5773 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
5774 printf("POSIX unlink of %s should fail "
5775 "with NT_STATUS_SHARING_VIOLATION "
5776 "got %s instead !\n",
5782 cli_close(cli1, fnum2);
5784 printf("Simple POSIX open test passed\n");
5789 if (fnum1 != (uint16_t)-1) {
5790 cli_close(cli1, fnum1);
5791 fnum1 = (uint16_t)-1;
5794 if (fnum2 != (uint16_t)-1) {
5795 cli_close(cli1, fnum2);
5796 fnum2 = (uint16_t)-1;
5799 cli_setatr(cli1, sname, 0, 0);
5800 cli_posix_unlink(cli1, sname);
5801 cli_setatr(cli1, hname, 0, 0);
5802 cli_posix_unlink(cli1, hname);
5803 cli_setatr(cli1, fname, 0, 0);
5804 cli_posix_unlink(cli1, fname);
5805 cli_setatr(cli1, dname, 0, 0);
5806 cli_posix_rmdir(cli1, dname);
5807 cli_setatr(cli1, fname_windows, 0, 0);
5808 cli_posix_unlink(cli1, fname_windows);
5810 if (!torture_close_connection(cli1)) {
5818 Test POSIX and Windows ACLs are rejected on symlinks.
5820 static bool run_acl_symlink_test(int dummy)
5822 static struct cli_state *cli;
5823 const char *fname = "posix_file";
5824 const char *sname = "posix_symlink";
5825 uint16_t fnum = (uint16_t)-1;
5826 bool correct = false;
5828 char *posix_acl = NULL;
5829 size_t posix_acl_len = 0;
5830 char *posix_acl_sym = NULL;
5831 size_t posix_acl_len_sym = 0;
5832 struct security_descriptor *sd = NULL;
5833 struct security_descriptor *sd_sym = NULL;
5834 TALLOC_CTX *frame = NULL;
5836 frame = talloc_stackframe();
5838 printf("Starting acl symlink test\n");
5840 if (!torture_open_connection(&cli, 0)) {
5845 smbXcli_conn_set_sockopt(cli->conn, sockops);
5847 status = torture_setup_unix_extensions(cli);
5848 if (!NT_STATUS_IS_OK(status)) {
5853 cli_setatr(cli, fname, 0, 0);
5854 cli_posix_unlink(cli, fname);
5855 cli_setatr(cli, sname, 0, 0);
5856 cli_posix_unlink(cli, sname);
5858 status = cli_ntcreate(cli,
5861 READ_CONTROL_ACCESS,
5863 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5870 if (!NT_STATUS_IS_OK(status)) {
5871 printf("cli_ntcreate of %s failed (%s)\n",
5877 /* Get the Windows ACL on the file. */
5878 status = cli_query_secdesc(cli,
5882 if (!NT_STATUS_IS_OK(status)) {
5883 printf("cli_query_secdesc failed (%s)\n",
5888 /* Get the POSIX ACL on the file. */
5889 status = cli_posix_getacl(cli,
5895 if (!NT_STATUS_IS_OK(status)) {
5896 printf("cli_posix_getacl failed (%s)\n",
5901 status = cli_close(cli, fnum);
5902 if (!NT_STATUS_IS_OK(status)) {
5903 printf("close failed (%s)\n", nt_errstr(status));
5906 fnum = (uint16_t)-1;
5908 /* Now create a symlink. */
5909 status = cli_posix_symlink(cli, fname, sname);
5910 if (!NT_STATUS_IS_OK(status)) {
5911 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
5918 /* Open a handle on the symlink. */
5919 status = cli_ntcreate(cli,
5922 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
5924 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5931 if (!NT_STATUS_IS_OK(status)) {
5932 printf("cli_posix_open of %s failed (%s)\n",
5938 /* Get the Windows ACL on the symlink handle. Should fail */
5939 status = cli_query_secdesc(cli,
5944 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5945 printf("cli_query_secdesc on a symlink gave %s. "
5946 "Should be NT_STATUS_ACCESS_DENIED.\n",
5951 /* Get the POSIX ACL on the symlink pathname. Should fail. */
5952 status = cli_posix_getacl(cli,
5958 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5959 printf("cli_posix_getacl on a symlink gave %s. "
5960 "Should be NT_STATUS_ACCESS_DENIED.\n",
5965 /* Set the Windows ACL on the symlink handle. Should fail */
5966 status = cli_set_security_descriptor(cli,
5971 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5972 printf("cli_query_secdesc on a symlink gave %s. "
5973 "Should be NT_STATUS_ACCESS_DENIED.\n",
5978 /* Set the POSIX ACL on the symlink pathname. Should fail. */
5979 status = cli_posix_setacl(cli,
5984 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5985 printf("cli_posix_getacl on a symlink gave %s. "
5986 "Should be NT_STATUS_ACCESS_DENIED.\n",
5991 printf("ACL symlink test passed\n");
5996 if (fnum != (uint16_t)-1) {
5997 cli_close(cli, fnum);
5998 fnum = (uint16_t)-1;
6001 cli_setatr(cli, sname, 0, 0);
6002 cli_posix_unlink(cli, sname);
6003 cli_setatr(cli, fname, 0, 0);
6004 cli_posix_unlink(cli, fname);
6006 if (!torture_close_connection(cli)) {
6015 Test POSIX can delete a file containing streams.
6017 static bool run_posix_stream_delete(int dummy)
6019 struct cli_state *cli1 = NULL;
6020 struct cli_state *cli2 = NULL;
6021 const char *fname = "streamfile";
6022 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6023 uint16_t fnum1 = (uint16_t)-1;
6024 bool correct = false;
6026 TALLOC_CTX *frame = NULL;
6028 frame = talloc_stackframe();
6030 printf("Starting POSIX stream delete test\n");
6032 if (!torture_open_connection(&cli1, 0) ||
6033 !torture_open_connection(&cli2, 1)) {
6038 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6039 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6041 status = torture_setup_unix_extensions(cli2);
6042 if (!NT_STATUS_IS_OK(status)) {
6046 cli_setatr(cli1, fname, 0, 0);
6047 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6049 /* Create the file. */
6050 status = cli_ntcreate(cli1,
6053 READ_CONTROL_ACCESS,
6055 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6062 if (!NT_STATUS_IS_OK(status)) {
6063 printf("cli_ntcreate of %s failed (%s)\n",
6069 status = cli_close(cli1, fnum1);
6070 if (!NT_STATUS_IS_OK(status)) {
6071 printf("cli_close of %s failed (%s)\n",
6076 fnum1 = (uint16_t)-1;
6078 /* Now create the stream. */
6079 status = cli_ntcreate(cli1,
6084 FILE_SHARE_READ|FILE_SHARE_WRITE,
6091 if (!NT_STATUS_IS_OK(status)) {
6092 printf("cli_ntcreate of %s failed (%s)\n",
6098 /* Leave the stream handle open... */
6100 /* POSIX unlink should fail. */
6101 status = cli_posix_unlink(cli2, fname);
6102 if (NT_STATUS_IS_OK(status)) {
6103 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6108 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6109 printf("cli_posix_unlink of %s failed with (%s) "
6110 "should have been NT_STATUS_SHARING_VIOLATION\n",
6116 /* Close the stream handle. */
6117 status = cli_close(cli1, fnum1);
6118 if (!NT_STATUS_IS_OK(status)) {
6119 printf("cli_close of %s failed (%s)\n",
6124 fnum1 = (uint16_t)-1;
6126 /* POSIX unlink after stream handle closed should succeed. */
6127 status = cli_posix_unlink(cli2, fname);
6128 if (!NT_STATUS_IS_OK(status)) {
6129 printf("cli_posix_unlink of %s failed (%s)\n",
6135 printf("POSIX stream delete test passed\n");
6140 if (fnum1 != (uint16_t)-1) {
6141 cli_close(cli1, fnum1);
6142 fnum1 = (uint16_t)-1;
6145 cli_setatr(cli1, fname, 0, 0);
6146 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6148 if (!torture_close_connection(cli1)) {
6151 if (!torture_close_connection(cli2)) {
6160 Test setting EA's are rejected on symlinks.
6162 static bool run_ea_symlink_test(int dummy)
6164 static struct cli_state *cli;
6165 const char *fname = "posix_file_ea";
6166 const char *sname = "posix_symlink_ea";
6167 const char *ea_name = "testea_name";
6168 const char *ea_value = "testea_value";
6169 uint16_t fnum = (uint16_t)-1;
6170 bool correct = false;
6173 struct ea_struct *eas = NULL;
6174 TALLOC_CTX *frame = NULL;
6176 frame = talloc_stackframe();
6178 printf("Starting EA symlink test\n");
6180 if (!torture_open_connection(&cli, 0)) {
6185 smbXcli_conn_set_sockopt(cli->conn, sockops);
6187 status = torture_setup_unix_extensions(cli);
6188 if (!NT_STATUS_IS_OK(status)) {
6193 cli_setatr(cli, fname, 0, 0);
6194 cli_posix_unlink(cli, fname);
6195 cli_setatr(cli, sname, 0, 0);
6196 cli_posix_unlink(cli, sname);
6198 status = cli_ntcreate(cli,
6201 READ_CONTROL_ACCESS,
6203 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6210 if (!NT_STATUS_IS_OK(status)) {
6211 printf("cli_ntcreate of %s failed (%s)\n",
6217 status = cli_close(cli, fnum);
6218 if (!NT_STATUS_IS_OK(status)) {
6219 printf("close failed (%s)\n",
6223 fnum = (uint16_t)-1;
6225 /* Set an EA on the path. */
6226 status = cli_set_ea_path(cli,
6230 strlen(ea_value)+1);
6232 if (!NT_STATUS_IS_OK(status)) {
6233 printf("cli_set_ea_path failed (%s)\n",
6238 /* Now create a symlink. */
6239 status = cli_posix_symlink(cli, fname, sname);
6240 if (!NT_STATUS_IS_OK(status)) {
6241 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6248 /* Get the EA list on the path. Should return value set. */
6249 status = cli_get_ea_list_path(cli,
6255 if (!NT_STATUS_IS_OK(status)) {
6256 printf("cli_get_ea_list_path failed (%s)\n",
6261 /* Ensure the EA we set is there. */
6262 for (i=0; i<num_eas; i++) {
6263 if (strcmp(eas[i].name, ea_name) == 0 &&
6264 eas[i].value.length == strlen(ea_value)+1 &&
6265 memcmp(eas[i].value.data,
6267 eas[i].value.length) == 0) {
6273 printf("Didn't find EA on pathname %s\n",
6281 /* Get the EA list on the symlink. Should return empty list. */
6282 status = cli_get_ea_list_path(cli,
6288 if (!NT_STATUS_IS_OK(status)) {
6289 printf("cli_get_ea_list_path failed (%s)\n",
6295 printf("cli_get_ea_list_path failed (%s)\n",
6300 /* Set an EA on the symlink. Should fail. */
6301 status = cli_set_ea_path(cli,
6305 strlen(ea_value)+1);
6307 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6308 printf("cli_set_ea_path on a symlink gave %s. "
6309 "Should be NT_STATUS_ACCESS_DENIED.\n",
6314 printf("EA symlink test passed\n");
6319 if (fnum != (uint16_t)-1) {
6320 cli_close(cli, fnum);
6321 fnum = (uint16_t)-1;
6324 cli_setatr(cli, sname, 0, 0);
6325 cli_posix_unlink(cli, sname);
6326 cli_setatr(cli, fname, 0, 0);
6327 cli_posix_unlink(cli, fname);
6329 if (!torture_close_connection(cli)) {
6338 Test POSIX locks are OFD-locks.
6340 static bool run_posix_ofd_lock_test(int dummy)
6342 static struct cli_state *cli;
6343 const char *fname = "posix_file";
6344 uint16_t fnum1 = (uint16_t)-1;
6345 uint16_t fnum2 = (uint16_t)-1;
6346 bool correct = false;
6348 TALLOC_CTX *frame = NULL;
6350 frame = talloc_stackframe();
6352 printf("Starting POSIX ofd-lock test\n");
6354 if (!torture_open_connection(&cli, 0)) {
6359 smbXcli_conn_set_sockopt(cli->conn, sockops);
6361 status = torture_setup_unix_extensions(cli);
6362 if (!NT_STATUS_IS_OK(status)) {
6367 cli_setatr(cli, fname, 0, 0);
6368 cli_posix_unlink(cli, fname);
6370 /* Open the file twice. */
6371 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
6373 if (!NT_STATUS_IS_OK(status)) {
6374 printf("First POSIX open of %s failed\n", fname);
6378 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
6379 if (!NT_STATUS_IS_OK(status)) {
6380 printf("First POSIX open of %s failed\n", fname);
6384 /* Set a 0-50 lock on fnum1. */
6385 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6386 if (!NT_STATUS_IS_OK(status)) {
6387 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
6391 /* Set a 60-100 lock on fnum2. */
6392 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
6393 if (!NT_STATUS_IS_OK(status)) {
6394 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
6398 /* close fnum1 - 0-50 lock should go away. */
6399 status = cli_close(cli, fnum1);
6400 if (!NT_STATUS_IS_OK(status)) {
6401 printf("close failed (%s)\n",
6405 fnum1 = (uint16_t)-1;
6407 /* Change the lock context. */
6408 cli_setpid(cli, cli_getpid(cli) + 1);
6410 /* Re-open fnum1. */
6411 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
6412 if (!NT_STATUS_IS_OK(status)) {
6413 printf("Third POSIX open of %s failed\n", fname);
6417 /* 60-100 lock should still be there. */
6418 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
6419 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
6420 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
6424 /* 0-50 lock should be gone. */
6425 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6426 if (!NT_STATUS_IS_OK(status)) {
6427 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
6431 printf("POSIX OFD lock test passed\n");
6436 if (fnum1 != (uint16_t)-1) {
6437 cli_close(cli, fnum1);
6438 fnum1 = (uint16_t)-1;
6440 if (fnum2 != (uint16_t)-1) {
6441 cli_close(cli, fnum2);
6442 fnum2 = (uint16_t)-1;
6445 cli_setatr(cli, fname, 0, 0);
6446 cli_posix_unlink(cli, fname);
6448 if (!torture_close_connection(cli)) {
6456 static uint32_t open_attrs_table[] = {
6457 FILE_ATTRIBUTE_NORMAL,
6458 FILE_ATTRIBUTE_ARCHIVE,
6459 FILE_ATTRIBUTE_READONLY,
6460 FILE_ATTRIBUTE_HIDDEN,
6461 FILE_ATTRIBUTE_SYSTEM,
6463 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
6464 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
6465 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
6466 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
6467 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
6468 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
6470 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
6471 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
6472 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
6473 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
6476 struct trunc_open_results {
6479 uint32_t trunc_attr;
6480 uint32_t result_attr;
6483 static struct trunc_open_results attr_results[] = {
6484 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
6485 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
6486 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
6487 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
6488 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
6489 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
6490 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6491 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6492 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
6493 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6494 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6495 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
6496 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6497 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6498 { 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 },
6499 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6500 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6501 { 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 },
6502 { 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 },
6503 { 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 },
6504 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6505 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6506 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
6507 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6508 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6509 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
6512 static bool run_openattrtest(int dummy)
6514 static struct cli_state *cli1;
6515 const char *fname = "\\openattr.file";
6517 bool correct = True;
6519 unsigned int i, j, k, l;
6522 printf("starting open attr test\n");
6524 if (!torture_open_connection(&cli1, 0)) {
6528 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6530 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
6531 cli_setatr(cli1, fname, 0, 0);
6532 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6534 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
6535 open_attrs_table[i], FILE_SHARE_NONE,
6536 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6537 if (!NT_STATUS_IS_OK(status)) {
6538 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
6542 status = cli_close(cli1, fnum1);
6543 if (!NT_STATUS_IS_OK(status)) {
6544 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
6548 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
6549 status = cli_ntcreate(cli1, fname, 0,
6550 FILE_READ_DATA|FILE_WRITE_DATA,
6551 open_attrs_table[j],
6552 FILE_SHARE_NONE, FILE_OVERWRITE,
6553 0, 0, &fnum1, NULL);
6554 if (!NT_STATUS_IS_OK(status)) {
6555 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
6556 if (attr_results[l].num == k) {
6557 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
6558 k, open_attrs_table[i],
6559 open_attrs_table[j],
6560 fname, NT_STATUS_V(status), nt_errstr(status));
6565 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6566 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
6567 k, open_attrs_table[i], open_attrs_table[j],
6572 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
6578 status = cli_close(cli1, fnum1);
6579 if (!NT_STATUS_IS_OK(status)) {
6580 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
6584 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
6585 if (!NT_STATUS_IS_OK(status)) {
6586 printf("getatr(2) failed (%s)\n", nt_errstr(status));
6591 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
6592 k, open_attrs_table[i], open_attrs_table[j], attr );
6595 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
6596 if (attr_results[l].num == k) {
6597 if (attr != attr_results[l].result_attr ||
6598 open_attrs_table[i] != attr_results[l].init_attr ||
6599 open_attrs_table[j] != attr_results[l].trunc_attr) {
6600 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
6601 open_attrs_table[i],
6602 open_attrs_table[j],
6604 attr_results[l].result_attr);
6614 cli_setatr(cli1, fname, 0, 0);
6615 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6617 printf("open attr test %s.\n", correct ? "passed" : "failed");
6619 if (!torture_close_connection(cli1)) {
6625 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
6626 const char *name, void *state)
6628 int *matched = (int *)state;
6629 if (matched != NULL) {
6632 return NT_STATUS_OK;
6636 test directory listing speed
6638 static bool run_dirtest(int dummy)
6641 static struct cli_state *cli;
6643 struct timeval core_start;
6644 bool correct = True;
6647 printf("starting directory test\n");
6649 if (!torture_open_connection(&cli, 0)) {
6653 smbXcli_conn_set_sockopt(cli->conn, sockops);
6656 for (i=0;i<torture_numops;i++) {
6658 slprintf(fname, sizeof(fname), "\\%x", (int)random());
6659 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
6660 fprintf(stderr,"Failed to open %s\n", fname);
6663 cli_close(cli, fnum);
6666 core_start = timeval_current();
6669 cli_list(cli, "a*.*", 0, list_fn, &matched);
6670 printf("Matched %d\n", matched);
6673 cli_list(cli, "b*.*", 0, list_fn, &matched);
6674 printf("Matched %d\n", matched);
6677 cli_list(cli, "xyzabc", 0, list_fn, &matched);
6678 printf("Matched %d\n", matched);
6680 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
6683 for (i=0;i<torture_numops;i++) {
6685 slprintf(fname, sizeof(fname), "\\%x", (int)random());
6686 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6689 if (!torture_close_connection(cli)) {
6693 printf("finished dirtest\n");
6698 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
6701 struct cli_state *pcli = (struct cli_state *)state;
6703 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
6705 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6706 return NT_STATUS_OK;
6708 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
6709 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6710 printf("del_fn: failed to rmdir %s\n,", fname );
6712 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
6713 printf("del_fn: failed to unlink %s\n,", fname );
6715 return NT_STATUS_OK;
6720 sees what IOCTLs are supported
6722 bool torture_ioctl_test(int dummy)
6724 static struct cli_state *cli;
6725 uint16_t device, function;
6727 const char *fname = "\\ioctl.dat";
6731 if (!torture_open_connection(&cli, 0)) {
6735 printf("starting ioctl test\n");
6737 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6739 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6740 if (!NT_STATUS_IS_OK(status)) {
6741 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
6745 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
6746 printf("ioctl device info: %s\n", nt_errstr(status));
6748 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
6749 printf("ioctl job info: %s\n", nt_errstr(status));
6751 for (device=0;device<0x100;device++) {
6752 printf("ioctl test with device = 0x%x\n", device);
6753 for (function=0;function<0x100;function++) {
6754 uint32_t code = (device<<16) | function;
6756 status = cli_raw_ioctl(cli, fnum, code, &blob);
6758 if (NT_STATUS_IS_OK(status)) {
6759 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
6761 data_blob_free(&blob);
6766 if (!torture_close_connection(cli)) {
6775 tries varients of chkpath
6777 bool torture_chkpath_test(int dummy)
6779 static struct cli_state *cli;
6784 if (!torture_open_connection(&cli, 0)) {
6788 printf("starting chkpath test\n");
6790 /* cleanup from an old run */
6791 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6792 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6793 cli_rmdir(cli, "\\chkpath.dir");
6795 status = cli_mkdir(cli, "\\chkpath.dir");
6796 if (!NT_STATUS_IS_OK(status)) {
6797 printf("mkdir1 failed : %s\n", nt_errstr(status));
6801 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
6802 if (!NT_STATUS_IS_OK(status)) {
6803 printf("mkdir2 failed : %s\n", nt_errstr(status));
6807 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
6809 if (!NT_STATUS_IS_OK(status)) {
6810 printf("open1 failed (%s)\n", nt_errstr(status));
6813 cli_close(cli, fnum);
6815 status = cli_chkpath(cli, "\\chkpath.dir");
6816 if (!NT_STATUS_IS_OK(status)) {
6817 printf("chkpath1 failed: %s\n", nt_errstr(status));
6821 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
6822 if (!NT_STATUS_IS_OK(status)) {
6823 printf("chkpath2 failed: %s\n", nt_errstr(status));
6827 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
6828 if (!NT_STATUS_IS_OK(status)) {
6829 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6830 NT_STATUS_NOT_A_DIRECTORY);
6832 printf("* chkpath on a file should fail\n");
6836 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
6837 if (!NT_STATUS_IS_OK(status)) {
6838 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
6839 NT_STATUS_OBJECT_NAME_NOT_FOUND);
6841 printf("* chkpath on a non existent file should fail\n");
6845 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6846 if (!NT_STATUS_IS_OK(status)) {
6847 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6848 NT_STATUS_OBJECT_PATH_NOT_FOUND);
6850 printf("* chkpath on a non existent component should fail\n");
6854 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6855 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6856 cli_rmdir(cli, "\\chkpath.dir");
6858 if (!torture_close_connection(cli)) {
6865 static bool run_eatest(int dummy)
6867 static struct cli_state *cli;
6868 const char *fname = "\\eatest.txt";
6869 bool correct = True;
6873 struct ea_struct *ea_list = NULL;
6874 TALLOC_CTX *mem_ctx = talloc_init("eatest");
6877 printf("starting eatest\n");
6879 if (!torture_open_connection(&cli, 0)) {
6880 talloc_destroy(mem_ctx);
6884 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6886 status = cli_ntcreate(cli, fname, 0,
6887 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6888 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6889 0x4044, 0, &fnum, NULL);
6890 if (!NT_STATUS_IS_OK(status)) {
6891 printf("open failed - %s\n", nt_errstr(status));
6892 talloc_destroy(mem_ctx);
6896 for (i = 0; i < 10; i++) {
6897 fstring ea_name, ea_val;
6899 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6900 memset(ea_val, (char)i+1, i+1);
6901 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6902 if (!NT_STATUS_IS_OK(status)) {
6903 printf("ea_set of name %s failed - %s\n", ea_name,
6905 talloc_destroy(mem_ctx);
6910 cli_close(cli, fnum);
6911 for (i = 0; i < 10; i++) {
6912 fstring ea_name, ea_val;
6914 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6915 memset(ea_val, (char)i+1, i+1);
6916 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6917 if (!NT_STATUS_IS_OK(status)) {
6918 printf("ea_set of name %s failed - %s\n", ea_name,
6920 talloc_destroy(mem_ctx);
6925 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6926 if (!NT_STATUS_IS_OK(status)) {
6927 printf("ea_get list failed - %s\n", nt_errstr(status));
6931 printf("num_eas = %d\n", (int)num_eas);
6933 if (num_eas != 20) {
6934 printf("Should be 20 EA's stored... failing.\n");
6938 for (i = 0; i < num_eas; i++) {
6939 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6940 dump_data(0, ea_list[i].value.data,
6941 ea_list[i].value.length);
6944 /* Setting EA's to zero length deletes them. Test this */
6945 printf("Now deleting all EA's - case indepenent....\n");
6948 cli_set_ea_path(cli, fname, "", "", 0);
6950 for (i = 0; i < 20; i++) {
6952 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6953 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6954 if (!NT_STATUS_IS_OK(status)) {
6955 printf("ea_set of name %s failed - %s\n", ea_name,
6957 talloc_destroy(mem_ctx);
6963 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6964 if (!NT_STATUS_IS_OK(status)) {
6965 printf("ea_get list failed - %s\n", nt_errstr(status));
6969 printf("num_eas = %d\n", (int)num_eas);
6970 for (i = 0; i < num_eas; i++) {
6971 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6972 dump_data(0, ea_list[i].value.data,
6973 ea_list[i].value.length);
6977 printf("deleting EA's failed.\n");
6981 /* Try and delete a non existent EA. */
6982 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6983 if (!NT_STATUS_IS_OK(status)) {
6984 printf("deleting non-existent EA 'foo' should succeed. %s\n",
6989 talloc_destroy(mem_ctx);
6990 if (!torture_close_connection(cli)) {
6997 static bool run_dirtest1(int dummy)
7000 static struct cli_state *cli;
7003 bool correct = True;
7005 printf("starting directory test\n");
7007 if (!torture_open_connection(&cli, 0)) {
7011 smbXcli_conn_set_sockopt(cli->conn, sockops);
7013 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7014 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7015 cli_rmdir(cli, "\\LISTDIR");
7016 cli_mkdir(cli, "\\LISTDIR");
7018 /* Create 1000 files and 1000 directories. */
7019 for (i=0;i<1000;i++) {
7021 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7022 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7023 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7024 0, 0, &fnum, NULL))) {
7025 fprintf(stderr,"Failed to open %s\n", fname);
7028 cli_close(cli, fnum);
7030 for (i=0;i<1000;i++) {
7032 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7033 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7034 fprintf(stderr,"Failed to open %s\n", fname);
7039 /* Now ensure that doing an old list sees both files and directories. */
7041 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7042 printf("num_seen = %d\n", num_seen );
7043 /* We should see 100 files + 1000 directories + . and .. */
7044 if (num_seen != 2002)
7047 /* Ensure if we have the "must have" bits we only see the
7051 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7052 printf("num_seen = %d\n", num_seen );
7053 if (num_seen != 1002)
7057 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7058 printf("num_seen = %d\n", num_seen );
7059 if (num_seen != 1000)
7062 /* Delete everything. */
7063 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7064 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7065 cli_rmdir(cli, "\\LISTDIR");
7068 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7069 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7070 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7073 if (!torture_close_connection(cli)) {
7077 printf("finished dirtest1\n");
7082 static bool run_error_map_extract(int dummy) {
7084 static struct cli_state *c_dos;
7085 static struct cli_state *c_nt;
7097 /* NT-Error connection */
7099 disable_spnego = true;
7100 if (!(c_nt = open_nbt_connection())) {
7101 disable_spnego = false;
7104 disable_spnego = false;
7106 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7109 if (!NT_STATUS_IS_OK(status)) {
7110 printf("%s rejected the NT-error negprot (%s)\n", host,
7116 status = cli_session_setup(c_nt, "", "", workgroup);
7117 if (!NT_STATUS_IS_OK(status)) {
7118 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7122 /* DOS-Error connection */
7124 disable_spnego = true;
7125 force_dos_errors = true;
7126 if (!(c_dos = open_nbt_connection())) {
7127 disable_spnego = false;
7128 force_dos_errors = false;
7131 disable_spnego = false;
7132 force_dos_errors = false;
7134 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7136 if (!NT_STATUS_IS_OK(status)) {
7137 printf("%s rejected the DOS-error negprot (%s)\n", host,
7139 cli_shutdown(c_dos);
7143 status = cli_session_setup(c_dos, "", "", workgroup);
7144 if (!NT_STATUS_IS_OK(status)) {
7145 printf("%s rejected the DOS-error initial session setup (%s)\n",
7146 host, nt_errstr(status));
7150 c_nt->map_dos_errors = false;
7151 c_dos->map_dos_errors = false;
7153 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7154 fstr_sprintf(user, "%X", error);
7156 status = cli_session_setup(c_nt, user,
7159 if (NT_STATUS_IS_OK(status)) {
7160 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7163 /* Case #1: 32-bit NT errors */
7164 if (!NT_STATUS_IS_DOS(status)) {
7167 printf("/** Dos error on NT connection! (%s) */\n",
7169 nt_status = NT_STATUS(0xc0000000);
7172 status = cli_session_setup(c_dos, user,
7175 if (NT_STATUS_IS_OK(status)) {
7176 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7179 /* Case #1: 32-bit NT errors */
7180 if (NT_STATUS_IS_DOS(status)) {
7181 printf("/** NT error on DOS connection! (%s) */\n",
7183 errnum = errclass = 0;
7185 errclass = NT_STATUS_DOS_CLASS(status);
7186 errnum = NT_STATUS_DOS_CODE(status);
7189 if (NT_STATUS_V(nt_status) != error) {
7190 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7191 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
7192 get_nt_error_c_code(talloc_tos(), nt_status));
7195 printf("\t{%s,\t%s,\t%s},\n",
7196 smb_dos_err_class(errclass),
7197 smb_dos_err_name(errclass, errnum),
7198 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7203 static bool run_sesssetup_bench(int dummy)
7205 static struct cli_state *c;
7206 const char *fname = "\\file.dat";
7211 if (!torture_open_connection(&c, 0)) {
7215 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7216 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7217 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7218 if (!NT_STATUS_IS_OK(status)) {
7219 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7223 for (i=0; i<torture_numops; i++) {
7224 status = cli_session_setup(
7228 if (!NT_STATUS_IS_OK(status)) {
7229 d_printf("(%s) cli_session_setup failed: %s\n",
7230 __location__, nt_errstr(status));
7234 d_printf("\r%d ", (int)cli_state_get_uid(c));
7236 status = cli_ulogoff(c);
7237 if (!NT_STATUS_IS_OK(status)) {
7238 d_printf("(%s) cli_ulogoff failed: %s\n",
7239 __location__, nt_errstr(status));
7247 static bool subst_test(const char *str, const char *user, const char *domain,
7248 uid_t uid, gid_t gid, const char *expected)
7253 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7255 if (strcmp(subst, expected) != 0) {
7256 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7257 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
7266 static void chain1_open_completion(struct tevent_req *req)
7270 status = cli_openx_recv(req, &fnum);
7273 d_printf("cli_openx_recv returned %s: %d\n",
7275 NT_STATUS_IS_OK(status) ? fnum : -1);
7278 static void chain1_write_completion(struct tevent_req *req)
7282 status = cli_write_andx_recv(req, &written);
7285 d_printf("cli_write_andx_recv returned %s: %d\n",
7287 NT_STATUS_IS_OK(status) ? (int)written : -1);
7290 static void chain1_close_completion(struct tevent_req *req)
7293 bool *done = (bool *)tevent_req_callback_data_void(req);
7295 status = cli_close_recv(req);
7300 d_printf("cli_close returned %s\n", nt_errstr(status));
7303 static bool run_chain1(int dummy)
7305 struct cli_state *cli1;
7306 struct tevent_context *evt = samba_tevent_context_init(NULL);
7307 struct tevent_req *reqs[3], *smbreqs[3];
7309 const char *str = "foobar";
7312 printf("starting chain1 test\n");
7313 if (!torture_open_connection(&cli1, 0)) {
7317 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7319 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
7320 O_CREAT|O_RDWR, 0, &smbreqs[0]);
7321 if (reqs[0] == NULL) return false;
7322 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
7325 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
7326 (const uint8_t *)str, 0, strlen(str)+1,
7327 smbreqs, 1, &smbreqs[1]);
7328 if (reqs[1] == NULL) return false;
7329 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
7331 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
7332 if (reqs[2] == NULL) return false;
7333 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
7335 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7336 if (!NT_STATUS_IS_OK(status)) {
7341 tevent_loop_once(evt);
7344 torture_close_connection(cli1);
7348 static void chain2_sesssetup_completion(struct tevent_req *req)
7351 status = cli_session_setup_guest_recv(req);
7352 d_printf("sesssetup returned %s\n", nt_errstr(status));
7355 static void chain2_tcon_completion(struct tevent_req *req)
7357 bool *done = (bool *)tevent_req_callback_data_void(req);
7359 status = cli_tcon_andx_recv(req);
7360 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
7364 static bool run_chain2(int dummy)
7366 struct cli_state *cli1;
7367 struct tevent_context *evt = samba_tevent_context_init(NULL);
7368 struct tevent_req *reqs[2], *smbreqs[2];
7372 printf("starting chain2 test\n");
7373 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
7374 port_to_use, SMB_SIGNING_DEFAULT, 0);
7375 if (!NT_STATUS_IS_OK(status)) {
7379 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7381 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
7383 if (reqs[0] == NULL) return false;
7384 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
7386 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
7387 "?????", NULL, 0, &smbreqs[1]);
7388 if (reqs[1] == NULL) return false;
7389 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
7391 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7392 if (!NT_STATUS_IS_OK(status)) {
7397 tevent_loop_once(evt);
7400 torture_close_connection(cli1);
7405 struct torture_createdel_state {
7406 struct tevent_context *ev;
7407 struct cli_state *cli;
7410 static void torture_createdel_created(struct tevent_req *subreq);
7411 static void torture_createdel_closed(struct tevent_req *subreq);
7413 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
7414 struct tevent_context *ev,
7415 struct cli_state *cli,
7418 struct tevent_req *req, *subreq;
7419 struct torture_createdel_state *state;
7421 req = tevent_req_create(mem_ctx, &state,
7422 struct torture_createdel_state);
7429 subreq = cli_ntcreate_send(
7430 state, ev, cli, name, 0,
7431 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
7432 FILE_ATTRIBUTE_NORMAL,
7433 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7434 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
7436 if (tevent_req_nomem(subreq, req)) {
7437 return tevent_req_post(req, ev);
7439 tevent_req_set_callback(subreq, torture_createdel_created, req);
7443 static void torture_createdel_created(struct tevent_req *subreq)
7445 struct tevent_req *req = tevent_req_callback_data(
7446 subreq, struct tevent_req);
7447 struct torture_createdel_state *state = tevent_req_data(
7448 req, struct torture_createdel_state);
7452 status = cli_ntcreate_recv(subreq, &fnum, NULL);
7453 TALLOC_FREE(subreq);
7454 if (tevent_req_nterror(req, status)) {
7455 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
7456 nt_errstr(status)));
7460 subreq = cli_close_send(state, state->ev, state->cli, fnum);
7461 if (tevent_req_nomem(subreq, req)) {
7464 tevent_req_set_callback(subreq, torture_createdel_closed, req);
7467 static void torture_createdel_closed(struct tevent_req *subreq)
7469 struct tevent_req *req = tevent_req_callback_data(
7470 subreq, struct tevent_req);
7473 status = cli_close_recv(subreq);
7474 if (tevent_req_nterror(req, status)) {
7475 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
7478 tevent_req_done(req);
7481 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
7483 return tevent_req_simple_recv_ntstatus(req);
7486 struct torture_createdels_state {
7487 struct tevent_context *ev;
7488 struct cli_state *cli;
7489 const char *base_name;
7493 struct tevent_req **reqs;
7496 static void torture_createdels_done(struct tevent_req *subreq);
7498 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
7499 struct tevent_context *ev,
7500 struct cli_state *cli,
7501 const char *base_name,
7505 struct tevent_req *req;
7506 struct torture_createdels_state *state;
7509 req = tevent_req_create(mem_ctx, &state,
7510 struct torture_createdels_state);
7516 state->base_name = talloc_strdup(state, base_name);
7517 if (tevent_req_nomem(state->base_name, req)) {
7518 return tevent_req_post(req, ev);
7520 state->num_files = MAX(num_parallel, num_files);
7522 state->received = 0;
7524 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
7525 if (tevent_req_nomem(state->reqs, req)) {
7526 return tevent_req_post(req, ev);
7529 for (i=0; i<num_parallel; i++) {
7532 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
7534 if (tevent_req_nomem(name, req)) {
7535 return tevent_req_post(req, ev);
7537 state->reqs[i] = torture_createdel_send(
7538 state->reqs, state->ev, state->cli, name);
7539 if (tevent_req_nomem(state->reqs[i], req)) {
7540 return tevent_req_post(req, ev);
7542 name = talloc_move(state->reqs[i], &name);
7543 tevent_req_set_callback(state->reqs[i],
7544 torture_createdels_done, req);
7550 static void torture_createdels_done(struct tevent_req *subreq)
7552 struct tevent_req *req = tevent_req_callback_data(
7553 subreq, struct tevent_req);
7554 struct torture_createdels_state *state = tevent_req_data(
7555 req, struct torture_createdels_state);
7556 size_t num_parallel = talloc_array_length(state->reqs);
7561 status = torture_createdel_recv(subreq);
7562 if (!NT_STATUS_IS_OK(status)){
7563 DEBUG(10, ("torture_createdel_recv returned %s\n",
7564 nt_errstr(status)));
7565 TALLOC_FREE(subreq);
7566 tevent_req_nterror(req, status);
7570 for (i=0; i<num_parallel; i++) {
7571 if (subreq == state->reqs[i]) {
7575 if (i == num_parallel) {
7576 DEBUG(10, ("received something we did not send\n"));
7577 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
7580 TALLOC_FREE(state->reqs[i]);
7582 if (state->sent >= state->num_files) {
7583 tevent_req_done(req);
7587 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
7589 if (tevent_req_nomem(name, req)) {
7592 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
7594 if (tevent_req_nomem(state->reqs[i], req)) {
7597 name = talloc_move(state->reqs[i], &name);
7598 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
7602 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
7604 return tevent_req_simple_recv_ntstatus(req);
7607 struct swallow_notify_state {
7608 struct tevent_context *ev;
7609 struct cli_state *cli;
7611 uint32_t completion_filter;
7613 bool (*fn)(uint32_t action, const char *name, void *priv);
7617 static void swallow_notify_done(struct tevent_req *subreq);
7619 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
7620 struct tevent_context *ev,
7621 struct cli_state *cli,
7623 uint32_t completion_filter,
7625 bool (*fn)(uint32_t action,
7630 struct tevent_req *req, *subreq;
7631 struct swallow_notify_state *state;
7633 req = tevent_req_create(mem_ctx, &state,
7634 struct swallow_notify_state);
7641 state->completion_filter = completion_filter;
7642 state->recursive = recursive;
7646 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
7647 0xffff, state->completion_filter,
7649 if (tevent_req_nomem(subreq, req)) {
7650 return tevent_req_post(req, ev);
7652 tevent_req_set_callback(subreq, swallow_notify_done, req);
7656 static void swallow_notify_done(struct tevent_req *subreq)
7658 struct tevent_req *req = tevent_req_callback_data(
7659 subreq, struct tevent_req);
7660 struct swallow_notify_state *state = tevent_req_data(
7661 req, struct swallow_notify_state);
7663 uint32_t i, num_changes;
7664 struct notify_change *changes;
7666 status = cli_notify_recv(subreq, state, &num_changes, &changes);
7667 TALLOC_FREE(subreq);
7668 if (!NT_STATUS_IS_OK(status)) {
7669 DEBUG(10, ("cli_notify_recv returned %s\n",
7670 nt_errstr(status)));
7671 tevent_req_nterror(req, status);
7675 for (i=0; i<num_changes; i++) {
7676 state->fn(changes[i].action, changes[i].name, state->priv);
7678 TALLOC_FREE(changes);
7680 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
7681 0xffff, state->completion_filter,
7683 if (tevent_req_nomem(subreq, req)) {
7686 tevent_req_set_callback(subreq, swallow_notify_done, req);
7689 static bool print_notifies(uint32_t action, const char *name, void *priv)
7691 if (DEBUGLEVEL > 5) {
7692 d_printf("%d %s\n", (int)action, name);
7697 static void notify_bench_done(struct tevent_req *req)
7699 int *num_finished = (int *)tevent_req_callback_data_void(req);
7703 static bool run_notify_bench(int dummy)
7705 const char *dname = "\\notify-bench";
7706 struct tevent_context *ev;
7709 struct tevent_req *req1;
7710 struct tevent_req *req2 = NULL;
7711 int i, num_unc_names;
7712 int num_finished = 0;
7714 printf("starting notify-bench test\n");
7716 if (use_multishare_conn) {
7718 unc_list = file_lines_load(multishare_conn_fname,
7719 &num_unc_names, 0, NULL);
7720 if (!unc_list || num_unc_names <= 0) {
7721 d_printf("Failed to load unc names list from '%s'\n",
7722 multishare_conn_fname);
7725 TALLOC_FREE(unc_list);
7730 ev = samba_tevent_context_init(talloc_tos());
7732 d_printf("tevent_context_init failed\n");
7736 for (i=0; i<num_unc_names; i++) {
7737 struct cli_state *cli;
7740 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
7742 if (base_fname == NULL) {
7746 if (!torture_open_connection(&cli, i)) {
7750 status = cli_ntcreate(cli, dname, 0,
7751 MAXIMUM_ALLOWED_ACCESS,
7752 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
7754 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
7757 if (!NT_STATUS_IS_OK(status)) {
7758 d_printf("Could not create %s: %s\n", dname,
7763 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
7764 FILE_NOTIFY_CHANGE_FILE_NAME |
7765 FILE_NOTIFY_CHANGE_DIR_NAME |
7766 FILE_NOTIFY_CHANGE_ATTRIBUTES |
7767 FILE_NOTIFY_CHANGE_LAST_WRITE,
7768 false, print_notifies, NULL);
7770 d_printf("Could not create notify request\n");
7774 req2 = torture_createdels_send(talloc_tos(), ev, cli,
7775 base_fname, 10, torture_numops);
7777 d_printf("Could not create createdels request\n");
7780 TALLOC_FREE(base_fname);
7782 tevent_req_set_callback(req2, notify_bench_done,
7786 while (num_finished < num_unc_names) {
7788 ret = tevent_loop_once(ev);
7790 d_printf("tevent_loop_once failed\n");
7795 if (!tevent_req_poll(req2, ev)) {
7796 d_printf("tevent_req_poll failed\n");
7799 status = torture_createdels_recv(req2);
7800 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
7805 static bool run_mangle1(int dummy)
7807 struct cli_state *cli;
7808 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
7812 time_t change_time, access_time, write_time;
7816 printf("starting mangle1 test\n");
7817 if (!torture_open_connection(&cli, 0)) {
7821 smbXcli_conn_set_sockopt(cli->conn, sockops);
7823 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7824 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7826 if (!NT_STATUS_IS_OK(status)) {
7827 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7830 cli_close(cli, fnum);
7832 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
7833 if (!NT_STATUS_IS_OK(status)) {
7834 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7838 d_printf("alt_name: %s\n", alt_name);
7840 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7841 if (!NT_STATUS_IS_OK(status)) {
7842 d_printf("cli_openx(%s) failed: %s\n", alt_name,
7846 cli_close(cli, fnum);
7848 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7849 &write_time, &size, &mode);
7850 if (!NT_STATUS_IS_OK(status)) {
7851 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7859 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7861 size_t *to_pull = (size_t *)priv;
7862 size_t thistime = *to_pull;
7864 thistime = MIN(thistime, n);
7865 if (thistime == 0) {
7869 memset(buf, 0, thistime);
7870 *to_pull -= thistime;
7874 static bool run_windows_write(int dummy)
7876 struct cli_state *cli1;
7880 const char *fname = "\\writetest.txt";
7881 struct timeval start_time;
7886 printf("starting windows_write test\n");
7887 if (!torture_open_connection(&cli1, 0)) {
7891 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7892 if (!NT_STATUS_IS_OK(status)) {
7893 printf("open failed (%s)\n", nt_errstr(status));
7897 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7899 start_time = timeval_current();
7901 for (i=0; i<torture_numops; i++) {
7903 off_t start = i * torture_blocksize;
7904 size_t to_pull = torture_blocksize - 1;
7906 status = cli_writeall(cli1, fnum, 0, &c,
7907 start + torture_blocksize - 1, 1, NULL);
7908 if (!NT_STATUS_IS_OK(status)) {
7909 printf("cli_write failed: %s\n", nt_errstr(status));
7913 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7914 null_source, &to_pull);
7915 if (!NT_STATUS_IS_OK(status)) {
7916 printf("cli_push returned: %s\n", nt_errstr(status));
7921 seconds = timeval_elapsed(&start_time);
7922 kbytes = (double)torture_blocksize * torture_numops;
7925 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7926 (double)seconds, (int)(kbytes/seconds));
7930 cli_close(cli1, fnum);
7931 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7932 torture_close_connection(cli1);
7936 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
7938 size_t max_pdu = 0x1FFFF;
7940 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
7944 if (smb1cli_conn_signing_is_active(cli->conn)) {
7948 if (smb1cli_conn_encryption_on(cli->conn)) {
7949 max_pdu = CLI_BUFFER_SIZE;
7952 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
7953 len_requested &= 0xFFFF;
7956 return MIN(len_requested,
7957 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
7960 static bool check_read_call(struct cli_state *cli,
7963 size_t len_requested)
7966 struct tevent_req *subreq = NULL;
7967 ssize_t len_read = 0;
7968 size_t len_expected = 0;
7969 struct tevent_context *ev = NULL;
7971 ev = samba_tevent_context_init(talloc_tos());
7976 subreq = cli_read_andx_send(talloc_tos(),
7983 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
7987 status = cli_read_andx_recv(subreq, &len_read, &buf);
7988 if (!NT_STATUS_IS_OK(status)) {
7989 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
7993 TALLOC_FREE(subreq);
7996 len_expected = calc_expected_return(cli, len_requested);
7998 if (len_expected > 0x10000 && len_read == 0x10000) {
7999 /* Windows servers only return a max of 0x10000,
8000 doesn't matter if you set CAP_LARGE_READX in
8001 the client sessionsetupX call or not. */
8002 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8003 (unsigned int)len_requested);
8004 } else if (len_read != len_expected) {
8005 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8006 (unsigned int)len_requested,
8007 (unsigned int)len_read,
8008 (unsigned int)len_expected);
8011 d_printf("Correct read reply.\n");
8017 /* Test large readX variants. */
8018 static bool large_readx_tests(struct cli_state *cli,
8022 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8023 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8026 /* A read of 0x10000 should return 0x10000 bytes. */
8027 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8030 /* A read of 0x10000 should return 0x10001 bytes. */
8031 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8034 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8035 the requested number of bytes. */
8036 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8039 /* A read of 1MB should return 1MB bytes (on Samba). */
8040 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
8044 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
8047 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
8050 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
8056 static bool run_large_readx(int dummy)
8058 uint8_t *buf = NULL;
8059 struct cli_state *cli1 = NULL;
8060 struct cli_state *cli2 = NULL;
8061 bool correct = false;
8062 const char *fname = "\\large_readx.dat";
8064 uint16_t fnum1 = UINT16_MAX;
8065 uint32_t normal_caps = 0;
8066 size_t file_size = 20*1024*1024;
8067 TALLOC_CTX *frame = talloc_stackframe();
8071 enum smb_signing_setting signing_setting;
8072 enum protocol_types protocol;
8076 .signing_setting = SMB_SIGNING_IF_REQUIRED,
8077 .protocol = PROTOCOL_NT1,
8079 .name = "NT1 - SIGNING_REQUIRED",
8080 .signing_setting = SMB_SIGNING_REQUIRED,
8081 .protocol = PROTOCOL_NT1,
8085 printf("starting large_readx test\n");
8087 if (!torture_open_connection(&cli1, 0)) {
8091 normal_caps = smb1cli_conn_capabilities(cli1->conn);
8093 if (!(normal_caps & CAP_LARGE_READX)) {
8094 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8095 (unsigned int)normal_caps);
8099 /* Create a file of size 4MB. */
8100 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
8101 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8102 0, 0, &fnum1, NULL);
8104 if (!NT_STATUS_IS_OK(status)) {
8105 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8109 /* Write file_size bytes. */
8110 buf = talloc_zero_array(frame, uint8_t, file_size);
8115 status = cli_writeall(cli1,
8122 if (!NT_STATUS_IS_OK(status)) {
8123 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
8127 status = cli_close(cli1, fnum1);
8128 if (!NT_STATUS_IS_OK(status)) {
8129 d_printf("cli_close failed: %s\n", nt_errstr(status));
8135 for (i=0; i < ARRAY_SIZE(runs); i++) {
8136 enum smb_signing_setting saved_signing_setting = signing_state;
8137 uint16_t fnum2 = -1;
8140 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
8142 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
8146 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
8148 signing_state = runs[i].signing_setting;
8149 cli2 = open_nbt_connection();
8150 signing_state = saved_signing_setting;
8155 status = smbXcli_negprot(cli2->conn,
8159 if (!NT_STATUS_IS_OK(status)) {
8163 status = cli_session_setup(cli2,
8167 if (!NT_STATUS_IS_OK(status)) {
8171 status = cli_tree_connect(cli2,
8175 strlen(password)+1);
8176 if (!NT_STATUS_IS_OK(status)) {
8180 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
8182 normal_caps = smb1cli_conn_capabilities(cli2->conn);
8184 if (!(normal_caps & CAP_LARGE_READX)) {
8185 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8186 (unsigned int)normal_caps);
8191 if (force_cli_encryption(cli2, share) == false) {
8194 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
8195 uint16_t major, minor;
8196 uint32_t caplow, caphigh;
8198 status = cli_unix_extensions_version(cli2,
8201 if (!NT_STATUS_IS_OK(status)) {
8206 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
8207 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
8208 0, 0, &fnum2, NULL);
8209 if (!NT_STATUS_IS_OK(status)) {
8210 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
8214 /* All reads must return less than file_size bytes. */
8215 if (!large_readx_tests(cli2, fnum2, buf)) {
8219 status = cli_close(cli2, fnum2);
8220 if (!NT_STATUS_IS_OK(status)) {
8221 d_printf("cli_close failed: %s\n", nt_errstr(status));
8226 if (!torture_close_connection(cli2)) {
8233 printf("Success on large_readx test\n");
8238 if (!torture_close_connection(cli2)) {
8244 if (fnum1 != UINT16_MAX) {
8245 status = cli_close(cli1, fnum1);
8246 if (!NT_STATUS_IS_OK(status)) {
8247 d_printf("cli_close failed: %s\n", nt_errstr(status));
8252 status = cli_unlink(cli1, fname,
8253 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8254 if (!NT_STATUS_IS_OK(status)) {
8255 printf("unlink failed (%s)\n", nt_errstr(status));
8258 if (!torture_close_connection(cli1)) {
8265 printf("finished large_readx test\n");
8269 static bool run_cli_echo(int dummy)
8271 struct cli_state *cli;
8274 printf("starting cli_echo test\n");
8275 if (!torture_open_connection(&cli, 0)) {
8278 smbXcli_conn_set_sockopt(cli->conn, sockops);
8280 status = cli_echo(cli, 5, data_blob_const("hello", 5));
8282 d_printf("cli_echo returned %s\n", nt_errstr(status));
8284 torture_close_connection(cli);
8285 return NT_STATUS_IS_OK(status);
8288 static bool run_uid_regression_test(int dummy)
8290 static struct cli_state *cli;
8293 bool correct = True;
8296 printf("starting uid regression test\n");
8298 if (!torture_open_connection(&cli, 0)) {
8302 smbXcli_conn_set_sockopt(cli->conn, sockops);
8304 /* Ok - now save then logoff our current user. */
8305 old_vuid = cli_state_get_uid(cli);
8307 status = cli_ulogoff(cli);
8308 if (!NT_STATUS_IS_OK(status)) {
8309 d_printf("(%s) cli_ulogoff failed: %s\n",
8310 __location__, nt_errstr(status));
8315 cli_state_set_uid(cli, old_vuid);
8317 /* Try an operation. */
8318 status = cli_mkdir(cli, "\\uid_reg_test");
8319 if (NT_STATUS_IS_OK(status)) {
8320 d_printf("(%s) cli_mkdir succeeded\n",
8325 /* Should be bad uid. */
8326 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
8327 NT_STATUS_USER_SESSION_DELETED)) {
8333 old_cnum = cli_state_get_tid(cli);
8335 /* Now try a SMBtdis with the invald vuid set to zero. */
8336 cli_state_set_uid(cli, 0);
8338 /* This should succeed. */
8339 status = cli_tdis(cli);
8341 if (NT_STATUS_IS_OK(status)) {
8342 d_printf("First tdis with invalid vuid should succeed.\n");
8344 d_printf("First tdis failed (%s)\n", nt_errstr(status));
8349 cli_state_set_uid(cli, old_vuid);
8350 cli_state_set_tid(cli, old_cnum);
8352 /* This should fail. */
8353 status = cli_tdis(cli);
8354 if (NT_STATUS_IS_OK(status)) {
8355 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
8359 /* Should be bad tid. */
8360 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
8361 NT_STATUS_NETWORK_NAME_DELETED)) {
8367 cli_rmdir(cli, "\\uid_reg_test");
8376 static const char *illegal_chars = "*\\/?<>|\":";
8377 static char force_shortname_chars[] = " +,.[];=\177";
8379 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
8380 const char *mask, void *state)
8382 struct cli_state *pcli = (struct cli_state *)state;
8384 NTSTATUS status = NT_STATUS_OK;
8386 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
8388 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
8389 return NT_STATUS_OK;
8391 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
8392 status = cli_rmdir(pcli, fname);
8393 if (!NT_STATUS_IS_OK(status)) {
8394 printf("del_fn: failed to rmdir %s\n,", fname );
8397 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8398 if (!NT_STATUS_IS_OK(status)) {
8399 printf("del_fn: failed to unlink %s\n,", fname );
8411 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
8412 const char *name, void *state)
8414 struct sn_state *s = (struct sn_state *)state;
8418 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
8419 i, finfo->name, finfo->short_name);
8422 if (strchr(force_shortname_chars, i)) {
8423 if (!finfo->short_name) {
8424 /* Shortname not created when it should be. */
8425 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
8426 __location__, finfo->name, i);
8429 } else if (finfo->short_name){
8430 /* Shortname created when it should not be. */
8431 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
8432 __location__, finfo->short_name, finfo->name);
8436 return NT_STATUS_OK;
8439 static bool run_shortname_test(int dummy)
8441 static struct cli_state *cli;
8442 bool correct = True;
8448 printf("starting shortname test\n");
8450 if (!torture_open_connection(&cli, 0)) {
8454 smbXcli_conn_set_sockopt(cli->conn, sockops);
8456 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
8457 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
8458 cli_rmdir(cli, "\\shortname");
8460 status = cli_mkdir(cli, "\\shortname");
8461 if (!NT_STATUS_IS_OK(status)) {
8462 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
8463 __location__, nt_errstr(status));
8468 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
8472 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
8479 for (i = 32; i < 128; i++) {
8480 uint16_t fnum = (uint16_t)-1;
8484 if (strchr(illegal_chars, i)) {
8489 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
8490 FILE_SHARE_READ|FILE_SHARE_WRITE,
8491 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
8492 if (!NT_STATUS_IS_OK(status)) {
8493 d_printf("(%s) cli_nt_create of %s failed: %s\n",
8494 __location__, fname, nt_errstr(status));
8498 cli_close(cli, fnum);
8501 status = cli_list(cli, "\\shortname\\test*.*", 0,
8502 shortname_list_fn, &s);
8503 if (s.matched != 1) {
8504 d_printf("(%s) failed to list %s: %s\n",
8505 __location__, fname, nt_errstr(status));
8510 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8511 if (!NT_STATUS_IS_OK(status)) {
8512 d_printf("(%s) failed to delete %s: %s\n",
8513 __location__, fname, nt_errstr(status));
8526 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
8527 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
8528 cli_rmdir(cli, "\\shortname");
8529 torture_close_connection(cli);
8533 static void pagedsearch_cb(struct tevent_req *req)
8536 struct tldap_message *msg;
8539 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
8540 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8541 d_printf("tldap_search_paged_recv failed: %s\n",
8542 tldap_rc2string(rc));
8545 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
8549 if (!tldap_entry_dn(msg, &dn)) {
8550 d_printf("tldap_entry_dn failed\n");
8553 d_printf("%s\n", dn);
8557 static bool run_tldap(int dummy)
8559 struct tldap_context *ld;
8563 struct sockaddr_storage addr;
8564 struct tevent_context *ev;
8565 struct tevent_req *req;
8569 if (!resolve_name(host, &addr, 0, false)) {
8570 d_printf("could not find host %s\n", host);
8573 status = open_socket_out(&addr, 389, 9999, &fd);
8574 if (!NT_STATUS_IS_OK(status)) {
8575 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
8579 ld = tldap_context_create(talloc_tos(), fd);
8582 d_printf("tldap_context_create failed\n");
8586 rc = tldap_fetch_rootdse(ld);
8587 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8588 d_printf("tldap_fetch_rootdse failed: %s\n",
8589 tldap_errstr(talloc_tos(), ld, rc));
8593 basedn = tldap_talloc_single_attribute(
8594 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
8595 if (basedn == NULL) {
8596 d_printf("no defaultNamingContext\n");
8599 d_printf("defaultNamingContext: %s\n", basedn);
8601 ev = samba_tevent_context_init(talloc_tos());
8603 d_printf("tevent_context_init failed\n");
8607 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
8608 TLDAP_SCOPE_SUB, "(objectclass=*)",
8610 NULL, 0, NULL, 0, 0, 0, 0, 5);
8612 d_printf("tldap_search_paged_send failed\n");
8615 tevent_req_set_callback(req, pagedsearch_cb, NULL);
8617 tevent_req_poll(req, ev);
8621 /* test search filters against rootDSE */
8622 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
8623 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
8625 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
8626 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
8627 talloc_tos(), NULL);
8628 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8629 d_printf("tldap_search with complex filter failed: %s\n",
8630 tldap_errstr(talloc_tos(), ld, rc));
8638 /* Torture test to ensure no regression of :
8639 https://bugzilla.samba.org/show_bug.cgi?id=7084
8642 static bool run_dir_createtime(int dummy)
8644 struct cli_state *cli;
8645 const char *dname = "\\testdir";
8646 const char *fname = "\\testdir\\testfile";
8648 struct timespec create_time;
8649 struct timespec create_time1;
8653 if (!torture_open_connection(&cli, 0)) {
8657 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8658 cli_rmdir(cli, dname);
8660 status = cli_mkdir(cli, dname);
8661 if (!NT_STATUS_IS_OK(status)) {
8662 printf("mkdir failed: %s\n", nt_errstr(status));
8666 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
8668 if (!NT_STATUS_IS_OK(status)) {
8669 printf("cli_qpathinfo2 returned %s\n",
8674 /* Sleep 3 seconds, then create a file. */
8677 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
8679 if (!NT_STATUS_IS_OK(status)) {
8680 printf("cli_openx failed: %s\n", nt_errstr(status));
8684 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
8686 if (!NT_STATUS_IS_OK(status)) {
8687 printf("cli_qpathinfo2 (2) returned %s\n",
8692 if (timespec_compare(&create_time1, &create_time)) {
8693 printf("run_dir_createtime: create time was updated (error)\n");
8695 printf("run_dir_createtime: create time was not updated (correct)\n");
8701 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8702 cli_rmdir(cli, dname);
8703 if (!torture_close_connection(cli)) {
8710 static bool run_streamerror(int dummy)
8712 struct cli_state *cli;
8713 const char *dname = "\\testdir";
8714 const char *streamname =
8715 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
8717 time_t change_time, access_time, write_time;
8719 uint16_t mode, fnum;
8722 if (!torture_open_connection(&cli, 0)) {
8726 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8727 cli_rmdir(cli, dname);
8729 status = cli_mkdir(cli, dname);
8730 if (!NT_STATUS_IS_OK(status)) {
8731 printf("mkdir failed: %s\n", nt_errstr(status));
8735 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
8736 &write_time, &size, &mode);
8737 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
8738 printf("pathinfo returned %s, expected "
8739 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8744 status = cli_ntcreate(cli, streamname, 0x16,
8745 FILE_READ_DATA|FILE_READ_EA|
8746 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
8747 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
8748 FILE_OPEN, 0, 0, &fnum, NULL);
8750 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
8751 printf("ntcreate returned %s, expected "
8752 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8758 cli_rmdir(cli, dname);
8762 struct pidtest_state {
8768 static void pid_echo_done(struct tevent_req *subreq);
8770 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
8771 struct tevent_context *ev,
8772 struct cli_state *cli)
8774 struct tevent_req *req, *subreq;
8775 struct pidtest_state *state;
8777 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
8782 SSVAL(state->vwv, 0, 1);
8783 state->data = data_blob_const("hello", 5);
8785 subreq = smb1cli_req_send(state,
8790 0, 0, /* *_flags2 */
8792 0xDEADBEEF, /* pid */
8795 ARRAY_SIZE(state->vwv), state->vwv,
8796 state->data.length, state->data.data);
8798 if (tevent_req_nomem(subreq, req)) {
8799 return tevent_req_post(req, ev);
8801 tevent_req_set_callback(subreq, pid_echo_done, req);
8805 static void pid_echo_done(struct tevent_req *subreq)
8807 struct tevent_req *req = tevent_req_callback_data(
8808 subreq, struct tevent_req);
8809 struct pidtest_state *state = tevent_req_data(
8810 req, struct pidtest_state);
8813 uint8_t *bytes = NULL;
8814 struct iovec *recv_iov = NULL;
8815 uint8_t *phdr = NULL;
8816 uint16_t pidlow = 0;
8817 uint16_t pidhigh = 0;
8818 struct smb1cli_req_expected_response expected[] = {
8820 .status = NT_STATUS_OK,
8825 status = smb1cli_req_recv(subreq, state,
8830 NULL, /* pvwv_offset */
8833 NULL, /* pbytes_offset */
8835 expected, ARRAY_SIZE(expected));
8837 TALLOC_FREE(subreq);
8839 if (!NT_STATUS_IS_OK(status)) {
8840 tevent_req_nterror(req, status);
8844 if (num_bytes != state->data.length) {
8845 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8849 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
8850 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8854 /* Check pid low/high == DEADBEEF */
8855 pidlow = SVAL(phdr, HDR_PID);
8856 if (pidlow != 0xBEEF){
8857 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
8858 (unsigned int)pidlow);
8859 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8862 pidhigh = SVAL(phdr, HDR_PIDHIGH);
8863 if (pidhigh != 0xDEAD){
8864 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
8865 (unsigned int)pidhigh);
8866 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8870 tevent_req_done(req);
8873 static NTSTATUS pid_echo_recv(struct tevent_req *req)
8875 return tevent_req_simple_recv_ntstatus(req);
8878 static bool run_pidhigh(int dummy)
8880 bool success = false;
8881 struct cli_state *cli = NULL;
8883 struct tevent_context *ev = NULL;
8884 struct tevent_req *req = NULL;
8885 TALLOC_CTX *frame = talloc_stackframe();
8887 printf("starting pid high test\n");
8888 if (!torture_open_connection(&cli, 0)) {
8891 smbXcli_conn_set_sockopt(cli->conn, sockops);
8893 ev = samba_tevent_context_init(frame);
8898 req = pid_echo_send(frame, ev, cli);
8903 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
8907 status = pid_echo_recv(req);
8908 if (NT_STATUS_IS_OK(status)) {
8909 printf("pid high test ok\n");
8916 torture_close_connection(cli);
8920 static bool run_local_substitute(int dummy)
8924 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
8925 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
8926 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
8927 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
8928 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
8929 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
8930 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
8931 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
8933 /* Different captialization rules in sub_basic... */
8935 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
8941 static bool run_local_base64(int dummy)
8946 for (i=1; i<2000; i++) {
8947 DATA_BLOB blob1, blob2;
8950 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
8952 generate_random_buffer(blob1.data, blob1.length);
8954 b64 = base64_encode_data_blob(talloc_tos(), blob1);
8956 d_fprintf(stderr, "base64_encode_data_blob failed "
8957 "for %d bytes\n", i);
8960 blob2 = base64_decode_data_blob(b64);
8963 if (data_blob_cmp(&blob1, &blob2)) {
8964 d_fprintf(stderr, "data_blob_cmp failed for %d "
8968 TALLOC_FREE(blob1.data);
8969 data_blob_free(&blob2);
8974 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
8979 static bool run_local_gencache(int dummy)
8985 struct memcache *mem;
8988 mem = memcache_init(NULL, 0);
8990 d_printf("%s: memcache_init failed\n", __location__);
8993 memcache_set_global(mem);
8995 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
8996 d_printf("%s: gencache_set() failed\n", __location__);
9000 if (!gencache_get("foo", NULL, NULL, NULL)) {
9001 d_printf("%s: gencache_get() failed\n", __location__);
9005 for (i=0; i<1000000; i++) {
9006 gencache_parse("foo", parse_fn, NULL);
9009 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9010 d_printf("%s: gencache_get() failed\n", __location__);
9015 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9016 d_printf("%s: gencache_get() failed\n", __location__);
9020 if (strcmp(val, "bar") != 0) {
9021 d_printf("%s: gencache_get() returned %s, expected %s\n",
9022 __location__, val, "bar");
9029 if (!gencache_del("foo")) {
9030 d_printf("%s: gencache_del() failed\n", __location__);
9033 if (gencache_del("foo")) {
9034 d_printf("%s: second gencache_del() succeeded\n",
9039 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
9040 d_printf("%s: gencache_get() on deleted entry "
9041 "succeeded\n", __location__);
9045 blob = data_blob_string_const_null("bar");
9046 tm = time(NULL) + 60;
9048 if (!gencache_set_data_blob("foo", &blob, tm)) {
9049 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
9053 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
9054 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
9058 if (strcmp((const char *)blob.data, "bar") != 0) {
9059 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
9060 __location__, (const char *)blob.data, "bar");
9061 data_blob_free(&blob);
9065 data_blob_free(&blob);
9067 if (!gencache_del("foo")) {
9068 d_printf("%s: gencache_del() failed\n", __location__);
9071 if (gencache_del("foo")) {
9072 d_printf("%s: second gencache_del() succeeded\n",
9077 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
9078 d_printf("%s: gencache_get_data_blob() on deleted entry "
9079 "succeeded\n", __location__);
9084 blob.data = (uint8_t *)&v;
9085 blob.length = sizeof(v);
9087 if (!gencache_set_data_blob("blob", &blob, tm)) {
9088 d_printf("%s: gencache_set_data_blob() failed\n",
9092 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
9093 d_printf("%s: gencache_get succeeded\n", __location__);
9100 static bool rbt_testval(struct db_context *db, const char *key,
9103 struct db_record *rec;
9104 TDB_DATA data = string_tdb_data(value);
9109 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
9111 d_fprintf(stderr, "fetch_locked failed\n");
9114 status = dbwrap_record_store(rec, data, 0);
9115 if (!NT_STATUS_IS_OK(status)) {
9116 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
9121 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
9123 d_fprintf(stderr, "second fetch_locked failed\n");
9127 dbvalue = dbwrap_record_get_value(rec);
9128 if ((dbvalue.dsize != data.dsize)
9129 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
9130 d_fprintf(stderr, "Got wrong data back\n");
9140 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
9142 int *count2 = (int *)private_data;
9147 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
9149 int *count2 = (int *)private_data;
9151 dbwrap_record_delete(rec);
9155 static bool run_local_rbtree(int dummy)
9157 struct db_context *db;
9164 db = db_open_rbt(NULL);
9167 d_fprintf(stderr, "db_open_rbt failed\n");
9171 for (i=0; i<1000; i++) {
9174 if (asprintf(&key, "key%ld", random()) == -1) {
9177 if (asprintf(&value, "value%ld", random()) == -1) {
9182 if (!rbt_testval(db, key, value)) {
9189 if (asprintf(&value, "value%ld", random()) == -1) {
9194 if (!rbt_testval(db, key, value)) {
9205 count = 0; count2 = 0;
9206 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
9208 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9209 if ((count != count2) || (count != 1000)) {
9212 count = 0; count2 = 0;
9213 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
9215 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9216 if ((count != count2) || (count != 1000)) {
9219 count = 0; count2 = 0;
9220 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
9222 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9223 if ((count != count2) || (count != 0)) {
9234 local test for character set functions
9236 This is a very simple test for the functionality in convert_string_error()
9238 static bool run_local_convert_string(int dummy)
9240 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
9241 const char *test_strings[2] = { "March", "M\303\244rz" };
9245 for (i=0; i<2; i++) {
9246 const char *str = test_strings[i];
9247 int len = strlen(str);
9248 size_t converted_size;
9251 memset(dst, 'X', sizeof(dst));
9253 /* first try with real source length */
9254 ret = convert_string_error(CH_UNIX, CH_UTF8,
9259 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
9263 if (converted_size != len) {
9264 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
9265 str, len, (int)converted_size);
9269 if (strncmp(str, dst, converted_size) != 0) {
9270 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
9274 if (strlen(str) != converted_size) {
9275 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
9276 (int)strlen(str), (int)converted_size);
9280 if (dst[converted_size] != 'X') {
9281 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
9285 /* now with srclen==-1, this causes the nul to be
9287 ret = convert_string_error(CH_UNIX, CH_UTF8,
9292 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
9296 if (converted_size != len+1) {
9297 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
9298 str, len, (int)converted_size);
9302 if (strncmp(str, dst, converted_size) != 0) {
9303 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
9307 if (len+1 != converted_size) {
9308 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
9309 len+1, (int)converted_size);
9313 if (dst[converted_size] != 'X') {
9314 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
9321 TALLOC_FREE(tmp_ctx);
9324 TALLOC_FREE(tmp_ctx);
9329 struct talloc_dict_test {
9333 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
9335 int *count = (int *)priv;
9340 static bool run_local_talloc_dict(int dummy)
9342 struct talloc_dict *dict;
9343 struct talloc_dict_test *t;
9344 int key, count, res;
9347 dict = talloc_dict_init(talloc_tos());
9352 t = talloc(talloc_tos(), struct talloc_dict_test);
9359 ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
9365 res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
9383 static bool run_local_string_to_sid(int dummy) {
9386 if (string_to_sid(&sid, "S--1-5-32-545")) {
9387 printf("allowing S--1-5-32-545\n");
9390 if (string_to_sid(&sid, "S-1-5-32-+545")) {
9391 printf("allowing S-1-5-32-+545\n");
9394 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")) {
9395 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
9398 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
9399 printf("allowing S-1-5-32-545-abc\n");
9402 if (string_to_sid(&sid, "S-300-5-32-545")) {
9403 printf("allowing S-300-5-32-545\n");
9406 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
9407 printf("allowing S-1-0xfffffffffffffe-32-545\n");
9410 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
9411 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
9414 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
9415 printf("could not parse S-1-0xfffffffffffe-32-545\n");
9418 if (!string_to_sid(&sid, "S-1-5-32-545")) {
9419 printf("could not parse S-1-5-32-545\n");
9422 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
9423 printf("mis-parsed S-1-5-32-545 as %s\n",
9424 sid_string_tos(&sid));
9430 static bool sid_to_string_test(const char *expected) {
9435 if (!string_to_sid(&sid, expected)) {
9436 printf("could not parse %s\n", expected);
9440 str = dom_sid_string(NULL, &sid);
9441 if (strcmp(str, expected)) {
9442 printf("Comparison failed (%s != %s)\n", str, expected);
9449 static bool run_local_sid_to_string(int dummy) {
9450 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
9452 if (!sid_to_string_test("S-1-545"))
9454 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
9459 static bool run_local_binary_to_sid(int dummy) {
9460 struct dom_sid *sid = talloc(NULL, struct dom_sid);
9461 static const uint8_t good_binary_sid[] = {
9462 0x1, /* revision number */
9464 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9465 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9466 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9467 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9468 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9469 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9470 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9471 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9472 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9473 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9474 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9475 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9476 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9477 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9478 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9479 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9482 static const uint8_t long_binary_sid[] = {
9483 0x1, /* revision number */
9485 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9486 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9487 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9488 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9489 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9490 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9491 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9492 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9493 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9494 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9495 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9496 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9497 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9498 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9499 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9500 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9501 0x1, 0x1, 0x1, 0x1, /* auth[15] */
9502 0x1, 0x1, 0x1, 0x1, /* auth[16] */
9503 0x1, 0x1, 0x1, 0x1, /* auth[17] */
9506 static const uint8_t long_binary_sid2[] = {
9507 0x1, /* revision number */
9509 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9510 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9511 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9512 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9513 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9514 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9515 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9516 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9517 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9518 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9519 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9520 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9521 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9522 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9523 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9524 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9525 0x1, 0x1, 0x1, 0x1, /* auth[15] */
9526 0x1, 0x1, 0x1, 0x1, /* auth[16] */
9527 0x1, 0x1, 0x1, 0x1, /* auth[17] */
9528 0x1, 0x1, 0x1, 0x1, /* auth[18] */
9529 0x1, 0x1, 0x1, 0x1, /* auth[19] */
9530 0x1, 0x1, 0x1, 0x1, /* auth[20] */
9531 0x1, 0x1, 0x1, 0x1, /* auth[21] */
9532 0x1, 0x1, 0x1, 0x1, /* auth[22] */
9533 0x1, 0x1, 0x1, 0x1, /* auth[23] */
9534 0x1, 0x1, 0x1, 0x1, /* auth[24] */
9535 0x1, 0x1, 0x1, 0x1, /* auth[25] */
9536 0x1, 0x1, 0x1, 0x1, /* auth[26] */
9537 0x1, 0x1, 0x1, 0x1, /* auth[27] */
9538 0x1, 0x1, 0x1, 0x1, /* auth[28] */
9539 0x1, 0x1, 0x1, 0x1, /* auth[29] */
9540 0x1, 0x1, 0x1, 0x1, /* auth[30] */
9541 0x1, 0x1, 0x1, 0x1, /* auth[31] */
9544 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
9547 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
9550 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
9556 /* Split a path name into filename and stream name components. Canonicalise
9557 * such that an implicit $DATA token is always explicit.
9559 * The "specification" of this function can be found in the
9560 * run_local_stream_name() function in torture.c, I've tried those
9561 * combinations against a W2k3 server.
9564 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
9565 char **pbase, char **pstream)
9568 char *stream = NULL;
9569 char *sname; /* stream name */
9570 const char *stype; /* stream type */
9572 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
9574 sname = strchr_m(fname, ':');
9576 if (sname == NULL) {
9577 if (pbase != NULL) {
9578 base = talloc_strdup(mem_ctx, fname);
9579 NT_STATUS_HAVE_NO_MEMORY(base);
9584 if (pbase != NULL) {
9585 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
9586 NT_STATUS_HAVE_NO_MEMORY(base);
9591 stype = strchr_m(sname, ':');
9593 if (stype == NULL) {
9594 sname = talloc_strdup(mem_ctx, sname);
9598 if (strcasecmp_m(stype, ":$DATA") != 0) {
9600 * If there is an explicit stream type, so far we only
9601 * allow $DATA. Is there anything else allowed? -- vl
9603 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
9605 return NT_STATUS_OBJECT_NAME_INVALID;
9607 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
9611 if (sname == NULL) {
9613 return NT_STATUS_NO_MEMORY;
9616 if (sname[0] == '\0') {
9618 * no stream name, so no stream
9623 if (pstream != NULL) {
9624 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
9625 if (stream == NULL) {
9628 return NT_STATUS_NO_MEMORY;
9631 * upper-case the type field
9633 (void)strupper_m(strchr_m(stream, ':')+1);
9637 if (pbase != NULL) {
9640 if (pstream != NULL) {
9643 return NT_STATUS_OK;
9646 static bool test_stream_name(const char *fname, const char *expected_base,
9647 const char *expected_stream,
9648 NTSTATUS expected_status)
9652 char *stream = NULL;
9654 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
9655 if (!NT_STATUS_EQUAL(status, expected_status)) {
9659 if (!NT_STATUS_IS_OK(status)) {
9663 if (base == NULL) goto error;
9665 if (strcmp(expected_base, base) != 0) goto error;
9667 if ((expected_stream != NULL) && (stream == NULL)) goto error;
9668 if ((expected_stream == NULL) && (stream != NULL)) goto error;
9670 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
9674 TALLOC_FREE(stream);
9678 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
9679 fname, expected_base ? expected_base : "<NULL>",
9680 expected_stream ? expected_stream : "<NULL>",
9681 nt_errstr(expected_status));
9682 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
9683 base ? base : "<NULL>", stream ? stream : "<NULL>",
9686 TALLOC_FREE(stream);
9690 static bool run_local_stream_name(int dummy)
9694 ret &= test_stream_name(
9695 "bla", "bla", NULL, NT_STATUS_OK);
9696 ret &= test_stream_name(
9697 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
9698 ret &= test_stream_name(
9699 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
9700 ret &= test_stream_name(
9701 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
9702 ret &= test_stream_name(
9703 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
9704 ret &= test_stream_name(
9705 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
9706 ret &= test_stream_name(
9707 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
9708 ret &= test_stream_name(
9709 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
9714 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
9716 if (a.length != b.length) {
9717 printf("a.length=%d != b.length=%d\n",
9718 (int)a.length, (int)b.length);
9721 if (memcmp(a.data, b.data, a.length) != 0) {
9722 printf("a.data and b.data differ\n");
9728 static bool run_local_memcache(int dummy)
9730 struct memcache *cache;
9732 DATA_BLOB d1, d2, d3;
9733 DATA_BLOB v1, v2, v3;
9735 TALLOC_CTX *mem_ctx;
9737 size_t size1, size2;
9740 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
9742 if (cache == NULL) {
9743 printf("memcache_init failed\n");
9747 d1 = data_blob_const("d1", 2);
9748 d2 = data_blob_const("d2", 2);
9749 d3 = data_blob_const("d3", 2);
9751 k1 = data_blob_const("d1", 2);
9752 k2 = data_blob_const("d2", 2);
9754 memcache_add(cache, STAT_CACHE, k1, d1);
9755 memcache_add(cache, GETWD_CACHE, k2, d2);
9757 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
9758 printf("could not find k1\n");
9761 if (!data_blob_equal(d1, v1)) {
9765 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
9766 printf("could not find k2\n");
9769 if (!data_blob_equal(d2, v2)) {
9773 memcache_add(cache, STAT_CACHE, k1, d3);
9775 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
9776 printf("could not find replaced k1\n");
9779 if (!data_blob_equal(d3, v3)) {
9783 memcache_add(cache, GETWD_CACHE, k1, d1);
9785 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
9786 printf("Did find k2, should have been purged\n");
9792 cache = memcache_init(NULL, 0);
9794 mem_ctx = talloc_init("foo");
9796 str1 = talloc_strdup(mem_ctx, "string1");
9797 str2 = talloc_strdup(mem_ctx, "string2");
9799 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
9800 data_blob_string_const("torture"), &str1);
9801 size1 = talloc_total_size(cache);
9803 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
9804 data_blob_string_const("torture"), &str2);
9805 size2 = talloc_total_size(cache);
9807 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
9809 if (size2 > size1) {
9810 printf("memcache leaks memory!\n");
9820 static void wbclient_done(struct tevent_req *req)
9823 struct winbindd_response *wb_resp;
9824 int *i = (int *)tevent_req_callback_data_void(req);
9826 wbc_err = wb_trans_recv(req, req, &wb_resp);
9829 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
9832 static bool run_wbclient_multi_ping(int dummy)
9834 struct tevent_context *ev;
9835 struct wb_context **wb_ctx;
9836 struct winbindd_request wb_req;
9837 bool result = false;
9840 BlockSignals(True, SIGPIPE);
9842 ev = tevent_context_init(talloc_tos());
9847 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
9848 if (wb_ctx == NULL) {
9852 ZERO_STRUCT(wb_req);
9853 wb_req.cmd = WINBINDD_PING;
9855 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
9857 for (i=0; i<torture_nprocs; i++) {
9858 wb_ctx[i] = wb_context_init(ev, NULL);
9859 if (wb_ctx[i] == NULL) {
9862 for (j=0; j<torture_numops; j++) {
9863 struct tevent_req *req;
9864 req = wb_trans_send(ev, ev, wb_ctx[i],
9865 (j % 2) == 0, &wb_req);
9869 tevent_req_set_callback(req, wbclient_done, &i);
9875 while (i < torture_nprocs * torture_numops) {
9876 tevent_loop_once(ev);
9885 static void getaddrinfo_finished(struct tevent_req *req)
9887 char *name = (char *)tevent_req_callback_data_void(req);
9888 struct addrinfo *ainfo;
9891 res = getaddrinfo_recv(req, &ainfo);
9893 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
9896 d_printf("gai(%s) succeeded\n", name);
9897 freeaddrinfo(ainfo);
9900 static bool run_getaddrinfo_send(int dummy)
9902 TALLOC_CTX *frame = talloc_stackframe();
9903 struct fncall_context *ctx;
9904 struct tevent_context *ev;
9905 bool result = false;
9906 const char *names[4] = { "www.samba.org", "notfound.samba.org",
9907 "www.slashdot.org", "heise.de" };
9908 struct tevent_req *reqs[4];
9911 ev = samba_tevent_context_init(frame);
9916 ctx = fncall_context_init(frame, 4);
9918 for (i=0; i<ARRAY_SIZE(names); i++) {
9919 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
9921 if (reqs[i] == NULL) {
9924 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
9925 discard_const_p(void, names[i]));
9928 for (i=0; i<ARRAY_SIZE(reqs); i++) {
9929 tevent_loop_once(ev);
9938 static bool dbtrans_inc(struct db_context *db)
9940 struct db_record *rec;
9946 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
9948 printf(__location__ "fetch_lock failed\n");
9952 value = dbwrap_record_get_value(rec);
9954 if (value.dsize != sizeof(uint32_t)) {
9955 printf(__location__ "value.dsize = %d\n",
9960 memcpy(&val, value.dptr, sizeof(val));
9963 status = dbwrap_record_store(
9964 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
9965 if (!NT_STATUS_IS_OK(status)) {
9966 printf(__location__ "store failed: %s\n",
9977 static bool run_local_dbtrans(int dummy)
9979 struct db_context *db;
9980 struct db_record *rec;
9986 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
9987 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
9990 printf("Could not open transtest.db\n");
9994 res = dbwrap_transaction_start(db);
9996 printf(__location__ "transaction_start failed\n");
10000 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10002 printf(__location__ "fetch_lock failed\n");
10006 value = dbwrap_record_get_value(rec);
10008 if (value.dptr == NULL) {
10010 status = dbwrap_record_store(
10011 rec, make_tdb_data((uint8_t *)&initial,
10014 if (!NT_STATUS_IS_OK(status)) {
10015 printf(__location__ "store returned %s\n",
10016 nt_errstr(status));
10023 res = dbwrap_transaction_commit(db);
10025 printf(__location__ "transaction_commit failed\n");
10030 uint32_t val, val2;
10033 res = dbwrap_transaction_start(db);
10035 printf(__location__ "transaction_start failed\n");
10039 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
10040 if (!NT_STATUS_IS_OK(status)) {
10041 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10042 nt_errstr(status));
10046 for (i=0; i<10; i++) {
10047 if (!dbtrans_inc(db)) {
10052 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
10053 if (!NT_STATUS_IS_OK(status)) {
10054 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10055 nt_errstr(status));
10059 if (val2 != val + 10) {
10060 printf(__location__ "val=%d, val2=%d\n",
10061 (int)val, (int)val2);
10065 printf("val2=%d\r", val2);
10067 res = dbwrap_transaction_commit(db);
10069 printf(__location__ "transaction_commit failed\n");
10079 * Just a dummy test to be run under a debugger. There's no real way
10080 * to inspect the tevent_select specific function from outside of
10084 static bool run_local_tevent_select(int dummy)
10086 struct tevent_context *ev;
10087 struct tevent_fd *fd1, *fd2;
10088 bool result = false;
10090 ev = tevent_context_init_byname(NULL, "select");
10092 d_fprintf(stderr, "tevent_context_init_byname failed\n");
10096 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
10098 d_fprintf(stderr, "tevent_add_fd failed\n");
10101 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
10103 d_fprintf(stderr, "tevent_add_fd failed\n");
10108 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
10110 d_fprintf(stderr, "tevent_add_fd failed\n");
10120 static bool run_local_hex_encode_buf(int dummy)
10126 for (i=0; i<sizeof(src); i++) {
10129 hex_encode_buf(buf, src, sizeof(src));
10130 if (strcmp(buf, "0001020304050607") != 0) {
10133 hex_encode_buf(buf, NULL, 0);
10134 if (buf[0] != '\0') {
10140 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
10162 "1001:1111:1111:1000:0:1111:1111:1111",
10171 static const char *remove_duplicate_addrs2_test_strings_result[] = {
10185 "1001:1111:1111:1000:0:1111:1111:1111"
10188 static bool run_local_remove_duplicate_addrs2(int dummy)
10190 struct ip_service test_vector[28];
10193 /* Construct the sockaddr_storage test vector. */
10194 for (i = 0; i < 28; i++) {
10195 struct addrinfo hints;
10196 struct addrinfo *res = NULL;
10199 memset(&hints, '\0', sizeof(hints));
10200 hints.ai_flags = AI_NUMERICHOST;
10201 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
10206 fprintf(stderr, "getaddrinfo failed on [%s]\n",
10207 remove_duplicate_addrs2_test_strings_vector[i]);
10210 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
10211 memcpy(&test_vector[i].ss,
10217 count = remove_duplicate_addrs2(test_vector, i);
10220 fprintf(stderr, "count wrong (%d) should be 14\n",
10225 for (i = 0; i < count; i++) {
10226 char addr[INET6_ADDRSTRLEN];
10228 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
10230 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
10231 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
10234 remove_duplicate_addrs2_test_strings_result[i]);
10239 printf("run_local_remove_duplicate_addrs2: success\n");
10243 static bool run_local_tdb_opener(int dummy)
10249 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
10250 O_RDWR|O_CREAT, 0755);
10252 perror("tdb_open failed");
10263 static bool run_local_tdb_writer(int dummy)
10269 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
10271 perror("tdb_open failed");
10275 val.dptr = (uint8_t *)&v;
10276 val.dsize = sizeof(v);
10282 ret = tdb_store(t, val, val, 0);
10284 printf("%s\n", tdb_errorstr(t));
10289 data = tdb_fetch(t, val);
10290 if (data.dptr != NULL) {
10291 SAFE_FREE(data.dptr);
10297 static double create_procs(bool (*fn)(int), bool *result)
10300 volatile pid_t *child_status;
10301 volatile bool *child_status_out;
10304 struct timeval start;
10308 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
10309 if (!child_status) {
10310 printf("Failed to setup shared memory\n");
10314 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
10315 if (!child_status_out) {
10316 printf("Failed to setup result status shared memory\n");
10320 for (i = 0; i < torture_nprocs; i++) {
10321 child_status[i] = 0;
10322 child_status_out[i] = True;
10325 start = timeval_current();
10327 for (i=0;i<torture_nprocs;i++) {
10330 pid_t mypid = getpid();
10331 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
10333 slprintf(myname,sizeof(myname),"CLIENT%d", i);
10336 if (torture_open_connection(¤t_cli, i)) break;
10337 if (tries-- == 0) {
10338 printf("pid %d failed to start\n", (int)getpid());
10344 child_status[i] = getpid();
10346 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
10348 child_status_out[i] = fn(i);
10355 for (i=0;i<torture_nprocs;i++) {
10356 if (child_status[i]) synccount++;
10358 if (synccount == torture_nprocs) break;
10360 } while (timeval_elapsed(&start) < 30);
10362 if (synccount != torture_nprocs) {
10363 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
10365 return timeval_elapsed(&start);
10368 /* start the client load */
10369 start = timeval_current();
10371 for (i=0;i<torture_nprocs;i++) {
10372 child_status[i] = 0;
10375 printf("%d clients started\n", torture_nprocs);
10377 for (i=0;i<torture_nprocs;i++) {
10378 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
10383 for (i=0;i<torture_nprocs;i++) {
10384 if (!child_status_out[i]) {
10388 return timeval_elapsed(&start);
10391 #define FLAG_MULTIPROC 1
10397 } torture_ops[] = {
10398 {"FDPASS", run_fdpasstest, 0},
10399 {"LOCK1", run_locktest1, 0},
10400 {"LOCK2", run_locktest2, 0},
10401 {"LOCK3", run_locktest3, 0},
10402 {"LOCK4", run_locktest4, 0},
10403 {"LOCK5", run_locktest5, 0},
10404 {"LOCK6", run_locktest6, 0},
10405 {"LOCK7", run_locktest7, 0},
10406 {"LOCK8", run_locktest8, 0},
10407 {"LOCK9", run_locktest9, 0},
10408 {"UNLINK", run_unlinktest, 0},
10409 {"BROWSE", run_browsetest, 0},
10410 {"ATTR", run_attrtest, 0},
10411 {"TRANS2", run_trans2test, 0},
10412 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
10413 {"TORTURE",run_torture, FLAG_MULTIPROC},
10414 {"RANDOMIPC", run_randomipc, 0},
10415 {"NEGNOWAIT", run_negprot_nowait, 0},
10416 {"NBENCH", run_nbench, 0},
10417 {"NBENCH2", run_nbench2, 0},
10418 {"OPLOCK1", run_oplock1, 0},
10419 {"OPLOCK2", run_oplock2, 0},
10420 {"OPLOCK4", run_oplock4, 0},
10421 {"DIR", run_dirtest, 0},
10422 {"DIR1", run_dirtest1, 0},
10423 {"DIR-CREATETIME", run_dir_createtime, 0},
10424 {"DENY1", torture_denytest1, 0},
10425 {"DENY2", torture_denytest2, 0},
10426 {"TCON", run_tcon_test, 0},
10427 {"TCONDEV", run_tcon_devtype_test, 0},
10428 {"RW1", run_readwritetest, 0},
10429 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
10430 {"RW3", run_readwritelarge, 0},
10431 {"RW-SIGNING", run_readwritelarge_signtest, 0},
10432 {"OPEN", run_opentest, 0},
10433 {"POSIX", run_simple_posix_open_test, 0},
10434 {"POSIX-APPEND", run_posix_append, 0},
10435 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
10436 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
10437 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
10438 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
10439 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
10440 {"ASYNC-ECHO", run_async_echo, 0},
10441 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
10442 { "SHORTNAME-TEST", run_shortname_test, 0},
10443 { "ADDRCHANGE", run_addrchange, 0},
10445 {"OPENATTR", run_openattrtest, 0},
10447 {"XCOPY", run_xcopy, 0},
10448 {"RENAME", run_rename, 0},
10449 {"DELETE", run_deletetest, 0},
10450 {"WILDDELETE", run_wild_deletetest, 0},
10451 {"DELETE-LN", run_deletetest_ln, 0},
10452 {"PROPERTIES", run_properties, 0},
10453 {"MANGLE", torture_mangle, 0},
10454 {"MANGLE1", run_mangle1, 0},
10455 {"W2K", run_w2ktest, 0},
10456 {"TRANS2SCAN", torture_trans2_scan, 0},
10457 {"NTTRANSSCAN", torture_nttrans_scan, 0},
10458 {"UTABLE", torture_utable, 0},
10459 {"CASETABLE", torture_casetable, 0},
10460 {"ERRMAPEXTRACT", run_error_map_extract, 0},
10461 {"PIPE_NUMBER", run_pipe_number, 0},
10462 {"TCON2", run_tcon2_test, 0},
10463 {"IOCTL", torture_ioctl_test, 0},
10464 {"CHKPATH", torture_chkpath_test, 0},
10465 {"FDSESS", run_fdsesstest, 0},
10466 { "EATEST", run_eatest, 0},
10467 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
10468 { "CHAIN1", run_chain1, 0},
10469 { "CHAIN2", run_chain2, 0},
10470 { "CHAIN3", run_chain3, 0},
10471 { "WINDOWS-WRITE", run_windows_write, 0},
10472 { "LARGE_READX", run_large_readx, 0},
10473 { "NTTRANS-CREATE", run_nttrans_create, 0},
10474 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
10475 { "CLI_ECHO", run_cli_echo, 0},
10476 { "GETADDRINFO", run_getaddrinfo_send, 0},
10477 { "TLDAP", run_tldap },
10478 { "STREAMERROR", run_streamerror },
10479 { "NOTIFY-BENCH", run_notify_bench },
10480 { "NOTIFY-BENCH2", run_notify_bench2 },
10481 { "NOTIFY-BENCH3", run_notify_bench3 },
10482 { "BAD-NBT-SESSION", run_bad_nbt_session },
10483 { "SMB-ANY-CONNECT", run_smb_any_connect },
10484 { "NOTIFY-ONLINE", run_notify_online },
10485 { "SMB2-BASIC", run_smb2_basic },
10486 { "SMB2-NEGPROT", run_smb2_negprot },
10487 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
10488 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
10489 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
10490 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
10491 { "CLEANUP1", run_cleanup1 },
10492 { "CLEANUP2", run_cleanup2 },
10493 { "CLEANUP3", run_cleanup3 },
10494 { "CLEANUP4", run_cleanup4 },
10495 { "OPLOCK-CANCEL", run_oplock_cancel },
10496 { "PIDHIGH", run_pidhigh },
10497 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
10498 { "LOCAL-GENCACHE", run_local_gencache, 0},
10499 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
10500 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
10501 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
10502 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
10503 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
10504 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
10505 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
10506 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
10507 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
10508 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
10509 { "LOCAL-BASE64", run_local_base64, 0},
10510 { "LOCAL-RBTREE", run_local_rbtree, 0},
10511 { "LOCAL-MEMCACHE", run_local_memcache, 0},
10512 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
10513 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
10514 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
10515 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
10516 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
10517 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
10518 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
10519 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
10520 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
10521 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
10522 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
10523 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
10524 { "local-tdb-opener", run_local_tdb_opener, 0 },
10525 { "local-tdb-writer", run_local_tdb_writer, 0 },
10526 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
10527 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
10528 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
10529 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
10533 * dummy function to satisfy linker dependency
10535 struct tevent_context *winbind_event_context(void);
10536 struct tevent_context *winbind_event_context(void)
10541 /****************************************************************************
10542 run a specified test or "ALL"
10543 ****************************************************************************/
10544 static bool run_test(const char *name)
10547 bool result = True;
10548 bool found = False;
10551 if (strequal(name,"ALL")) {
10552 for (i=0;torture_ops[i].name;i++) {
10553 run_test(torture_ops[i].name);
10558 for (i=0;torture_ops[i].name;i++) {
10559 fstr_sprintf(randomfname, "\\XX%x",
10560 (unsigned)random());
10562 if (strequal(name, torture_ops[i].name)) {
10564 printf("Running %s\n", name);
10565 if (torture_ops[i].flags & FLAG_MULTIPROC) {
10566 t = create_procs(torture_ops[i].fn, &result);
10569 printf("TEST %s FAILED!\n", name);
10572 struct timeval start;
10573 start = timeval_current();
10574 if (!torture_ops[i].fn(0)) {
10576 printf("TEST %s FAILED!\n", name);
10578 t = timeval_elapsed(&start);
10580 printf("%s took %g secs\n\n", name, t);
10585 printf("Did not find a test named %s\n", name);
10593 static void usage(void)
10597 printf("WARNING samba4 test suite is much more complete nowadays.\n");
10598 printf("Please use samba4 torture.\n\n");
10600 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
10602 printf("\t-d debuglevel\n");
10603 printf("\t-U user%%pass\n");
10604 printf("\t-k use kerberos\n");
10605 printf("\t-N numprocs\n");
10606 printf("\t-n my_netbios_name\n");
10607 printf("\t-W workgroup\n");
10608 printf("\t-o num_operations\n");
10609 printf("\t-O socket_options\n");
10610 printf("\t-m maximum protocol\n");
10611 printf("\t-L use oplocks\n");
10612 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
10613 printf("\t-A showall\n");
10614 printf("\t-p port\n");
10615 printf("\t-s seed\n");
10616 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
10617 printf("\t-f filename filename to test\n");
10618 printf("\t-e encrypt\n");
10621 printf("tests are:");
10622 for (i=0;torture_ops[i].name;i++) {
10623 printf(" %s", torture_ops[i].name);
10627 printf("default test is ALL\n");
10632 /****************************************************************************
10634 ****************************************************************************/
10635 int main(int argc,char *argv[])
10641 bool correct = True;
10642 TALLOC_CTX *frame = talloc_stackframe();
10643 int seed = time(NULL);
10645 #ifdef HAVE_SETBUFFER
10646 setbuffer(stdout, NULL, 0);
10649 setup_logging("smbtorture", DEBUG_STDOUT);
10654 if (is_default_dyn_CONFIGFILE()) {
10655 if(getenv("SMB_CONF_PATH")) {
10656 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
10659 lp_load_global(get_dyn_CONFIGFILE());
10666 for(p = argv[1]; *p; p++)
10670 if (strncmp(argv[1], "//", 2)) {
10674 fstrcpy(host, &argv[1][2]);
10675 p = strchr_m(&host[2],'/');
10680 fstrcpy(share, p+1);
10682 fstrcpy(myname, get_myname(talloc_tos()));
10684 fprintf(stderr, "Failed to get my hostname.\n");
10688 if (*username == 0 && getenv("LOGNAME")) {
10689 fstrcpy(username,getenv("LOGNAME"));
10695 fstrcpy(workgroup, lp_workgroup());
10697 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
10701 port_to_use = atoi(optarg);
10704 seed = atoi(optarg);
10707 fstrcpy(workgroup,optarg);
10710 lp_set_cmdline("client max protocol", optarg);
10713 torture_nprocs = atoi(optarg);
10716 torture_numops = atoi(optarg);
10719 lp_set_cmdline("log level", optarg);
10725 use_oplocks = True;
10728 local_path = optarg;
10731 torture_showall = True;
10734 fstrcpy(myname, optarg);
10737 client_txt = optarg;
10744 use_kerberos = True;
10746 d_printf("No kerberos support compiled in\n");
10752 fstrcpy(username,optarg);
10753 p = strchr_m(username,'%');
10756 fstrcpy(password, p+1);
10761 fstrcpy(multishare_conn_fname, optarg);
10762 use_multishare_conn = True;
10765 torture_blocksize = atoi(optarg);
10768 test_filename = SMB_STRDUP(optarg);
10771 printf("Unknown option %c (%d)\n", (char)opt, opt);
10776 d_printf("using seed %d\n", seed);
10780 if(use_kerberos && !gotuser) gotpass = True;
10783 char pwd[256] = {0};
10786 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
10788 fstrcpy(password, pwd);
10793 printf("host=%s share=%s user=%s myname=%s\n",
10794 host, share, username, myname);
10796 if (argc == optind) {
10797 correct = run_test("ALL");
10799 for (i=optind;i<argc;i++) {
10800 if (!run_test(argv[i])) {
10806 TALLOC_FREE(frame);