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 struct cli_credentials *torture_creds;
52 static const char *sockops="TCP_NODELAY";
54 static int port_to_use=0;
55 int torture_numops=100;
56 int torture_blocksize=1024*1024;
57 static int procnum; /* records process count number when forking */
58 static struct cli_state *current_cli;
59 static fstring randomfname;
60 static bool use_oplocks;
61 static bool use_level_II_oplocks;
62 static const char *client_txt = "client_oplocks.txt";
63 static bool disable_spnego;
64 static bool use_kerberos;
65 static bool force_dos_errors;
66 static fstring multishare_conn_fname;
67 static bool use_multishare_conn = False;
68 static bool do_encrypt;
69 static const char *local_path = NULL;
70 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
73 bool torture_showall = False;
75 static double create_procs(bool (*fn)(int), bool *result);
77 /********************************************************************
78 Ensure a connection is encrypted.
79 ********************************************************************/
81 static bool force_cli_encryption(struct cli_state *c,
82 const char *sharename)
84 uint16_t major, minor;
85 uint32_t caplow, caphigh;
88 if (!SERVER_HAS_UNIX_CIFS(c)) {
89 d_printf("Encryption required and "
90 "server that doesn't support "
91 "UNIX extensions - failing connect\n");
95 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
97 if (!NT_STATUS_IS_OK(status)) {
98 d_printf("Encryption required and "
99 "can't get UNIX CIFS extensions "
100 "version from server: %s\n", nt_errstr(status));
104 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
105 d_printf("Encryption required and "
106 "share %s doesn't support "
107 "encryption.\n", sharename);
111 status = cli_smb1_setup_encryption(c, torture_creds);
112 if (!NT_STATUS_IS_OK(status)) {
113 d_printf("Encryption required and "
114 "setup failed with error %s.\n",
123 static struct cli_state *open_nbt_connection(void)
129 if (disable_spnego) {
130 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
134 flags |= CLI_FULL_CONNECTION_OPLOCKS;
137 if (use_level_II_oplocks) {
138 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
142 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
145 if (force_dos_errors) {
146 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
149 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
150 signing_state, flags, &c);
151 if (!NT_STATUS_IS_OK(status)) {
152 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
156 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
161 /****************************************************************************
162 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
163 ****************************************************************************/
165 static bool cli_bad_session_request(int fd,
166 struct nmb_name *calling, struct nmb_name *called)
175 uint8_t message_type;
177 struct tevent_context *ev;
178 struct tevent_req *req;
180 frame = talloc_stackframe();
182 iov[0].iov_base = len_buf;
183 iov[0].iov_len = sizeof(len_buf);
185 /* put in the destination name */
187 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
189 if (iov[1].iov_base == NULL) {
192 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
193 talloc_get_size(iov[1].iov_base));
197 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
199 if (iov[2].iov_base == NULL) {
202 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
203 talloc_get_size(iov[2].iov_base));
205 /* Deliberately corrupt the name len (first byte) */
206 *((uint8_t *)iov[2].iov_base) = 100;
208 /* send a session request (RFC 1002) */
209 /* setup the packet length
210 * Remove four bytes from the length count, since the length
211 * field in the NBT Session Service header counts the number
212 * of bytes which follow. The cli_send_smb() function knows
213 * about this and accounts for those four bytes.
217 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
218 SCVAL(len_buf,0,0x81);
220 len = write_data_iov(fd, iov, 3);
225 ev = samba_tevent_context_init(frame);
229 req = read_smb_send(frame, ev, fd);
233 if (!tevent_req_poll(req, ev)) {
236 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
243 message_type = CVAL(inbuf, 0);
244 if (message_type != 0x83) {
245 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
250 if (smb_len(inbuf) != 1) {
251 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
252 (int)smb_len(inbuf));
256 error = CVAL(inbuf, 4);
258 d_fprintf(stderr, "Expected error 0x82, got %d\n",
269 /* Insert a NULL at the first separator of the given path and return a pointer
270 * to the remainder of the string.
273 terminate_path_at_separator(char * path)
281 if ((p = strchr_m(path, '/'))) {
286 if ((p = strchr_m(path, '\\'))) {
296 parse a //server/share type UNC name
298 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
299 char **hostname, char **sharename)
303 *hostname = *sharename = NULL;
305 if (strncmp(unc_name, "\\\\", 2) &&
306 strncmp(unc_name, "//", 2)) {
310 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
311 p = terminate_path_at_separator(*hostname);
314 *sharename = talloc_strdup(mem_ctx, p);
315 terminate_path_at_separator(*sharename);
318 if (*hostname && *sharename) {
322 TALLOC_FREE(*hostname);
323 TALLOC_FREE(*sharename);
327 static bool torture_open_connection_share(struct cli_state **c,
328 const char *hostname,
329 const char *sharename)
335 flags |= CLI_FULL_CONNECTION_OPLOCKS;
336 if (use_level_II_oplocks)
337 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
339 status = cli_full_connection_creds(c,
349 if (!NT_STATUS_IS_OK(status)) {
350 printf("failed to open share connection: //%s/%s port:%d - %s\n",
351 hostname, sharename, port_to_use, nt_errstr(status));
355 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
358 return force_cli_encryption(*c,
364 bool torture_open_connection(struct cli_state **c, int conn_index)
366 char **unc_list = NULL;
367 int num_unc_names = 0;
370 if (use_multishare_conn==True) {
372 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
373 if (!unc_list || num_unc_names <= 0) {
374 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
378 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
380 printf("Failed to parse UNC name %s\n",
381 unc_list[conn_index % num_unc_names]);
382 TALLOC_FREE(unc_list);
386 result = torture_open_connection_share(c, h, s);
388 /* h, s were copied earlier */
389 TALLOC_FREE(unc_list);
393 return torture_open_connection_share(c, host, share);
396 bool torture_init_connection(struct cli_state **pcli)
398 struct cli_state *cli;
400 cli = open_nbt_connection();
409 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
411 uint16_t old_vuid = cli_state_get_uid(cli);
415 cli_state_set_uid(cli, 0);
416 status = cli_session_setup_creds(cli, torture_creds);
417 ret = NT_STATUS_IS_OK(status);
418 *new_vuid = cli_state_get_uid(cli);
419 cli_state_set_uid(cli, old_vuid);
424 bool torture_close_connection(struct cli_state *c)
429 status = cli_tdis(c);
430 if (!NT_STATUS_IS_OK(status)) {
431 printf("tdis failed (%s)\n", nt_errstr(status));
441 /* check if the server produced the expected dos or nt error code */
442 static bool check_both_error(int line, NTSTATUS status,
443 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
445 if (NT_STATUS_IS_DOS(status)) {
449 /* Check DOS error */
450 cclass = NT_STATUS_DOS_CLASS(status);
451 num = NT_STATUS_DOS_CODE(status);
453 if (eclass != cclass || ecode != num) {
454 printf("unexpected error code class=%d code=%d\n",
455 (int)cclass, (int)num);
456 printf(" expected %d/%d %s (line=%d)\n",
457 (int)eclass, (int)ecode, nt_errstr(nterr), line);
462 if (!NT_STATUS_EQUAL(nterr, status)) {
463 printf("unexpected error code %s\n",
465 printf(" expected %s (line=%d)\n",
466 nt_errstr(nterr), line);
475 /* check if the server produced the expected error code */
476 static bool check_error(int line, NTSTATUS status,
477 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
479 if (NT_STATUS_IS_DOS(status)) {
483 /* Check DOS error */
485 cclass = NT_STATUS_DOS_CLASS(status);
486 num = NT_STATUS_DOS_CODE(status);
488 if (eclass != cclass || ecode != num) {
489 printf("unexpected error code class=%d code=%d\n",
490 (int)cclass, (int)num);
491 printf(" expected %d/%d %s (line=%d)\n",
492 (int)eclass, (int)ecode, nt_errstr(nterr),
500 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
501 printf("unexpected error code %s\n",
503 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
513 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
517 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
519 while (!NT_STATUS_IS_OK(status)) {
520 if (!check_both_error(__LINE__, status, ERRDOS,
521 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
525 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
532 static bool rw_torture(struct cli_state *c)
534 const char *lockfname = "\\torture.lck";
538 pid_t pid2, pid = getpid();
545 memset(buf, '\0', sizeof(buf));
547 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
549 if (!NT_STATUS_IS_OK(status)) {
550 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
552 if (!NT_STATUS_IS_OK(status)) {
553 printf("open of %s failed (%s)\n",
554 lockfname, nt_errstr(status));
558 for (i=0;i<torture_numops;i++) {
559 unsigned n = (unsigned)sys_random()%10;
562 printf("%d\r", i); fflush(stdout);
564 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
566 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
570 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
572 if (!NT_STATUS_IS_OK(status)) {
573 printf("open failed (%s)\n", nt_errstr(status));
578 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
580 if (!NT_STATUS_IS_OK(status)) {
581 printf("write failed (%s)\n", nt_errstr(status));
586 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
587 sizeof(pid)+(j*sizeof(buf)),
589 if (!NT_STATUS_IS_OK(status)) {
590 printf("write failed (%s)\n",
598 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
600 if (!NT_STATUS_IS_OK(status)) {
601 printf("read failed (%s)\n", nt_errstr(status));
603 } else if (nread != sizeof(pid)) {
604 printf("read/write compare failed: "
605 "recv %ld req %ld\n", (unsigned long)nread,
606 (unsigned long)sizeof(pid));
611 printf("data corruption!\n");
615 status = cli_close(c, fnum);
616 if (!NT_STATUS_IS_OK(status)) {
617 printf("close failed (%s)\n", nt_errstr(status));
621 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
622 if (!NT_STATUS_IS_OK(status)) {
623 printf("unlink failed (%s)\n", nt_errstr(status));
627 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
628 if (!NT_STATUS_IS_OK(status)) {
629 printf("unlock failed (%s)\n", nt_errstr(status));
635 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
642 static bool run_torture(int dummy)
644 struct cli_state *cli;
649 smbXcli_conn_set_sockopt(cli->conn, sockops);
651 ret = rw_torture(cli);
653 if (!torture_close_connection(cli)) {
660 static bool rw_torture3(struct cli_state *c, char *lockfname)
662 uint16_t fnum = (uint16_t)-1;
667 unsigned countprev = 0;
670 NTSTATUS status = NT_STATUS_OK;
673 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
675 SIVAL(buf, i, sys_random());
682 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
683 if (!NT_STATUS_IS_OK(status)) {
684 printf("unlink failed (%s) (normal, this file should "
685 "not exist)\n", nt_errstr(status));
688 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
690 if (!NT_STATUS_IS_OK(status)) {
691 printf("first open read/write of %s failed (%s)\n",
692 lockfname, nt_errstr(status));
698 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
700 status = cli_openx(c, lockfname, O_RDONLY,
702 if (NT_STATUS_IS_OK(status)) {
707 if (!NT_STATUS_IS_OK(status)) {
708 printf("second open read-only of %s failed (%s)\n",
709 lockfname, nt_errstr(status));
715 for (count = 0; count < sizeof(buf); count += sent)
717 if (count >= countprev) {
718 printf("%d %8d\r", i, count);
721 countprev += (sizeof(buf) / 20);
726 sent = ((unsigned)sys_random()%(20))+ 1;
727 if (sent > sizeof(buf) - count)
729 sent = sizeof(buf) - count;
732 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
734 if (!NT_STATUS_IS_OK(status)) {
735 printf("write failed (%s)\n",
742 status = cli_read(c, fnum, buf_rd+count, count,
743 sizeof(buf)-count, &sent);
744 if(!NT_STATUS_IS_OK(status)) {
745 printf("read failed offset:%d size:%ld (%s)\n",
746 count, (unsigned long)sizeof(buf)-count,
750 } else if (sent > 0) {
751 if (memcmp(buf_rd+count, buf+count, sent) != 0)
753 printf("read/write compare failed\n");
754 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
763 status = cli_close(c, fnum);
764 if (!NT_STATUS_IS_OK(status)) {
765 printf("close failed (%s)\n", nt_errstr(status));
772 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
774 const char *lockfname = "\\torture2.lck";
784 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
785 if (!NT_STATUS_IS_OK(status)) {
786 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
789 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
791 if (!NT_STATUS_IS_OK(status)) {
792 printf("first open read/write of %s failed (%s)\n",
793 lockfname, nt_errstr(status));
797 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
798 if (!NT_STATUS_IS_OK(status)) {
799 printf("second open read-only of %s failed (%s)\n",
800 lockfname, nt_errstr(status));
801 cli_close(c1, fnum1);
805 for (i = 0; i < torture_numops; i++)
807 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
809 printf("%d\r", i); fflush(stdout);
812 generate_random_buffer((unsigned char *)buf, buf_size);
814 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("write failed (%s)\n", nt_errstr(status));
822 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
823 if(!NT_STATUS_IS_OK(status)) {
824 printf("read failed (%s)\n", nt_errstr(status));
827 } else if (bytes_read != buf_size) {
828 printf("read failed\n");
829 printf("read %ld, expected %ld\n",
830 (unsigned long)bytes_read,
831 (unsigned long)buf_size);
836 if (memcmp(buf_rd, buf, buf_size) != 0)
838 printf("read/write compare failed\n");
844 status = cli_close(c2, fnum2);
845 if (!NT_STATUS_IS_OK(status)) {
846 printf("close failed (%s)\n", nt_errstr(status));
850 status = cli_close(c1, fnum1);
851 if (!NT_STATUS_IS_OK(status)) {
852 printf("close failed (%s)\n", nt_errstr(status));
856 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
857 if (!NT_STATUS_IS_OK(status)) {
858 printf("unlink failed (%s)\n", nt_errstr(status));
865 static bool run_readwritetest(int dummy)
867 struct cli_state *cli1, *cli2;
868 bool test1, test2 = False;
870 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
873 smbXcli_conn_set_sockopt(cli1->conn, sockops);
874 smbXcli_conn_set_sockopt(cli2->conn, sockops);
876 printf("starting readwritetest\n");
878 test1 = rw_torture2(cli1, cli2);
879 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
882 test2 = rw_torture2(cli1, cli1);
883 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
886 if (!torture_close_connection(cli1)) {
890 if (!torture_close_connection(cli2)) {
894 return (test1 && test2);
897 static bool run_readwritemulti(int dummy)
899 struct cli_state *cli;
904 smbXcli_conn_set_sockopt(cli->conn, sockops);
906 printf("run_readwritemulti: fname %s\n", randomfname);
907 test = rw_torture3(cli, randomfname);
909 if (!torture_close_connection(cli)) {
916 static bool run_readwritelarge_internal(void)
918 static struct cli_state *cli1;
920 const char *lockfname = "\\large.dat";
926 if (!torture_open_connection(&cli1, 0)) {
929 smbXcli_conn_set_sockopt(cli1->conn, sockops);
930 memset(buf,'\0',sizeof(buf));
932 printf("starting readwritelarge_internal\n");
934 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
936 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
938 if (!NT_STATUS_IS_OK(status)) {
939 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
943 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
945 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
947 if (!NT_STATUS_IS_OK(status)) {
948 printf("qfileinfo failed (%s)\n", nt_errstr(status));
952 if (fsize == sizeof(buf))
953 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
954 (unsigned long)fsize);
956 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
957 (unsigned long)fsize);
961 status = cli_close(cli1, fnum1);
962 if (!NT_STATUS_IS_OK(status)) {
963 printf("close failed (%s)\n", nt_errstr(status));
967 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
968 if (!NT_STATUS_IS_OK(status)) {
969 printf("unlink failed (%s)\n", nt_errstr(status));
973 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
975 if (!NT_STATUS_IS_OK(status)) {
976 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
980 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
982 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
984 if (!NT_STATUS_IS_OK(status)) {
985 printf("qfileinfo failed (%s)\n", nt_errstr(status));
989 if (fsize == sizeof(buf))
990 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
991 (unsigned long)fsize);
993 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
994 (unsigned long)fsize);
999 /* ToDo - set allocation. JRA */
1000 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1001 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1004 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1006 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1010 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1013 status = cli_close(cli1, fnum1);
1014 if (!NT_STATUS_IS_OK(status)) {
1015 printf("close failed (%s)\n", nt_errstr(status));
1019 if (!torture_close_connection(cli1)) {
1025 static bool run_readwritelarge(int dummy)
1027 return run_readwritelarge_internal();
1030 static bool run_readwritelarge_signtest(int dummy)
1033 signing_state = SMB_SIGNING_REQUIRED;
1034 ret = run_readwritelarge_internal();
1035 signing_state = SMB_SIGNING_DEFAULT;
1042 #define ival(s) strtol(s, NULL, 0)
1044 /* run a test that simulates an approximate netbench client load */
1045 static bool run_netbench(int client)
1047 struct cli_state *cli;
1052 const char *params[20];
1053 bool correct = True;
1059 smbXcli_conn_set_sockopt(cli->conn, sockops);
1063 slprintf(cname,sizeof(cname)-1, "client%d", client);
1065 f = fopen(client_txt, "r");
1072 while (fgets(line, sizeof(line)-1, f)) {
1076 line[strlen(line)-1] = 0;
1078 /* printf("[%d] %s\n", line_count, line); */
1080 all_string_sub(line,"client1", cname, sizeof(line));
1082 /* parse the command parameters */
1083 params[0] = strtok_r(line, " ", &saveptr);
1085 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1089 if (i < 2) continue;
1091 if (!strncmp(params[0],"SMB", 3)) {
1092 printf("ERROR: You are using a dbench 1 load file\n");
1096 if (!strcmp(params[0],"NTCreateX")) {
1097 nb_createx(params[1], ival(params[2]), ival(params[3]),
1099 } else if (!strcmp(params[0],"Close")) {
1100 nb_close(ival(params[1]));
1101 } else if (!strcmp(params[0],"Rename")) {
1102 nb_rename(params[1], params[2]);
1103 } else if (!strcmp(params[0],"Unlink")) {
1104 nb_unlink(params[1]);
1105 } else if (!strcmp(params[0],"Deltree")) {
1106 nb_deltree(params[1]);
1107 } else if (!strcmp(params[0],"Rmdir")) {
1108 nb_rmdir(params[1]);
1109 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1110 nb_qpathinfo(params[1]);
1111 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1112 nb_qfileinfo(ival(params[1]));
1113 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1114 nb_qfsinfo(ival(params[1]));
1115 } else if (!strcmp(params[0],"FIND_FIRST")) {
1116 nb_findfirst(params[1]);
1117 } else if (!strcmp(params[0],"WriteX")) {
1118 nb_writex(ival(params[1]),
1119 ival(params[2]), ival(params[3]), ival(params[4]));
1120 } else if (!strcmp(params[0],"ReadX")) {
1121 nb_readx(ival(params[1]),
1122 ival(params[2]), ival(params[3]), ival(params[4]));
1123 } else if (!strcmp(params[0],"Flush")) {
1124 nb_flush(ival(params[1]));
1126 printf("Unknown operation %s\n", params[0]);
1134 if (!torture_close_connection(cli)) {
1142 /* run a test that simulates an approximate netbench client load */
1143 static bool run_nbench(int dummy)
1146 bool correct = True;
1148 nbio_shmem(torture_nprocs);
1152 signal(SIGALRM, nb_alarm);
1154 t = create_procs(run_netbench, &correct);
1157 printf("\nThroughput %g MB/sec\n",
1158 1.0e-6 * nbio_total() / t);
1164 This test checks for two things:
1166 1) correct support for retaining locks over a close (ie. the server
1167 must not use posix semantics)
1168 2) support for lock timeouts
1170 static bool run_locktest1(int dummy)
1172 struct cli_state *cli1, *cli2;
1173 const char *fname = "\\lockt1.lck";
1174 uint16_t fnum1, fnum2, fnum3;
1176 unsigned lock_timeout;
1179 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1182 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1183 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1185 printf("starting locktest1\n");
1187 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1189 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1191 if (!NT_STATUS_IS_OK(status)) {
1192 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1196 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1197 if (!NT_STATUS_IS_OK(status)) {
1198 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1202 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1203 if (!NT_STATUS_IS_OK(status)) {
1204 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1208 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1209 if (!NT_STATUS_IS_OK(status)) {
1210 printf("lock1 failed (%s)\n", nt_errstr(status));
1214 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1215 if (NT_STATUS_IS_OK(status)) {
1216 printf("lock2 succeeded! This is a locking bug\n");
1219 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1220 NT_STATUS_LOCK_NOT_GRANTED)) {
1225 lock_timeout = (1 + (random() % 20));
1226 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1228 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1229 if (NT_STATUS_IS_OK(status)) {
1230 printf("lock3 succeeded! This is a locking bug\n");
1233 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1234 NT_STATUS_FILE_LOCK_CONFLICT)) {
1240 if (ABS(t2 - t1) < lock_timeout-1) {
1241 printf("error: This server appears not to support timed lock requests\n");
1244 printf("server slept for %u seconds for a %u second timeout\n",
1245 (unsigned int)(t2-t1), lock_timeout);
1247 status = cli_close(cli1, fnum2);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 printf("close1 failed (%s)\n", nt_errstr(status));
1253 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1254 if (NT_STATUS_IS_OK(status)) {
1255 printf("lock4 succeeded! This is a locking bug\n");
1258 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1259 NT_STATUS_FILE_LOCK_CONFLICT)) {
1264 status = cli_close(cli1, fnum1);
1265 if (!NT_STATUS_IS_OK(status)) {
1266 printf("close2 failed (%s)\n", nt_errstr(status));
1270 status = cli_close(cli2, fnum3);
1271 if (!NT_STATUS_IS_OK(status)) {
1272 printf("close3 failed (%s)\n", nt_errstr(status));
1276 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 printf("unlink failed (%s)\n", nt_errstr(status));
1283 if (!torture_close_connection(cli1)) {
1287 if (!torture_close_connection(cli2)) {
1291 printf("Passed locktest1\n");
1296 this checks to see if a secondary tconx can use open files from an
1299 static bool run_tcon_test(int dummy)
1301 static struct cli_state *cli;
1302 const char *fname = "\\tcontest.tmp";
1304 uint32_t cnum1, cnum2, cnum3;
1305 struct smbXcli_tcon *orig_tcon = NULL;
1306 uint16_t vuid1, vuid2;
1311 memset(buf, '\0', sizeof(buf));
1313 if (!torture_open_connection(&cli, 0)) {
1316 smbXcli_conn_set_sockopt(cli->conn, sockops);
1318 printf("starting tcontest\n");
1320 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1322 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1323 if (!NT_STATUS_IS_OK(status)) {
1324 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1328 cnum1 = cli_state_get_tid(cli);
1329 vuid1 = cli_state_get_uid(cli);
1331 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 printf("initial write failed (%s)", nt_errstr(status));
1337 orig_tcon = cli_state_save_tcon(cli);
1338 if (orig_tcon == NULL) {
1342 status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1343 if (!NT_STATUS_IS_OK(status)) {
1344 printf("%s refused 2nd tree connect (%s)\n", host,
1350 cnum2 = cli_state_get_tid(cli);
1351 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1352 vuid2 = cli_state_get_uid(cli) + 1;
1354 /* try a write with the wrong tid */
1355 cli_state_set_tid(cli, cnum2);
1357 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1358 if (NT_STATUS_IS_OK(status)) {
1359 printf("* server allows write with wrong TID\n");
1362 printf("server fails write with wrong TID : %s\n",
1367 /* try a write with an invalid tid */
1368 cli_state_set_tid(cli, cnum3);
1370 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1371 if (NT_STATUS_IS_OK(status)) {
1372 printf("* server allows write with invalid TID\n");
1375 printf("server fails write with invalid TID : %s\n",
1379 /* try a write with an invalid vuid */
1380 cli_state_set_uid(cli, vuid2);
1381 cli_state_set_tid(cli, cnum1);
1383 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1384 if (NT_STATUS_IS_OK(status)) {
1385 printf("* server allows write with invalid VUID\n");
1388 printf("server fails write with invalid VUID : %s\n",
1392 cli_state_set_tid(cli, cnum1);
1393 cli_state_set_uid(cli, vuid1);
1395 status = cli_close(cli, fnum1);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 printf("close failed (%s)\n", nt_errstr(status));
1401 cli_state_set_tid(cli, cnum2);
1403 status = cli_tdis(cli);
1404 if (!NT_STATUS_IS_OK(status)) {
1405 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1409 cli_state_restore_tcon(cli, orig_tcon);
1411 cli_state_set_tid(cli, cnum1);
1413 if (!torture_close_connection(cli)) {
1422 checks for old style tcon support
1424 static bool run_tcon2_test(int dummy)
1426 static struct cli_state *cli;
1427 uint16_t cnum, max_xmit;
1431 if (!torture_open_connection(&cli, 0)) {
1434 smbXcli_conn_set_sockopt(cli->conn, sockops);
1436 printf("starting tcon2 test\n");
1438 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1442 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1446 if (!NT_STATUS_IS_OK(status)) {
1447 printf("tcon2 failed : %s\n", nt_errstr(status));
1449 printf("tcon OK : max_xmit=%d cnum=%d\n",
1450 (int)max_xmit, (int)cnum);
1453 if (!torture_close_connection(cli)) {
1457 printf("Passed tcon2 test\n");
1461 static bool tcon_devtest(struct cli_state *cli,
1462 const char *myshare, const char *devtype,
1463 const char *return_devtype,
1464 NTSTATUS expected_error)
1469 status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
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_creds(&cli1,
1523 NULL, /* service_type */
1528 if (!NT_STATUS_IS_OK(status)) {
1529 printf("could not open connection\n");
1533 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1536 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1539 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1542 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1545 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1548 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1551 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1554 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1557 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1560 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1566 printf("Passed tcondevtest\n");
1573 This test checks that
1575 1) the server supports multiple locking contexts on the one SMB
1576 connection, distinguished by PID.
1578 2) the server correctly fails overlapping locks made by the same PID (this
1579 goes against POSIX behaviour, which is why it is tricky to implement)
1581 3) the server denies unlock requests by an incorrect client PID
1583 static bool run_locktest2(int dummy)
1585 static struct cli_state *cli;
1586 const char *fname = "\\lockt2.lck";
1587 uint16_t fnum1, fnum2, fnum3;
1588 bool correct = True;
1591 if (!torture_open_connection(&cli, 0)) {
1595 smbXcli_conn_set_sockopt(cli->conn, sockops);
1597 printf("starting locktest2\n");
1599 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1603 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1604 if (!NT_STATUS_IS_OK(status)) {
1605 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1609 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1610 if (!NT_STATUS_IS_OK(status)) {
1611 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1617 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1618 if (!NT_STATUS_IS_OK(status)) {
1619 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1625 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1626 if (!NT_STATUS_IS_OK(status)) {
1627 printf("lock1 failed (%s)\n", nt_errstr(status));
1631 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1632 if (NT_STATUS_IS_OK(status)) {
1633 printf("WRITE lock1 succeeded! This is a locking bug\n");
1636 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1637 NT_STATUS_LOCK_NOT_GRANTED)) {
1642 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1643 if (NT_STATUS_IS_OK(status)) {
1644 printf("WRITE lock2 succeeded! This is a locking bug\n");
1647 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1648 NT_STATUS_LOCK_NOT_GRANTED)) {
1653 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1654 if (NT_STATUS_IS_OK(status)) {
1655 printf("READ lock2 succeeded! This is a locking bug\n");
1658 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1659 NT_STATUS_FILE_LOCK_CONFLICT)) {
1664 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1665 if (!NT_STATUS_IS_OK(status)) {
1666 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1669 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1670 printf("unlock at 100 succeeded! This is a locking bug\n");
1674 status = cli_unlock(cli, fnum1, 0, 4);
1675 if (NT_STATUS_IS_OK(status)) {
1676 printf("unlock1 succeeded! This is a locking bug\n");
1679 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1680 NT_STATUS_RANGE_NOT_LOCKED)) {
1685 status = cli_unlock(cli, fnum1, 0, 8);
1686 if (NT_STATUS_IS_OK(status)) {
1687 printf("unlock2 succeeded! This is a locking bug\n");
1690 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1691 NT_STATUS_RANGE_NOT_LOCKED)) {
1696 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1697 if (NT_STATUS_IS_OK(status)) {
1698 printf("lock3 succeeded! This is a locking bug\n");
1701 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1702 NT_STATUS_LOCK_NOT_GRANTED)) {
1709 status = cli_close(cli, fnum1);
1710 if (!NT_STATUS_IS_OK(status)) {
1711 printf("close1 failed (%s)\n", nt_errstr(status));
1715 status = cli_close(cli, fnum2);
1716 if (!NT_STATUS_IS_OK(status)) {
1717 printf("close2 failed (%s)\n", nt_errstr(status));
1721 status = cli_close(cli, fnum3);
1722 if (!NT_STATUS_IS_OK(status)) {
1723 printf("close3 failed (%s)\n", nt_errstr(status));
1727 if (!torture_close_connection(cli)) {
1731 printf("locktest2 finished\n");
1738 This test checks that
1740 1) the server supports the full offset range in lock requests
1742 static bool run_locktest3(int dummy)
1744 static struct cli_state *cli1, *cli2;
1745 const char *fname = "\\lockt3.lck";
1746 uint16_t fnum1, fnum2;
1749 bool correct = True;
1752 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1754 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1757 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1758 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1760 printf("starting locktest3\n");
1762 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1764 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1766 if (!NT_STATUS_IS_OK(status)) {
1767 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1771 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1772 if (!NT_STATUS_IS_OK(status)) {
1773 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1777 for (offset=i=0;i<torture_numops;i++) {
1780 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 printf("lock1 %d failed (%s)\n",
1788 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1789 if (!NT_STATUS_IS_OK(status)) {
1790 printf("lock2 %d failed (%s)\n",
1797 for (offset=i=0;i<torture_numops;i++) {
1800 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1801 if (NT_STATUS_IS_OK(status)) {
1802 printf("error: lock1 %d succeeded!\n", i);
1806 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1807 if (NT_STATUS_IS_OK(status)) {
1808 printf("error: lock2 %d succeeded!\n", i);
1812 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1813 if (NT_STATUS_IS_OK(status)) {
1814 printf("error: lock3 %d succeeded!\n", i);
1818 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1819 if (NT_STATUS_IS_OK(status)) {
1820 printf("error: lock4 %d succeeded!\n", i);
1825 for (offset=i=0;i<torture_numops;i++) {
1828 status = cli_unlock(cli1, fnum1, offset-1, 1);
1829 if (!NT_STATUS_IS_OK(status)) {
1830 printf("unlock1 %d failed (%s)\n",
1836 status = cli_unlock(cli2, fnum2, offset-2, 1);
1837 if (!NT_STATUS_IS_OK(status)) {
1838 printf("unlock2 %d failed (%s)\n",
1845 status = cli_close(cli1, fnum1);
1846 if (!NT_STATUS_IS_OK(status)) {
1847 printf("close1 failed (%s)\n", nt_errstr(status));
1851 status = cli_close(cli2, fnum2);
1852 if (!NT_STATUS_IS_OK(status)) {
1853 printf("close2 failed (%s)\n", nt_errstr(status));
1857 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1858 if (!NT_STATUS_IS_OK(status)) {
1859 printf("unlink failed (%s)\n", nt_errstr(status));
1863 if (!torture_close_connection(cli1)) {
1867 if (!torture_close_connection(cli2)) {
1871 printf("finished locktest3\n");
1876 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1877 char *buf, off_t offset, size_t size,
1878 size_t *nread, size_t expect)
1883 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1885 if(!NT_STATUS_IS_OK(status)) {
1887 } else if (l_nread != expect) {
1898 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1899 printf("** "); correct = False; \
1903 looks at overlapping locks
1905 static bool run_locktest4(int dummy)
1907 static struct cli_state *cli1, *cli2;
1908 const char *fname = "\\lockt4.lck";
1909 uint16_t fnum1, fnum2, f;
1912 bool correct = True;
1915 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1919 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1920 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1922 printf("starting locktest4\n");
1924 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1926 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1927 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1929 memset(buf, 0, sizeof(buf));
1931 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1933 if (!NT_STATUS_IS_OK(status)) {
1934 printf("Failed to create file: %s\n", nt_errstr(status));
1939 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1940 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1941 EXPECTED(ret, False);
1942 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1944 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1945 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1946 EXPECTED(ret, True);
1947 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1949 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1950 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1951 EXPECTED(ret, False);
1952 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1954 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1955 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1956 EXPECTED(ret, True);
1957 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1959 ret = (cli_setpid(cli1, 1),
1960 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1961 (cli_setpid(cli1, 2),
1962 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1963 EXPECTED(ret, False);
1964 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1966 ret = (cli_setpid(cli1, 1),
1967 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1968 (cli_setpid(cli1, 2),
1969 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1970 EXPECTED(ret, True);
1971 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1973 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1974 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1975 EXPECTED(ret, True);
1976 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1978 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1979 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1980 EXPECTED(ret, False);
1981 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1983 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1984 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1985 EXPECTED(ret, False);
1986 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1988 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1989 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
1990 EXPECTED(ret, True);
1991 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1993 ret = (cli_setpid(cli1, 1),
1994 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1995 (cli_setpid(cli1, 2),
1996 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
1997 EXPECTED(ret, False);
1998 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2000 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2001 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2002 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2003 EXPECTED(ret, False);
2004 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2007 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2008 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2009 EXPECTED(ret, False);
2010 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2012 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2013 ret = NT_STATUS_IS_OK(status);
2015 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2017 ret = NT_STATUS_IS_OK(status);
2019 EXPECTED(ret, False);
2020 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2023 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2024 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2025 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2026 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2027 EXPECTED(ret, True);
2028 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2031 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2032 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2033 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2034 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2035 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2037 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2038 EXPECTED(ret, True);
2039 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2041 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2042 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2043 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2045 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2046 EXPECTED(ret, True);
2047 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2049 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2050 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2051 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2053 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2054 EXPECTED(ret, True);
2055 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2057 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2058 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2059 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2060 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2062 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2063 EXPECTED(ret, True);
2064 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2066 cli_close(cli1, fnum1);
2067 cli_close(cli2, fnum2);
2068 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2069 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2070 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2071 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2072 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2073 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2074 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2076 cli_close(cli1, fnum1);
2077 EXPECTED(ret, True);
2078 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2081 cli_close(cli1, fnum1);
2082 cli_close(cli2, fnum2);
2083 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2084 torture_close_connection(cli1);
2085 torture_close_connection(cli2);
2087 printf("finished locktest4\n");
2092 looks at lock upgrade/downgrade.
2094 static bool run_locktest5(int dummy)
2096 static struct cli_state *cli1, *cli2;
2097 const char *fname = "\\lockt5.lck";
2098 uint16_t fnum1, fnum2, fnum3;
2101 bool correct = True;
2104 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2108 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2109 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2111 printf("starting locktest5\n");
2113 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2115 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2116 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2117 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2119 memset(buf, 0, sizeof(buf));
2121 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2123 if (!NT_STATUS_IS_OK(status)) {
2124 printf("Failed to create file: %s\n", nt_errstr(status));
2129 /* Check for NT bug... */
2130 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2131 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2132 cli_close(cli1, fnum1);
2133 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2134 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2135 ret = NT_STATUS_IS_OK(status);
2136 EXPECTED(ret, True);
2137 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2138 cli_close(cli1, fnum1);
2139 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2140 cli_unlock(cli1, fnum3, 0, 1);
2142 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2143 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2144 EXPECTED(ret, True);
2145 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2147 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2148 ret = NT_STATUS_IS_OK(status);
2149 EXPECTED(ret, False);
2151 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2153 /* Unlock the process 2 lock. */
2154 cli_unlock(cli2, fnum2, 0, 4);
2156 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2157 ret = NT_STATUS_IS_OK(status);
2158 EXPECTED(ret, False);
2160 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2162 /* Unlock the process 1 fnum3 lock. */
2163 cli_unlock(cli1, fnum3, 0, 4);
2165 /* Stack 2 more locks here. */
2166 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2167 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2169 EXPECTED(ret, True);
2170 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2172 /* Unlock the first process lock, then check this was the WRITE lock that was
2175 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2176 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2178 EXPECTED(ret, True);
2179 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2181 /* Unlock the process 2 lock. */
2182 cli_unlock(cli2, fnum2, 0, 4);
2184 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2186 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2187 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2188 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2190 EXPECTED(ret, True);
2191 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2193 /* Ensure the next unlock fails. */
2194 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2195 EXPECTED(ret, False);
2196 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2198 /* Ensure connection 2 can get a write lock. */
2199 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2200 ret = NT_STATUS_IS_OK(status);
2201 EXPECTED(ret, True);
2203 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2207 cli_close(cli1, fnum1);
2208 cli_close(cli2, fnum2);
2209 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2210 if (!torture_close_connection(cli1)) {
2213 if (!torture_close_connection(cli2)) {
2217 printf("finished locktest5\n");
2223 tries the unusual lockingX locktype bits
2225 static bool run_locktest6(int dummy)
2227 static struct cli_state *cli;
2228 const char *fname[1] = { "\\lock6.txt" };
2233 if (!torture_open_connection(&cli, 0)) {
2237 smbXcli_conn_set_sockopt(cli->conn, sockops);
2239 printf("starting locktest6\n");
2242 printf("Testing %s\n", fname[i]);
2244 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2246 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2247 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2248 cli_close(cli, fnum);
2249 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2251 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2252 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2253 cli_close(cli, fnum);
2254 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2256 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2259 torture_close_connection(cli);
2261 printf("finished locktest6\n");
2265 static bool run_locktest7(int dummy)
2267 struct cli_state *cli1;
2268 const char *fname = "\\lockt7.lck";
2271 bool correct = False;
2275 if (!torture_open_connection(&cli1, 0)) {
2279 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2281 printf("starting locktest7\n");
2283 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2285 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2287 memset(buf, 0, sizeof(buf));
2289 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2291 if (!NT_STATUS_IS_OK(status)) {
2292 printf("Failed to create file: %s\n", nt_errstr(status));
2296 cli_setpid(cli1, 1);
2298 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2299 if (!NT_STATUS_IS_OK(status)) {
2300 printf("Unable to apply read lock on range 130:4, "
2301 "error was %s\n", nt_errstr(status));
2304 printf("pid1 successfully locked range 130:4 for READ\n");
2307 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2308 if (!NT_STATUS_IS_OK(status)) {
2309 printf("pid1 unable to read the range 130:4, error was %s\n",
2312 } else if (nread != 4) {
2313 printf("pid1 unable to read the range 130:4, "
2314 "recv %ld req %d\n", (unsigned long)nread, 4);
2317 printf("pid1 successfully read the range 130:4\n");
2320 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2321 if (!NT_STATUS_IS_OK(status)) {
2322 printf("pid1 unable to write to the range 130:4, error was "
2323 "%s\n", nt_errstr(status));
2324 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2325 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2329 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2333 cli_setpid(cli1, 2);
2335 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2336 if (!NT_STATUS_IS_OK(status)) {
2337 printf("pid2 unable to read the range 130:4, error was %s\n",
2340 } else if (nread != 4) {
2341 printf("pid2 unable to read the range 130:4, "
2342 "recv %ld req %d\n", (unsigned long)nread, 4);
2345 printf("pid2 successfully read the range 130:4\n");
2348 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2349 if (!NT_STATUS_IS_OK(status)) {
2350 printf("pid2 unable to write to the range 130:4, error was "
2351 "%s\n", nt_errstr(status));
2352 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2353 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2357 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2361 cli_setpid(cli1, 1);
2362 cli_unlock(cli1, fnum1, 130, 4);
2364 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2365 if (!NT_STATUS_IS_OK(status)) {
2366 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2369 printf("pid1 successfully locked range 130:4 for WRITE\n");
2372 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2373 if (!NT_STATUS_IS_OK(status)) {
2374 printf("pid1 unable to read the range 130:4, error was %s\n",
2377 } else if (nread != 4) {
2378 printf("pid1 unable to read the range 130:4, "
2379 "recv %ld req %d\n", (unsigned long)nread, 4);
2382 printf("pid1 successfully read the range 130:4\n");
2385 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 printf("pid1 unable to write to the range 130:4, error was "
2388 "%s\n", nt_errstr(status));
2391 printf("pid1 successfully wrote to the range 130:4\n");
2394 cli_setpid(cli1, 2);
2396 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2397 if (!NT_STATUS_IS_OK(status)) {
2398 printf("pid2 unable to read the range 130:4, error was "
2399 "%s\n", nt_errstr(status));
2400 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2401 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2405 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2406 (unsigned long)nread);
2410 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2411 if (!NT_STATUS_IS_OK(status)) {
2412 printf("pid2 unable to write to the range 130:4, error was "
2413 "%s\n", nt_errstr(status));
2414 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2415 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2419 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2423 cli_unlock(cli1, fnum1, 130, 0);
2427 cli_close(cli1, fnum1);
2428 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2429 torture_close_connection(cli1);
2431 printf("finished locktest7\n");
2436 * This demonstrates a problem with our use of GPFS share modes: A file
2437 * descriptor sitting in the pending close queue holding a GPFS share mode
2438 * blocks opening a file another time. Happens with Word 2007 temp files.
2439 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2440 * open is denied with NT_STATUS_SHARING_VIOLATION.
2443 static bool run_locktest8(int dummy)
2445 struct cli_state *cli1;
2446 const char *fname = "\\lockt8.lck";
2447 uint16_t fnum1, fnum2;
2449 bool correct = False;
2452 if (!torture_open_connection(&cli1, 0)) {
2456 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2458 printf("starting locktest8\n");
2460 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2462 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2464 if (!NT_STATUS_IS_OK(status)) {
2465 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2469 memset(buf, 0, sizeof(buf));
2471 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2472 if (!NT_STATUS_IS_OK(status)) {
2473 d_fprintf(stderr, "cli_openx second time returned %s\n",
2478 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2479 if (!NT_STATUS_IS_OK(status)) {
2480 printf("Unable to apply read lock on range 1:1, error was "
2481 "%s\n", nt_errstr(status));
2485 status = cli_close(cli1, fnum1);
2486 if (!NT_STATUS_IS_OK(status)) {
2487 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2491 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2492 if (!NT_STATUS_IS_OK(status)) {
2493 d_fprintf(stderr, "cli_openx third time returned %s\n",
2501 cli_close(cli1, fnum1);
2502 cli_close(cli1, fnum2);
2503 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2504 torture_close_connection(cli1);
2506 printf("finished locktest8\n");
2511 * This test is designed to be run in conjunction with
2512 * external NFS or POSIX locks taken in the filesystem.
2513 * It checks that the smbd server will block until the
2514 * lock is released and then acquire it. JRA.
2517 static bool got_alarm;
2518 static struct cli_state *alarm_cli;
2520 static void alarm_handler(int dummy)
2525 static void alarm_handler_parent(int dummy)
2527 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2530 static void do_local_lock(int read_fd, int write_fd)
2535 const char *local_pathname = NULL;
2538 local_pathname = talloc_asprintf(talloc_tos(),
2539 "%s/lockt9.lck", local_path);
2540 if (!local_pathname) {
2541 printf("child: alloc fail\n");
2545 unlink(local_pathname);
2546 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2548 printf("child: open of %s failed %s.\n",
2549 local_pathname, strerror(errno));
2553 /* Now take a fcntl lock. */
2554 lock.l_type = F_WRLCK;
2555 lock.l_whence = SEEK_SET;
2558 lock.l_pid = getpid();
2560 ret = fcntl(fd,F_SETLK,&lock);
2562 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2563 local_pathname, strerror(errno));
2566 printf("child: got lock 0:4 on file %s.\n",
2571 CatchSignal(SIGALRM, alarm_handler);
2573 /* Signal the parent. */
2574 if (write(write_fd, &c, 1) != 1) {
2575 printf("child: start signal fail %s.\n",
2582 /* Wait for the parent to be ready. */
2583 if (read(read_fd, &c, 1) != 1) {
2584 printf("child: reply signal fail %s.\n",
2592 printf("child: released lock 0:4 on file %s.\n",
2598 static bool run_locktest9(int dummy)
2600 struct cli_state *cli1;
2601 const char *fname = "\\lockt9.lck";
2603 bool correct = False;
2604 int pipe_in[2], pipe_out[2];
2608 struct timeval start;
2612 printf("starting locktest9\n");
2614 if (local_path == NULL) {
2615 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2619 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2624 if (child_pid == -1) {
2628 if (child_pid == 0) {
2630 do_local_lock(pipe_out[0], pipe_in[1]);
2640 ret = read(pipe_in[0], &c, 1);
2642 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2647 if (!torture_open_connection(&cli1, 0)) {
2651 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2653 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2655 if (!NT_STATUS_IS_OK(status)) {
2656 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2660 /* Ensure the child has the lock. */
2661 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2662 if (NT_STATUS_IS_OK(status)) {
2663 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2666 d_printf("Child has the lock.\n");
2669 /* Tell the child to wait 5 seconds then exit. */
2670 ret = write(pipe_out[1], &c, 1);
2672 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2677 /* Wait 20 seconds for the lock. */
2679 CatchSignal(SIGALRM, alarm_handler_parent);
2682 start = timeval_current();
2684 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2685 if (!NT_STATUS_IS_OK(status)) {
2686 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2687 "%s\n", nt_errstr(status));
2692 seconds = timeval_elapsed(&start);
2694 printf("Parent got the lock after %.2f seconds.\n",
2697 status = cli_close(cli1, fnum);
2698 if (!NT_STATUS_IS_OK(status)) {
2699 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2706 cli_close(cli1, fnum);
2707 torture_close_connection(cli1);
2711 printf("finished locktest9\n");
2716 test whether fnums and tids open on one VC are available on another (a major
2719 static bool run_fdpasstest(int dummy)
2721 struct cli_state *cli1, *cli2;
2722 const char *fname = "\\fdpass.tst";
2727 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2730 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2731 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2733 printf("starting fdpasstest\n");
2735 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2737 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2739 if (!NT_STATUS_IS_OK(status)) {
2740 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2744 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2746 if (!NT_STATUS_IS_OK(status)) {
2747 printf("write failed (%s)\n", nt_errstr(status));
2751 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2752 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2753 cli_setpid(cli2, cli_getpid(cli1));
2755 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2756 printf("read succeeded! nasty security hole [%s]\n", buf);
2760 cli_close(cli1, fnum1);
2761 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2763 torture_close_connection(cli1);
2764 torture_close_connection(cli2);
2766 printf("finished fdpasstest\n");
2770 static bool run_fdsesstest(int dummy)
2772 struct cli_state *cli;
2774 uint16_t saved_vuid;
2776 uint32_t saved_cnum;
2777 const char *fname = "\\fdsess.tst";
2778 const char *fname1 = "\\fdsess1.tst";
2785 if (!torture_open_connection(&cli, 0))
2787 smbXcli_conn_set_sockopt(cli->conn, sockops);
2789 if (!torture_cli_session_setup2(cli, &new_vuid))
2792 saved_cnum = cli_state_get_tid(cli);
2793 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
2795 new_cnum = cli_state_get_tid(cli);
2796 cli_state_set_tid(cli, saved_cnum);
2798 printf("starting fdsesstest\n");
2800 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2801 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2803 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2804 if (!NT_STATUS_IS_OK(status)) {
2805 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2809 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2811 if (!NT_STATUS_IS_OK(status)) {
2812 printf("write failed (%s)\n", nt_errstr(status));
2816 saved_vuid = cli_state_get_uid(cli);
2817 cli_state_set_uid(cli, new_vuid);
2819 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2820 printf("read succeeded with different vuid! "
2821 "nasty security hole [%s]\n", buf);
2824 /* Try to open a file with different vuid, samba cnum. */
2825 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2826 printf("create with different vuid, same cnum succeeded.\n");
2827 cli_close(cli, fnum2);
2828 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2830 printf("create with different vuid, same cnum failed.\n");
2831 printf("This will cause problems with service clients.\n");
2835 cli_state_set_uid(cli, saved_vuid);
2837 /* Try with same vuid, different cnum. */
2838 cli_state_set_tid(cli, new_cnum);
2840 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2841 printf("read succeeded with different cnum![%s]\n", buf);
2845 cli_state_set_tid(cli, saved_cnum);
2846 cli_close(cli, fnum1);
2847 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2849 torture_close_connection(cli);
2851 printf("finished fdsesstest\n");
2856 This test checks that
2858 1) the server does not allow an unlink on a file that is open
2860 static bool run_unlinktest(int dummy)
2862 struct cli_state *cli;
2863 const char *fname = "\\unlink.tst";
2865 bool correct = True;
2868 if (!torture_open_connection(&cli, 0)) {
2872 smbXcli_conn_set_sockopt(cli->conn, sockops);
2874 printf("starting unlink test\n");
2876 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2880 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2881 if (!NT_STATUS_IS_OK(status)) {
2882 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2886 status = cli_unlink(cli, fname,
2887 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2888 if (NT_STATUS_IS_OK(status)) {
2889 printf("error: server allowed unlink on an open file\n");
2892 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2893 NT_STATUS_SHARING_VIOLATION);
2896 cli_close(cli, fnum);
2897 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2899 if (!torture_close_connection(cli)) {
2903 printf("unlink test finished\n");
2910 test how many open files this server supports on the one socket
2912 static bool run_maxfidtest(int dummy)
2914 struct cli_state *cli;
2916 uint16_t fnums[0x11000];
2919 bool correct = True;
2925 printf("failed to connect\n");
2929 smbXcli_conn_set_sockopt(cli->conn, sockops);
2931 for (i=0; i<0x11000; i++) {
2932 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2933 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2935 if (!NT_STATUS_IS_OK(status)) {
2936 printf("open of %s failed (%s)\n",
2937 fname, nt_errstr(status));
2938 printf("maximum fnum is %d\n", i);
2946 printf("cleaning up\n");
2948 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2949 cli_close(cli, fnums[i]);
2951 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2952 if (!NT_STATUS_IS_OK(status)) {
2953 printf("unlink of %s failed (%s)\n",
2954 fname, nt_errstr(status));
2961 printf("maxfid test finished\n");
2962 if (!torture_close_connection(cli)) {
2968 /* generate a random buffer */
2969 static void rand_buf(char *buf, int len)
2972 *buf = (char)sys_random();
2977 /* send smb negprot commands, not reading the response */
2978 static bool run_negprot_nowait(int dummy)
2980 struct tevent_context *ev;
2982 struct cli_state *cli;
2983 bool correct = True;
2985 printf("starting negprot nowait test\n");
2987 ev = samba_tevent_context_init(talloc_tos());
2992 if (!(cli = open_nbt_connection())) {
2997 for (i=0;i<50000;i++) {
2998 struct tevent_req *req;
3000 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3001 PROTOCOL_CORE, PROTOCOL_NT1, 0);
3006 if (!tevent_req_poll(req, ev)) {
3007 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3015 if (torture_close_connection(cli)) {
3019 printf("finished negprot nowait test\n");
3024 /* send smb negprot commands, not reading the response */
3025 static bool run_bad_nbt_session(int dummy)
3027 struct nmb_name called, calling;
3028 struct sockaddr_storage ss;
3033 printf("starting bad nbt session test\n");
3035 make_nmb_name(&calling, myname, 0x0);
3036 make_nmb_name(&called , host, 0x20);
3038 if (!resolve_name(host, &ss, 0x20, true)) {
3039 d_fprintf(stderr, "Could not resolve name %s\n", host);
3043 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3044 if (!NT_STATUS_IS_OK(status)) {
3045 d_fprintf(stderr, "open_socket_out failed: %s\n",
3050 ret = cli_bad_session_request(fd, &calling, &called);
3053 d_fprintf(stderr, "open_socket_out failed: %s\n",
3058 printf("finished bad nbt session test\n");
3062 /* send random IPC commands */
3063 static bool run_randomipc(int dummy)
3065 char *rparam = NULL;
3067 unsigned int rdrcnt,rprcnt;
3069 int api, param_len, i;
3070 struct cli_state *cli;
3071 bool correct = True;
3074 printf("starting random ipc test\n");
3076 if (!torture_open_connection(&cli, 0)) {
3080 for (i=0;i<count;i++) {
3081 api = sys_random() % 500;
3082 param_len = (sys_random() % 64);
3084 rand_buf(param, param_len);
3089 param, param_len, 8,
3090 NULL, 0, CLI_BUFFER_SIZE,
3094 printf("%d/%d\r", i,count);
3097 printf("%d/%d\n", i, count);
3099 if (!torture_close_connection(cli)) {
3106 printf("finished random ipc test\n");
3113 static void browse_callback(const char *sname, uint32_t stype,
3114 const char *comment, void *state)
3116 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3122 This test checks the browse list code
3125 static bool run_browsetest(int dummy)
3127 static struct cli_state *cli;
3128 bool correct = True;
3130 printf("starting browse test\n");
3132 if (!torture_open_connection(&cli, 0)) {
3136 printf("domain list:\n");
3137 cli_NetServerEnum(cli, cli->server_domain,
3138 SV_TYPE_DOMAIN_ENUM,
3139 browse_callback, NULL);
3141 printf("machine list:\n");
3142 cli_NetServerEnum(cli, cli->server_domain,
3144 browse_callback, NULL);
3146 if (!torture_close_connection(cli)) {
3150 printf("browse test finished\n");
3158 This checks how the getatr calls works
3160 static bool run_attrtest(int dummy)
3162 struct cli_state *cli;
3165 const char *fname = "\\attrib123456789.tst";
3166 bool correct = True;
3169 printf("starting attrib test\n");
3171 if (!torture_open_connection(&cli, 0)) {
3175 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3176 cli_openx(cli, fname,
3177 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3178 cli_close(cli, fnum);
3180 status = cli_getatr(cli, fname, NULL, NULL, &t);
3181 if (!NT_STATUS_IS_OK(status)) {
3182 printf("getatr failed (%s)\n", nt_errstr(status));
3186 if (abs(t - time(NULL)) > 60*60*24*10) {
3187 printf("ERROR: SMBgetatr bug. time is %s",
3193 t2 = t-60*60*24; /* 1 day ago */
3195 status = cli_setatr(cli, fname, 0, t2);
3196 if (!NT_STATUS_IS_OK(status)) {
3197 printf("setatr failed (%s)\n", nt_errstr(status));
3201 status = cli_getatr(cli, fname, NULL, NULL, &t);
3202 if (!NT_STATUS_IS_OK(status)) {
3203 printf("getatr failed (%s)\n", nt_errstr(status));
3208 printf("ERROR: getatr/setatr bug. times are\n%s",
3210 printf("%s", ctime(&t2));
3214 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3216 if (!torture_close_connection(cli)) {
3220 printf("attrib test finished\n");
3227 This checks a couple of trans2 calls
3229 static bool run_trans2test(int dummy)
3231 struct cli_state *cli;
3234 time_t c_time, a_time, m_time;
3235 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3236 const char *fname = "\\trans2.tst";
3237 const char *dname = "\\trans2";
3238 const char *fname2 = "\\trans2\\trans2.tst";
3240 bool correct = True;
3244 printf("starting trans2 test\n");
3246 if (!torture_open_connection(&cli, 0)) {
3250 status = cli_get_fs_attr_info(cli, &fs_attr);
3251 if (!NT_STATUS_IS_OK(status)) {
3252 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3257 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3258 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3259 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3260 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3261 if (!NT_STATUS_IS_OK(status)) {
3262 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3266 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3267 if (!NT_STATUS_IS_OK(status)) {
3268 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3271 else if (strcmp(pname, fname)) {
3272 printf("qfilename gave different name? [%s] [%s]\n",
3277 cli_close(cli, fnum);
3281 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3282 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3284 if (!NT_STATUS_IS_OK(status)) {
3285 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3288 cli_close(cli, fnum);
3290 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3292 if (!NT_STATUS_IS_OK(status)) {
3293 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3296 time_t t = time(NULL);
3298 if (c_time != m_time) {
3299 printf("create time=%s", ctime(&c_time));
3300 printf("modify time=%s", ctime(&m_time));
3301 printf("This system appears to have sticky create times\n");
3303 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3304 printf("access time=%s", ctime(&a_time));
3305 printf("This system appears to set a midnight access time\n");
3309 if (abs(m_time - t) > 60*60*24*7) {
3310 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3316 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3317 cli_openx(cli, fname,
3318 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3319 cli_close(cli, fnum);
3320 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3321 &m_time_ts, &size, NULL, NULL);
3322 if (!NT_STATUS_IS_OK(status)) {
3323 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3326 if (w_time_ts.tv_sec < 60*60*24*2) {
3327 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3328 printf("This system appears to set a initial 0 write time\n");
3333 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3336 /* check if the server updates the directory modification time
3337 when creating a new file */
3338 status = cli_mkdir(cli, dname);
3339 if (!NT_STATUS_IS_OK(status)) {
3340 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3344 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3345 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3346 if (!NT_STATUS_IS_OK(status)) {
3347 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3351 cli_openx(cli, fname2,
3352 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3353 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3354 cli_close(cli, fnum);
3355 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3356 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3357 if (!NT_STATUS_IS_OK(status)) {
3358 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3361 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3363 printf("This system does not update directory modification times\n");
3367 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3368 cli_rmdir(cli, dname);
3370 if (!torture_close_connection(cli)) {
3374 printf("trans2 test finished\n");
3380 This checks new W2K calls.
3383 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3385 uint8_t *buf = NULL;
3389 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3390 CLI_BUFFER_SIZE, NULL, &buf, &len);
3391 if (!NT_STATUS_IS_OK(status)) {
3392 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3395 printf("qfileinfo: level %d, len = %u\n", level, len);
3396 dump_data(0, (uint8_t *)buf, len);
3403 static bool run_w2ktest(int dummy)
3405 struct cli_state *cli;
3407 const char *fname = "\\w2ktest\\w2k.tst";
3409 bool correct = True;
3411 printf("starting w2k test\n");
3413 if (!torture_open_connection(&cli, 0)) {
3417 cli_openx(cli, fname,
3418 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3420 for (level = 1004; level < 1040; level++) {
3421 new_trans(cli, fnum, level);
3424 cli_close(cli, fnum);
3426 if (!torture_close_connection(cli)) {
3430 printf("w2k test finished\n");
3437 this is a harness for some oplock tests
3439 static bool run_oplock1(int dummy)
3441 struct cli_state *cli1;
3442 const char *fname = "\\lockt1.lck";
3444 bool correct = True;
3447 printf("starting oplock test 1\n");
3449 if (!torture_open_connection(&cli1, 0)) {
3453 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3455 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3457 cli1->use_oplocks = True;
3459 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3461 if (!NT_STATUS_IS_OK(status)) {
3462 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3466 cli1->use_oplocks = False;
3468 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3469 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3471 status = cli_close(cli1, fnum1);
3472 if (!NT_STATUS_IS_OK(status)) {
3473 printf("close2 failed (%s)\n", nt_errstr(status));
3477 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3478 if (!NT_STATUS_IS_OK(status)) {
3479 printf("unlink failed (%s)\n", nt_errstr(status));
3483 if (!torture_close_connection(cli1)) {
3487 printf("finished oplock test 1\n");
3492 static bool run_oplock2(int dummy)
3494 struct cli_state *cli1, *cli2;
3495 const char *fname = "\\lockt2.lck";
3496 uint16_t fnum1, fnum2;
3497 int saved_use_oplocks = use_oplocks;
3499 bool correct = True;
3500 volatile bool *shared_correct;
3504 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3505 *shared_correct = True;
3507 use_level_II_oplocks = True;
3510 printf("starting oplock test 2\n");
3512 if (!torture_open_connection(&cli1, 0)) {
3513 use_level_II_oplocks = False;
3514 use_oplocks = saved_use_oplocks;
3518 if (!torture_open_connection(&cli2, 1)) {
3519 use_level_II_oplocks = False;
3520 use_oplocks = saved_use_oplocks;
3524 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3526 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3527 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3529 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3531 if (!NT_STATUS_IS_OK(status)) {
3532 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3536 /* Don't need the globals any more. */
3537 use_level_II_oplocks = False;
3538 use_oplocks = saved_use_oplocks;
3542 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3543 if (!NT_STATUS_IS_OK(status)) {
3544 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3545 *shared_correct = False;
3551 status = cli_close(cli2, fnum2);
3552 if (!NT_STATUS_IS_OK(status)) {
3553 printf("close2 failed (%s)\n", nt_errstr(status));
3554 *shared_correct = False;
3562 /* Ensure cli1 processes the break. Empty file should always return 0
3564 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3565 if (!NT_STATUS_IS_OK(status)) {
3566 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3568 } else if (nread != 0) {
3569 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3570 (unsigned long)nread, 0);
3574 /* Should now be at level II. */
3575 /* Test if sending a write locks causes a break to none. */
3576 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3577 if (!NT_STATUS_IS_OK(status)) {
3578 printf("lock failed (%s)\n", nt_errstr(status));
3582 cli_unlock(cli1, fnum1, 0, 4);
3586 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3587 if (!NT_STATUS_IS_OK(status)) {
3588 printf("lock failed (%s)\n", nt_errstr(status));
3592 cli_unlock(cli1, fnum1, 0, 4);
3596 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3598 status = cli_close(cli1, fnum1);
3599 if (!NT_STATUS_IS_OK(status)) {
3600 printf("close1 failed (%s)\n", nt_errstr(status));
3606 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3607 if (!NT_STATUS_IS_OK(status)) {
3608 printf("unlink failed (%s)\n", nt_errstr(status));
3612 if (!torture_close_connection(cli1)) {
3616 if (!*shared_correct) {
3620 printf("finished oplock test 2\n");
3625 struct oplock4_state {
3626 struct tevent_context *ev;
3627 struct cli_state *cli;
3632 static void oplock4_got_break(struct tevent_req *req);
3633 static void oplock4_got_open(struct tevent_req *req);
3635 static bool run_oplock4(int dummy)
3637 struct tevent_context *ev;
3638 struct cli_state *cli1, *cli2;
3639 struct tevent_req *oplock_req, *open_req;
3640 const char *fname = "\\lockt4.lck";
3641 const char *fname_ln = "\\lockt4_ln.lck";
3642 uint16_t fnum1, fnum2;
3643 int saved_use_oplocks = use_oplocks;
3645 bool correct = true;
3649 struct oplock4_state *state;
3651 printf("starting oplock test 4\n");
3653 if (!torture_open_connection(&cli1, 0)) {
3654 use_level_II_oplocks = false;
3655 use_oplocks = saved_use_oplocks;
3659 if (!torture_open_connection(&cli2, 1)) {
3660 use_level_II_oplocks = false;
3661 use_oplocks = saved_use_oplocks;
3665 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3666 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3668 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3669 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3671 /* Create the file. */
3672 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3674 if (!NT_STATUS_IS_OK(status)) {
3675 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3679 status = cli_close(cli1, fnum1);
3680 if (!NT_STATUS_IS_OK(status)) {
3681 printf("close1 failed (%s)\n", nt_errstr(status));
3685 /* Now create a hardlink. */
3686 status = cli_nt_hardlink(cli1, fname, fname_ln);
3687 if (!NT_STATUS_IS_OK(status)) {
3688 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3692 /* Prove that opening hardlinks cause deny modes to conflict. */
3693 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3694 if (!NT_STATUS_IS_OK(status)) {
3695 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3699 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3700 if (NT_STATUS_IS_OK(status)) {
3701 printf("open of %s succeeded - should fail with sharing violation.\n",
3706 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3707 printf("open of %s should fail with sharing violation. Got %s\n",
3708 fname_ln, nt_errstr(status));
3712 status = cli_close(cli1, fnum1);
3713 if (!NT_STATUS_IS_OK(status)) {
3714 printf("close1 failed (%s)\n", nt_errstr(status));
3718 cli1->use_oplocks = true;
3719 cli2->use_oplocks = true;
3721 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3722 if (!NT_STATUS_IS_OK(status)) {
3723 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3727 ev = samba_tevent_context_init(talloc_tos());
3729 printf("tevent_context_init failed\n");
3733 state = talloc(ev, struct oplock4_state);
3734 if (state == NULL) {
3735 printf("talloc failed\n");
3740 state->got_break = &got_break;
3741 state->fnum2 = &fnum2;
3743 oplock_req = cli_smb_oplock_break_waiter_send(
3744 talloc_tos(), ev, cli1);
3745 if (oplock_req == NULL) {
3746 printf("cli_smb_oplock_break_waiter_send failed\n");
3749 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3751 open_req = cli_openx_send(
3752 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3753 if (open_req == NULL) {
3754 printf("cli_openx_send failed\n");
3757 tevent_req_set_callback(open_req, oplock4_got_open, state);
3762 while (!got_break || fnum2 == 0xffff) {
3764 ret = tevent_loop_once(ev);
3766 printf("tevent_loop_once failed: %s\n",
3772 status = cli_close(cli2, fnum2);
3773 if (!NT_STATUS_IS_OK(status)) {
3774 printf("close2 failed (%s)\n", nt_errstr(status));
3778 status = cli_close(cli1, fnum1);
3779 if (!NT_STATUS_IS_OK(status)) {
3780 printf("close1 failed (%s)\n", nt_errstr(status));
3784 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3785 if (!NT_STATUS_IS_OK(status)) {
3786 printf("unlink failed (%s)\n", nt_errstr(status));
3790 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3791 if (!NT_STATUS_IS_OK(status)) {
3792 printf("unlink failed (%s)\n", nt_errstr(status));
3796 if (!torture_close_connection(cli1)) {
3804 printf("finished oplock test 4\n");
3809 static void oplock4_got_break(struct tevent_req *req)
3811 struct oplock4_state *state = tevent_req_callback_data(
3812 req, struct oplock4_state);
3817 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3819 if (!NT_STATUS_IS_OK(status)) {
3820 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3824 *state->got_break = true;
3826 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3829 printf("cli_oplock_ack_send failed\n");
3834 static void oplock4_got_open(struct tevent_req *req)
3836 struct oplock4_state *state = tevent_req_callback_data(
3837 req, struct oplock4_state);
3840 status = cli_openx_recv(req, state->fnum2);
3841 if (!NT_STATUS_IS_OK(status)) {
3842 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3843 *state->fnum2 = 0xffff;
3848 Test delete on close semantics.
3850 static bool run_deletetest(int dummy)
3852 struct cli_state *cli1 = NULL;
3853 struct cli_state *cli2 = NULL;
3854 const char *fname = "\\delete.file";
3855 uint16_t fnum1 = (uint16_t)-1;
3856 uint16_t fnum2 = (uint16_t)-1;
3857 bool correct = false;
3860 printf("starting delete test\n");
3862 if (!torture_open_connection(&cli1, 0)) {
3866 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3868 /* Test 1 - this should delete the file on close. */
3870 cli_setatr(cli1, fname, 0, 0);
3871 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3873 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3874 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3875 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
3876 if (!NT_STATUS_IS_OK(status)) {
3877 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3881 status = cli_close(cli1, fnum1);
3882 if (!NT_STATUS_IS_OK(status)) {
3883 printf("[1] close failed (%s)\n", nt_errstr(status));
3887 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3888 if (NT_STATUS_IS_OK(status)) {
3889 printf("[1] open of %s succeeded (should fail)\n", fname);
3893 printf("first delete on close test succeeded.\n");
3895 /* Test 2 - this should delete the file on close. */
3897 cli_setatr(cli1, fname, 0, 0);
3898 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3900 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3901 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3902 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3903 if (!NT_STATUS_IS_OK(status)) {
3904 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3908 status = cli_nt_delete_on_close(cli1, fnum1, true);
3909 if (!NT_STATUS_IS_OK(status)) {
3910 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3914 status = cli_close(cli1, fnum1);
3915 if (!NT_STATUS_IS_OK(status)) {
3916 printf("[2] close failed (%s)\n", nt_errstr(status));
3920 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3921 if (NT_STATUS_IS_OK(status)) {
3922 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3923 status = cli_close(cli1, fnum1);
3924 if (!NT_STATUS_IS_OK(status)) {
3925 printf("[2] close failed (%s)\n", nt_errstr(status));
3927 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3931 printf("second delete on close test succeeded.\n");
3934 cli_setatr(cli1, fname, 0, 0);
3935 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3937 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3938 FILE_ATTRIBUTE_NORMAL,
3939 FILE_SHARE_READ|FILE_SHARE_WRITE,
3940 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3941 if (!NT_STATUS_IS_OK(status)) {
3942 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3946 /* This should fail with a sharing violation - open for delete is only compatible
3947 with SHARE_DELETE. */
3949 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3950 FILE_ATTRIBUTE_NORMAL,
3951 FILE_SHARE_READ|FILE_SHARE_WRITE,
3952 FILE_OPEN, 0, 0, &fnum2, NULL);
3953 if (NT_STATUS_IS_OK(status)) {
3954 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3958 /* This should succeed. */
3959 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3960 FILE_ATTRIBUTE_NORMAL,
3961 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3962 FILE_OPEN, 0, 0, &fnum2, NULL);
3963 if (!NT_STATUS_IS_OK(status)) {
3964 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
3968 status = cli_nt_delete_on_close(cli1, fnum1, true);
3969 if (!NT_STATUS_IS_OK(status)) {
3970 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3974 status = cli_close(cli1, fnum1);
3975 if (!NT_STATUS_IS_OK(status)) {
3976 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3980 status = cli_close(cli1, fnum2);
3981 if (!NT_STATUS_IS_OK(status)) {
3982 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3986 /* This should fail - file should no longer be there. */
3988 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3989 if (NT_STATUS_IS_OK(status)) {
3990 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3991 status = cli_close(cli1, fnum1);
3992 if (!NT_STATUS_IS_OK(status)) {
3993 printf("[3] close failed (%s)\n", nt_errstr(status));
3995 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3999 printf("third delete on close test succeeded.\n");
4002 cli_setatr(cli1, fname, 0, 0);
4003 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4005 status = cli_ntcreate(cli1, fname, 0,
4006 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4007 FILE_ATTRIBUTE_NORMAL,
4008 FILE_SHARE_READ|FILE_SHARE_WRITE,
4009 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4010 if (!NT_STATUS_IS_OK(status)) {
4011 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4015 /* This should succeed. */
4016 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4017 FILE_ATTRIBUTE_NORMAL,
4018 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4019 FILE_OPEN, 0, 0, &fnum2, NULL);
4020 if (!NT_STATUS_IS_OK(status)) {
4021 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4025 status = cli_close(cli1, fnum2);
4026 if (!NT_STATUS_IS_OK(status)) {
4027 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4031 status = cli_nt_delete_on_close(cli1, fnum1, true);
4032 if (!NT_STATUS_IS_OK(status)) {
4033 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4037 /* This should fail - no more opens once delete on close set. */
4038 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4039 FILE_ATTRIBUTE_NORMAL,
4040 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4041 FILE_OPEN, 0, 0, &fnum2, NULL);
4042 if (NT_STATUS_IS_OK(status)) {
4043 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4047 status = cli_close(cli1, fnum1);
4048 if (!NT_STATUS_IS_OK(status)) {
4049 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4053 printf("fourth delete on close test succeeded.\n");
4056 cli_setatr(cli1, fname, 0, 0);
4057 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4059 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4060 if (!NT_STATUS_IS_OK(status)) {
4061 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4065 /* This should fail - only allowed on NT opens with DELETE access. */
4067 status = cli_nt_delete_on_close(cli1, fnum1, true);
4068 if (NT_STATUS_IS_OK(status)) {
4069 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4073 status = cli_close(cli1, fnum1);
4074 if (!NT_STATUS_IS_OK(status)) {
4075 printf("[5] close failed (%s)\n", nt_errstr(status));
4079 printf("fifth delete on close test succeeded.\n");
4082 cli_setatr(cli1, fname, 0, 0);
4083 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4085 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4086 FILE_ATTRIBUTE_NORMAL,
4087 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4088 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4089 if (!NT_STATUS_IS_OK(status)) {
4090 printf("[6] open of %s failed (%s)\n", fname,
4095 /* This should fail - only allowed on NT opens with DELETE access. */
4097 status = cli_nt_delete_on_close(cli1, fnum1, true);
4098 if (NT_STATUS_IS_OK(status)) {
4099 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4103 status = cli_close(cli1, fnum1);
4104 if (!NT_STATUS_IS_OK(status)) {
4105 printf("[6] close failed (%s)\n", nt_errstr(status));
4109 printf("sixth delete on close test succeeded.\n");
4112 cli_setatr(cli1, fname, 0, 0);
4113 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4115 status = cli_ntcreate(cli1, fname, 0,
4116 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4117 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4118 0, 0, &fnum1, NULL);
4119 if (!NT_STATUS_IS_OK(status)) {
4120 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4124 status = cli_nt_delete_on_close(cli1, fnum1, true);
4125 if (!NT_STATUS_IS_OK(status)) {
4126 printf("[7] setting delete_on_close on file failed !\n");
4130 status = cli_nt_delete_on_close(cli1, fnum1, false);
4131 if (!NT_STATUS_IS_OK(status)) {
4132 printf("[7] unsetting delete_on_close on file failed !\n");
4136 status = cli_close(cli1, fnum1);
4137 if (!NT_STATUS_IS_OK(status)) {
4138 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4142 /* This next open should succeed - we reset the flag. */
4143 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4144 if (!NT_STATUS_IS_OK(status)) {
4145 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4149 status = cli_close(cli1, fnum1);
4150 if (!NT_STATUS_IS_OK(status)) {
4151 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4155 printf("seventh delete on close test succeeded.\n");
4158 cli_setatr(cli1, fname, 0, 0);
4159 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4161 if (!torture_open_connection(&cli2, 1)) {
4162 printf("[8] failed to open second connection.\n");
4166 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4168 status = cli_ntcreate(cli1, fname, 0,
4169 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4170 FILE_ATTRIBUTE_NORMAL,
4171 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4172 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4173 if (!NT_STATUS_IS_OK(status)) {
4174 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4178 status = cli_ntcreate(cli2, fname, 0,
4179 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4180 FILE_ATTRIBUTE_NORMAL,
4181 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4182 FILE_OPEN, 0, 0, &fnum2, NULL);
4183 if (!NT_STATUS_IS_OK(status)) {
4184 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4188 status = cli_nt_delete_on_close(cli1, fnum1, true);
4189 if (!NT_STATUS_IS_OK(status)) {
4190 printf("[8] setting delete_on_close on file failed !\n");
4194 status = cli_close(cli1, fnum1);
4195 if (!NT_STATUS_IS_OK(status)) {
4196 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4200 status = cli_close(cli2, fnum2);
4201 if (!NT_STATUS_IS_OK(status)) {
4202 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4206 /* This should fail.. */
4207 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4208 if (NT_STATUS_IS_OK(status)) {
4209 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4213 printf("eighth delete on close test succeeded.\n");
4217 /* This should fail - we need to set DELETE_ACCESS. */
4218 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4219 FILE_ATTRIBUTE_NORMAL,
4222 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4223 if (NT_STATUS_IS_OK(status)) {
4224 printf("[9] open of %s succeeded should have failed!\n", fname);
4228 printf("ninth delete on close test succeeded.\n");
4232 status = cli_ntcreate(cli1, fname, 0,
4233 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4234 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4235 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4237 if (!NT_STATUS_IS_OK(status)) {
4238 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4242 /* This should delete the file. */
4243 status = cli_close(cli1, fnum1);
4244 if (!NT_STATUS_IS_OK(status)) {
4245 printf("[10] close failed (%s)\n", nt_errstr(status));
4249 /* This should fail.. */
4250 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4251 if (NT_STATUS_IS_OK(status)) {
4252 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4256 printf("tenth delete on close test succeeded.\n");
4260 cli_setatr(cli1, fname, 0, 0);
4261 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4263 /* Can we open a read-only file with delete access? */
4265 /* Create a readonly file. */
4266 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4267 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4268 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4269 if (!NT_STATUS_IS_OK(status)) {
4270 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4274 status = cli_close(cli1, fnum1);
4275 if (!NT_STATUS_IS_OK(status)) {
4276 printf("[11] close failed (%s)\n", nt_errstr(status));
4280 /* Now try open for delete access. */
4281 status = cli_ntcreate(cli1, fname, 0,
4282 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4284 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4285 FILE_OPEN, 0, 0, &fnum1, NULL);
4286 if (!NT_STATUS_IS_OK(status)) {
4287 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4291 cli_close(cli1, fnum1);
4293 printf("eleventh delete on close test succeeded.\n");
4297 * like test 4 but with initial delete on close
4300 cli_setatr(cli1, fname, 0, 0);
4301 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4303 status = cli_ntcreate(cli1, fname, 0,
4304 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4305 FILE_ATTRIBUTE_NORMAL,
4306 FILE_SHARE_READ|FILE_SHARE_WRITE,
4308 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4309 if (!NT_STATUS_IS_OK(status)) {
4310 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4314 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4315 FILE_ATTRIBUTE_NORMAL,
4316 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4317 FILE_OPEN, 0, 0, &fnum2, NULL);
4318 if (!NT_STATUS_IS_OK(status)) {
4319 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4323 status = cli_close(cli1, fnum2);
4324 if (!NT_STATUS_IS_OK(status)) {
4325 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4329 status = cli_nt_delete_on_close(cli1, fnum1, true);
4330 if (!NT_STATUS_IS_OK(status)) {
4331 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4335 /* This should fail - no more opens once delete on close set. */
4336 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4337 FILE_ATTRIBUTE_NORMAL,
4338 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4339 FILE_OPEN, 0, 0, &fnum2, NULL);
4340 if (NT_STATUS_IS_OK(status)) {
4341 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4345 status = cli_nt_delete_on_close(cli1, fnum1, false);
4346 if (!NT_STATUS_IS_OK(status)) {
4347 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4351 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4352 FILE_ATTRIBUTE_NORMAL,
4353 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4354 FILE_OPEN, 0, 0, &fnum2, NULL);
4355 if (!NT_STATUS_IS_OK(status)) {
4356 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4360 status = cli_close(cli1, fnum2);
4361 if (!NT_STATUS_IS_OK(status)) {
4362 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4366 status = cli_close(cli1, fnum1);
4367 if (!NT_STATUS_IS_OK(status)) {
4368 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4373 * setting delete on close on the handle does
4374 * not unset the initial delete on close...
4376 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4377 FILE_ATTRIBUTE_NORMAL,
4378 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4379 FILE_OPEN, 0, 0, &fnum2, NULL);
4380 if (NT_STATUS_IS_OK(status)) {
4381 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4383 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4384 printf("ntcreate returned %s, expected "
4385 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4390 printf("twelfth delete on close test succeeded.\n");
4393 printf("finished delete test\n");
4398 /* FIXME: This will crash if we aborted before cli2 got
4399 * intialized, because these functions don't handle
4400 * uninitialized connections. */
4402 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4403 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4404 cli_setatr(cli1, fname, 0, 0);
4405 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4407 if (cli1 && !torture_close_connection(cli1)) {
4410 if (cli2 && !torture_close_connection(cli2)) {
4418 Test wildcard delete.
4420 static bool run_wild_deletetest(int dummy)
4422 struct cli_state *cli = NULL;
4423 const char *dname = "\\WTEST";
4424 const char *fname = "\\WTEST\\A";
4425 const char *wunlink_name = "\\WTEST\\*";
4426 uint16_t fnum1 = (uint16_t)-1;
4427 bool correct = false;
4430 printf("starting wildcard delete test\n");
4432 if (!torture_open_connection(&cli, 0)) {
4436 smbXcli_conn_set_sockopt(cli->conn, sockops);
4438 cli_unlink(cli, fname, 0);
4439 cli_rmdir(cli, dname);
4440 status = cli_mkdir(cli, dname);
4441 if (!NT_STATUS_IS_OK(status)) {
4442 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4445 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4446 if (!NT_STATUS_IS_OK(status)) {
4447 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4450 status = cli_close(cli, fnum1);
4454 * Note the unlink attribute-type of zero. This should
4455 * map into FILE_ATTRIBUTE_NORMAL at the server even
4456 * on a wildcard delete.
4459 status = cli_unlink(cli, wunlink_name, 0);
4460 if (!NT_STATUS_IS_OK(status)) {
4461 printf("unlink of %s failed %s!\n",
4462 wunlink_name, nt_errstr(status));
4466 printf("finished wildcard delete test\n");
4472 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4473 cli_unlink(cli, fname, 0);
4474 cli_rmdir(cli, dname);
4476 if (cli && !torture_close_connection(cli)) {
4482 static bool run_deletetest_ln(int dummy)
4484 struct cli_state *cli;
4485 const char *fname = "\\delete1";
4486 const char *fname_ln = "\\delete1_ln";
4490 bool correct = true;
4493 printf("starting deletetest-ln\n");
4495 if (!torture_open_connection(&cli, 0)) {
4499 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4500 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4502 smbXcli_conn_set_sockopt(cli->conn, sockops);
4504 /* Create the file. */
4505 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4506 if (!NT_STATUS_IS_OK(status)) {
4507 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4511 status = cli_close(cli, fnum);
4512 if (!NT_STATUS_IS_OK(status)) {
4513 printf("close1 failed (%s)\n", nt_errstr(status));
4517 /* Now create a hardlink. */
4518 status = cli_nt_hardlink(cli, fname, fname_ln);
4519 if (!NT_STATUS_IS_OK(status)) {
4520 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4524 /* Open the original file. */
4525 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4526 FILE_ATTRIBUTE_NORMAL,
4527 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4528 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4529 if (!NT_STATUS_IS_OK(status)) {
4530 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4534 /* Unlink the hard link path. */
4535 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4536 FILE_ATTRIBUTE_NORMAL,
4537 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4538 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4539 if (!NT_STATUS_IS_OK(status)) {
4540 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4543 status = cli_nt_delete_on_close(cli, fnum1, true);
4544 if (!NT_STATUS_IS_OK(status)) {
4545 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4546 __location__, fname_ln, nt_errstr(status));
4550 status = cli_close(cli, fnum1);
4551 if (!NT_STATUS_IS_OK(status)) {
4552 printf("close %s failed (%s)\n",
4553 fname_ln, nt_errstr(status));
4557 status = cli_close(cli, fnum);
4558 if (!NT_STATUS_IS_OK(status)) {
4559 printf("close %s failed (%s)\n",
4560 fname, nt_errstr(status));
4564 /* Ensure the original file is still there. */
4565 status = cli_getatr(cli, fname, NULL, NULL, &t);
4566 if (!NT_STATUS_IS_OK(status)) {
4567 printf("%s getatr on file %s failed (%s)\n",
4574 /* Ensure the link path is gone. */
4575 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4576 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4577 printf("%s, getatr for file %s returned wrong error code %s "
4578 "- should have been deleted\n",
4580 fname_ln, nt_errstr(status));
4584 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4585 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4587 if (!torture_close_connection(cli)) {
4591 printf("finished deletetest-ln\n");
4597 print out server properties
4599 static bool run_properties(int dummy)
4601 struct cli_state *cli;
4602 bool correct = True;
4604 printf("starting properties test\n");
4608 if (!torture_open_connection(&cli, 0)) {
4612 smbXcli_conn_set_sockopt(cli->conn, sockops);
4614 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4616 if (!torture_close_connection(cli)) {
4625 /* FIRST_DESIRED_ACCESS 0xf019f */
4626 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4627 FILE_READ_EA| /* 0xf */ \
4628 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4629 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4630 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4631 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4632 /* SECOND_DESIRED_ACCESS 0xe0080 */
4633 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4634 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4635 WRITE_OWNER_ACCESS /* 0xe0000 */
4638 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4639 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4641 WRITE_OWNER_ACCESS /* */
4645 Test ntcreate calls made by xcopy
4647 static bool run_xcopy(int dummy)
4649 static struct cli_state *cli1;
4650 const char *fname = "\\test.txt";
4651 bool correct = True;
4652 uint16_t fnum1, fnum2;
4655 printf("starting xcopy test\n");
4657 if (!torture_open_connection(&cli1, 0)) {
4661 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4662 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4663 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4664 if (!NT_STATUS_IS_OK(status)) {
4665 printf("First open failed - %s\n", nt_errstr(status));
4669 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4670 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4671 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4672 if (!NT_STATUS_IS_OK(status)) {
4673 printf("second open failed - %s\n", nt_errstr(status));
4677 if (!torture_close_connection(cli1)) {
4685 Test rename on files open with share delete and no share delete.
4687 static bool run_rename(int dummy)
4689 static struct cli_state *cli1;
4690 const char *fname = "\\test.txt";
4691 const char *fname1 = "\\test1.txt";
4692 bool correct = True;
4697 printf("starting rename test\n");
4699 if (!torture_open_connection(&cli1, 0)) {
4703 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4704 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4706 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4707 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4708 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4709 if (!NT_STATUS_IS_OK(status)) {
4710 printf("First open failed - %s\n", nt_errstr(status));
4714 status = cli_rename(cli1, fname, fname1, false);
4715 if (!NT_STATUS_IS_OK(status)) {
4716 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4718 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4722 status = cli_close(cli1, fnum1);
4723 if (!NT_STATUS_IS_OK(status)) {
4724 printf("close - 1 failed (%s)\n", nt_errstr(status));
4728 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4729 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4730 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4732 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4734 FILE_SHARE_DELETE|FILE_SHARE_READ,
4736 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4737 if (!NT_STATUS_IS_OK(status)) {
4738 printf("Second open failed - %s\n", nt_errstr(status));
4742 status = cli_rename(cli1, fname, fname1, false);
4743 if (!NT_STATUS_IS_OK(status)) {
4744 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4747 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4750 status = cli_close(cli1, fnum1);
4751 if (!NT_STATUS_IS_OK(status)) {
4752 printf("close - 2 failed (%s)\n", nt_errstr(status));
4756 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4757 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4759 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4760 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4761 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4762 if (!NT_STATUS_IS_OK(status)) {
4763 printf("Third open failed - %s\n", nt_errstr(status));
4772 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4773 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4774 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4777 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4778 printf("[8] setting delete_on_close on file failed !\n");
4782 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4783 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4789 status = cli_rename(cli1, fname, fname1, false);
4790 if (!NT_STATUS_IS_OK(status)) {
4791 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4794 printf("Third rename succeeded (SHARE_NONE)\n");
4797 status = cli_close(cli1, fnum1);
4798 if (!NT_STATUS_IS_OK(status)) {
4799 printf("close - 3 failed (%s)\n", nt_errstr(status));
4803 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4804 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4808 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4809 FILE_ATTRIBUTE_NORMAL,
4810 FILE_SHARE_READ | FILE_SHARE_WRITE,
4811 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4812 if (!NT_STATUS_IS_OK(status)) {
4813 printf("Fourth open failed - %s\n", nt_errstr(status));
4817 status = cli_rename(cli1, fname, fname1, false);
4818 if (!NT_STATUS_IS_OK(status)) {
4819 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4821 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4825 status = cli_close(cli1, fnum1);
4826 if (!NT_STATUS_IS_OK(status)) {
4827 printf("close - 4 failed (%s)\n", nt_errstr(status));
4831 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4832 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4836 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4837 FILE_ATTRIBUTE_NORMAL,
4838 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4839 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4840 if (!NT_STATUS_IS_OK(status)) {
4841 printf("Fifth open failed - %s\n", nt_errstr(status));
4845 status = cli_rename(cli1, fname, fname1, false);
4846 if (!NT_STATUS_IS_OK(status)) {
4847 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4850 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4854 * Now check if the first name still exists ...
4857 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4858 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4859 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4860 printf("Opening original file after rename of open file fails: %s\n",
4864 printf("Opening original file after rename of open file works ...\n");
4865 (void)cli_close(cli1, fnum2);
4869 status = cli_close(cli1, fnum1);
4870 if (!NT_STATUS_IS_OK(status)) {
4871 printf("close - 5 failed (%s)\n", nt_errstr(status));
4875 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4876 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4877 if (!NT_STATUS_IS_OK(status)) {
4878 printf("getatr on file %s failed - %s ! \n",
4879 fname1, nt_errstr(status));
4882 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4883 printf("Renamed file %s has wrong attr 0x%x "
4884 "(should be 0x%x)\n",
4887 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4890 printf("Renamed file %s has archive bit set\n", fname1);
4894 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4895 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4897 if (!torture_close_connection(cli1)) {
4905 Test rename into a directory with an ACL denying it.
4907 static bool run_rename_access(int dummy)
4909 static struct cli_state *cli = NULL;
4910 static struct cli_state *posix_cli = NULL;
4911 const char *src = "test.txt";
4912 const char *dname = "dir";
4913 const char *dst = "dir\\test.txt";
4914 const char *dsrc = "test.dir";
4915 const char *ddst = "dir\\test.dir";
4916 uint16_t fnum = (uint16_t)-1;
4917 struct security_descriptor *sd = NULL;
4918 struct security_descriptor *newsd = NULL;
4920 TALLOC_CTX *frame = NULL;
4922 frame = talloc_stackframe();
4923 printf("starting rename access test\n");
4925 /* Windows connection. */
4926 if (!torture_open_connection(&cli, 0)) {
4930 smbXcli_conn_set_sockopt(cli->conn, sockops);
4932 /* Posix connection. */
4933 if (!torture_open_connection(&posix_cli, 0)) {
4937 smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
4939 status = torture_setup_unix_extensions(posix_cli);
4940 if (!NT_STATUS_IS_OK(status)) {
4944 /* Start with a clean slate. */
4945 cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4946 cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4947 cli_rmdir(cli, dsrc);
4948 cli_rmdir(cli, ddst);
4949 cli_rmdir(cli, dname);
4952 * Setup the destination directory with a DENY ACE to
4953 * prevent new files within it.
4955 status = cli_ntcreate(cli,
4958 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
4959 WRITE_DAC_ACCESS|FILE_READ_DATA|
4961 FILE_ATTRIBUTE_DIRECTORY,
4962 FILE_SHARE_READ|FILE_SHARE_WRITE,
4964 FILE_DIRECTORY_FILE,
4968 if (!NT_STATUS_IS_OK(status)) {
4969 printf("Create of %s - %s\n", dname, nt_errstr(status));
4973 status = cli_query_secdesc(cli,
4977 if (!NT_STATUS_IS_OK(status)) {
4978 printf("cli_query_secdesc failed for %s (%s)\n",
4979 dname, nt_errstr(status));
4983 newsd = security_descriptor_dacl_create(frame,
4988 SEC_ACE_TYPE_ACCESS_DENIED,
4989 SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
4992 if (newsd == NULL) {
4995 sd->dacl = security_acl_concatenate(frame,
4998 if (sd->dacl == NULL) {
5001 status = cli_set_secdesc(cli, fnum, sd);
5002 if (!NT_STATUS_IS_OK(status)) {
5003 printf("cli_set_secdesc failed for %s (%s)\n",
5004 dname, nt_errstr(status));
5007 status = cli_close(cli, fnum);
5008 if (!NT_STATUS_IS_OK(status)) {
5009 printf("close failed for %s (%s)\n",
5010 dname, nt_errstr(status));
5013 /* Now go around the back and chmod to 777 via POSIX. */
5014 status = cli_posix_chmod(posix_cli, dname, 0777);
5015 if (!NT_STATUS_IS_OK(status)) {
5016 printf("cli_posix_chmod failed for %s (%s)\n",
5017 dname, nt_errstr(status));
5021 /* Check we can't create a file within dname via Windows. */
5022 status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5023 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5024 cli_close(posix_cli, fnum);
5025 printf("Create of %s should be ACCESS denied, was %s\n",
5026 dst, nt_errstr(status));
5030 /* Make the sample file/directory. */
5031 status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5032 if (!NT_STATUS_IS_OK(status)) {
5033 printf("open of %s failed (%s)\n", src, nt_errstr(status));
5036 status = cli_close(cli, fnum);
5037 if (!NT_STATUS_IS_OK(status)) {
5038 printf("cli_close failed (%s)\n", nt_errstr(status));
5042 status = cli_mkdir(cli, dsrc);
5043 if (!NT_STATUS_IS_OK(status)) {
5044 printf("cli_mkdir of %s failed (%s)\n",
5045 dsrc, nt_errstr(status));
5050 * OK - renames of the new file and directory into the
5051 * dst directory should fail.
5054 status = cli_rename(cli, src, dst, false);
5055 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5056 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5057 src, dst, nt_errstr(status));
5060 status = cli_rename(cli, dsrc, ddst, false);
5061 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5062 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5063 src, dst, nt_errstr(status));
5073 torture_close_connection(posix_cli);
5077 if (fnum != (uint64_t)-1) {
5078 cli_close(cli, fnum);
5080 cli_unlink(cli, src,
5081 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5082 cli_unlink(cli, dst,
5083 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5084 cli_rmdir(cli, dsrc);
5085 cli_rmdir(cli, ddst);
5086 cli_rmdir(cli, dname);
5088 torture_close_connection(cli);
5096 Test owner rights ACE.
5098 static bool run_owner_rights(int dummy)
5100 static struct cli_state *cli = NULL;
5101 const char *fname = "owner_rights.txt";
5102 uint16_t fnum = (uint16_t)-1;
5103 struct security_descriptor *sd = NULL;
5104 struct security_descriptor *newsd = NULL;
5106 TALLOC_CTX *frame = NULL;
5108 frame = talloc_stackframe();
5109 printf("starting owner rights test\n");
5111 /* Windows connection. */
5112 if (!torture_open_connection(&cli, 0)) {
5116 smbXcli_conn_set_sockopt(cli->conn, sockops);
5118 /* Start with a clean slate. */
5119 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5121 /* Create the test file. */
5122 /* Now try and open for read and write-dac. */
5123 status = cli_ntcreate(cli,
5127 FILE_ATTRIBUTE_NORMAL,
5128 FILE_SHARE_READ|FILE_SHARE_WRITE|
5135 if (!NT_STATUS_IS_OK(status)) {
5136 printf("Create of %s - %s\n", fname, nt_errstr(status));
5140 /* Get the original SD. */
5141 status = cli_query_secdesc(cli,
5145 if (!NT_STATUS_IS_OK(status)) {
5146 printf("cli_query_secdesc failed for %s (%s)\n",
5147 fname, nt_errstr(status));
5152 * Add an "owner-rights" ACE denying WRITE_DATA,
5153 * and an "owner-rights" ACE allowing READ_DATA.
5156 newsd = security_descriptor_dacl_create(frame,
5161 SEC_ACE_TYPE_ACCESS_DENIED,
5165 SEC_ACE_TYPE_ACCESS_ALLOWED,
5169 if (newsd == NULL) {
5172 sd->dacl = security_acl_concatenate(frame,
5175 if (sd->dacl == NULL) {
5178 status = cli_set_secdesc(cli, fnum, sd);
5179 if (!NT_STATUS_IS_OK(status)) {
5180 printf("cli_set_secdesc failed for %s (%s)\n",
5181 fname, nt_errstr(status));
5184 status = cli_close(cli, fnum);
5185 if (!NT_STATUS_IS_OK(status)) {
5186 printf("close failed for %s (%s)\n",
5187 fname, nt_errstr(status));
5190 fnum = (uint16_t)-1;
5192 /* Try and open for FILE_WRITE_DATA */
5193 status = cli_ntcreate(cli,
5197 FILE_ATTRIBUTE_NORMAL,
5198 FILE_SHARE_READ|FILE_SHARE_WRITE|
5205 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5206 printf("Open of %s - %s\n", fname, nt_errstr(status));
5210 /* Now try and open for FILE_READ_DATA */
5211 status = cli_ntcreate(cli,
5215 FILE_ATTRIBUTE_NORMAL,
5216 FILE_SHARE_READ|FILE_SHARE_WRITE|
5223 if (!NT_STATUS_IS_OK(status)) {
5224 printf("Open of %s - %s\n", fname, nt_errstr(status));
5228 status = cli_close(cli, fnum);
5229 if (!NT_STATUS_IS_OK(status)) {
5230 printf("close failed for %s (%s)\n",
5231 fname, nt_errstr(status));
5235 /* Restore clean slate. */
5237 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5239 /* Create the test file. */
5240 status = cli_ntcreate(cli,
5244 FILE_ATTRIBUTE_NORMAL,
5245 FILE_SHARE_READ|FILE_SHARE_WRITE|
5252 if (!NT_STATUS_IS_OK(status)) {
5253 printf("Create of %s - %s\n", fname, nt_errstr(status));
5257 /* Get the original SD. */
5258 status = cli_query_secdesc(cli,
5262 if (!NT_STATUS_IS_OK(status)) {
5263 printf("cli_query_secdesc failed for %s (%s)\n",
5264 fname, nt_errstr(status));
5269 * Add an "owner-rights ACE denying WRITE_DATA,
5270 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5273 newsd = security_descriptor_dacl_create(frame,
5278 SEC_ACE_TYPE_ACCESS_DENIED,
5282 SEC_ACE_TYPE_ACCESS_ALLOWED,
5283 FILE_READ_DATA|FILE_WRITE_DATA,
5286 if (newsd == NULL) {
5289 sd->dacl = security_acl_concatenate(frame,
5292 if (sd->dacl == NULL) {
5295 status = cli_set_secdesc(cli, fnum, sd);
5296 if (!NT_STATUS_IS_OK(status)) {
5297 printf("cli_set_secdesc failed for %s (%s)\n",
5298 fname, nt_errstr(status));
5301 status = cli_close(cli, fnum);
5302 if (!NT_STATUS_IS_OK(status)) {
5303 printf("close failed for %s (%s)\n",
5304 fname, nt_errstr(status));
5307 fnum = (uint16_t)-1;
5309 /* Try and open for FILE_WRITE_DATA */
5310 status = cli_ntcreate(cli,
5314 FILE_ATTRIBUTE_NORMAL,
5315 FILE_SHARE_READ|FILE_SHARE_WRITE|
5322 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5323 printf("Open of %s - %s\n", fname, nt_errstr(status));
5327 /* Now try and open for FILE_READ_DATA */
5328 status = cli_ntcreate(cli,
5332 FILE_ATTRIBUTE_NORMAL,
5333 FILE_SHARE_READ|FILE_SHARE_WRITE|
5340 if (!NT_STATUS_IS_OK(status)) {
5341 printf("Open of %s - %s\n", fname, nt_errstr(status));
5345 status = cli_close(cli, fnum);
5346 if (!NT_STATUS_IS_OK(status)) {
5347 printf("close failed for %s (%s)\n",
5348 fname, nt_errstr(status));
5352 /* Restore clean slate. */
5354 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5357 /* Create the test file. */
5358 status = cli_ntcreate(cli,
5362 FILE_ATTRIBUTE_NORMAL,
5363 FILE_SHARE_READ|FILE_SHARE_WRITE|
5370 if (!NT_STATUS_IS_OK(status)) {
5371 printf("Create of %s - %s\n", fname, nt_errstr(status));
5375 /* Get the original SD. */
5376 status = cli_query_secdesc(cli,
5380 if (!NT_STATUS_IS_OK(status)) {
5381 printf("cli_query_secdesc failed for %s (%s)\n",
5382 fname, nt_errstr(status));
5387 * Add an "authenticated users" ACE allowing READ_DATA,
5388 * add an "owner-rights" denying READ_DATA,
5389 * and an "authenticated users" ACE allowing WRITE_DATA.
5392 newsd = security_descriptor_dacl_create(frame,
5396 SID_NT_AUTHENTICATED_USERS,
5397 SEC_ACE_TYPE_ACCESS_ALLOWED,
5401 SEC_ACE_TYPE_ACCESS_DENIED,
5404 SID_NT_AUTHENTICATED_USERS,
5405 SEC_ACE_TYPE_ACCESS_ALLOWED,
5409 if (newsd == NULL) {
5410 printf("newsd == NULL\n");
5413 sd->dacl = security_acl_concatenate(frame,
5416 if (sd->dacl == NULL) {
5417 printf("sd->dacl == NULL\n");
5420 status = cli_set_secdesc(cli, fnum, sd);
5421 if (!NT_STATUS_IS_OK(status)) {
5422 printf("cli_set_secdesc failed for %s (%s)\n",
5423 fname, nt_errstr(status));
5426 status = cli_close(cli, fnum);
5427 if (!NT_STATUS_IS_OK(status)) {
5428 printf("close failed for %s (%s)\n",
5429 fname, nt_errstr(status));
5432 fnum = (uint16_t)-1;
5434 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5435 status = cli_ntcreate(cli,
5438 FILE_READ_DATA|FILE_WRITE_DATA,
5439 FILE_ATTRIBUTE_NORMAL,
5440 FILE_SHARE_READ|FILE_SHARE_WRITE|
5447 if (!NT_STATUS_IS_OK(status)) {
5448 printf("Open of %s - %s\n", fname, nt_errstr(status));
5452 status = cli_close(cli, fnum);
5453 if (!NT_STATUS_IS_OK(status)) {
5454 printf("close failed for %s (%s)\n",
5455 fname, nt_errstr(status));
5459 cli_unlink(cli, fname,
5460 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5468 if (fnum != (uint16_t)-1) {
5469 cli_close(cli, fnum);
5471 cli_unlink(cli, fname,
5472 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5473 torture_close_connection(cli);
5480 static bool run_pipe_number(int dummy)
5482 struct cli_state *cli1;
5483 const char *pipe_name = "\\SPOOLSS";
5488 printf("starting pipenumber test\n");
5489 if (!torture_open_connection(&cli1, 0)) {
5493 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5495 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
5496 FILE_ATTRIBUTE_NORMAL,
5497 FILE_SHARE_READ|FILE_SHARE_WRITE,
5498 FILE_OPEN_IF, 0, 0, &fnum, NULL);
5499 if (!NT_STATUS_IS_OK(status)) {
5500 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
5504 printf("\r%6d", num_pipes);
5507 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
5508 torture_close_connection(cli1);
5513 Test open mode returns on read-only files.
5515 static bool run_opentest(int dummy)
5517 static struct cli_state *cli1;
5518 static struct cli_state *cli2;
5519 const char *fname = "\\readonly.file";
5520 uint16_t fnum1, fnum2;
5523 bool correct = True;
5527 printf("starting open test\n");
5529 if (!torture_open_connection(&cli1, 0)) {
5533 cli_setatr(cli1, fname, 0, 0);
5534 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5536 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5538 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5539 if (!NT_STATUS_IS_OK(status)) {
5540 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5544 status = cli_close(cli1, fnum1);
5545 if (!NT_STATUS_IS_OK(status)) {
5546 printf("close2 failed (%s)\n", nt_errstr(status));
5550 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
5551 if (!NT_STATUS_IS_OK(status)) {
5552 printf("cli_setatr failed (%s)\n", nt_errstr(status));
5556 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5557 if (!NT_STATUS_IS_OK(status)) {
5558 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5562 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5563 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5565 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
5566 NT_STATUS_ACCESS_DENIED)) {
5567 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5570 printf("finished open test 1\n");
5572 cli_close(cli1, fnum1);
5574 /* Now try not readonly and ensure ERRbadshare is returned. */
5576 cli_setatr(cli1, fname, 0, 0);
5578 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5579 if (!NT_STATUS_IS_OK(status)) {
5580 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5584 /* This will fail - but the error should be ERRshare. */
5585 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5587 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5588 NT_STATUS_SHARING_VIOLATION)) {
5589 printf("correct error code ERRDOS/ERRbadshare returned\n");
5592 status = cli_close(cli1, fnum1);
5593 if (!NT_STATUS_IS_OK(status)) {
5594 printf("close2 failed (%s)\n", nt_errstr(status));
5598 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5600 printf("finished open test 2\n");
5602 /* Test truncate open disposition on file opened for read. */
5603 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5604 if (!NT_STATUS_IS_OK(status)) {
5605 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5609 /* write 20 bytes. */
5611 memset(buf, '\0', 20);
5613 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5614 if (!NT_STATUS_IS_OK(status)) {
5615 printf("write failed (%s)\n", nt_errstr(status));
5619 status = cli_close(cli1, fnum1);
5620 if (!NT_STATUS_IS_OK(status)) {
5621 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5625 /* Ensure size == 20. */
5626 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5627 if (!NT_STATUS_IS_OK(status)) {
5628 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5633 printf("(3) file size != 20\n");
5637 /* Now test if we can truncate a file opened for readonly. */
5638 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5639 if (!NT_STATUS_IS_OK(status)) {
5640 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5644 status = cli_close(cli1, fnum1);
5645 if (!NT_STATUS_IS_OK(status)) {
5646 printf("close2 failed (%s)\n", nt_errstr(status));
5650 /* Ensure size == 0. */
5651 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5652 if (!NT_STATUS_IS_OK(status)) {
5653 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5658 printf("(3) file size != 0\n");
5661 printf("finished open test 3\n");
5663 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5665 printf("Do ctemp tests\n");
5666 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5667 if (!NT_STATUS_IS_OK(status)) {
5668 printf("ctemp failed (%s)\n", nt_errstr(status));
5672 printf("ctemp gave path %s\n", tmp_path);
5673 status = cli_close(cli1, fnum1);
5674 if (!NT_STATUS_IS_OK(status)) {
5675 printf("close of temp failed (%s)\n", nt_errstr(status));
5678 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5679 if (!NT_STATUS_IS_OK(status)) {
5680 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5683 /* Test the non-io opens... */
5685 if (!torture_open_connection(&cli2, 1)) {
5689 cli_setatr(cli2, fname, 0, 0);
5690 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5692 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5694 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5695 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5696 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5697 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5698 if (!NT_STATUS_IS_OK(status)) {
5699 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5703 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5704 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5705 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5706 if (!NT_STATUS_IS_OK(status)) {
5707 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5711 status = cli_close(cli1, fnum1);
5712 if (!NT_STATUS_IS_OK(status)) {
5713 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5717 status = cli_close(cli2, fnum2);
5718 if (!NT_STATUS_IS_OK(status)) {
5719 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5723 printf("non-io open test #1 passed.\n");
5725 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5727 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5729 status = cli_ntcreate(cli1, fname, 0,
5730 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5731 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5732 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5733 if (!NT_STATUS_IS_OK(status)) {
5734 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5738 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5739 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5740 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5741 if (!NT_STATUS_IS_OK(status)) {
5742 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5746 status = cli_close(cli1, fnum1);
5747 if (!NT_STATUS_IS_OK(status)) {
5748 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5752 status = cli_close(cli2, fnum2);
5753 if (!NT_STATUS_IS_OK(status)) {
5754 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5758 printf("non-io open test #2 passed.\n");
5760 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5762 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5764 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5765 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5766 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5767 if (!NT_STATUS_IS_OK(status)) {
5768 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5772 status = cli_ntcreate(cli2, fname, 0,
5773 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5774 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5775 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5776 if (!NT_STATUS_IS_OK(status)) {
5777 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5781 status = cli_close(cli1, fnum1);
5782 if (!NT_STATUS_IS_OK(status)) {
5783 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5787 status = cli_close(cli2, fnum2);
5788 if (!NT_STATUS_IS_OK(status)) {
5789 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5793 printf("non-io open test #3 passed.\n");
5795 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5797 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5799 status = cli_ntcreate(cli1, fname, 0,
5800 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5801 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5802 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5803 if (!NT_STATUS_IS_OK(status)) {
5804 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5808 status = cli_ntcreate(cli2, fname, 0,
5809 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5810 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5811 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5812 if (NT_STATUS_IS_OK(status)) {
5813 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5817 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5819 status = cli_close(cli1, fnum1);
5820 if (!NT_STATUS_IS_OK(status)) {
5821 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5825 printf("non-io open test #4 passed.\n");
5827 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5829 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5831 status = cli_ntcreate(cli1, fname, 0,
5832 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5833 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5834 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5835 if (!NT_STATUS_IS_OK(status)) {
5836 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5840 status = cli_ntcreate(cli2, fname, 0,
5841 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5842 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5843 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5844 if (!NT_STATUS_IS_OK(status)) {
5845 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5849 status = cli_close(cli1, fnum1);
5850 if (!NT_STATUS_IS_OK(status)) {
5851 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5855 status = cli_close(cli2, fnum2);
5856 if (!NT_STATUS_IS_OK(status)) {
5857 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5861 printf("non-io open test #5 passed.\n");
5863 printf("TEST #6 testing 1 non-io open, one io open\n");
5865 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5867 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5868 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5869 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5870 if (!NT_STATUS_IS_OK(status)) {
5871 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5875 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5876 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5877 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5878 if (!NT_STATUS_IS_OK(status)) {
5879 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5883 status = cli_close(cli1, fnum1);
5884 if (!NT_STATUS_IS_OK(status)) {
5885 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5889 status = cli_close(cli2, fnum2);
5890 if (!NT_STATUS_IS_OK(status)) {
5891 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5895 printf("non-io open test #6 passed.\n");
5897 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5899 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5901 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5902 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5903 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5904 if (!NT_STATUS_IS_OK(status)) {
5905 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5909 status = cli_ntcreate(cli2, fname, 0,
5910 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5911 FILE_ATTRIBUTE_NORMAL,
5912 FILE_SHARE_READ|FILE_SHARE_DELETE,
5913 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5914 if (NT_STATUS_IS_OK(status)) {
5915 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5919 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5921 status = cli_close(cli1, fnum1);
5922 if (!NT_STATUS_IS_OK(status)) {
5923 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5927 printf("non-io open test #7 passed.\n");
5929 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5931 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5932 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5933 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5934 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5935 if (!NT_STATUS_IS_OK(status)) {
5936 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5941 /* Write to ensure we have to update the file time. */
5942 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5944 if (!NT_STATUS_IS_OK(status)) {
5945 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5950 status = cli_close(cli1, fnum1);
5951 if (!NT_STATUS_IS_OK(status)) {
5952 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5958 if (!torture_close_connection(cli1)) {
5961 if (!torture_close_connection(cli2)) {
5968 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5970 uint16_t major, minor;
5971 uint32_t caplow, caphigh;
5974 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5975 printf("Server doesn't support UNIX CIFS extensions.\n");
5976 return NT_STATUS_NOT_SUPPORTED;
5979 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5981 if (!NT_STATUS_IS_OK(status)) {
5982 printf("Server didn't return UNIX CIFS extensions: %s\n",
5987 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5989 if (!NT_STATUS_IS_OK(status)) {
5990 printf("Server doesn't support setting UNIX CIFS extensions: "
5991 "%s.\n", nt_errstr(status));
5995 return NT_STATUS_OK;
5999 Test POSIX open /mkdir calls.
6001 static bool run_simple_posix_open_test(int dummy)
6003 static struct cli_state *cli1;
6004 const char *fname = "posix:file";
6005 const char *hname = "posix:hlink";
6006 const char *sname = "posix:symlink";
6007 const char *dname = "posix:dir";
6010 uint16_t fnum1 = (uint16_t)-1;
6011 SMB_STRUCT_STAT sbuf;
6012 bool correct = false;
6015 const char *fname_windows = "windows_file";
6016 uint16_t fnum2 = (uint16_t)-1;
6018 printf("Starting simple POSIX open test\n");
6020 if (!torture_open_connection(&cli1, 0)) {
6024 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6026 status = torture_setup_unix_extensions(cli1);
6027 if (!NT_STATUS_IS_OK(status)) {
6031 cli_setatr(cli1, fname, 0, 0);
6032 cli_posix_unlink(cli1, fname);
6033 cli_setatr(cli1, dname, 0, 0);
6034 cli_posix_rmdir(cli1, dname);
6035 cli_setatr(cli1, hname, 0, 0);
6036 cli_posix_unlink(cli1, hname);
6037 cli_setatr(cli1, sname, 0, 0);
6038 cli_posix_unlink(cli1, sname);
6039 cli_setatr(cli1, fname_windows, 0, 0);
6040 cli_posix_unlink(cli1, fname_windows);
6042 /* Create a directory. */
6043 status = cli_posix_mkdir(cli1, dname, 0777);
6044 if (!NT_STATUS_IS_OK(status)) {
6045 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6049 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6051 if (!NT_STATUS_IS_OK(status)) {
6052 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6056 /* Test ftruncate - set file size. */
6057 status = cli_ftruncate(cli1, fnum1, 1000);
6058 if (!NT_STATUS_IS_OK(status)) {
6059 printf("ftruncate failed (%s)\n", nt_errstr(status));
6063 /* Ensure st_size == 1000 */
6064 status = cli_posix_stat(cli1, fname, &sbuf);
6065 if (!NT_STATUS_IS_OK(status)) {
6066 printf("stat failed (%s)\n", nt_errstr(status));
6070 if (sbuf.st_ex_size != 1000) {
6071 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6075 /* Ensure st_mode == 0600 */
6076 if ((sbuf.st_ex_mode & 07777) != 0600) {
6077 printf("posix_open - bad permissions 0%o != 0600\n",
6078 (unsigned int)(sbuf.st_ex_mode & 07777));
6082 /* Test ftruncate - set file size back to zero. */
6083 status = cli_ftruncate(cli1, fnum1, 0);
6084 if (!NT_STATUS_IS_OK(status)) {
6085 printf("ftruncate failed (%s)\n", nt_errstr(status));
6089 status = cli_close(cli1, fnum1);
6090 if (!NT_STATUS_IS_OK(status)) {
6091 printf("close failed (%s)\n", nt_errstr(status));
6095 /* Now open the file again for read only. */
6096 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6097 if (!NT_STATUS_IS_OK(status)) {
6098 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
6102 /* Now unlink while open. */
6103 status = cli_posix_unlink(cli1, fname);
6104 if (!NT_STATUS_IS_OK(status)) {
6105 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6109 status = cli_close(cli1, fnum1);
6110 if (!NT_STATUS_IS_OK(status)) {
6111 printf("close(2) failed (%s)\n", nt_errstr(status));
6115 /* Ensure the file has gone. */
6116 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6117 if (NT_STATUS_IS_OK(status)) {
6118 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
6122 /* Create again to test open with O_TRUNC. */
6123 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
6124 if (!NT_STATUS_IS_OK(status)) {
6125 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6129 /* Test ftruncate - set file size. */
6130 status = cli_ftruncate(cli1, fnum1, 1000);
6131 if (!NT_STATUS_IS_OK(status)) {
6132 printf("ftruncate failed (%s)\n", nt_errstr(status));
6136 /* Ensure st_size == 1000 */
6137 status = cli_posix_stat(cli1, fname, &sbuf);
6138 if (!NT_STATUS_IS_OK(status)) {
6139 printf("stat failed (%s)\n", nt_errstr(status));
6143 if (sbuf.st_ex_size != 1000) {
6144 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6148 status = cli_close(cli1, fnum1);
6149 if (!NT_STATUS_IS_OK(status)) {
6150 printf("close(2) failed (%s)\n", nt_errstr(status));
6154 /* Re-open with O_TRUNC. */
6155 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
6156 if (!NT_STATUS_IS_OK(status)) {
6157 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6161 /* Ensure st_size == 0 */
6162 status = cli_posix_stat(cli1, fname, &sbuf);
6163 if (!NT_STATUS_IS_OK(status)) {
6164 printf("stat failed (%s)\n", nt_errstr(status));
6168 if (sbuf.st_ex_size != 0) {
6169 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
6173 status = cli_close(cli1, fnum1);
6174 if (!NT_STATUS_IS_OK(status)) {
6175 printf("close failed (%s)\n", nt_errstr(status));
6179 status = cli_posix_unlink(cli1, fname);
6180 if (!NT_STATUS_IS_OK(status)) {
6181 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6185 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
6186 if (!NT_STATUS_IS_OK(status)) {
6187 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6188 dname, nt_errstr(status));
6192 cli_close(cli1, fnum1);
6194 /* What happens when we try and POSIX open a directory for write ? */
6195 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
6196 if (NT_STATUS_IS_OK(status)) {
6197 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
6200 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
6201 NT_STATUS_FILE_IS_A_DIRECTORY)) {
6206 /* Create the file. */
6207 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6209 if (!NT_STATUS_IS_OK(status)) {
6210 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6214 /* Write some data into it. */
6215 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6217 if (!NT_STATUS_IS_OK(status)) {
6218 printf("cli_write failed: %s\n", nt_errstr(status));
6222 cli_close(cli1, fnum1);
6224 /* Now create a hardlink. */
6225 status = cli_posix_hardlink(cli1, fname, hname);
6226 if (!NT_STATUS_IS_OK(status)) {
6227 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
6231 /* Now create a symlink. */
6232 status = cli_posix_symlink(cli1, fname, sname);
6233 if (!NT_STATUS_IS_OK(status)) {
6234 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
6238 /* Open the hardlink for read. */
6239 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
6240 if (!NT_STATUS_IS_OK(status)) {
6241 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
6245 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
6246 if (!NT_STATUS_IS_OK(status)) {
6247 printf("POSIX read of %s failed (%s)\n", hname,
6250 } else if (nread != 10) {
6251 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6252 hname, (unsigned long)nread, 10);
6256 if (memcmp(buf, "TEST DATA\n", 10)) {
6257 printf("invalid data read from hardlink\n");
6261 /* Do a POSIX lock/unlock. */
6262 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
6263 if (!NT_STATUS_IS_OK(status)) {
6264 printf("POSIX lock failed %s\n", nt_errstr(status));
6268 /* Punch a hole in the locked area. */
6269 status = cli_posix_unlock(cli1, fnum1, 10, 80);
6270 if (!NT_STATUS_IS_OK(status)) {
6271 printf("POSIX unlock failed %s\n", nt_errstr(status));
6275 cli_close(cli1, fnum1);
6277 /* Open the symlink for read - this should fail. A POSIX
6278 client should not be doing opens on a symlink. */
6279 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
6280 if (NT_STATUS_IS_OK(status)) {
6281 printf("POSIX open of %s succeeded (should have failed)\n", sname);
6284 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
6285 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
6286 printf("POSIX open of %s should have failed "
6287 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6288 "failed with %s instead.\n",
6289 sname, nt_errstr(status));
6294 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
6295 if (!NT_STATUS_IS_OK(status)) {
6296 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
6300 if (strcmp(namebuf, fname) != 0) {
6301 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6302 sname, fname, namebuf);
6306 status = cli_posix_rmdir(cli1, dname);
6307 if (!NT_STATUS_IS_OK(status)) {
6308 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
6312 /* Check directory opens with a specific permission. */
6313 status = cli_posix_mkdir(cli1, dname, 0700);
6314 if (!NT_STATUS_IS_OK(status)) {
6315 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6319 /* Ensure st_mode == 0700 */
6320 status = cli_posix_stat(cli1, dname, &sbuf);
6321 if (!NT_STATUS_IS_OK(status)) {
6322 printf("stat failed (%s)\n", nt_errstr(status));
6326 if ((sbuf.st_ex_mode & 07777) != 0700) {
6327 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6328 (unsigned int)(sbuf.st_ex_mode & 07777));
6333 * Now create a Windows file, and attempt a POSIX unlink.
6334 * This should fail with a sharing violation but due to:
6336 * [Bug 9571] Unlink after open causes smbd to panic
6338 * ensure we've fixed the lock ordering violation.
6341 status = cli_ntcreate(cli1, fname_windows, 0,
6342 FILE_READ_DATA|FILE_WRITE_DATA, 0,
6343 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6345 0x0, 0x0, &fnum2, NULL);
6346 if (!NT_STATUS_IS_OK(status)) {
6347 printf("Windows create of %s failed (%s)\n", fname_windows,
6352 /* Now try posix_unlink. */
6353 status = cli_posix_unlink(cli1, fname_windows);
6354 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6355 printf("POSIX unlink of %s should fail "
6356 "with NT_STATUS_SHARING_VIOLATION "
6357 "got %s instead !\n",
6363 cli_close(cli1, fnum2);
6365 printf("Simple POSIX open test passed\n");
6370 if (fnum1 != (uint16_t)-1) {
6371 cli_close(cli1, fnum1);
6372 fnum1 = (uint16_t)-1;
6375 if (fnum2 != (uint16_t)-1) {
6376 cli_close(cli1, fnum2);
6377 fnum2 = (uint16_t)-1;
6380 cli_setatr(cli1, sname, 0, 0);
6381 cli_posix_unlink(cli1, sname);
6382 cli_setatr(cli1, hname, 0, 0);
6383 cli_posix_unlink(cli1, hname);
6384 cli_setatr(cli1, fname, 0, 0);
6385 cli_posix_unlink(cli1, fname);
6386 cli_setatr(cli1, dname, 0, 0);
6387 cli_posix_rmdir(cli1, dname);
6388 cli_setatr(cli1, fname_windows, 0, 0);
6389 cli_posix_unlink(cli1, fname_windows);
6391 if (!torture_close_connection(cli1)) {
6399 Test POSIX and Windows ACLs are rejected on symlinks.
6401 static bool run_acl_symlink_test(int dummy)
6403 static struct cli_state *cli;
6404 const char *fname = "posix_file";
6405 const char *sname = "posix_symlink";
6406 uint16_t fnum = (uint16_t)-1;
6407 bool correct = false;
6409 char *posix_acl = NULL;
6410 size_t posix_acl_len = 0;
6411 char *posix_acl_sym = NULL;
6412 size_t posix_acl_len_sym = 0;
6413 struct security_descriptor *sd = NULL;
6414 struct security_descriptor *sd_sym = NULL;
6415 TALLOC_CTX *frame = NULL;
6417 frame = talloc_stackframe();
6419 printf("Starting acl symlink test\n");
6421 if (!torture_open_connection(&cli, 0)) {
6426 smbXcli_conn_set_sockopt(cli->conn, sockops);
6428 status = torture_setup_unix_extensions(cli);
6429 if (!NT_STATUS_IS_OK(status)) {
6434 cli_setatr(cli, fname, 0, 0);
6435 cli_posix_unlink(cli, fname);
6436 cli_setatr(cli, sname, 0, 0);
6437 cli_posix_unlink(cli, sname);
6439 status = cli_ntcreate(cli,
6442 READ_CONTROL_ACCESS,
6444 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6451 if (!NT_STATUS_IS_OK(status)) {
6452 printf("cli_ntcreate of %s failed (%s)\n",
6458 /* Get the Windows ACL on the file. */
6459 status = cli_query_secdesc(cli,
6463 if (!NT_STATUS_IS_OK(status)) {
6464 printf("cli_query_secdesc failed (%s)\n",
6469 /* Get the POSIX ACL on the file. */
6470 status = cli_posix_getacl(cli,
6476 if (!NT_STATUS_IS_OK(status)) {
6477 printf("cli_posix_getacl failed (%s)\n",
6482 status = cli_close(cli, fnum);
6483 if (!NT_STATUS_IS_OK(status)) {
6484 printf("close failed (%s)\n", nt_errstr(status));
6487 fnum = (uint16_t)-1;
6489 /* Now create a symlink. */
6490 status = cli_posix_symlink(cli, fname, sname);
6491 if (!NT_STATUS_IS_OK(status)) {
6492 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6499 /* Open a handle on the symlink. */
6500 status = cli_ntcreate(cli,
6503 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
6505 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6512 if (!NT_STATUS_IS_OK(status)) {
6513 printf("cli_posix_open of %s failed (%s)\n",
6519 /* Get the Windows ACL on the symlink handle. Should fail */
6520 status = cli_query_secdesc(cli,
6525 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6526 printf("cli_query_secdesc on a symlink gave %s. "
6527 "Should be NT_STATUS_ACCESS_DENIED.\n",
6532 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6533 status = cli_posix_getacl(cli,
6539 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6540 printf("cli_posix_getacl on a symlink gave %s. "
6541 "Should be NT_STATUS_ACCESS_DENIED.\n",
6546 /* Set the Windows ACL on the symlink handle. Should fail */
6547 status = cli_set_security_descriptor(cli,
6552 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6553 printf("cli_query_secdesc on a symlink gave %s. "
6554 "Should be NT_STATUS_ACCESS_DENIED.\n",
6559 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6560 status = cli_posix_setacl(cli,
6565 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6566 printf("cli_posix_getacl on a symlink gave %s. "
6567 "Should be NT_STATUS_ACCESS_DENIED.\n",
6572 printf("ACL symlink test passed\n");
6577 if (fnum != (uint16_t)-1) {
6578 cli_close(cli, fnum);
6579 fnum = (uint16_t)-1;
6582 cli_setatr(cli, sname, 0, 0);
6583 cli_posix_unlink(cli, sname);
6584 cli_setatr(cli, fname, 0, 0);
6585 cli_posix_unlink(cli, fname);
6587 if (!torture_close_connection(cli)) {
6596 Test POSIX can delete a file containing streams.
6598 static bool run_posix_stream_delete(int dummy)
6600 struct cli_state *cli1 = NULL;
6601 struct cli_state *cli2 = NULL;
6602 const char *fname = "streamfile";
6603 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6604 uint16_t fnum1 = (uint16_t)-1;
6605 bool correct = false;
6607 TALLOC_CTX *frame = NULL;
6609 frame = talloc_stackframe();
6611 printf("Starting POSIX stream delete test\n");
6613 if (!torture_open_connection(&cli1, 0) ||
6614 !torture_open_connection(&cli2, 1)) {
6619 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6620 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6622 status = torture_setup_unix_extensions(cli2);
6623 if (!NT_STATUS_IS_OK(status)) {
6627 cli_setatr(cli1, fname, 0, 0);
6628 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6630 /* Create the file. */
6631 status = cli_ntcreate(cli1,
6634 READ_CONTROL_ACCESS,
6636 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6643 if (!NT_STATUS_IS_OK(status)) {
6644 printf("cli_ntcreate of %s failed (%s)\n",
6650 status = cli_close(cli1, fnum1);
6651 if (!NT_STATUS_IS_OK(status)) {
6652 printf("cli_close of %s failed (%s)\n",
6657 fnum1 = (uint16_t)-1;
6659 /* Now create the stream. */
6660 status = cli_ntcreate(cli1,
6665 FILE_SHARE_READ|FILE_SHARE_WRITE,
6672 if (!NT_STATUS_IS_OK(status)) {
6673 printf("cli_ntcreate of %s failed (%s)\n",
6679 /* Leave the stream handle open... */
6681 /* POSIX unlink should fail. */
6682 status = cli_posix_unlink(cli2, fname);
6683 if (NT_STATUS_IS_OK(status)) {
6684 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6689 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6690 printf("cli_posix_unlink of %s failed with (%s) "
6691 "should have been NT_STATUS_SHARING_VIOLATION\n",
6697 /* Close the stream handle. */
6698 status = cli_close(cli1, fnum1);
6699 if (!NT_STATUS_IS_OK(status)) {
6700 printf("cli_close of %s failed (%s)\n",
6705 fnum1 = (uint16_t)-1;
6707 /* POSIX unlink after stream handle closed should succeed. */
6708 status = cli_posix_unlink(cli2, fname);
6709 if (!NT_STATUS_IS_OK(status)) {
6710 printf("cli_posix_unlink of %s failed (%s)\n",
6716 printf("POSIX stream delete test passed\n");
6721 if (fnum1 != (uint16_t)-1) {
6722 cli_close(cli1, fnum1);
6723 fnum1 = (uint16_t)-1;
6726 cli_setatr(cli1, fname, 0, 0);
6727 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6729 if (!torture_close_connection(cli1)) {
6732 if (!torture_close_connection(cli2)) {
6741 Test setting EA's are rejected on symlinks.
6743 static bool run_ea_symlink_test(int dummy)
6745 static struct cli_state *cli;
6746 const char *fname = "posix_file_ea";
6747 const char *sname = "posix_symlink_ea";
6748 const char *ea_name = "testea_name";
6749 const char *ea_value = "testea_value";
6750 uint16_t fnum = (uint16_t)-1;
6751 bool correct = false;
6754 struct ea_struct *eas = NULL;
6755 TALLOC_CTX *frame = NULL;
6757 frame = talloc_stackframe();
6759 printf("Starting EA symlink test\n");
6761 if (!torture_open_connection(&cli, 0)) {
6766 smbXcli_conn_set_sockopt(cli->conn, sockops);
6768 status = torture_setup_unix_extensions(cli);
6769 if (!NT_STATUS_IS_OK(status)) {
6774 cli_setatr(cli, fname, 0, 0);
6775 cli_posix_unlink(cli, fname);
6776 cli_setatr(cli, sname, 0, 0);
6777 cli_posix_unlink(cli, sname);
6779 status = cli_ntcreate(cli,
6782 READ_CONTROL_ACCESS,
6784 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6791 if (!NT_STATUS_IS_OK(status)) {
6792 printf("cli_ntcreate of %s failed (%s)\n",
6798 status = cli_close(cli, fnum);
6799 if (!NT_STATUS_IS_OK(status)) {
6800 printf("close failed (%s)\n",
6804 fnum = (uint16_t)-1;
6806 /* Set an EA on the path. */
6807 status = cli_set_ea_path(cli,
6811 strlen(ea_value)+1);
6813 if (!NT_STATUS_IS_OK(status)) {
6814 printf("cli_set_ea_path failed (%s)\n",
6819 /* Now create a symlink. */
6820 status = cli_posix_symlink(cli, fname, sname);
6821 if (!NT_STATUS_IS_OK(status)) {
6822 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6829 /* Get the EA list on the path. Should return value set. */
6830 status = cli_get_ea_list_path(cli,
6836 if (!NT_STATUS_IS_OK(status)) {
6837 printf("cli_get_ea_list_path failed (%s)\n",
6842 /* Ensure the EA we set is there. */
6843 for (i=0; i<num_eas; i++) {
6844 if (strcmp(eas[i].name, ea_name) == 0 &&
6845 eas[i].value.length == strlen(ea_value)+1 &&
6846 memcmp(eas[i].value.data,
6848 eas[i].value.length) == 0) {
6854 printf("Didn't find EA on pathname %s\n",
6862 /* Get the EA list on the symlink. Should return empty list. */
6863 status = cli_get_ea_list_path(cli,
6869 if (!NT_STATUS_IS_OK(status)) {
6870 printf("cli_get_ea_list_path failed (%s)\n",
6876 printf("cli_get_ea_list_path failed (%s)\n",
6881 /* Set an EA on the symlink. Should fail. */
6882 status = cli_set_ea_path(cli,
6886 strlen(ea_value)+1);
6888 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6889 printf("cli_set_ea_path on a symlink gave %s. "
6890 "Should be NT_STATUS_ACCESS_DENIED.\n",
6895 printf("EA symlink test passed\n");
6900 if (fnum != (uint16_t)-1) {
6901 cli_close(cli, fnum);
6902 fnum = (uint16_t)-1;
6905 cli_setatr(cli, sname, 0, 0);
6906 cli_posix_unlink(cli, sname);
6907 cli_setatr(cli, fname, 0, 0);
6908 cli_posix_unlink(cli, fname);
6910 if (!torture_close_connection(cli)) {
6919 Test POSIX locks are OFD-locks.
6921 static bool run_posix_ofd_lock_test(int dummy)
6923 static struct cli_state *cli;
6924 const char *fname = "posix_file";
6925 uint16_t fnum1 = (uint16_t)-1;
6926 uint16_t fnum2 = (uint16_t)-1;
6927 bool correct = false;
6929 TALLOC_CTX *frame = NULL;
6931 frame = talloc_stackframe();
6933 printf("Starting POSIX ofd-lock test\n");
6935 if (!torture_open_connection(&cli, 0)) {
6940 smbXcli_conn_set_sockopt(cli->conn, sockops);
6942 status = torture_setup_unix_extensions(cli);
6943 if (!NT_STATUS_IS_OK(status)) {
6948 cli_setatr(cli, fname, 0, 0);
6949 cli_posix_unlink(cli, fname);
6951 /* Open the file twice. */
6952 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
6954 if (!NT_STATUS_IS_OK(status)) {
6955 printf("First POSIX open of %s failed\n", fname);
6959 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
6960 if (!NT_STATUS_IS_OK(status)) {
6961 printf("First POSIX open of %s failed\n", fname);
6965 /* Set a 0-50 lock on fnum1. */
6966 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6967 if (!NT_STATUS_IS_OK(status)) {
6968 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
6972 /* Set a 60-100 lock on fnum2. */
6973 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
6974 if (!NT_STATUS_IS_OK(status)) {
6975 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
6979 /* close fnum1 - 0-50 lock should go away. */
6980 status = cli_close(cli, fnum1);
6981 if (!NT_STATUS_IS_OK(status)) {
6982 printf("close failed (%s)\n",
6986 fnum1 = (uint16_t)-1;
6988 /* Change the lock context. */
6989 cli_setpid(cli, cli_getpid(cli) + 1);
6991 /* Re-open fnum1. */
6992 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
6993 if (!NT_STATUS_IS_OK(status)) {
6994 printf("Third POSIX open of %s failed\n", fname);
6998 /* 60-100 lock should still be there. */
6999 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
7000 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
7001 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
7005 /* 0-50 lock should be gone. */
7006 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7007 if (!NT_STATUS_IS_OK(status)) {
7008 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
7012 printf("POSIX OFD lock test passed\n");
7017 if (fnum1 != (uint16_t)-1) {
7018 cli_close(cli, fnum1);
7019 fnum1 = (uint16_t)-1;
7021 if (fnum2 != (uint16_t)-1) {
7022 cli_close(cli, fnum2);
7023 fnum2 = (uint16_t)-1;
7026 cli_setatr(cli, fname, 0, 0);
7027 cli_posix_unlink(cli, fname);
7029 if (!torture_close_connection(cli)) {
7037 static uint32_t open_attrs_table[] = {
7038 FILE_ATTRIBUTE_NORMAL,
7039 FILE_ATTRIBUTE_ARCHIVE,
7040 FILE_ATTRIBUTE_READONLY,
7041 FILE_ATTRIBUTE_HIDDEN,
7042 FILE_ATTRIBUTE_SYSTEM,
7044 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7045 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7046 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7047 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7048 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7049 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7051 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7052 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7053 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7054 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7057 struct trunc_open_results {
7060 uint32_t trunc_attr;
7061 uint32_t result_attr;
7064 static struct trunc_open_results attr_results[] = {
7065 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7066 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7067 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7068 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7069 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7070 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7071 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7072 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7073 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7074 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7075 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7076 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7077 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7078 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7079 { 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 },
7080 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7081 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7082 { 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 },
7083 { 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 },
7084 { 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 },
7085 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7086 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7087 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7088 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7089 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7090 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7093 static bool run_openattrtest(int dummy)
7095 static struct cli_state *cli1;
7096 const char *fname = "\\openattr.file";
7098 bool correct = True;
7100 unsigned int i, j, k, l;
7103 printf("starting open attr test\n");
7105 if (!torture_open_connection(&cli1, 0)) {
7109 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7111 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7112 cli_setatr(cli1, fname, 0, 0);
7113 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7115 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7116 open_attrs_table[i], FILE_SHARE_NONE,
7117 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7118 if (!NT_STATUS_IS_OK(status)) {
7119 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7123 status = cli_close(cli1, fnum1);
7124 if (!NT_STATUS_IS_OK(status)) {
7125 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7129 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7130 status = cli_ntcreate(cli1, fname, 0,
7131 FILE_READ_DATA|FILE_WRITE_DATA,
7132 open_attrs_table[j],
7133 FILE_SHARE_NONE, FILE_OVERWRITE,
7134 0, 0, &fnum1, NULL);
7135 if (!NT_STATUS_IS_OK(status)) {
7136 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7137 if (attr_results[l].num == k) {
7138 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7139 k, open_attrs_table[i],
7140 open_attrs_table[j],
7141 fname, NT_STATUS_V(status), nt_errstr(status));
7146 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7147 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7148 k, open_attrs_table[i], open_attrs_table[j],
7153 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7159 status = cli_close(cli1, fnum1);
7160 if (!NT_STATUS_IS_OK(status)) {
7161 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7165 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7166 if (!NT_STATUS_IS_OK(status)) {
7167 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7172 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7173 k, open_attrs_table[i], open_attrs_table[j], attr );
7176 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7177 if (attr_results[l].num == k) {
7178 if (attr != attr_results[l].result_attr ||
7179 open_attrs_table[i] != attr_results[l].init_attr ||
7180 open_attrs_table[j] != attr_results[l].trunc_attr) {
7181 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7182 open_attrs_table[i],
7183 open_attrs_table[j],
7185 attr_results[l].result_attr);
7195 cli_setatr(cli1, fname, 0, 0);
7196 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7198 printf("open attr test %s.\n", correct ? "passed" : "failed");
7200 if (!torture_close_connection(cli1)) {
7206 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7207 const char *name, void *state)
7209 int *matched = (int *)state;
7210 if (matched != NULL) {
7213 return NT_STATUS_OK;
7217 test directory listing speed
7219 static bool run_dirtest(int dummy)
7222 static struct cli_state *cli;
7224 struct timeval core_start;
7225 bool correct = True;
7228 printf("starting directory test\n");
7230 if (!torture_open_connection(&cli, 0)) {
7234 smbXcli_conn_set_sockopt(cli->conn, sockops);
7237 for (i=0;i<torture_numops;i++) {
7239 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7240 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7241 fprintf(stderr,"Failed to open %s\n", fname);
7244 cli_close(cli, fnum);
7247 core_start = timeval_current();
7250 cli_list(cli, "a*.*", 0, list_fn, &matched);
7251 printf("Matched %d\n", matched);
7254 cli_list(cli, "b*.*", 0, list_fn, &matched);
7255 printf("Matched %d\n", matched);
7258 cli_list(cli, "xyzabc", 0, list_fn, &matched);
7259 printf("Matched %d\n", matched);
7261 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7264 for (i=0;i<torture_numops;i++) {
7266 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7267 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7270 if (!torture_close_connection(cli)) {
7274 printf("finished dirtest\n");
7279 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7282 struct cli_state *pcli = (struct cli_state *)state;
7284 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7286 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7287 return NT_STATUS_OK;
7289 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7290 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7291 printf("del_fn: failed to rmdir %s\n,", fname );
7293 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7294 printf("del_fn: failed to unlink %s\n,", fname );
7296 return NT_STATUS_OK;
7301 sees what IOCTLs are supported
7303 bool torture_ioctl_test(int dummy)
7305 static struct cli_state *cli;
7306 uint16_t device, function;
7308 const char *fname = "\\ioctl.dat";
7312 if (!torture_open_connection(&cli, 0)) {
7316 printf("starting ioctl test\n");
7318 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7320 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7321 if (!NT_STATUS_IS_OK(status)) {
7322 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7326 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7327 printf("ioctl device info: %s\n", nt_errstr(status));
7329 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7330 printf("ioctl job info: %s\n", nt_errstr(status));
7332 for (device=0;device<0x100;device++) {
7333 printf("ioctl test with device = 0x%x\n", device);
7334 for (function=0;function<0x100;function++) {
7335 uint32_t code = (device<<16) | function;
7337 status = cli_raw_ioctl(cli, fnum, code, &blob);
7339 if (NT_STATUS_IS_OK(status)) {
7340 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7342 data_blob_free(&blob);
7347 if (!torture_close_connection(cli)) {
7356 tries varients of chkpath
7358 bool torture_chkpath_test(int dummy)
7360 static struct cli_state *cli;
7365 if (!torture_open_connection(&cli, 0)) {
7369 printf("starting chkpath test\n");
7371 /* cleanup from an old run */
7372 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7373 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7374 cli_rmdir(cli, "\\chkpath.dir");
7376 status = cli_mkdir(cli, "\\chkpath.dir");
7377 if (!NT_STATUS_IS_OK(status)) {
7378 printf("mkdir1 failed : %s\n", nt_errstr(status));
7382 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7383 if (!NT_STATUS_IS_OK(status)) {
7384 printf("mkdir2 failed : %s\n", nt_errstr(status));
7388 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7390 if (!NT_STATUS_IS_OK(status)) {
7391 printf("open1 failed (%s)\n", nt_errstr(status));
7394 cli_close(cli, fnum);
7396 status = cli_chkpath(cli, "\\chkpath.dir");
7397 if (!NT_STATUS_IS_OK(status)) {
7398 printf("chkpath1 failed: %s\n", nt_errstr(status));
7402 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7403 if (!NT_STATUS_IS_OK(status)) {
7404 printf("chkpath2 failed: %s\n", nt_errstr(status));
7408 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7409 if (!NT_STATUS_IS_OK(status)) {
7410 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7411 NT_STATUS_NOT_A_DIRECTORY);
7413 printf("* chkpath on a file should fail\n");
7417 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7418 if (!NT_STATUS_IS_OK(status)) {
7419 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7420 NT_STATUS_OBJECT_NAME_NOT_FOUND);
7422 printf("* chkpath on a non existent file should fail\n");
7426 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7427 if (!NT_STATUS_IS_OK(status)) {
7428 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7429 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7431 printf("* chkpath on a non existent component should fail\n");
7435 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7436 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7437 cli_rmdir(cli, "\\chkpath.dir");
7439 if (!torture_close_connection(cli)) {
7446 static bool run_eatest(int dummy)
7448 static struct cli_state *cli;
7449 const char *fname = "\\eatest.txt";
7450 bool correct = True;
7454 struct ea_struct *ea_list = NULL;
7455 TALLOC_CTX *mem_ctx = talloc_init("eatest");
7458 printf("starting eatest\n");
7460 if (!torture_open_connection(&cli, 0)) {
7461 talloc_destroy(mem_ctx);
7465 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7467 status = cli_ntcreate(cli, fname, 0,
7468 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7469 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7470 0x4044, 0, &fnum, NULL);
7471 if (!NT_STATUS_IS_OK(status)) {
7472 printf("open failed - %s\n", nt_errstr(status));
7473 talloc_destroy(mem_ctx);
7477 for (i = 0; i < 10; i++) {
7478 fstring ea_name, ea_val;
7480 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7481 memset(ea_val, (char)i+1, i+1);
7482 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7483 if (!NT_STATUS_IS_OK(status)) {
7484 printf("ea_set of name %s failed - %s\n", ea_name,
7486 talloc_destroy(mem_ctx);
7491 cli_close(cli, fnum);
7492 for (i = 0; i < 10; i++) {
7493 fstring ea_name, ea_val;
7495 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7496 memset(ea_val, (char)i+1, i+1);
7497 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7498 if (!NT_STATUS_IS_OK(status)) {
7499 printf("ea_set of name %s failed - %s\n", ea_name,
7501 talloc_destroy(mem_ctx);
7506 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7507 if (!NT_STATUS_IS_OK(status)) {
7508 printf("ea_get list failed - %s\n", nt_errstr(status));
7512 printf("num_eas = %d\n", (int)num_eas);
7514 if (num_eas != 20) {
7515 printf("Should be 20 EA's stored... failing.\n");
7519 for (i = 0; i < num_eas; i++) {
7520 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7521 dump_data(0, ea_list[i].value.data,
7522 ea_list[i].value.length);
7525 /* Setting EA's to zero length deletes them. Test this */
7526 printf("Now deleting all EA's - case indepenent....\n");
7529 cli_set_ea_path(cli, fname, "", "", 0);
7531 for (i = 0; i < 20; i++) {
7533 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7534 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7535 if (!NT_STATUS_IS_OK(status)) {
7536 printf("ea_set of name %s failed - %s\n", ea_name,
7538 talloc_destroy(mem_ctx);
7544 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7545 if (!NT_STATUS_IS_OK(status)) {
7546 printf("ea_get list failed - %s\n", nt_errstr(status));
7550 printf("num_eas = %d\n", (int)num_eas);
7551 for (i = 0; i < num_eas; i++) {
7552 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7553 dump_data(0, ea_list[i].value.data,
7554 ea_list[i].value.length);
7558 printf("deleting EA's failed.\n");
7562 /* Try and delete a non existent EA. */
7563 status = cli_set_ea_path(cli, fname, "foo", "", 0);
7564 if (!NT_STATUS_IS_OK(status)) {
7565 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7570 talloc_destroy(mem_ctx);
7571 if (!torture_close_connection(cli)) {
7578 static bool run_dirtest1(int dummy)
7581 static struct cli_state *cli;
7584 bool correct = True;
7586 printf("starting directory test\n");
7588 if (!torture_open_connection(&cli, 0)) {
7592 smbXcli_conn_set_sockopt(cli->conn, sockops);
7594 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7595 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7596 cli_rmdir(cli, "\\LISTDIR");
7597 cli_mkdir(cli, "\\LISTDIR");
7599 /* Create 1000 files and 1000 directories. */
7600 for (i=0;i<1000;i++) {
7602 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7603 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7604 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7605 0, 0, &fnum, NULL))) {
7606 fprintf(stderr,"Failed to open %s\n", fname);
7609 cli_close(cli, fnum);
7611 for (i=0;i<1000;i++) {
7613 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7614 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7615 fprintf(stderr,"Failed to open %s\n", fname);
7620 /* Now ensure that doing an old list sees both files and directories. */
7622 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7623 printf("num_seen = %d\n", num_seen );
7624 /* We should see 100 files + 1000 directories + . and .. */
7625 if (num_seen != 2002)
7628 /* Ensure if we have the "must have" bits we only see the
7632 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7633 printf("num_seen = %d\n", num_seen );
7634 if (num_seen != 1002)
7638 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7639 printf("num_seen = %d\n", num_seen );
7640 if (num_seen != 1000)
7643 /* Delete everything. */
7644 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7645 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7646 cli_rmdir(cli, "\\LISTDIR");
7649 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7650 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7651 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7654 if (!torture_close_connection(cli)) {
7658 printf("finished dirtest1\n");
7663 static bool run_error_map_extract(int dummy) {
7665 static struct cli_state *c_dos;
7666 static struct cli_state *c_nt;
7678 /* NT-Error connection */
7680 disable_spnego = true;
7681 if (!(c_nt = open_nbt_connection())) {
7682 disable_spnego = false;
7685 disable_spnego = false;
7687 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7690 if (!NT_STATUS_IS_OK(status)) {
7691 printf("%s rejected the NT-error negprot (%s)\n", host,
7697 status = cli_session_setup_anon(c_nt);
7698 if (!NT_STATUS_IS_OK(status)) {
7699 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7703 /* DOS-Error connection */
7705 disable_spnego = true;
7706 force_dos_errors = true;
7707 if (!(c_dos = open_nbt_connection())) {
7708 disable_spnego = false;
7709 force_dos_errors = false;
7712 disable_spnego = false;
7713 force_dos_errors = false;
7715 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7717 if (!NT_STATUS_IS_OK(status)) {
7718 printf("%s rejected the DOS-error negprot (%s)\n", host,
7720 cli_shutdown(c_dos);
7724 status = cli_session_setup_anon(c_dos);
7725 if (!NT_STATUS_IS_OK(status)) {
7726 printf("%s rejected the DOS-error initial session setup (%s)\n",
7727 host, nt_errstr(status));
7731 c_nt->map_dos_errors = false;
7732 c_dos->map_dos_errors = false;
7734 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7735 struct cli_credentials *user_creds = NULL;
7737 fstr_sprintf(user, "%X", error);
7739 user_creds = cli_session_creds_init(talloc_tos(),
7744 false, /* use_kerberos */
7745 false, /* fallback_after_kerberos */
7746 false, /* use_ccache */
7747 false); /* password_is_nt_hash */
7748 if (user_creds == NULL) {
7749 printf("cli_session_creds_init(%s) failed\n", user);
7753 status = cli_session_setup_creds(c_nt, user_creds);
7754 if (NT_STATUS_IS_OK(status)) {
7755 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7758 /* Case #1: 32-bit NT errors */
7759 if (!NT_STATUS_IS_DOS(status)) {
7762 printf("/** Dos error on NT connection! (%s) */\n",
7764 nt_status = NT_STATUS(0xc0000000);
7767 status = cli_session_setup_creds(c_dos, user_creds);
7768 if (NT_STATUS_IS_OK(status)) {
7769 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7772 /* Case #1: 32-bit NT errors */
7773 if (NT_STATUS_IS_DOS(status)) {
7774 printf("/** NT error on DOS connection! (%s) */\n",
7776 errnum = errclass = 0;
7778 errclass = NT_STATUS_DOS_CLASS(status);
7779 errnum = NT_STATUS_DOS_CODE(status);
7782 if (NT_STATUS_V(nt_status) != error) {
7783 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7784 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
7785 get_nt_error_c_code(talloc_tos(), nt_status));
7788 printf("\t{%s,\t%s,\t%s},\n",
7789 smb_dos_err_class(errclass),
7790 smb_dos_err_name(errclass, errnum),
7791 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7793 TALLOC_FREE(user_creds);
7798 static bool run_sesssetup_bench(int dummy)
7800 static struct cli_state *c;
7801 const char *fname = "\\file.dat";
7806 if (!torture_open_connection(&c, 0)) {
7810 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7811 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7812 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7813 if (!NT_STATUS_IS_OK(status)) {
7814 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7818 for (i=0; i<torture_numops; i++) {
7819 status = cli_session_setup_creds(c, torture_creds);
7820 if (!NT_STATUS_IS_OK(status)) {
7821 d_printf("(%s) cli_session_setup_creds failed: %s\n",
7822 __location__, nt_errstr(status));
7826 d_printf("\r%d ", (int)cli_state_get_uid(c));
7828 status = cli_ulogoff(c);
7829 if (!NT_STATUS_IS_OK(status)) {
7830 d_printf("(%s) cli_ulogoff failed: %s\n",
7831 __location__, nt_errstr(status));
7839 static bool subst_test(const char *str, const char *user, const char *domain,
7840 uid_t uid, gid_t gid, const char *expected)
7845 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7847 if (strcmp(subst, expected) != 0) {
7848 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7849 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
7858 static void chain1_open_completion(struct tevent_req *req)
7862 status = cli_openx_recv(req, &fnum);
7865 d_printf("cli_openx_recv returned %s: %d\n",
7867 NT_STATUS_IS_OK(status) ? fnum : -1);
7870 static void chain1_write_completion(struct tevent_req *req)
7874 status = cli_write_andx_recv(req, &written);
7877 d_printf("cli_write_andx_recv returned %s: %d\n",
7879 NT_STATUS_IS_OK(status) ? (int)written : -1);
7882 static void chain1_close_completion(struct tevent_req *req)
7885 bool *done = (bool *)tevent_req_callback_data_void(req);
7887 status = cli_close_recv(req);
7892 d_printf("cli_close returned %s\n", nt_errstr(status));
7895 static bool run_chain1(int dummy)
7897 struct cli_state *cli1;
7898 struct tevent_context *evt = samba_tevent_context_init(NULL);
7899 struct tevent_req *reqs[3], *smbreqs[3];
7901 const char *str = "foobar";
7904 printf("starting chain1 test\n");
7905 if (!torture_open_connection(&cli1, 0)) {
7909 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7911 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
7912 O_CREAT|O_RDWR, 0, &smbreqs[0]);
7913 if (reqs[0] == NULL) return false;
7914 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
7917 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
7918 (const uint8_t *)str, 0, strlen(str)+1,
7919 smbreqs, 1, &smbreqs[1]);
7920 if (reqs[1] == NULL) return false;
7921 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
7923 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
7924 if (reqs[2] == NULL) return false;
7925 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
7927 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7928 if (!NT_STATUS_IS_OK(status)) {
7933 tevent_loop_once(evt);
7936 torture_close_connection(cli1);
7940 static void chain2_sesssetup_completion(struct tevent_req *req)
7943 status = cli_session_setup_guest_recv(req);
7944 d_printf("sesssetup returned %s\n", nt_errstr(status));
7947 static void chain2_tcon_completion(struct tevent_req *req)
7949 bool *done = (bool *)tevent_req_callback_data_void(req);
7951 status = cli_tcon_andx_recv(req);
7952 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
7956 static bool run_chain2(int dummy)
7958 struct cli_state *cli1;
7959 struct tevent_context *evt = samba_tevent_context_init(NULL);
7960 struct tevent_req *reqs[2], *smbreqs[2];
7964 printf("starting chain2 test\n");
7965 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
7966 port_to_use, SMB_SIGNING_DEFAULT, 0);
7967 if (!NT_STATUS_IS_OK(status)) {
7971 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7973 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
7975 if (reqs[0] == NULL) return false;
7976 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
7978 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
7979 "?????", NULL, 0, &smbreqs[1]);
7980 if (reqs[1] == NULL) return false;
7981 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
7983 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7984 if (!NT_STATUS_IS_OK(status)) {
7989 tevent_loop_once(evt);
7992 torture_close_connection(cli1);
7997 struct torture_createdel_state {
7998 struct tevent_context *ev;
7999 struct cli_state *cli;
8002 static void torture_createdel_created(struct tevent_req *subreq);
8003 static void torture_createdel_closed(struct tevent_req *subreq);
8005 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8006 struct tevent_context *ev,
8007 struct cli_state *cli,
8010 struct tevent_req *req, *subreq;
8011 struct torture_createdel_state *state;
8013 req = tevent_req_create(mem_ctx, &state,
8014 struct torture_createdel_state);
8021 subreq = cli_ntcreate_send(
8022 state, ev, cli, name, 0,
8023 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8024 FILE_ATTRIBUTE_NORMAL,
8025 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8026 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
8028 if (tevent_req_nomem(subreq, req)) {
8029 return tevent_req_post(req, ev);
8031 tevent_req_set_callback(subreq, torture_createdel_created, req);
8035 static void torture_createdel_created(struct tevent_req *subreq)
8037 struct tevent_req *req = tevent_req_callback_data(
8038 subreq, struct tevent_req);
8039 struct torture_createdel_state *state = tevent_req_data(
8040 req, struct torture_createdel_state);
8044 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8045 TALLOC_FREE(subreq);
8046 if (tevent_req_nterror(req, status)) {
8047 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8048 nt_errstr(status)));
8052 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8053 if (tevent_req_nomem(subreq, req)) {
8056 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8059 static void torture_createdel_closed(struct tevent_req *subreq)
8061 struct tevent_req *req = tevent_req_callback_data(
8062 subreq, struct tevent_req);
8065 status = cli_close_recv(subreq);
8066 if (tevent_req_nterror(req, status)) {
8067 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8070 tevent_req_done(req);
8073 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8075 return tevent_req_simple_recv_ntstatus(req);
8078 struct torture_createdels_state {
8079 struct tevent_context *ev;
8080 struct cli_state *cli;
8081 const char *base_name;
8085 struct tevent_req **reqs;
8088 static void torture_createdels_done(struct tevent_req *subreq);
8090 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8091 struct tevent_context *ev,
8092 struct cli_state *cli,
8093 const char *base_name,
8097 struct tevent_req *req;
8098 struct torture_createdels_state *state;
8101 req = tevent_req_create(mem_ctx, &state,
8102 struct torture_createdels_state);
8108 state->base_name = talloc_strdup(state, base_name);
8109 if (tevent_req_nomem(state->base_name, req)) {
8110 return tevent_req_post(req, ev);
8112 state->num_files = MAX(num_parallel, num_files);
8114 state->received = 0;
8116 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8117 if (tevent_req_nomem(state->reqs, req)) {
8118 return tevent_req_post(req, ev);
8121 for (i=0; i<num_parallel; i++) {
8124 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8126 if (tevent_req_nomem(name, req)) {
8127 return tevent_req_post(req, ev);
8129 state->reqs[i] = torture_createdel_send(
8130 state->reqs, state->ev, state->cli, name);
8131 if (tevent_req_nomem(state->reqs[i], req)) {
8132 return tevent_req_post(req, ev);
8134 name = talloc_move(state->reqs[i], &name);
8135 tevent_req_set_callback(state->reqs[i],
8136 torture_createdels_done, req);
8142 static void torture_createdels_done(struct tevent_req *subreq)
8144 struct tevent_req *req = tevent_req_callback_data(
8145 subreq, struct tevent_req);
8146 struct torture_createdels_state *state = tevent_req_data(
8147 req, struct torture_createdels_state);
8148 size_t num_parallel = talloc_array_length(state->reqs);
8153 status = torture_createdel_recv(subreq);
8154 if (!NT_STATUS_IS_OK(status)){
8155 DEBUG(10, ("torture_createdel_recv returned %s\n",
8156 nt_errstr(status)));
8157 TALLOC_FREE(subreq);
8158 tevent_req_nterror(req, status);
8162 for (i=0; i<num_parallel; i++) {
8163 if (subreq == state->reqs[i]) {
8167 if (i == num_parallel) {
8168 DEBUG(10, ("received something we did not send\n"));
8169 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8172 TALLOC_FREE(state->reqs[i]);
8174 if (state->sent >= state->num_files) {
8175 tevent_req_done(req);
8179 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8181 if (tevent_req_nomem(name, req)) {
8184 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8186 if (tevent_req_nomem(state->reqs[i], req)) {
8189 name = talloc_move(state->reqs[i], &name);
8190 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8194 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8196 return tevent_req_simple_recv_ntstatus(req);
8199 struct swallow_notify_state {
8200 struct tevent_context *ev;
8201 struct cli_state *cli;
8203 uint32_t completion_filter;
8205 bool (*fn)(uint32_t action, const char *name, void *priv);
8209 static void swallow_notify_done(struct tevent_req *subreq);
8211 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8212 struct tevent_context *ev,
8213 struct cli_state *cli,
8215 uint32_t completion_filter,
8217 bool (*fn)(uint32_t action,
8222 struct tevent_req *req, *subreq;
8223 struct swallow_notify_state *state;
8225 req = tevent_req_create(mem_ctx, &state,
8226 struct swallow_notify_state);
8233 state->completion_filter = completion_filter;
8234 state->recursive = recursive;
8238 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8239 0xffff, state->completion_filter,
8241 if (tevent_req_nomem(subreq, req)) {
8242 return tevent_req_post(req, ev);
8244 tevent_req_set_callback(subreq, swallow_notify_done, req);
8248 static void swallow_notify_done(struct tevent_req *subreq)
8250 struct tevent_req *req = tevent_req_callback_data(
8251 subreq, struct tevent_req);
8252 struct swallow_notify_state *state = tevent_req_data(
8253 req, struct swallow_notify_state);
8255 uint32_t i, num_changes;
8256 struct notify_change *changes;
8258 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8259 TALLOC_FREE(subreq);
8260 if (!NT_STATUS_IS_OK(status)) {
8261 DEBUG(10, ("cli_notify_recv returned %s\n",
8262 nt_errstr(status)));
8263 tevent_req_nterror(req, status);
8267 for (i=0; i<num_changes; i++) {
8268 state->fn(changes[i].action, changes[i].name, state->priv);
8270 TALLOC_FREE(changes);
8272 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8273 0xffff, state->completion_filter,
8275 if (tevent_req_nomem(subreq, req)) {
8278 tevent_req_set_callback(subreq, swallow_notify_done, req);
8281 static bool print_notifies(uint32_t action, const char *name, void *priv)
8283 if (DEBUGLEVEL > 5) {
8284 d_printf("%d %s\n", (int)action, name);
8289 static void notify_bench_done(struct tevent_req *req)
8291 int *num_finished = (int *)tevent_req_callback_data_void(req);
8295 static bool run_notify_bench(int dummy)
8297 const char *dname = "\\notify-bench";
8298 struct tevent_context *ev;
8301 struct tevent_req *req1;
8302 struct tevent_req *req2 = NULL;
8303 int i, num_unc_names;
8304 int num_finished = 0;
8306 printf("starting notify-bench test\n");
8308 if (use_multishare_conn) {
8310 unc_list = file_lines_load(multishare_conn_fname,
8311 &num_unc_names, 0, NULL);
8312 if (!unc_list || num_unc_names <= 0) {
8313 d_printf("Failed to load unc names list from '%s'\n",
8314 multishare_conn_fname);
8317 TALLOC_FREE(unc_list);
8322 ev = samba_tevent_context_init(talloc_tos());
8324 d_printf("tevent_context_init failed\n");
8328 for (i=0; i<num_unc_names; i++) {
8329 struct cli_state *cli;
8332 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8334 if (base_fname == NULL) {
8338 if (!torture_open_connection(&cli, i)) {
8342 status = cli_ntcreate(cli, dname, 0,
8343 MAXIMUM_ALLOWED_ACCESS,
8344 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8346 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8349 if (!NT_STATUS_IS_OK(status)) {
8350 d_printf("Could not create %s: %s\n", dname,
8355 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8356 FILE_NOTIFY_CHANGE_FILE_NAME |
8357 FILE_NOTIFY_CHANGE_DIR_NAME |
8358 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8359 FILE_NOTIFY_CHANGE_LAST_WRITE,
8360 false, print_notifies, NULL);
8362 d_printf("Could not create notify request\n");
8366 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8367 base_fname, 10, torture_numops);
8369 d_printf("Could not create createdels request\n");
8372 TALLOC_FREE(base_fname);
8374 tevent_req_set_callback(req2, notify_bench_done,
8378 while (num_finished < num_unc_names) {
8380 ret = tevent_loop_once(ev);
8382 d_printf("tevent_loop_once failed\n");
8387 if (!tevent_req_poll(req2, ev)) {
8388 d_printf("tevent_req_poll failed\n");
8391 status = torture_createdels_recv(req2);
8392 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8397 static bool run_mangle1(int dummy)
8399 struct cli_state *cli;
8400 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8404 time_t change_time, access_time, write_time;
8408 printf("starting mangle1 test\n");
8409 if (!torture_open_connection(&cli, 0)) {
8413 smbXcli_conn_set_sockopt(cli->conn, sockops);
8415 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8416 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8418 if (!NT_STATUS_IS_OK(status)) {
8419 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8422 cli_close(cli, fnum);
8424 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8425 if (!NT_STATUS_IS_OK(status)) {
8426 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8430 d_printf("alt_name: %s\n", alt_name);
8432 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8433 if (!NT_STATUS_IS_OK(status)) {
8434 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8438 cli_close(cli, fnum);
8440 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8441 &write_time, &size, &mode);
8442 if (!NT_STATUS_IS_OK(status)) {
8443 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8451 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8452 struct file_info *f,
8456 if (f->short_name == NULL) {
8457 return NT_STATUS_OK;
8460 if (strlen(f->short_name) == 0) {
8461 return NT_STATUS_OK;
8464 printf("unexpected shortname: %s\n", f->short_name);
8466 return NT_STATUS_OBJECT_NAME_INVALID;
8469 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8470 struct file_info *f,
8476 printf("name: %s\n", f->name);
8477 fstrcpy(name, f->name);
8478 return NT_STATUS_OK;
8481 static bool run_mangle_illegal(int dummy)
8483 struct cli_state *cli = NULL;
8484 struct cli_state *cli_posix = NULL;
8485 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8486 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8487 char *mangled_path = NULL;
8493 printf("starting mangle-illegal test\n");
8495 if (!torture_open_connection(&cli, 0)) {
8499 smbXcli_conn_set_sockopt(cli->conn, sockops);
8501 if (!torture_open_connection(&cli_posix, 0)) {
8505 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8507 status = torture_setup_unix_extensions(cli_posix);
8508 if (!NT_STATUS_IS_OK(status)) {
8512 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8513 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8514 if (!NT_STATUS_IS_OK(status)) {
8515 printf("mkdir1 failed : %s\n", nt_errstr(status));
8520 * Create a file with illegal NTFS characters and test that we
8521 * get a usable mangled name
8524 cli_setatr(cli_posix, illegal_fname, 0, 0);
8525 cli_posix_unlink(cli_posix, illegal_fname);
8527 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8529 if (!NT_STATUS_IS_OK(status)) {
8530 printf("POSIX create of %s failed (%s)\n",
8531 illegal_fname, nt_errstr(status));
8535 status = cli_close(cli_posix, fnum);
8536 if (!NT_STATUS_IS_OK(status)) {
8537 printf("close failed (%s)\n", nt_errstr(status));
8541 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8542 if (!NT_STATUS_IS_OK(status)) {
8543 d_printf("cli_list failed: %s\n", nt_errstr(status));
8547 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8548 if (mangled_path == NULL) {
8552 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8553 if (!NT_STATUS_IS_OK(status)) {
8554 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8555 TALLOC_FREE(mangled_path);
8558 TALLOC_FREE(mangled_path);
8559 cli_close(cli, fnum);
8561 cli_setatr(cli_posix, illegal_fname, 0, 0);
8562 cli_posix_unlink(cli_posix, illegal_fname);
8565 * Create a file with a long name and check that we got *no* short name.
8568 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8569 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8571 if (!NT_STATUS_IS_OK(status)) {
8572 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8575 cli_close(cli, fnum);
8577 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8578 if (!NT_STATUS_IS_OK(status)) {
8579 d_printf("cli_list failed\n");
8583 cli_unlink(cli, fname, 0);
8584 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8586 if (!torture_close_connection(cli_posix)) {
8590 if (!torture_close_connection(cli)) {
8597 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8599 size_t *to_pull = (size_t *)priv;
8600 size_t thistime = *to_pull;
8602 thistime = MIN(thistime, n);
8603 if (thistime == 0) {
8607 memset(buf, 0, thistime);
8608 *to_pull -= thistime;
8612 static bool run_windows_write(int dummy)
8614 struct cli_state *cli1;
8618 const char *fname = "\\writetest.txt";
8619 struct timeval start_time;
8624 printf("starting windows_write test\n");
8625 if (!torture_open_connection(&cli1, 0)) {
8629 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8630 if (!NT_STATUS_IS_OK(status)) {
8631 printf("open failed (%s)\n", nt_errstr(status));
8635 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8637 start_time = timeval_current();
8639 for (i=0; i<torture_numops; i++) {
8641 off_t start = i * torture_blocksize;
8642 size_t to_pull = torture_blocksize - 1;
8644 status = cli_writeall(cli1, fnum, 0, &c,
8645 start + torture_blocksize - 1, 1, NULL);
8646 if (!NT_STATUS_IS_OK(status)) {
8647 printf("cli_write failed: %s\n", nt_errstr(status));
8651 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8652 null_source, &to_pull);
8653 if (!NT_STATUS_IS_OK(status)) {
8654 printf("cli_push returned: %s\n", nt_errstr(status));
8659 seconds = timeval_elapsed(&start_time);
8660 kbytes = (double)torture_blocksize * torture_numops;
8663 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8664 (double)seconds, (int)(kbytes/seconds));
8668 cli_close(cli1, fnum);
8669 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8670 torture_close_connection(cli1);
8674 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8676 size_t max_pdu = 0x1FFFF;
8678 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8682 if (smb1cli_conn_signing_is_active(cli->conn)) {
8686 if (smb1cli_conn_encryption_on(cli->conn)) {
8687 max_pdu = CLI_BUFFER_SIZE;
8690 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8691 len_requested &= 0xFFFF;
8694 return MIN(len_requested,
8695 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8698 static bool check_read_call(struct cli_state *cli,
8701 size_t len_requested)
8704 struct tevent_req *subreq = NULL;
8705 ssize_t len_read = 0;
8706 size_t len_expected = 0;
8707 struct tevent_context *ev = NULL;
8709 ev = samba_tevent_context_init(talloc_tos());
8714 subreq = cli_read_andx_send(talloc_tos(),
8721 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8725 status = cli_read_andx_recv(subreq, &len_read, &buf);
8726 if (!NT_STATUS_IS_OK(status)) {
8727 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8731 TALLOC_FREE(subreq);
8734 len_expected = calc_expected_return(cli, len_requested);
8736 if (len_expected > 0x10000 && len_read == 0x10000) {
8737 /* Windows servers only return a max of 0x10000,
8738 doesn't matter if you set CAP_LARGE_READX in
8739 the client sessionsetupX call or not. */
8740 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8741 (unsigned int)len_requested);
8742 } else if (len_read != len_expected) {
8743 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8744 (unsigned int)len_requested,
8745 (unsigned int)len_read,
8746 (unsigned int)len_expected);
8749 d_printf("Correct read reply.\n");
8755 /* Test large readX variants. */
8756 static bool large_readx_tests(struct cli_state *cli,
8760 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8761 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8764 /* A read of 0x10000 should return 0x10000 bytes. */
8765 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8768 /* A read of 0x10000 should return 0x10001 bytes. */
8769 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8772 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8773 the requested number of bytes. */
8774 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8777 /* A read of 1MB should return 1MB bytes (on Samba). */
8778 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
8782 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
8785 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
8788 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
8794 static bool run_large_readx(int dummy)
8796 uint8_t *buf = NULL;
8797 struct cli_state *cli1 = NULL;
8798 struct cli_state *cli2 = NULL;
8799 bool correct = false;
8800 const char *fname = "\\large_readx.dat";
8802 uint16_t fnum1 = UINT16_MAX;
8803 uint32_t normal_caps = 0;
8804 size_t file_size = 20*1024*1024;
8805 TALLOC_CTX *frame = talloc_stackframe();
8809 enum smb_signing_setting signing_setting;
8810 enum protocol_types protocol;
8814 .signing_setting = SMB_SIGNING_IF_REQUIRED,
8815 .protocol = PROTOCOL_NT1,
8817 .name = "NT1 - SIGNING_REQUIRED",
8818 .signing_setting = SMB_SIGNING_REQUIRED,
8819 .protocol = PROTOCOL_NT1,
8823 printf("starting large_readx test\n");
8825 if (!torture_open_connection(&cli1, 0)) {
8829 normal_caps = smb1cli_conn_capabilities(cli1->conn);
8831 if (!(normal_caps & CAP_LARGE_READX)) {
8832 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8833 (unsigned int)normal_caps);
8837 /* Create a file of size 4MB. */
8838 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
8839 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8840 0, 0, &fnum1, NULL);
8842 if (!NT_STATUS_IS_OK(status)) {
8843 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8847 /* Write file_size bytes. */
8848 buf = talloc_zero_array(frame, uint8_t, file_size);
8853 status = cli_writeall(cli1,
8860 if (!NT_STATUS_IS_OK(status)) {
8861 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
8865 status = cli_close(cli1, fnum1);
8866 if (!NT_STATUS_IS_OK(status)) {
8867 d_printf("cli_close failed: %s\n", nt_errstr(status));
8873 for (i=0; i < ARRAY_SIZE(runs); i++) {
8874 enum smb_signing_setting saved_signing_setting = signing_state;
8875 uint16_t fnum2 = -1;
8878 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
8880 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
8884 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
8886 signing_state = runs[i].signing_setting;
8887 cli2 = open_nbt_connection();
8888 signing_state = saved_signing_setting;
8893 status = smbXcli_negprot(cli2->conn,
8897 if (!NT_STATUS_IS_OK(status)) {
8901 status = cli_session_setup_creds(cli2, torture_creds);
8902 if (!NT_STATUS_IS_OK(status)) {
8906 status = cli_tree_connect(cli2,
8910 if (!NT_STATUS_IS_OK(status)) {
8914 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
8916 normal_caps = smb1cli_conn_capabilities(cli2->conn);
8918 if (!(normal_caps & CAP_LARGE_READX)) {
8919 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8920 (unsigned int)normal_caps);
8925 if (force_cli_encryption(cli2, share) == false) {
8928 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
8929 uint16_t major, minor;
8930 uint32_t caplow, caphigh;
8932 status = cli_unix_extensions_version(cli2,
8935 if (!NT_STATUS_IS_OK(status)) {
8940 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
8941 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
8942 0, 0, &fnum2, NULL);
8943 if (!NT_STATUS_IS_OK(status)) {
8944 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
8948 /* All reads must return less than file_size bytes. */
8949 if (!large_readx_tests(cli2, fnum2, buf)) {
8953 status = cli_close(cli2, fnum2);
8954 if (!NT_STATUS_IS_OK(status)) {
8955 d_printf("cli_close failed: %s\n", nt_errstr(status));
8960 if (!torture_close_connection(cli2)) {
8967 printf("Success on large_readx test\n");
8972 if (!torture_close_connection(cli2)) {
8978 if (fnum1 != UINT16_MAX) {
8979 status = cli_close(cli1, fnum1);
8980 if (!NT_STATUS_IS_OK(status)) {
8981 d_printf("cli_close failed: %s\n", nt_errstr(status));
8986 status = cli_unlink(cli1, fname,
8987 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8988 if (!NT_STATUS_IS_OK(status)) {
8989 printf("unlink failed (%s)\n", nt_errstr(status));
8992 if (!torture_close_connection(cli1)) {
8999 printf("finished large_readx test\n");
9003 static bool run_cli_echo(int dummy)
9005 struct cli_state *cli;
9008 printf("starting cli_echo test\n");
9009 if (!torture_open_connection(&cli, 0)) {
9012 smbXcli_conn_set_sockopt(cli->conn, sockops);
9014 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9016 d_printf("cli_echo returned %s\n", nt_errstr(status));
9018 torture_close_connection(cli);
9019 return NT_STATUS_IS_OK(status);
9022 static bool run_uid_regression_test(int dummy)
9024 static struct cli_state *cli;
9027 bool correct = True;
9028 struct smbXcli_tcon *orig_tcon = NULL;
9031 printf("starting uid regression test\n");
9033 if (!torture_open_connection(&cli, 0)) {
9037 smbXcli_conn_set_sockopt(cli->conn, sockops);
9039 /* Ok - now save then logoff our current user. */
9040 old_vuid = cli_state_get_uid(cli);
9042 status = cli_ulogoff(cli);
9043 if (!NT_STATUS_IS_OK(status)) {
9044 d_printf("(%s) cli_ulogoff failed: %s\n",
9045 __location__, nt_errstr(status));
9050 cli_state_set_uid(cli, old_vuid);
9052 /* Try an operation. */
9053 status = cli_mkdir(cli, "\\uid_reg_test");
9054 if (NT_STATUS_IS_OK(status)) {
9055 d_printf("(%s) cli_mkdir succeeded\n",
9060 /* Should be bad uid. */
9061 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9062 NT_STATUS_USER_SESSION_DELETED)) {
9068 old_cnum = cli_state_get_tid(cli);
9069 orig_tcon = cli_state_save_tcon(cli);
9070 if (orig_tcon == NULL) {
9075 /* Now try a SMBtdis with the invald vuid set to zero. */
9076 cli_state_set_uid(cli, 0);
9078 /* This should succeed. */
9079 status = cli_tdis(cli);
9081 if (NT_STATUS_IS_OK(status)) {
9082 d_printf("First tdis with invalid vuid should succeed.\n");
9084 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9086 cli_state_restore_tcon(cli, orig_tcon);
9090 cli_state_restore_tcon(cli, orig_tcon);
9091 cli_state_set_uid(cli, old_vuid);
9092 cli_state_set_tid(cli, old_cnum);
9094 /* This should fail. */
9095 status = cli_tdis(cli);
9096 if (NT_STATUS_IS_OK(status)) {
9097 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9101 /* Should be bad tid. */
9102 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9103 NT_STATUS_NETWORK_NAME_DELETED)) {
9109 cli_rmdir(cli, "\\uid_reg_test");
9118 static const char *illegal_chars = "*\\/?<>|\":";
9119 static char force_shortname_chars[] = " +,.[];=\177";
9121 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9122 const char *mask, void *state)
9124 struct cli_state *pcli = (struct cli_state *)state;
9126 NTSTATUS status = NT_STATUS_OK;
9128 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9130 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9131 return NT_STATUS_OK;
9133 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9134 status = cli_rmdir(pcli, fname);
9135 if (!NT_STATUS_IS_OK(status)) {
9136 printf("del_fn: failed to rmdir %s\n,", fname );
9139 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9140 if (!NT_STATUS_IS_OK(status)) {
9141 printf("del_fn: failed to unlink %s\n,", fname );
9153 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9154 const char *name, void *state)
9156 struct sn_state *s = (struct sn_state *)state;
9160 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9161 i, finfo->name, finfo->short_name);
9164 if (strchr(force_shortname_chars, i)) {
9165 if (!finfo->short_name) {
9166 /* Shortname not created when it should be. */
9167 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9168 __location__, finfo->name, i);
9171 } else if (finfo->short_name){
9172 /* Shortname created when it should not be. */
9173 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9174 __location__, finfo->short_name, finfo->name);
9178 return NT_STATUS_OK;
9181 static bool run_shortname_test(int dummy)
9183 static struct cli_state *cli;
9184 bool correct = True;
9190 printf("starting shortname test\n");
9192 if (!torture_open_connection(&cli, 0)) {
9196 smbXcli_conn_set_sockopt(cli->conn, sockops);
9198 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9199 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9200 cli_rmdir(cli, "\\shortname");
9202 status = cli_mkdir(cli, "\\shortname");
9203 if (!NT_STATUS_IS_OK(status)) {
9204 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9205 __location__, nt_errstr(status));
9210 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9214 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9221 for (i = 32; i < 128; i++) {
9222 uint16_t fnum = (uint16_t)-1;
9226 if (strchr(illegal_chars, i)) {
9231 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9232 FILE_SHARE_READ|FILE_SHARE_WRITE,
9233 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9234 if (!NT_STATUS_IS_OK(status)) {
9235 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9236 __location__, fname, nt_errstr(status));
9240 cli_close(cli, fnum);
9243 status = cli_list(cli, "\\shortname\\test*.*", 0,
9244 shortname_list_fn, &s);
9245 if (s.matched != 1) {
9246 d_printf("(%s) failed to list %s: %s\n",
9247 __location__, fname, nt_errstr(status));
9252 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9253 if (!NT_STATUS_IS_OK(status)) {
9254 d_printf("(%s) failed to delete %s: %s\n",
9255 __location__, fname, nt_errstr(status));
9268 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9269 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9270 cli_rmdir(cli, "\\shortname");
9271 torture_close_connection(cli);
9275 static void pagedsearch_cb(struct tevent_req *req)
9278 struct tldap_message *msg;
9281 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9282 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9283 d_printf("tldap_search_paged_recv failed: %s\n",
9284 tldap_rc2string(rc));
9287 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9291 if (!tldap_entry_dn(msg, &dn)) {
9292 d_printf("tldap_entry_dn failed\n");
9295 d_printf("%s\n", dn);
9299 static bool run_tldap(int dummy)
9301 struct tldap_context *ld;
9305 struct sockaddr_storage addr;
9306 struct tevent_context *ev;
9307 struct tevent_req *req;
9311 if (!resolve_name(host, &addr, 0, false)) {
9312 d_printf("could not find host %s\n", host);
9315 status = open_socket_out(&addr, 389, 9999, &fd);
9316 if (!NT_STATUS_IS_OK(status)) {
9317 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9321 ld = tldap_context_create(talloc_tos(), fd);
9324 d_printf("tldap_context_create failed\n");
9328 rc = tldap_fetch_rootdse(ld);
9329 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9330 d_printf("tldap_fetch_rootdse failed: %s\n",
9331 tldap_errstr(talloc_tos(), ld, rc));
9335 basedn = tldap_talloc_single_attribute(
9336 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9337 if (basedn == NULL) {
9338 d_printf("no defaultNamingContext\n");
9341 d_printf("defaultNamingContext: %s\n", basedn);
9343 ev = samba_tevent_context_init(talloc_tos());
9345 d_printf("tevent_context_init failed\n");
9349 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9350 TLDAP_SCOPE_SUB, "(objectclass=*)",
9352 NULL, 0, NULL, 0, 0, 0, 0, 5);
9354 d_printf("tldap_search_paged_send failed\n");
9357 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9359 tevent_req_poll(req, ev);
9363 /* test search filters against rootDSE */
9364 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9365 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9367 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9368 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9369 talloc_tos(), NULL);
9370 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9371 d_printf("tldap_search with complex filter failed: %s\n",
9372 tldap_errstr(talloc_tos(), ld, rc));
9380 /* Torture test to ensure no regression of :
9381 https://bugzilla.samba.org/show_bug.cgi?id=7084
9384 static bool run_dir_createtime(int dummy)
9386 struct cli_state *cli;
9387 const char *dname = "\\testdir";
9388 const char *fname = "\\testdir\\testfile";
9390 struct timespec create_time;
9391 struct timespec create_time1;
9395 if (!torture_open_connection(&cli, 0)) {
9399 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9400 cli_rmdir(cli, dname);
9402 status = cli_mkdir(cli, dname);
9403 if (!NT_STATUS_IS_OK(status)) {
9404 printf("mkdir failed: %s\n", nt_errstr(status));
9408 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9410 if (!NT_STATUS_IS_OK(status)) {
9411 printf("cli_qpathinfo2 returned %s\n",
9416 /* Sleep 3 seconds, then create a file. */
9419 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9421 if (!NT_STATUS_IS_OK(status)) {
9422 printf("cli_openx failed: %s\n", nt_errstr(status));
9426 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9428 if (!NT_STATUS_IS_OK(status)) {
9429 printf("cli_qpathinfo2 (2) returned %s\n",
9434 if (timespec_compare(&create_time1, &create_time)) {
9435 printf("run_dir_createtime: create time was updated (error)\n");
9437 printf("run_dir_createtime: create time was not updated (correct)\n");
9443 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9444 cli_rmdir(cli, dname);
9445 if (!torture_close_connection(cli)) {
9452 static bool run_streamerror(int dummy)
9454 struct cli_state *cli;
9455 const char *dname = "\\testdir";
9456 const char *streamname =
9457 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9459 time_t change_time, access_time, write_time;
9461 uint16_t mode, fnum;
9464 if (!torture_open_connection(&cli, 0)) {
9468 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9469 cli_rmdir(cli, dname);
9471 status = cli_mkdir(cli, dname);
9472 if (!NT_STATUS_IS_OK(status)) {
9473 printf("mkdir failed: %s\n", nt_errstr(status));
9477 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9478 &write_time, &size, &mode);
9479 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9480 printf("pathinfo returned %s, expected "
9481 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9486 status = cli_ntcreate(cli, streamname, 0x16,
9487 FILE_READ_DATA|FILE_READ_EA|
9488 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9489 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9490 FILE_OPEN, 0, 0, &fnum, NULL);
9492 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9493 printf("ntcreate returned %s, expected "
9494 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9500 cli_rmdir(cli, dname);
9504 struct pidtest_state {
9510 static void pid_echo_done(struct tevent_req *subreq);
9512 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9513 struct tevent_context *ev,
9514 struct cli_state *cli)
9516 struct tevent_req *req, *subreq;
9517 struct pidtest_state *state;
9519 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9524 SSVAL(state->vwv, 0, 1);
9525 state->data = data_blob_const("hello", 5);
9527 subreq = smb1cli_req_send(state,
9532 0, 0, /* *_flags2 */
9534 0xDEADBEEF, /* pid */
9537 ARRAY_SIZE(state->vwv), state->vwv,
9538 state->data.length, state->data.data);
9540 if (tevent_req_nomem(subreq, req)) {
9541 return tevent_req_post(req, ev);
9543 tevent_req_set_callback(subreq, pid_echo_done, req);
9547 static void pid_echo_done(struct tevent_req *subreq)
9549 struct tevent_req *req = tevent_req_callback_data(
9550 subreq, struct tevent_req);
9551 struct pidtest_state *state = tevent_req_data(
9552 req, struct pidtest_state);
9555 uint8_t *bytes = NULL;
9556 struct iovec *recv_iov = NULL;
9557 uint8_t *phdr = NULL;
9558 uint16_t pidlow = 0;
9559 uint16_t pidhigh = 0;
9560 struct smb1cli_req_expected_response expected[] = {
9562 .status = NT_STATUS_OK,
9567 status = smb1cli_req_recv(subreq, state,
9572 NULL, /* pvwv_offset */
9575 NULL, /* pbytes_offset */
9577 expected, ARRAY_SIZE(expected));
9579 TALLOC_FREE(subreq);
9581 if (!NT_STATUS_IS_OK(status)) {
9582 tevent_req_nterror(req, status);
9586 if (num_bytes != state->data.length) {
9587 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9591 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9592 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9596 /* Check pid low/high == DEADBEEF */
9597 pidlow = SVAL(phdr, HDR_PID);
9598 if (pidlow != 0xBEEF){
9599 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9600 (unsigned int)pidlow);
9601 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9604 pidhigh = SVAL(phdr, HDR_PIDHIGH);
9605 if (pidhigh != 0xDEAD){
9606 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9607 (unsigned int)pidhigh);
9608 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9612 tevent_req_done(req);
9615 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9617 return tevent_req_simple_recv_ntstatus(req);
9620 static bool run_pidhigh(int dummy)
9622 bool success = false;
9623 struct cli_state *cli = NULL;
9625 struct tevent_context *ev = NULL;
9626 struct tevent_req *req = NULL;
9627 TALLOC_CTX *frame = talloc_stackframe();
9629 printf("starting pid high test\n");
9630 if (!torture_open_connection(&cli, 0)) {
9633 smbXcli_conn_set_sockopt(cli->conn, sockops);
9635 ev = samba_tevent_context_init(frame);
9640 req = pid_echo_send(frame, ev, cli);
9645 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
9649 status = pid_echo_recv(req);
9650 if (NT_STATUS_IS_OK(status)) {
9651 printf("pid high test ok\n");
9658 torture_close_connection(cli);
9663 Test Windows open on a bad POSIX symlink.
9665 static bool run_symlink_open_test(int dummy)
9667 static struct cli_state *cli;
9668 const char *fname = "non_existant_file";
9669 const char *sname = "dangling_symlink";
9670 uint16_t fnum = (uint16_t)-1;
9671 bool correct = false;
9673 TALLOC_CTX *frame = NULL;
9675 frame = talloc_stackframe();
9677 printf("Starting Windows bad symlink open test\n");
9679 if (!torture_open_connection(&cli, 0)) {
9684 smbXcli_conn_set_sockopt(cli->conn, sockops);
9686 status = torture_setup_unix_extensions(cli);
9687 if (!NT_STATUS_IS_OK(status)) {
9692 /* Ensure nothing exists. */
9693 cli_setatr(cli, fname, 0, 0);
9694 cli_posix_unlink(cli, fname);
9695 cli_setatr(cli, sname, 0, 0);
9696 cli_posix_unlink(cli, sname);
9698 /* Create a symlink pointing nowhere. */
9699 status = cli_posix_symlink(cli, fname, sname);
9700 if (!NT_STATUS_IS_OK(status)) {
9701 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
9708 /* Now ensure that a Windows open doesn't hang. */
9709 status = cli_ntcreate(cli,
9712 FILE_READ_DATA|FILE_WRITE_DATA,
9714 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
9722 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
9723 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
9724 * we use O_NOFOLLOW on the server or not.
9726 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
9727 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
9731 printf("cli_ntcreate of %s returned %s - should return"
9732 " either (%s) or (%s)\n",
9735 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
9736 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
9744 if (fnum != (uint16_t)-1) {
9745 cli_close(cli, fnum);
9746 fnum = (uint16_t)-1;
9749 cli_setatr(cli, sname, 0, 0);
9750 cli_posix_unlink(cli, sname);
9751 cli_setatr(cli, fname, 0, 0);
9752 cli_posix_unlink(cli, fname);
9754 if (!torture_close_connection(cli)) {
9762 static bool run_local_substitute(int dummy)
9766 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
9767 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
9768 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
9769 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
9770 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
9771 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
9772 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
9773 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
9775 /* Different captialization rules in sub_basic... */
9777 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
9783 static bool run_local_base64(int dummy)
9788 for (i=1; i<2000; i++) {
9789 DATA_BLOB blob1, blob2;
9792 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
9794 generate_random_buffer(blob1.data, blob1.length);
9796 b64 = base64_encode_data_blob(talloc_tos(), blob1);
9798 d_fprintf(stderr, "base64_encode_data_blob failed "
9799 "for %d bytes\n", i);
9802 blob2 = base64_decode_data_blob(b64);
9805 if (data_blob_cmp(&blob1, &blob2)) {
9806 d_fprintf(stderr, "data_blob_cmp failed for %d "
9810 TALLOC_FREE(blob1.data);
9811 data_blob_free(&blob2);
9816 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
9821 static bool run_local_gencache(int dummy)
9827 struct memcache *mem;
9830 mem = memcache_init(NULL, 0);
9832 d_printf("%s: memcache_init failed\n", __location__);
9835 memcache_set_global(mem);
9837 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
9838 d_printf("%s: gencache_set() failed\n", __location__);
9842 if (!gencache_get("foo", NULL, NULL, NULL)) {
9843 d_printf("%s: gencache_get() failed\n", __location__);
9847 for (i=0; i<1000000; i++) {
9848 gencache_parse("foo", parse_fn, NULL);
9851 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9852 d_printf("%s: gencache_get() failed\n", __location__);
9857 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9858 d_printf("%s: gencache_get() failed\n", __location__);
9862 if (strcmp(val, "bar") != 0) {
9863 d_printf("%s: gencache_get() returned %s, expected %s\n",
9864 __location__, val, "bar");
9871 if (!gencache_del("foo")) {
9872 d_printf("%s: gencache_del() failed\n", __location__);
9875 if (gencache_del("foo")) {
9876 d_printf("%s: second gencache_del() succeeded\n",
9881 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
9882 d_printf("%s: gencache_get() on deleted entry "
9883 "succeeded\n", __location__);
9887 blob = data_blob_string_const_null("bar");
9888 tm = time(NULL) + 60;
9890 if (!gencache_set_data_blob("foo", &blob, tm)) {
9891 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
9895 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
9896 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
9900 if (strcmp((const char *)blob.data, "bar") != 0) {
9901 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
9902 __location__, (const char *)blob.data, "bar");
9903 data_blob_free(&blob);
9907 data_blob_free(&blob);
9909 if (!gencache_del("foo")) {
9910 d_printf("%s: gencache_del() failed\n", __location__);
9913 if (gencache_del("foo")) {
9914 d_printf("%s: second gencache_del() succeeded\n",
9919 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
9920 d_printf("%s: gencache_get_data_blob() on deleted entry "
9921 "succeeded\n", __location__);
9926 blob.data = (uint8_t *)&v;
9927 blob.length = sizeof(v);
9929 if (!gencache_set_data_blob("blob", &blob, tm)) {
9930 d_printf("%s: gencache_set_data_blob() failed\n",
9934 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
9935 d_printf("%s: gencache_get succeeded\n", __location__);
9942 static bool rbt_testval(struct db_context *db, const char *key,
9945 struct db_record *rec;
9946 TDB_DATA data = string_tdb_data(value);
9951 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
9953 d_fprintf(stderr, "fetch_locked failed\n");
9956 status = dbwrap_record_store(rec, data, 0);
9957 if (!NT_STATUS_IS_OK(status)) {
9958 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
9963 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
9965 d_fprintf(stderr, "second fetch_locked failed\n");
9969 dbvalue = dbwrap_record_get_value(rec);
9970 if ((dbvalue.dsize != data.dsize)
9971 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
9972 d_fprintf(stderr, "Got wrong data back\n");
9982 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
9984 int *count2 = (int *)private_data;
9989 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
9991 int *count2 = (int *)private_data;
9993 dbwrap_record_delete(rec);
9997 static bool run_local_rbtree(int dummy)
9999 struct db_context *db;
10006 db = db_open_rbt(NULL);
10009 d_fprintf(stderr, "db_open_rbt failed\n");
10013 for (i=0; i<1000; i++) {
10016 if (asprintf(&key, "key%ld", random()) == -1) {
10019 if (asprintf(&value, "value%ld", random()) == -1) {
10024 if (!rbt_testval(db, key, value)) {
10031 if (asprintf(&value, "value%ld", random()) == -1) {
10036 if (!rbt_testval(db, key, value)) {
10047 count = 0; count2 = 0;
10048 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10050 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10051 if ((count != count2) || (count != 1000)) {
10054 count = 0; count2 = 0;
10055 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10057 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10058 if ((count != count2) || (count != 1000)) {
10061 count = 0; count2 = 0;
10062 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10064 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10065 if ((count != count2) || (count != 0)) {
10076 local test for character set functions
10078 This is a very simple test for the functionality in convert_string_error()
10080 static bool run_local_convert_string(int dummy)
10082 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10083 const char *test_strings[2] = { "March", "M\303\244rz" };
10087 for (i=0; i<2; i++) {
10088 const char *str = test_strings[i];
10089 int len = strlen(str);
10090 size_t converted_size;
10093 memset(dst, 'X', sizeof(dst));
10095 /* first try with real source length */
10096 ret = convert_string_error(CH_UNIX, CH_UTF8,
10101 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10105 if (converted_size != len) {
10106 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10107 str, len, (int)converted_size);
10111 if (strncmp(str, dst, converted_size) != 0) {
10112 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10116 if (strlen(str) != converted_size) {
10117 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10118 (int)strlen(str), (int)converted_size);
10122 if (dst[converted_size] != 'X') {
10123 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10127 /* now with srclen==-1, this causes the nul to be
10129 ret = convert_string_error(CH_UNIX, CH_UTF8,
10134 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10138 if (converted_size != len+1) {
10139 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10140 str, len, (int)converted_size);
10144 if (strncmp(str, dst, converted_size) != 0) {
10145 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10149 if (len+1 != converted_size) {
10150 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10151 len+1, (int)converted_size);
10155 if (dst[converted_size] != 'X') {
10156 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10163 TALLOC_FREE(tmp_ctx);
10166 TALLOC_FREE(tmp_ctx);
10171 struct talloc_dict_test {
10175 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
10177 int *count = (int *)priv;
10182 static bool run_local_talloc_dict(int dummy)
10184 struct talloc_dict *dict;
10185 struct talloc_dict_test *t;
10186 int key, count, res;
10189 dict = talloc_dict_init(talloc_tos());
10190 if (dict == NULL) {
10194 t = talloc(talloc_tos(), struct talloc_dict_test);
10201 ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
10207 res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
10216 if (count != res) {
10225 static bool run_local_string_to_sid(int dummy) {
10226 struct dom_sid sid;
10228 if (string_to_sid(&sid, "S--1-5-32-545")) {
10229 printf("allowing S--1-5-32-545\n");
10232 if (string_to_sid(&sid, "S-1-5-32-+545")) {
10233 printf("allowing S-1-5-32-+545\n");
10236 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")) {
10237 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10240 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10241 printf("allowing S-1-5-32-545-abc\n");
10244 if (string_to_sid(&sid, "S-300-5-32-545")) {
10245 printf("allowing S-300-5-32-545\n");
10248 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10249 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10252 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10253 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10256 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10257 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10260 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10261 printf("could not parse S-1-5-32-545\n");
10264 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10265 printf("mis-parsed S-1-5-32-545 as %s\n",
10266 sid_string_tos(&sid));
10272 static bool sid_to_string_test(const char *expected) {
10275 struct dom_sid sid;
10277 if (!string_to_sid(&sid, expected)) {
10278 printf("could not parse %s\n", expected);
10282 str = dom_sid_string(NULL, &sid);
10283 if (strcmp(str, expected)) {
10284 printf("Comparison failed (%s != %s)\n", str, expected);
10291 static bool run_local_sid_to_string(int dummy) {
10292 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10294 if (!sid_to_string_test("S-1-545"))
10296 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10301 static bool run_local_binary_to_sid(int dummy) {
10302 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10303 static const uint8_t good_binary_sid[] = {
10304 0x1, /* revision number */
10305 15, /* num auths */
10306 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10307 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10308 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10309 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10310 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10311 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10312 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10313 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10314 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10315 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10316 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10317 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10318 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10319 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10320 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10321 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10324 static const uint8_t long_binary_sid[] = {
10325 0x1, /* revision number */
10326 15, /* num auths */
10327 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10328 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10329 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10330 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10331 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10332 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10333 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10334 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10335 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10336 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10337 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10338 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10339 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10340 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10341 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10342 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10343 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10344 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10345 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10348 static const uint8_t long_binary_sid2[] = {
10349 0x1, /* revision number */
10350 32, /* num auths */
10351 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10352 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10353 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10354 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10355 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10356 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10357 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10358 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10359 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10360 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10361 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10362 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10363 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10364 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10365 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10366 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10367 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10368 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10369 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10370 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10371 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10372 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10373 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10374 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10375 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10376 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10377 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10378 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10379 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10380 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10381 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10382 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10383 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10386 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10389 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10392 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10398 /* Split a path name into filename and stream name components. Canonicalise
10399 * such that an implicit $DATA token is always explicit.
10401 * The "specification" of this function can be found in the
10402 * run_local_stream_name() function in torture.c, I've tried those
10403 * combinations against a W2k3 server.
10406 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10407 char **pbase, char **pstream)
10410 char *stream = NULL;
10411 char *sname; /* stream name */
10412 const char *stype; /* stream type */
10414 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10416 sname = strchr_m(fname, ':');
10418 if (sname == NULL) {
10419 if (pbase != NULL) {
10420 base = talloc_strdup(mem_ctx, fname);
10421 NT_STATUS_HAVE_NO_MEMORY(base);
10426 if (pbase != NULL) {
10427 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10428 NT_STATUS_HAVE_NO_MEMORY(base);
10433 stype = strchr_m(sname, ':');
10435 if (stype == NULL) {
10436 sname = talloc_strdup(mem_ctx, sname);
10440 if (strcasecmp_m(stype, ":$DATA") != 0) {
10442 * If there is an explicit stream type, so far we only
10443 * allow $DATA. Is there anything else allowed? -- vl
10445 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10447 return NT_STATUS_OBJECT_NAME_INVALID;
10449 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10453 if (sname == NULL) {
10455 return NT_STATUS_NO_MEMORY;
10458 if (sname[0] == '\0') {
10460 * no stream name, so no stream
10465 if (pstream != NULL) {
10466 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10467 if (stream == NULL) {
10468 TALLOC_FREE(sname);
10470 return NT_STATUS_NO_MEMORY;
10473 * upper-case the type field
10475 (void)strupper_m(strchr_m(stream, ':')+1);
10479 if (pbase != NULL) {
10482 if (pstream != NULL) {
10485 return NT_STATUS_OK;
10488 static bool test_stream_name(const char *fname, const char *expected_base,
10489 const char *expected_stream,
10490 NTSTATUS expected_status)
10494 char *stream = NULL;
10496 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10497 if (!NT_STATUS_EQUAL(status, expected_status)) {
10501 if (!NT_STATUS_IS_OK(status)) {
10505 if (base == NULL) goto error;
10507 if (strcmp(expected_base, base) != 0) goto error;
10509 if ((expected_stream != NULL) && (stream == NULL)) goto error;
10510 if ((expected_stream == NULL) && (stream != NULL)) goto error;
10512 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10516 TALLOC_FREE(stream);
10520 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10521 fname, expected_base ? expected_base : "<NULL>",
10522 expected_stream ? expected_stream : "<NULL>",
10523 nt_errstr(expected_status));
10524 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10525 base ? base : "<NULL>", stream ? stream : "<NULL>",
10526 nt_errstr(status));
10528 TALLOC_FREE(stream);
10532 static bool run_local_stream_name(int dummy)
10536 ret &= test_stream_name(
10537 "bla", "bla", NULL, NT_STATUS_OK);
10538 ret &= test_stream_name(
10539 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10540 ret &= test_stream_name(
10541 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10542 ret &= test_stream_name(
10543 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10544 ret &= test_stream_name(
10545 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10546 ret &= test_stream_name(
10547 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10548 ret &= test_stream_name(
10549 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10550 ret &= test_stream_name(
10551 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10556 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10558 if (a.length != b.length) {
10559 printf("a.length=%d != b.length=%d\n",
10560 (int)a.length, (int)b.length);
10563 if (memcmp(a.data, b.data, a.length) != 0) {
10564 printf("a.data and b.data differ\n");
10570 static bool run_local_memcache(int dummy)
10572 struct memcache *cache;
10574 DATA_BLOB d1, d2, d3;
10575 DATA_BLOB v1, v2, v3;
10577 TALLOC_CTX *mem_ctx;
10579 size_t size1, size2;
10582 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10584 if (cache == NULL) {
10585 printf("memcache_init failed\n");
10589 d1 = data_blob_const("d1", 2);
10590 d2 = data_blob_const("d2", 2);
10591 d3 = data_blob_const("d3", 2);
10593 k1 = data_blob_const("d1", 2);
10594 k2 = data_blob_const("d2", 2);
10596 memcache_add(cache, STAT_CACHE, k1, d1);
10597 memcache_add(cache, GETWD_CACHE, k2, d2);
10599 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10600 printf("could not find k1\n");
10603 if (!data_blob_equal(d1, v1)) {
10607 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
10608 printf("could not find k2\n");
10611 if (!data_blob_equal(d2, v2)) {
10615 memcache_add(cache, STAT_CACHE, k1, d3);
10617 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10618 printf("could not find replaced k1\n");
10621 if (!data_blob_equal(d3, v3)) {
10625 memcache_add(cache, GETWD_CACHE, k1, d1);
10627 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
10628 printf("Did find k2, should have been purged\n");
10632 TALLOC_FREE(cache);
10634 cache = memcache_init(NULL, 0);
10636 mem_ctx = talloc_init("foo");
10638 str1 = talloc_strdup(mem_ctx, "string1");
10639 str2 = talloc_strdup(mem_ctx, "string2");
10641 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10642 data_blob_string_const("torture"), &str1);
10643 size1 = talloc_total_size(cache);
10645 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10646 data_blob_string_const("torture"), &str2);
10647 size2 = talloc_total_size(cache);
10649 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
10651 if (size2 > size1) {
10652 printf("memcache leaks memory!\n");
10658 TALLOC_FREE(cache);
10662 static void wbclient_done(struct tevent_req *req)
10665 struct winbindd_response *wb_resp;
10666 int *i = (int *)tevent_req_callback_data_void(req);
10668 wbc_err = wb_trans_recv(req, req, &wb_resp);
10671 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
10674 static bool run_wbclient_multi_ping(int dummy)
10676 struct tevent_context *ev;
10677 struct wb_context **wb_ctx;
10678 struct winbindd_request wb_req;
10679 bool result = false;
10682 BlockSignals(True, SIGPIPE);
10684 ev = tevent_context_init(talloc_tos());
10689 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
10690 if (wb_ctx == NULL) {
10694 ZERO_STRUCT(wb_req);
10695 wb_req.cmd = WINBINDD_PING;
10697 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
10699 for (i=0; i<torture_nprocs; i++) {
10700 wb_ctx[i] = wb_context_init(ev, NULL);
10701 if (wb_ctx[i] == NULL) {
10704 for (j=0; j<torture_numops; j++) {
10705 struct tevent_req *req;
10706 req = wb_trans_send(ev, ev, wb_ctx[i],
10707 (j % 2) == 0, &wb_req);
10711 tevent_req_set_callback(req, wbclient_done, &i);
10717 while (i < torture_nprocs * torture_numops) {
10718 tevent_loop_once(ev);
10727 static void getaddrinfo_finished(struct tevent_req *req)
10729 char *name = (char *)tevent_req_callback_data_void(req);
10730 struct addrinfo *ainfo;
10733 res = getaddrinfo_recv(req, &ainfo);
10735 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
10738 d_printf("gai(%s) succeeded\n", name);
10739 freeaddrinfo(ainfo);
10742 static bool run_getaddrinfo_send(int dummy)
10744 TALLOC_CTX *frame = talloc_stackframe();
10745 struct fncall_context *ctx;
10746 struct tevent_context *ev;
10747 bool result = false;
10748 const char *names[4] = { "www.samba.org", "notfound.samba.org",
10749 "www.slashdot.org", "heise.de" };
10750 struct tevent_req *reqs[4];
10753 ev = samba_tevent_context_init(frame);
10758 ctx = fncall_context_init(frame, 4);
10760 for (i=0; i<ARRAY_SIZE(names); i++) {
10761 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
10763 if (reqs[i] == NULL) {
10766 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
10767 discard_const_p(void, names[i]));
10770 for (i=0; i<ARRAY_SIZE(reqs); i++) {
10771 tevent_loop_once(ev);
10776 TALLOC_FREE(frame);
10780 static bool dbtrans_inc(struct db_context *db)
10782 struct db_record *rec;
10788 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10790 printf(__location__ "fetch_lock failed\n");
10794 value = dbwrap_record_get_value(rec);
10796 if (value.dsize != sizeof(uint32_t)) {
10797 printf(__location__ "value.dsize = %d\n",
10802 memcpy(&val, value.dptr, sizeof(val));
10805 status = dbwrap_record_store(
10806 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
10807 if (!NT_STATUS_IS_OK(status)) {
10808 printf(__location__ "store failed: %s\n",
10809 nt_errstr(status));
10819 static bool run_local_dbtrans(int dummy)
10821 struct db_context *db;
10822 struct db_record *rec;
10828 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
10829 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
10832 printf("Could not open transtest.db\n");
10836 res = dbwrap_transaction_start(db);
10838 printf(__location__ "transaction_start failed\n");
10842 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10844 printf(__location__ "fetch_lock failed\n");
10848 value = dbwrap_record_get_value(rec);
10850 if (value.dptr == NULL) {
10852 status = dbwrap_record_store(
10853 rec, make_tdb_data((uint8_t *)&initial,
10856 if (!NT_STATUS_IS_OK(status)) {
10857 printf(__location__ "store returned %s\n",
10858 nt_errstr(status));
10865 res = dbwrap_transaction_commit(db);
10867 printf(__location__ "transaction_commit failed\n");
10872 uint32_t val, val2;
10875 res = dbwrap_transaction_start(db);
10877 printf(__location__ "transaction_start failed\n");
10881 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
10882 if (!NT_STATUS_IS_OK(status)) {
10883 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10884 nt_errstr(status));
10888 for (i=0; i<10; i++) {
10889 if (!dbtrans_inc(db)) {
10894 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
10895 if (!NT_STATUS_IS_OK(status)) {
10896 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10897 nt_errstr(status));
10901 if (val2 != val + 10) {
10902 printf(__location__ "val=%d, val2=%d\n",
10903 (int)val, (int)val2);
10907 printf("val2=%d\r", val2);
10909 res = dbwrap_transaction_commit(db);
10911 printf(__location__ "transaction_commit failed\n");
10921 * Just a dummy test to be run under a debugger. There's no real way
10922 * to inspect the tevent_select specific function from outside of
10926 static bool run_local_tevent_select(int dummy)
10928 struct tevent_context *ev;
10929 struct tevent_fd *fd1, *fd2;
10930 bool result = false;
10932 ev = tevent_context_init_byname(NULL, "select");
10934 d_fprintf(stderr, "tevent_context_init_byname failed\n");
10938 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
10940 d_fprintf(stderr, "tevent_add_fd failed\n");
10943 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
10945 d_fprintf(stderr, "tevent_add_fd failed\n");
10950 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
10952 d_fprintf(stderr, "tevent_add_fd failed\n");
10962 static bool run_local_hex_encode_buf(int dummy)
10968 for (i=0; i<sizeof(src); i++) {
10971 hex_encode_buf(buf, src, sizeof(src));
10972 if (strcmp(buf, "0001020304050607") != 0) {
10975 hex_encode_buf(buf, NULL, 0);
10976 if (buf[0] != '\0') {
10982 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11004 "1001:1111:1111:1000:0:1111:1111:1111",
11013 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11027 "1001:1111:1111:1000:0:1111:1111:1111"
11030 static bool run_local_remove_duplicate_addrs2(int dummy)
11032 struct ip_service test_vector[28];
11035 /* Construct the sockaddr_storage test vector. */
11036 for (i = 0; i < 28; i++) {
11037 struct addrinfo hints;
11038 struct addrinfo *res = NULL;
11041 memset(&hints, '\0', sizeof(hints));
11042 hints.ai_flags = AI_NUMERICHOST;
11043 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11048 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11049 remove_duplicate_addrs2_test_strings_vector[i]);
11052 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11053 memcpy(&test_vector[i].ss,
11059 count = remove_duplicate_addrs2(test_vector, i);
11062 fprintf(stderr, "count wrong (%d) should be 14\n",
11067 for (i = 0; i < count; i++) {
11068 char addr[INET6_ADDRSTRLEN];
11070 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11072 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11073 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11076 remove_duplicate_addrs2_test_strings_result[i]);
11081 printf("run_local_remove_duplicate_addrs2: success\n");
11085 static bool run_local_tdb_opener(int dummy)
11091 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11092 O_RDWR|O_CREAT, 0755);
11094 perror("tdb_open failed");
11105 static bool run_local_tdb_writer(int dummy)
11111 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11113 perror("tdb_open failed");
11117 val.dptr = (uint8_t *)&v;
11118 val.dsize = sizeof(v);
11124 ret = tdb_store(t, val, val, 0);
11126 printf("%s\n", tdb_errorstr(t));
11131 data = tdb_fetch(t, val);
11132 if (data.dptr != NULL) {
11133 SAFE_FREE(data.dptr);
11139 static bool run_local_canonicalize_path(int dummy)
11141 const char *src[] = {
11148 ".././././../../../boo",
11152 const char *dst[] = {
11165 for (i = 0; src[i] != NULL; i++) {
11166 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11168 perror("talloc fail\n");
11171 if (strcmp(d, dst[i]) != 0) {
11173 "canonicalize missmatch %s -> %s != %s",
11174 src[i], d, dst[i]);
11182 static bool run_ign_bad_negprot(int dummy)
11184 struct tevent_context *ev;
11185 struct tevent_req *req;
11186 struct smbXcli_conn *conn;
11187 struct sockaddr_storage ss;
11192 printf("starting ignore bad negprot\n");
11194 ok = resolve_name(host, &ss, 0x20, true);
11196 d_fprintf(stderr, "Could not resolve name %s\n", host);
11200 status = open_socket_out(&ss, 445, 10000, &fd);
11201 if (!NT_STATUS_IS_OK(status)) {
11202 d_fprintf(stderr, "open_socket_out failed: %s\n",
11203 nt_errstr(status));
11207 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11209 if (conn == NULL) {
11210 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11214 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11215 if (NT_STATUS_IS_OK(status)) {
11216 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11220 ev = samba_tevent_context_init(talloc_tos());
11222 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11226 req = smb1cli_session_setup_nt1_send(
11227 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11228 data_blob_null, data_blob_null, 0x40,
11229 "Windows 2000 2195", "Windows 2000 5.0");
11231 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11235 ok = tevent_req_poll_ntstatus(req, ev, &status);
11237 d_fprintf(stderr, "tevent_req_poll failed\n");
11241 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11243 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11244 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11245 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11246 nt_errstr(status));
11252 printf("starting ignore bad negprot\n");
11257 static double create_procs(bool (*fn)(int), bool *result)
11260 volatile pid_t *child_status;
11261 volatile bool *child_status_out;
11264 struct timeval start;
11268 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11269 if (!child_status) {
11270 printf("Failed to setup shared memory\n");
11274 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11275 if (!child_status_out) {
11276 printf("Failed to setup result status shared memory\n");
11280 for (i = 0; i < torture_nprocs; i++) {
11281 child_status[i] = 0;
11282 child_status_out[i] = True;
11285 start = timeval_current();
11287 for (i=0;i<torture_nprocs;i++) {
11290 pid_t mypid = getpid();
11291 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11293 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11296 if (torture_open_connection(¤t_cli, i)) break;
11297 if (tries-- == 0) {
11298 printf("pid %d failed to start\n", (int)getpid());
11304 child_status[i] = getpid();
11306 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11308 child_status_out[i] = fn(i);
11315 for (i=0;i<torture_nprocs;i++) {
11316 if (child_status[i]) synccount++;
11318 if (synccount == torture_nprocs) break;
11320 } while (timeval_elapsed(&start) < 30);
11322 if (synccount != torture_nprocs) {
11323 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11325 return timeval_elapsed(&start);
11328 /* start the client load */
11329 start = timeval_current();
11331 for (i=0;i<torture_nprocs;i++) {
11332 child_status[i] = 0;
11335 printf("%d clients started\n", torture_nprocs);
11337 for (i=0;i<torture_nprocs;i++) {
11338 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11343 for (i=0;i<torture_nprocs;i++) {
11344 if (!child_status_out[i]) {
11348 return timeval_elapsed(&start);
11351 #define FLAG_MULTIPROC 1
11357 } torture_ops[] = {
11358 {"FDPASS", run_fdpasstest, 0},
11359 {"LOCK1", run_locktest1, 0},
11360 {"LOCK2", run_locktest2, 0},
11361 {"LOCK3", run_locktest3, 0},
11362 {"LOCK4", run_locktest4, 0},
11363 {"LOCK5", run_locktest5, 0},
11364 {"LOCK6", run_locktest6, 0},
11365 {"LOCK7", run_locktest7, 0},
11366 {"LOCK8", run_locktest8, 0},
11367 {"LOCK9", run_locktest9, 0},
11368 {"UNLINK", run_unlinktest, 0},
11369 {"BROWSE", run_browsetest, 0},
11370 {"ATTR", run_attrtest, 0},
11371 {"TRANS2", run_trans2test, 0},
11372 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
11373 {"TORTURE",run_torture, FLAG_MULTIPROC},
11374 {"RANDOMIPC", run_randomipc, 0},
11375 {"NEGNOWAIT", run_negprot_nowait, 0},
11376 {"NBENCH", run_nbench, 0},
11377 {"NBENCH2", run_nbench2, 0},
11378 {"OPLOCK1", run_oplock1, 0},
11379 {"OPLOCK2", run_oplock2, 0},
11380 {"OPLOCK4", run_oplock4, 0},
11381 {"DIR", run_dirtest, 0},
11382 {"DIR1", run_dirtest1, 0},
11383 {"DIR-CREATETIME", run_dir_createtime, 0},
11384 {"DENY1", torture_denytest1, 0},
11385 {"DENY2", torture_denytest2, 0},
11386 {"TCON", run_tcon_test, 0},
11387 {"TCONDEV", run_tcon_devtype_test, 0},
11388 {"RW1", run_readwritetest, 0},
11389 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
11390 {"RW3", run_readwritelarge, 0},
11391 {"RW-SIGNING", run_readwritelarge_signtest, 0},
11392 {"OPEN", run_opentest, 0},
11393 {"POSIX", run_simple_posix_open_test, 0},
11394 {"POSIX-APPEND", run_posix_append, 0},
11395 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
11396 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
11397 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
11398 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
11399 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
11400 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
11401 {"ASYNC-ECHO", run_async_echo, 0},
11402 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
11403 { "SHORTNAME-TEST", run_shortname_test, 0},
11404 { "ADDRCHANGE", run_addrchange, 0},
11406 {"OPENATTR", run_openattrtest, 0},
11408 {"XCOPY", run_xcopy, 0},
11409 {"RENAME", run_rename, 0},
11410 {"RENAME-ACCESS", run_rename_access, 0},
11411 {"OWNER-RIGHTS", run_owner_rights, 0},
11412 {"DELETE", run_deletetest, 0},
11413 {"WILDDELETE", run_wild_deletetest, 0},
11414 {"DELETE-LN", run_deletetest_ln, 0},
11415 {"PROPERTIES", run_properties, 0},
11416 {"MANGLE", torture_mangle, 0},
11417 {"MANGLE1", run_mangle1, 0},
11418 {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
11419 {"W2K", run_w2ktest, 0},
11420 {"TRANS2SCAN", torture_trans2_scan, 0},
11421 {"NTTRANSSCAN", torture_nttrans_scan, 0},
11422 {"UTABLE", torture_utable, 0},
11423 {"CASETABLE", torture_casetable, 0},
11424 {"ERRMAPEXTRACT", run_error_map_extract, 0},
11425 {"PIPE_NUMBER", run_pipe_number, 0},
11426 {"TCON2", run_tcon2_test, 0},
11427 {"IOCTL", torture_ioctl_test, 0},
11428 {"CHKPATH", torture_chkpath_test, 0},
11429 {"FDSESS", run_fdsesstest, 0},
11430 { "EATEST", run_eatest, 0},
11431 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
11432 { "CHAIN1", run_chain1, 0},
11433 { "CHAIN2", run_chain2, 0},
11434 { "CHAIN3", run_chain3, 0},
11435 { "WINDOWS-WRITE", run_windows_write, 0},
11436 { "LARGE_READX", run_large_readx, 0},
11437 { "NTTRANS-CREATE", run_nttrans_create, 0},
11438 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
11439 { "CLI_ECHO", run_cli_echo, 0},
11440 { "GETADDRINFO", run_getaddrinfo_send, 0},
11441 { "TLDAP", run_tldap },
11442 { "STREAMERROR", run_streamerror },
11443 { "NOTIFY-BENCH", run_notify_bench },
11444 { "NOTIFY-BENCH2", run_notify_bench2 },
11445 { "NOTIFY-BENCH3", run_notify_bench3 },
11446 { "BAD-NBT-SESSION", run_bad_nbt_session },
11447 { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
11448 { "SMB-ANY-CONNECT", run_smb_any_connect },
11449 { "NOTIFY-ONLINE", run_notify_online },
11450 { "SMB2-BASIC", run_smb2_basic },
11451 { "SMB2-NEGPROT", run_smb2_negprot },
11452 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
11453 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
11454 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
11455 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
11456 { "SMB2-FTRUNCATE", run_smb2_ftruncate },
11457 { "CLEANUP1", run_cleanup1 },
11458 { "CLEANUP2", run_cleanup2 },
11459 { "CLEANUP3", run_cleanup3 },
11460 { "CLEANUP4", run_cleanup4 },
11461 { "OPLOCK-CANCEL", run_oplock_cancel },
11462 { "PIDHIGH", run_pidhigh },
11463 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
11464 { "LOCAL-GENCACHE", run_local_gencache, 0},
11465 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
11466 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
11467 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2, 0 },
11468 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
11469 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
11470 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
11471 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
11472 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
11473 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
11474 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
11475 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
11476 { "LOCAL-BASE64", run_local_base64, 0},
11477 { "LOCAL-RBTREE", run_local_rbtree, 0},
11478 { "LOCAL-MEMCACHE", run_local_memcache, 0},
11479 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
11480 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
11481 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
11482 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
11483 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
11484 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
11485 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
11486 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
11487 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
11488 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
11489 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
11490 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
11491 { "local-tdb-opener", run_local_tdb_opener, 0 },
11492 { "local-tdb-writer", run_local_tdb_writer, 0 },
11493 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
11494 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
11495 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
11496 { "LOCAL-G-LOCK1", run_g_lock1, 0 },
11497 { "LOCAL-G-LOCK2", run_g_lock2, 0 },
11498 { "LOCAL-G-LOCK3", run_g_lock3, 0 },
11499 { "LOCAL-G-LOCK4", run_g_lock4, 0 },
11500 { "LOCAL-G-LOCK5", run_g_lock5, 0 },
11501 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
11502 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
11506 * dummy function to satisfy linker dependency
11508 struct tevent_context *winbind_event_context(void);
11509 struct tevent_context *winbind_event_context(void)
11514 /****************************************************************************
11515 run a specified test or "ALL"
11516 ****************************************************************************/
11517 static bool run_test(const char *name)
11520 bool result = True;
11521 bool found = False;
11524 if (strequal(name,"ALL")) {
11525 for (i=0;torture_ops[i].name;i++) {
11526 run_test(torture_ops[i].name);
11531 for (i=0;torture_ops[i].name;i++) {
11532 fstr_sprintf(randomfname, "\\XX%x",
11533 (unsigned)random());
11535 if (strequal(name, torture_ops[i].name)) {
11537 printf("Running %s\n", name);
11538 if (torture_ops[i].flags & FLAG_MULTIPROC) {
11539 t = create_procs(torture_ops[i].fn, &result);
11542 printf("TEST %s FAILED!\n", name);
11545 struct timeval start;
11546 start = timeval_current();
11547 if (!torture_ops[i].fn(0)) {
11549 printf("TEST %s FAILED!\n", name);
11551 t = timeval_elapsed(&start);
11553 printf("%s took %g secs\n\n", name, t);
11558 printf("Did not find a test named %s\n", name);
11566 static void usage(void)
11570 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11571 printf("Please use samba4 torture.\n\n");
11573 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11575 printf("\t-d debuglevel\n");
11576 printf("\t-U user%%pass\n");
11577 printf("\t-k use kerberos\n");
11578 printf("\t-N numprocs\n");
11579 printf("\t-n my_netbios_name\n");
11580 printf("\t-W workgroup\n");
11581 printf("\t-o num_operations\n");
11582 printf("\t-O socket_options\n");
11583 printf("\t-m maximum protocol\n");
11584 printf("\t-L use oplocks\n");
11585 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11586 printf("\t-A showall\n");
11587 printf("\t-p port\n");
11588 printf("\t-s seed\n");
11589 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11590 printf("\t-f filename filename to test\n");
11591 printf("\t-e encrypt\n");
11594 printf("tests are:");
11595 for (i=0;torture_ops[i].name;i++) {
11596 printf(" %s", torture_ops[i].name);
11600 printf("default test is ALL\n");
11605 /****************************************************************************
11607 ****************************************************************************/
11608 int main(int argc,char *argv[])
11614 bool correct = True;
11615 TALLOC_CTX *frame = talloc_stackframe();
11616 int seed = time(NULL);
11618 #ifdef HAVE_SETBUFFER
11619 setbuffer(stdout, NULL, 0);
11622 setup_logging("smbtorture", DEBUG_STDOUT);
11627 if (is_default_dyn_CONFIGFILE()) {
11628 if(getenv("SMB_CONF_PATH")) {
11629 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11632 lp_load_global(get_dyn_CONFIGFILE());
11639 for(p = argv[1]; *p; p++)
11643 if (strncmp(argv[1], "//", 2)) {
11647 fstrcpy(host, &argv[1][2]);
11648 p = strchr_m(&host[2],'/');
11653 fstrcpy(share, p+1);
11655 fstrcpy(myname, get_myname(talloc_tos()));
11657 fprintf(stderr, "Failed to get my hostname.\n");
11661 if (*username == 0 && getenv("LOGNAME")) {
11662 fstrcpy(username,getenv("LOGNAME"));
11668 fstrcpy(workgroup, lp_workgroup());
11670 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
11674 port_to_use = atoi(optarg);
11677 seed = atoi(optarg);
11680 fstrcpy(workgroup,optarg);
11683 lp_set_cmdline("client max protocol", optarg);
11686 torture_nprocs = atoi(optarg);
11689 torture_numops = atoi(optarg);
11692 lp_set_cmdline("log level", optarg);
11698 use_oplocks = True;
11701 local_path = optarg;
11704 torture_showall = True;
11707 fstrcpy(myname, optarg);
11710 client_txt = optarg;
11717 use_kerberos = True;
11719 d_printf("No kerberos support compiled in\n");
11725 fstrcpy(username,optarg);
11726 p = strchr_m(username,'%');
11729 fstrcpy(password, p+1);
11734 fstrcpy(multishare_conn_fname, optarg);
11735 use_multishare_conn = True;
11738 torture_blocksize = atoi(optarg);
11741 test_filename = SMB_STRDUP(optarg);
11744 printf("Unknown option %c (%d)\n", (char)opt, opt);
11749 d_printf("using seed %d\n", seed);
11753 if(use_kerberos && !gotuser) gotpass = True;
11756 char pwd[256] = {0};
11759 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
11761 fstrcpy(password, pwd);
11766 printf("host=%s share=%s user=%s myname=%s\n",
11767 host, share, username, myname);
11769 torture_creds = cli_session_creds_init(frame,
11775 false, /* fallback_after_kerberos */
11776 false, /* use_ccache */
11777 false); /* password_is_nt_hash */
11778 if (torture_creds == NULL) {
11779 d_printf("cli_session_creds_init() failed.\n");
11783 if (argc == optind) {
11784 correct = run_test("ALL");
11786 for (i=optind;i<argc;i++) {
11787 if (!run_test(argv[i])) {
11793 TALLOC_FREE(frame);