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 uint16_t cnum1, cnum2, cnum3;
1305 uint16_t vuid1, vuid2;
1310 memset(buf, '\0', sizeof(buf));
1312 if (!torture_open_connection(&cli, 0)) {
1315 smbXcli_conn_set_sockopt(cli->conn, sockops);
1317 printf("starting tcontest\n");
1319 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1321 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1322 if (!NT_STATUS_IS_OK(status)) {
1323 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1327 cnum1 = cli_state_get_tid(cli);
1328 vuid1 = cli_state_get_uid(cli);
1330 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 printf("initial write failed (%s)", nt_errstr(status));
1336 status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1337 if (!NT_STATUS_IS_OK(status)) {
1338 printf("%s refused 2nd tree connect (%s)\n", host,
1344 cnum2 = cli_state_get_tid(cli);
1345 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1346 vuid2 = cli_state_get_uid(cli) + 1;
1348 /* try a write with the wrong tid */
1349 cli_state_set_tid(cli, cnum2);
1351 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1352 if (NT_STATUS_IS_OK(status)) {
1353 printf("* server allows write with wrong TID\n");
1356 printf("server fails write with wrong TID : %s\n",
1361 /* try a write with an invalid tid */
1362 cli_state_set_tid(cli, cnum3);
1364 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1365 if (NT_STATUS_IS_OK(status)) {
1366 printf("* server allows write with invalid TID\n");
1369 printf("server fails write with invalid TID : %s\n",
1373 /* try a write with an invalid vuid */
1374 cli_state_set_uid(cli, vuid2);
1375 cli_state_set_tid(cli, cnum1);
1377 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1378 if (NT_STATUS_IS_OK(status)) {
1379 printf("* server allows write with invalid VUID\n");
1382 printf("server fails write with invalid VUID : %s\n",
1386 cli_state_set_tid(cli, cnum1);
1387 cli_state_set_uid(cli, vuid1);
1389 status = cli_close(cli, fnum1);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 printf("close failed (%s)\n", nt_errstr(status));
1395 cli_state_set_tid(cli, cnum2);
1397 status = cli_tdis(cli);
1398 if (!NT_STATUS_IS_OK(status)) {
1399 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1403 cli_state_set_tid(cli, cnum1);
1405 if (!torture_close_connection(cli)) {
1414 checks for old style tcon support
1416 static bool run_tcon2_test(int dummy)
1418 static struct cli_state *cli;
1419 uint16_t cnum, max_xmit;
1423 if (!torture_open_connection(&cli, 0)) {
1426 smbXcli_conn_set_sockopt(cli->conn, sockops);
1428 printf("starting tcon2 test\n");
1430 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1434 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1438 if (!NT_STATUS_IS_OK(status)) {
1439 printf("tcon2 failed : %s\n", nt_errstr(status));
1441 printf("tcon OK : max_xmit=%d cnum=%d\n",
1442 (int)max_xmit, (int)cnum);
1445 if (!torture_close_connection(cli)) {
1449 printf("Passed tcon2 test\n");
1453 static bool tcon_devtest(struct cli_state *cli,
1454 const char *myshare, const char *devtype,
1455 const char *return_devtype,
1456 NTSTATUS expected_error)
1461 status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
1463 if (NT_STATUS_IS_OK(expected_error)) {
1464 if (NT_STATUS_IS_OK(status)) {
1465 if (strcmp(cli->dev, return_devtype) == 0) {
1468 printf("tconX to share %s with type %s "
1469 "succeeded but returned the wrong "
1470 "device type (got [%s] but should have got [%s])\n",
1471 myshare, devtype, cli->dev, return_devtype);
1475 printf("tconX to share %s with type %s "
1476 "should have succeeded but failed\n",
1482 if (NT_STATUS_IS_OK(status)) {
1483 printf("tconx to share %s with type %s "
1484 "should have failed but succeeded\n",
1488 if (NT_STATUS_EQUAL(status, expected_error)) {
1491 printf("Returned unexpected error\n");
1500 checks for correct tconX support
1502 static bool run_tcon_devtype_test(int dummy)
1504 static struct cli_state *cli1 = NULL;
1509 status = cli_full_connection_creds(&cli1,
1515 NULL, /* service_type */
1520 if (!NT_STATUS_IS_OK(status)) {
1521 printf("could not open connection\n");
1525 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1528 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1531 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1534 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1537 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1540 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1543 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1546 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1549 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1552 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1558 printf("Passed tcondevtest\n");
1565 This test checks that
1567 1) the server supports multiple locking contexts on the one SMB
1568 connection, distinguished by PID.
1570 2) the server correctly fails overlapping locks made by the same PID (this
1571 goes against POSIX behaviour, which is why it is tricky to implement)
1573 3) the server denies unlock requests by an incorrect client PID
1575 static bool run_locktest2(int dummy)
1577 static struct cli_state *cli;
1578 const char *fname = "\\lockt2.lck";
1579 uint16_t fnum1, fnum2, fnum3;
1580 bool correct = True;
1583 if (!torture_open_connection(&cli, 0)) {
1587 smbXcli_conn_set_sockopt(cli->conn, sockops);
1589 printf("starting locktest2\n");
1591 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1595 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1596 if (!NT_STATUS_IS_OK(status)) {
1597 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1601 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1602 if (!NT_STATUS_IS_OK(status)) {
1603 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1609 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1610 if (!NT_STATUS_IS_OK(status)) {
1611 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1617 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1618 if (!NT_STATUS_IS_OK(status)) {
1619 printf("lock1 failed (%s)\n", nt_errstr(status));
1623 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1624 if (NT_STATUS_IS_OK(status)) {
1625 printf("WRITE lock1 succeeded! This is a locking bug\n");
1628 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1629 NT_STATUS_LOCK_NOT_GRANTED)) {
1634 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1635 if (NT_STATUS_IS_OK(status)) {
1636 printf("WRITE lock2 succeeded! This is a locking bug\n");
1639 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1640 NT_STATUS_LOCK_NOT_GRANTED)) {
1645 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1646 if (NT_STATUS_IS_OK(status)) {
1647 printf("READ lock2 succeeded! This is a locking bug\n");
1650 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1651 NT_STATUS_FILE_LOCK_CONFLICT)) {
1656 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1657 if (!NT_STATUS_IS_OK(status)) {
1658 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1661 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1662 printf("unlock at 100 succeeded! This is a locking bug\n");
1666 status = cli_unlock(cli, fnum1, 0, 4);
1667 if (NT_STATUS_IS_OK(status)) {
1668 printf("unlock1 succeeded! This is a locking bug\n");
1671 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1672 NT_STATUS_RANGE_NOT_LOCKED)) {
1677 status = cli_unlock(cli, fnum1, 0, 8);
1678 if (NT_STATUS_IS_OK(status)) {
1679 printf("unlock2 succeeded! This is a locking bug\n");
1682 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1683 NT_STATUS_RANGE_NOT_LOCKED)) {
1688 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1689 if (NT_STATUS_IS_OK(status)) {
1690 printf("lock3 succeeded! This is a locking bug\n");
1693 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1694 NT_STATUS_LOCK_NOT_GRANTED)) {
1701 status = cli_close(cli, fnum1);
1702 if (!NT_STATUS_IS_OK(status)) {
1703 printf("close1 failed (%s)\n", nt_errstr(status));
1707 status = cli_close(cli, fnum2);
1708 if (!NT_STATUS_IS_OK(status)) {
1709 printf("close2 failed (%s)\n", nt_errstr(status));
1713 status = cli_close(cli, fnum3);
1714 if (!NT_STATUS_IS_OK(status)) {
1715 printf("close3 failed (%s)\n", nt_errstr(status));
1719 if (!torture_close_connection(cli)) {
1723 printf("locktest2 finished\n");
1730 This test checks that
1732 1) the server supports the full offset range in lock requests
1734 static bool run_locktest3(int dummy)
1736 static struct cli_state *cli1, *cli2;
1737 const char *fname = "\\lockt3.lck";
1738 uint16_t fnum1, fnum2;
1741 bool correct = True;
1744 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1746 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1749 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1750 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1752 printf("starting locktest3\n");
1754 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1756 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1758 if (!NT_STATUS_IS_OK(status)) {
1759 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1763 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1764 if (!NT_STATUS_IS_OK(status)) {
1765 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1769 for (offset=i=0;i<torture_numops;i++) {
1772 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1773 if (!NT_STATUS_IS_OK(status)) {
1774 printf("lock1 %d failed (%s)\n",
1780 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 printf("lock2 %d failed (%s)\n",
1789 for (offset=i=0;i<torture_numops;i++) {
1792 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1793 if (NT_STATUS_IS_OK(status)) {
1794 printf("error: lock1 %d succeeded!\n", i);
1798 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1799 if (NT_STATUS_IS_OK(status)) {
1800 printf("error: lock2 %d succeeded!\n", i);
1804 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1805 if (NT_STATUS_IS_OK(status)) {
1806 printf("error: lock3 %d succeeded!\n", i);
1810 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1811 if (NT_STATUS_IS_OK(status)) {
1812 printf("error: lock4 %d succeeded!\n", i);
1817 for (offset=i=0;i<torture_numops;i++) {
1820 status = cli_unlock(cli1, fnum1, offset-1, 1);
1821 if (!NT_STATUS_IS_OK(status)) {
1822 printf("unlock1 %d failed (%s)\n",
1828 status = cli_unlock(cli2, fnum2, offset-2, 1);
1829 if (!NT_STATUS_IS_OK(status)) {
1830 printf("unlock2 %d failed (%s)\n",
1837 status = cli_close(cli1, fnum1);
1838 if (!NT_STATUS_IS_OK(status)) {
1839 printf("close1 failed (%s)\n", nt_errstr(status));
1843 status = cli_close(cli2, fnum2);
1844 if (!NT_STATUS_IS_OK(status)) {
1845 printf("close2 failed (%s)\n", nt_errstr(status));
1849 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1850 if (!NT_STATUS_IS_OK(status)) {
1851 printf("unlink failed (%s)\n", nt_errstr(status));
1855 if (!torture_close_connection(cli1)) {
1859 if (!torture_close_connection(cli2)) {
1863 printf("finished locktest3\n");
1868 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1869 char *buf, off_t offset, size_t size,
1870 size_t *nread, size_t expect)
1875 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1877 if(!NT_STATUS_IS_OK(status)) {
1879 } else if (l_nread != expect) {
1890 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1891 printf("** "); correct = False; \
1895 looks at overlapping locks
1897 static bool run_locktest4(int dummy)
1899 static struct cli_state *cli1, *cli2;
1900 const char *fname = "\\lockt4.lck";
1901 uint16_t fnum1, fnum2, f;
1904 bool correct = True;
1907 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1911 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1912 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1914 printf("starting locktest4\n");
1916 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1918 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1919 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1921 memset(buf, 0, sizeof(buf));
1923 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1925 if (!NT_STATUS_IS_OK(status)) {
1926 printf("Failed to create file: %s\n", nt_errstr(status));
1931 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1932 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1933 EXPECTED(ret, False);
1934 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1936 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1937 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1938 EXPECTED(ret, True);
1939 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1941 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1942 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1943 EXPECTED(ret, False);
1944 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1946 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1947 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1948 EXPECTED(ret, True);
1949 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1951 ret = (cli_setpid(cli1, 1),
1952 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1953 (cli_setpid(cli1, 2),
1954 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1955 EXPECTED(ret, False);
1956 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1958 ret = (cli_setpid(cli1, 1),
1959 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1960 (cli_setpid(cli1, 2),
1961 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1962 EXPECTED(ret, True);
1963 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1965 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1966 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1967 EXPECTED(ret, True);
1968 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1970 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1971 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1972 EXPECTED(ret, False);
1973 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1975 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1976 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1977 EXPECTED(ret, False);
1978 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1980 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1981 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
1982 EXPECTED(ret, True);
1983 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1985 ret = (cli_setpid(cli1, 1),
1986 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1987 (cli_setpid(cli1, 2),
1988 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
1989 EXPECTED(ret, False);
1990 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1992 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
1993 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
1994 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1995 EXPECTED(ret, False);
1996 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1999 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2000 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2001 EXPECTED(ret, False);
2002 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2004 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2005 ret = NT_STATUS_IS_OK(status);
2007 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2009 ret = NT_STATUS_IS_OK(status);
2011 EXPECTED(ret, False);
2012 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2015 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2016 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2017 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2018 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2019 EXPECTED(ret, True);
2020 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2023 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2024 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2025 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2026 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2027 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2029 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2030 EXPECTED(ret, True);
2031 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2033 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2034 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2035 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2037 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2038 EXPECTED(ret, True);
2039 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2041 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2042 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2043 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2045 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2046 EXPECTED(ret, True);
2047 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2049 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2050 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2051 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2052 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2054 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2055 EXPECTED(ret, True);
2056 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2058 cli_close(cli1, fnum1);
2059 cli_close(cli2, fnum2);
2060 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2061 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2062 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2063 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2064 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2065 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2066 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2068 cli_close(cli1, fnum1);
2069 EXPECTED(ret, True);
2070 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2073 cli_close(cli1, fnum1);
2074 cli_close(cli2, fnum2);
2075 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2076 torture_close_connection(cli1);
2077 torture_close_connection(cli2);
2079 printf("finished locktest4\n");
2084 looks at lock upgrade/downgrade.
2086 static bool run_locktest5(int dummy)
2088 static struct cli_state *cli1, *cli2;
2089 const char *fname = "\\lockt5.lck";
2090 uint16_t fnum1, fnum2, fnum3;
2093 bool correct = True;
2096 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2100 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2101 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2103 printf("starting locktest5\n");
2105 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2107 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2108 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2109 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2111 memset(buf, 0, sizeof(buf));
2113 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2115 if (!NT_STATUS_IS_OK(status)) {
2116 printf("Failed to create file: %s\n", nt_errstr(status));
2121 /* Check for NT bug... */
2122 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2123 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2124 cli_close(cli1, fnum1);
2125 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2126 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2127 ret = NT_STATUS_IS_OK(status);
2128 EXPECTED(ret, True);
2129 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2130 cli_close(cli1, fnum1);
2131 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2132 cli_unlock(cli1, fnum3, 0, 1);
2134 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2135 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2136 EXPECTED(ret, True);
2137 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2139 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2140 ret = NT_STATUS_IS_OK(status);
2141 EXPECTED(ret, False);
2143 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2145 /* Unlock the process 2 lock. */
2146 cli_unlock(cli2, fnum2, 0, 4);
2148 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2149 ret = NT_STATUS_IS_OK(status);
2150 EXPECTED(ret, False);
2152 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2154 /* Unlock the process 1 fnum3 lock. */
2155 cli_unlock(cli1, fnum3, 0, 4);
2157 /* Stack 2 more locks here. */
2158 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2159 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2161 EXPECTED(ret, True);
2162 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2164 /* Unlock the first process lock, then check this was the WRITE lock that was
2167 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2168 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2170 EXPECTED(ret, True);
2171 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2173 /* Unlock the process 2 lock. */
2174 cli_unlock(cli2, fnum2, 0, 4);
2176 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2178 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2179 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2180 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2182 EXPECTED(ret, True);
2183 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2185 /* Ensure the next unlock fails. */
2186 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2187 EXPECTED(ret, False);
2188 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2190 /* Ensure connection 2 can get a write lock. */
2191 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2192 ret = NT_STATUS_IS_OK(status);
2193 EXPECTED(ret, True);
2195 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2199 cli_close(cli1, fnum1);
2200 cli_close(cli2, fnum2);
2201 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2202 if (!torture_close_connection(cli1)) {
2205 if (!torture_close_connection(cli2)) {
2209 printf("finished locktest5\n");
2215 tries the unusual lockingX locktype bits
2217 static bool run_locktest6(int dummy)
2219 static struct cli_state *cli;
2220 const char *fname[1] = { "\\lock6.txt" };
2225 if (!torture_open_connection(&cli, 0)) {
2229 smbXcli_conn_set_sockopt(cli->conn, sockops);
2231 printf("starting locktest6\n");
2234 printf("Testing %s\n", fname[i]);
2236 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2238 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2239 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2240 cli_close(cli, fnum);
2241 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2243 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2244 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2245 cli_close(cli, fnum);
2246 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2248 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2251 torture_close_connection(cli);
2253 printf("finished locktest6\n");
2257 static bool run_locktest7(int dummy)
2259 struct cli_state *cli1;
2260 const char *fname = "\\lockt7.lck";
2263 bool correct = False;
2267 if (!torture_open_connection(&cli1, 0)) {
2271 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2273 printf("starting locktest7\n");
2275 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2277 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2279 memset(buf, 0, sizeof(buf));
2281 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2283 if (!NT_STATUS_IS_OK(status)) {
2284 printf("Failed to create file: %s\n", nt_errstr(status));
2288 cli_setpid(cli1, 1);
2290 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2291 if (!NT_STATUS_IS_OK(status)) {
2292 printf("Unable to apply read lock on range 130:4, "
2293 "error was %s\n", nt_errstr(status));
2296 printf("pid1 successfully locked range 130:4 for READ\n");
2299 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2300 if (!NT_STATUS_IS_OK(status)) {
2301 printf("pid1 unable to read the range 130:4, error was %s\n",
2304 } else if (nread != 4) {
2305 printf("pid1 unable to read the range 130:4, "
2306 "recv %ld req %d\n", (unsigned long)nread, 4);
2309 printf("pid1 successfully read the range 130:4\n");
2312 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2313 if (!NT_STATUS_IS_OK(status)) {
2314 printf("pid1 unable to write to the range 130:4, error was "
2315 "%s\n", nt_errstr(status));
2316 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2317 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2321 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2325 cli_setpid(cli1, 2);
2327 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2328 if (!NT_STATUS_IS_OK(status)) {
2329 printf("pid2 unable to read the range 130:4, error was %s\n",
2332 } else if (nread != 4) {
2333 printf("pid2 unable to read the range 130:4, "
2334 "recv %ld req %d\n", (unsigned long)nread, 4);
2337 printf("pid2 successfully read the range 130:4\n");
2340 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 printf("pid2 unable to write to the range 130:4, error was "
2343 "%s\n", nt_errstr(status));
2344 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2345 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2349 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2353 cli_setpid(cli1, 1);
2354 cli_unlock(cli1, fnum1, 130, 4);
2356 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2357 if (!NT_STATUS_IS_OK(status)) {
2358 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2361 printf("pid1 successfully locked range 130:4 for WRITE\n");
2364 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2365 if (!NT_STATUS_IS_OK(status)) {
2366 printf("pid1 unable to read the range 130:4, error was %s\n",
2369 } else if (nread != 4) {
2370 printf("pid1 unable to read the range 130:4, "
2371 "recv %ld req %d\n", (unsigned long)nread, 4);
2374 printf("pid1 successfully read the range 130:4\n");
2377 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 printf("pid1 unable to write to the range 130:4, error was "
2380 "%s\n", nt_errstr(status));
2383 printf("pid1 successfully wrote to the range 130:4\n");
2386 cli_setpid(cli1, 2);
2388 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2389 if (!NT_STATUS_IS_OK(status)) {
2390 printf("pid2 unable to read the range 130:4, error was "
2391 "%s\n", nt_errstr(status));
2392 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2393 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2397 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2398 (unsigned long)nread);
2402 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2403 if (!NT_STATUS_IS_OK(status)) {
2404 printf("pid2 unable to write to the range 130:4, error was "
2405 "%s\n", nt_errstr(status));
2406 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2407 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2411 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2415 cli_unlock(cli1, fnum1, 130, 0);
2419 cli_close(cli1, fnum1);
2420 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2421 torture_close_connection(cli1);
2423 printf("finished locktest7\n");
2428 * This demonstrates a problem with our use of GPFS share modes: A file
2429 * descriptor sitting in the pending close queue holding a GPFS share mode
2430 * blocks opening a file another time. Happens with Word 2007 temp files.
2431 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2432 * open is denied with NT_STATUS_SHARING_VIOLATION.
2435 static bool run_locktest8(int dummy)
2437 struct cli_state *cli1;
2438 const char *fname = "\\lockt8.lck";
2439 uint16_t fnum1, fnum2;
2441 bool correct = False;
2444 if (!torture_open_connection(&cli1, 0)) {
2448 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2450 printf("starting locktest8\n");
2452 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2454 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2456 if (!NT_STATUS_IS_OK(status)) {
2457 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2461 memset(buf, 0, sizeof(buf));
2463 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2464 if (!NT_STATUS_IS_OK(status)) {
2465 d_fprintf(stderr, "cli_openx second time returned %s\n",
2470 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2471 if (!NT_STATUS_IS_OK(status)) {
2472 printf("Unable to apply read lock on range 1:1, error was "
2473 "%s\n", nt_errstr(status));
2477 status = cli_close(cli1, fnum1);
2478 if (!NT_STATUS_IS_OK(status)) {
2479 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2483 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2484 if (!NT_STATUS_IS_OK(status)) {
2485 d_fprintf(stderr, "cli_openx third time returned %s\n",
2493 cli_close(cli1, fnum1);
2494 cli_close(cli1, fnum2);
2495 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2496 torture_close_connection(cli1);
2498 printf("finished locktest8\n");
2503 * This test is designed to be run in conjunction with
2504 * external NFS or POSIX locks taken in the filesystem.
2505 * It checks that the smbd server will block until the
2506 * lock is released and then acquire it. JRA.
2509 static bool got_alarm;
2510 static struct cli_state *alarm_cli;
2512 static void alarm_handler(int dummy)
2517 static void alarm_handler_parent(int dummy)
2519 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2522 static void do_local_lock(int read_fd, int write_fd)
2527 const char *local_pathname = NULL;
2530 local_pathname = talloc_asprintf(talloc_tos(),
2531 "%s/lockt9.lck", local_path);
2532 if (!local_pathname) {
2533 printf("child: alloc fail\n");
2537 unlink(local_pathname);
2538 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2540 printf("child: open of %s failed %s.\n",
2541 local_pathname, strerror(errno));
2545 /* Now take a fcntl lock. */
2546 lock.l_type = F_WRLCK;
2547 lock.l_whence = SEEK_SET;
2550 lock.l_pid = getpid();
2552 ret = fcntl(fd,F_SETLK,&lock);
2554 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2555 local_pathname, strerror(errno));
2558 printf("child: got lock 0:4 on file %s.\n",
2563 CatchSignal(SIGALRM, alarm_handler);
2565 /* Signal the parent. */
2566 if (write(write_fd, &c, 1) != 1) {
2567 printf("child: start signal fail %s.\n",
2574 /* Wait for the parent to be ready. */
2575 if (read(read_fd, &c, 1) != 1) {
2576 printf("child: reply signal fail %s.\n",
2584 printf("child: released lock 0:4 on file %s.\n",
2590 static bool run_locktest9(int dummy)
2592 struct cli_state *cli1;
2593 const char *fname = "\\lockt9.lck";
2595 bool correct = False;
2596 int pipe_in[2], pipe_out[2];
2600 struct timeval start;
2604 printf("starting locktest9\n");
2606 if (local_path == NULL) {
2607 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2611 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2616 if (child_pid == -1) {
2620 if (child_pid == 0) {
2622 do_local_lock(pipe_out[0], pipe_in[1]);
2632 ret = read(pipe_in[0], &c, 1);
2634 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2639 if (!torture_open_connection(&cli1, 0)) {
2643 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2645 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2647 if (!NT_STATUS_IS_OK(status)) {
2648 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2652 /* Ensure the child has the lock. */
2653 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2654 if (NT_STATUS_IS_OK(status)) {
2655 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2658 d_printf("Child has the lock.\n");
2661 /* Tell the child to wait 5 seconds then exit. */
2662 ret = write(pipe_out[1], &c, 1);
2664 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2669 /* Wait 20 seconds for the lock. */
2671 CatchSignal(SIGALRM, alarm_handler_parent);
2674 start = timeval_current();
2676 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2677 if (!NT_STATUS_IS_OK(status)) {
2678 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2679 "%s\n", nt_errstr(status));
2684 seconds = timeval_elapsed(&start);
2686 printf("Parent got the lock after %.2f seconds.\n",
2689 status = cli_close(cli1, fnum);
2690 if (!NT_STATUS_IS_OK(status)) {
2691 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2698 cli_close(cli1, fnum);
2699 torture_close_connection(cli1);
2703 printf("finished locktest9\n");
2708 test whether fnums and tids open on one VC are available on another (a major
2711 static bool run_fdpasstest(int dummy)
2713 struct cli_state *cli1, *cli2;
2714 const char *fname = "\\fdpass.tst";
2719 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2722 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2723 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2725 printf("starting fdpasstest\n");
2727 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2729 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2731 if (!NT_STATUS_IS_OK(status)) {
2732 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2736 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2738 if (!NT_STATUS_IS_OK(status)) {
2739 printf("write failed (%s)\n", nt_errstr(status));
2743 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2744 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2745 cli_setpid(cli2, cli_getpid(cli1));
2747 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2748 printf("read succeeded! nasty security hole [%s]\n", buf);
2752 cli_close(cli1, fnum1);
2753 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2755 torture_close_connection(cli1);
2756 torture_close_connection(cli2);
2758 printf("finished fdpasstest\n");
2762 static bool run_fdsesstest(int dummy)
2764 struct cli_state *cli;
2766 uint16_t saved_vuid;
2768 uint16_t saved_cnum;
2769 const char *fname = "\\fdsess.tst";
2770 const char *fname1 = "\\fdsess1.tst";
2777 if (!torture_open_connection(&cli, 0))
2779 smbXcli_conn_set_sockopt(cli->conn, sockops);
2781 if (!torture_cli_session_setup2(cli, &new_vuid))
2784 saved_cnum = cli_state_get_tid(cli);
2785 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
2787 new_cnum = cli_state_get_tid(cli);
2788 cli_state_set_tid(cli, saved_cnum);
2790 printf("starting fdsesstest\n");
2792 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2793 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2795 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2796 if (!NT_STATUS_IS_OK(status)) {
2797 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2801 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2803 if (!NT_STATUS_IS_OK(status)) {
2804 printf("write failed (%s)\n", nt_errstr(status));
2808 saved_vuid = cli_state_get_uid(cli);
2809 cli_state_set_uid(cli, new_vuid);
2811 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2812 printf("read succeeded with different vuid! "
2813 "nasty security hole [%s]\n", buf);
2816 /* Try to open a file with different vuid, samba cnum. */
2817 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2818 printf("create with different vuid, same cnum succeeded.\n");
2819 cli_close(cli, fnum2);
2820 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2822 printf("create with different vuid, same cnum failed.\n");
2823 printf("This will cause problems with service clients.\n");
2827 cli_state_set_uid(cli, saved_vuid);
2829 /* Try with same vuid, different cnum. */
2830 cli_state_set_tid(cli, new_cnum);
2832 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2833 printf("read succeeded with different cnum![%s]\n", buf);
2837 cli_state_set_tid(cli, saved_cnum);
2838 cli_close(cli, fnum1);
2839 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2841 torture_close_connection(cli);
2843 printf("finished fdsesstest\n");
2848 This test checks that
2850 1) the server does not allow an unlink on a file that is open
2852 static bool run_unlinktest(int dummy)
2854 struct cli_state *cli;
2855 const char *fname = "\\unlink.tst";
2857 bool correct = True;
2860 if (!torture_open_connection(&cli, 0)) {
2864 smbXcli_conn_set_sockopt(cli->conn, sockops);
2866 printf("starting unlink test\n");
2868 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2872 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2873 if (!NT_STATUS_IS_OK(status)) {
2874 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2878 status = cli_unlink(cli, fname,
2879 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2880 if (NT_STATUS_IS_OK(status)) {
2881 printf("error: server allowed unlink on an open file\n");
2884 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2885 NT_STATUS_SHARING_VIOLATION);
2888 cli_close(cli, fnum);
2889 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2891 if (!torture_close_connection(cli)) {
2895 printf("unlink test finished\n");
2902 test how many open files this server supports on the one socket
2904 static bool run_maxfidtest(int dummy)
2906 struct cli_state *cli;
2908 uint16_t fnums[0x11000];
2911 bool correct = True;
2917 printf("failed to connect\n");
2921 smbXcli_conn_set_sockopt(cli->conn, sockops);
2923 for (i=0; i<0x11000; i++) {
2924 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2925 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2927 if (!NT_STATUS_IS_OK(status)) {
2928 printf("open of %s failed (%s)\n",
2929 fname, nt_errstr(status));
2930 printf("maximum fnum is %d\n", i);
2938 printf("cleaning up\n");
2940 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2941 cli_close(cli, fnums[i]);
2943 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2944 if (!NT_STATUS_IS_OK(status)) {
2945 printf("unlink of %s failed (%s)\n",
2946 fname, nt_errstr(status));
2953 printf("maxfid test finished\n");
2954 if (!torture_close_connection(cli)) {
2960 /* generate a random buffer */
2961 static void rand_buf(char *buf, int len)
2964 *buf = (char)sys_random();
2969 /* send smb negprot commands, not reading the response */
2970 static bool run_negprot_nowait(int dummy)
2972 struct tevent_context *ev;
2974 struct cli_state *cli;
2975 bool correct = True;
2977 printf("starting negprot nowait test\n");
2979 ev = samba_tevent_context_init(talloc_tos());
2984 if (!(cli = open_nbt_connection())) {
2989 for (i=0;i<50000;i++) {
2990 struct tevent_req *req;
2992 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
2993 PROTOCOL_CORE, PROTOCOL_NT1, 0);
2998 if (!tevent_req_poll(req, ev)) {
2999 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3007 if (torture_close_connection(cli)) {
3011 printf("finished negprot nowait test\n");
3016 /* send smb negprot commands, not reading the response */
3017 static bool run_bad_nbt_session(int dummy)
3019 struct nmb_name called, calling;
3020 struct sockaddr_storage ss;
3025 printf("starting bad nbt session test\n");
3027 make_nmb_name(&calling, myname, 0x0);
3028 make_nmb_name(&called , host, 0x20);
3030 if (!resolve_name(host, &ss, 0x20, true)) {
3031 d_fprintf(stderr, "Could not resolve name %s\n", host);
3035 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3036 if (!NT_STATUS_IS_OK(status)) {
3037 d_fprintf(stderr, "open_socket_out failed: %s\n",
3042 ret = cli_bad_session_request(fd, &calling, &called);
3045 d_fprintf(stderr, "open_socket_out failed: %s\n",
3050 printf("finished bad nbt session test\n");
3054 /* send random IPC commands */
3055 static bool run_randomipc(int dummy)
3057 char *rparam = NULL;
3059 unsigned int rdrcnt,rprcnt;
3061 int api, param_len, i;
3062 struct cli_state *cli;
3063 bool correct = True;
3066 printf("starting random ipc test\n");
3068 if (!torture_open_connection(&cli, 0)) {
3072 for (i=0;i<count;i++) {
3073 api = sys_random() % 500;
3074 param_len = (sys_random() % 64);
3076 rand_buf(param, param_len);
3081 param, param_len, 8,
3082 NULL, 0, CLI_BUFFER_SIZE,
3086 printf("%d/%d\r", i,count);
3089 printf("%d/%d\n", i, count);
3091 if (!torture_close_connection(cli)) {
3098 printf("finished random ipc test\n");
3105 static void browse_callback(const char *sname, uint32_t stype,
3106 const char *comment, void *state)
3108 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3114 This test checks the browse list code
3117 static bool run_browsetest(int dummy)
3119 static struct cli_state *cli;
3120 bool correct = True;
3122 printf("starting browse test\n");
3124 if (!torture_open_connection(&cli, 0)) {
3128 printf("domain list:\n");
3129 cli_NetServerEnum(cli, cli->server_domain,
3130 SV_TYPE_DOMAIN_ENUM,
3131 browse_callback, NULL);
3133 printf("machine list:\n");
3134 cli_NetServerEnum(cli, cli->server_domain,
3136 browse_callback, NULL);
3138 if (!torture_close_connection(cli)) {
3142 printf("browse test finished\n");
3150 This checks how the getatr calls works
3152 static bool run_attrtest(int dummy)
3154 struct cli_state *cli;
3157 const char *fname = "\\attrib123456789.tst";
3158 bool correct = True;
3161 printf("starting attrib test\n");
3163 if (!torture_open_connection(&cli, 0)) {
3167 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3168 cli_openx(cli, fname,
3169 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3170 cli_close(cli, fnum);
3172 status = cli_getatr(cli, fname, NULL, NULL, &t);
3173 if (!NT_STATUS_IS_OK(status)) {
3174 printf("getatr failed (%s)\n", nt_errstr(status));
3178 if (abs(t - time(NULL)) > 60*60*24*10) {
3179 printf("ERROR: SMBgetatr bug. time is %s",
3185 t2 = t-60*60*24; /* 1 day ago */
3187 status = cli_setatr(cli, fname, 0, t2);
3188 if (!NT_STATUS_IS_OK(status)) {
3189 printf("setatr failed (%s)\n", nt_errstr(status));
3193 status = cli_getatr(cli, fname, NULL, NULL, &t);
3194 if (!NT_STATUS_IS_OK(status)) {
3195 printf("getatr failed (%s)\n", nt_errstr(status));
3200 printf("ERROR: getatr/setatr bug. times are\n%s",
3202 printf("%s", ctime(&t2));
3206 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3208 if (!torture_close_connection(cli)) {
3212 printf("attrib test finished\n");
3219 This checks a couple of trans2 calls
3221 static bool run_trans2test(int dummy)
3223 struct cli_state *cli;
3226 time_t c_time, a_time, m_time;
3227 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3228 const char *fname = "\\trans2.tst";
3229 const char *dname = "\\trans2";
3230 const char *fname2 = "\\trans2\\trans2.tst";
3232 bool correct = True;
3236 printf("starting trans2 test\n");
3238 if (!torture_open_connection(&cli, 0)) {
3242 status = cli_get_fs_attr_info(cli, &fs_attr);
3243 if (!NT_STATUS_IS_OK(status)) {
3244 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3249 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3250 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3251 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3252 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3253 if (!NT_STATUS_IS_OK(status)) {
3254 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3258 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3259 if (!NT_STATUS_IS_OK(status)) {
3260 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3263 else if (strcmp(pname, fname)) {
3264 printf("qfilename gave different name? [%s] [%s]\n",
3269 cli_close(cli, fnum);
3273 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3274 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3276 if (!NT_STATUS_IS_OK(status)) {
3277 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3280 cli_close(cli, fnum);
3282 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3284 if (!NT_STATUS_IS_OK(status)) {
3285 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3288 time_t t = time(NULL);
3290 if (c_time != m_time) {
3291 printf("create time=%s", ctime(&c_time));
3292 printf("modify time=%s", ctime(&m_time));
3293 printf("This system appears to have sticky create times\n");
3295 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3296 printf("access time=%s", ctime(&a_time));
3297 printf("This system appears to set a midnight access time\n");
3301 if (abs(m_time - t) > 60*60*24*7) {
3302 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3308 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3309 cli_openx(cli, fname,
3310 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3311 cli_close(cli, fnum);
3312 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3313 &m_time_ts, &size, NULL, NULL);
3314 if (!NT_STATUS_IS_OK(status)) {
3315 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3318 if (w_time_ts.tv_sec < 60*60*24*2) {
3319 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3320 printf("This system appears to set a initial 0 write time\n");
3325 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3328 /* check if the server updates the directory modification time
3329 when creating a new file */
3330 status = cli_mkdir(cli, dname);
3331 if (!NT_STATUS_IS_OK(status)) {
3332 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3336 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3337 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3338 if (!NT_STATUS_IS_OK(status)) {
3339 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3343 cli_openx(cli, fname2,
3344 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3345 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3346 cli_close(cli, fnum);
3347 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3348 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3349 if (!NT_STATUS_IS_OK(status)) {
3350 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3353 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3355 printf("This system does not update directory modification times\n");
3359 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3360 cli_rmdir(cli, dname);
3362 if (!torture_close_connection(cli)) {
3366 printf("trans2 test finished\n");
3372 This checks new W2K calls.
3375 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3377 uint8_t *buf = NULL;
3381 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3382 CLI_BUFFER_SIZE, NULL, &buf, &len);
3383 if (!NT_STATUS_IS_OK(status)) {
3384 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3387 printf("qfileinfo: level %d, len = %u\n", level, len);
3388 dump_data(0, (uint8_t *)buf, len);
3395 static bool run_w2ktest(int dummy)
3397 struct cli_state *cli;
3399 const char *fname = "\\w2ktest\\w2k.tst";
3401 bool correct = True;
3403 printf("starting w2k test\n");
3405 if (!torture_open_connection(&cli, 0)) {
3409 cli_openx(cli, fname,
3410 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3412 for (level = 1004; level < 1040; level++) {
3413 new_trans(cli, fnum, level);
3416 cli_close(cli, fnum);
3418 if (!torture_close_connection(cli)) {
3422 printf("w2k test finished\n");
3429 this is a harness for some oplock tests
3431 static bool run_oplock1(int dummy)
3433 struct cli_state *cli1;
3434 const char *fname = "\\lockt1.lck";
3436 bool correct = True;
3439 printf("starting oplock test 1\n");
3441 if (!torture_open_connection(&cli1, 0)) {
3445 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3447 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3449 cli1->use_oplocks = True;
3451 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3453 if (!NT_STATUS_IS_OK(status)) {
3454 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3458 cli1->use_oplocks = False;
3460 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3461 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3463 status = cli_close(cli1, fnum1);
3464 if (!NT_STATUS_IS_OK(status)) {
3465 printf("close2 failed (%s)\n", nt_errstr(status));
3469 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3470 if (!NT_STATUS_IS_OK(status)) {
3471 printf("unlink failed (%s)\n", nt_errstr(status));
3475 if (!torture_close_connection(cli1)) {
3479 printf("finished oplock test 1\n");
3484 static bool run_oplock2(int dummy)
3486 struct cli_state *cli1, *cli2;
3487 const char *fname = "\\lockt2.lck";
3488 uint16_t fnum1, fnum2;
3489 int saved_use_oplocks = use_oplocks;
3491 bool correct = True;
3492 volatile bool *shared_correct;
3496 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3497 *shared_correct = True;
3499 use_level_II_oplocks = True;
3502 printf("starting oplock test 2\n");
3504 if (!torture_open_connection(&cli1, 0)) {
3505 use_level_II_oplocks = False;
3506 use_oplocks = saved_use_oplocks;
3510 if (!torture_open_connection(&cli2, 1)) {
3511 use_level_II_oplocks = False;
3512 use_oplocks = saved_use_oplocks;
3516 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3518 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3519 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3521 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3523 if (!NT_STATUS_IS_OK(status)) {
3524 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3528 /* Don't need the globals any more. */
3529 use_level_II_oplocks = False;
3530 use_oplocks = saved_use_oplocks;
3534 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3535 if (!NT_STATUS_IS_OK(status)) {
3536 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3537 *shared_correct = False;
3543 status = cli_close(cli2, fnum2);
3544 if (!NT_STATUS_IS_OK(status)) {
3545 printf("close2 failed (%s)\n", nt_errstr(status));
3546 *shared_correct = False;
3554 /* Ensure cli1 processes the break. Empty file should always return 0
3556 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3557 if (!NT_STATUS_IS_OK(status)) {
3558 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3560 } else if (nread != 0) {
3561 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3562 (unsigned long)nread, 0);
3566 /* Should now be at level II. */
3567 /* Test if sending a write locks causes a break to none. */
3568 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3569 if (!NT_STATUS_IS_OK(status)) {
3570 printf("lock failed (%s)\n", nt_errstr(status));
3574 cli_unlock(cli1, fnum1, 0, 4);
3578 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3579 if (!NT_STATUS_IS_OK(status)) {
3580 printf("lock failed (%s)\n", nt_errstr(status));
3584 cli_unlock(cli1, fnum1, 0, 4);
3588 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3590 status = cli_close(cli1, fnum1);
3591 if (!NT_STATUS_IS_OK(status)) {
3592 printf("close1 failed (%s)\n", nt_errstr(status));
3598 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3599 if (!NT_STATUS_IS_OK(status)) {
3600 printf("unlink failed (%s)\n", nt_errstr(status));
3604 if (!torture_close_connection(cli1)) {
3608 if (!*shared_correct) {
3612 printf("finished oplock test 2\n");
3617 struct oplock4_state {
3618 struct tevent_context *ev;
3619 struct cli_state *cli;
3624 static void oplock4_got_break(struct tevent_req *req);
3625 static void oplock4_got_open(struct tevent_req *req);
3627 static bool run_oplock4(int dummy)
3629 struct tevent_context *ev;
3630 struct cli_state *cli1, *cli2;
3631 struct tevent_req *oplock_req, *open_req;
3632 const char *fname = "\\lockt4.lck";
3633 const char *fname_ln = "\\lockt4_ln.lck";
3634 uint16_t fnum1, fnum2;
3635 int saved_use_oplocks = use_oplocks;
3637 bool correct = true;
3641 struct oplock4_state *state;
3643 printf("starting oplock test 4\n");
3645 if (!torture_open_connection(&cli1, 0)) {
3646 use_level_II_oplocks = false;
3647 use_oplocks = saved_use_oplocks;
3651 if (!torture_open_connection(&cli2, 1)) {
3652 use_level_II_oplocks = false;
3653 use_oplocks = saved_use_oplocks;
3657 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3658 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3660 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3661 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3663 /* Create the file. */
3664 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3666 if (!NT_STATUS_IS_OK(status)) {
3667 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3671 status = cli_close(cli1, fnum1);
3672 if (!NT_STATUS_IS_OK(status)) {
3673 printf("close1 failed (%s)\n", nt_errstr(status));
3677 /* Now create a hardlink. */
3678 status = cli_nt_hardlink(cli1, fname, fname_ln);
3679 if (!NT_STATUS_IS_OK(status)) {
3680 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3684 /* Prove that opening hardlinks cause deny modes to conflict. */
3685 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3686 if (!NT_STATUS_IS_OK(status)) {
3687 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3691 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3692 if (NT_STATUS_IS_OK(status)) {
3693 printf("open of %s succeeded - should fail with sharing violation.\n",
3698 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3699 printf("open of %s should fail with sharing violation. Got %s\n",
3700 fname_ln, nt_errstr(status));
3704 status = cli_close(cli1, fnum1);
3705 if (!NT_STATUS_IS_OK(status)) {
3706 printf("close1 failed (%s)\n", nt_errstr(status));
3710 cli1->use_oplocks = true;
3711 cli2->use_oplocks = true;
3713 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3714 if (!NT_STATUS_IS_OK(status)) {
3715 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3719 ev = samba_tevent_context_init(talloc_tos());
3721 printf("tevent_context_init failed\n");
3725 state = talloc(ev, struct oplock4_state);
3726 if (state == NULL) {
3727 printf("talloc failed\n");
3732 state->got_break = &got_break;
3733 state->fnum2 = &fnum2;
3735 oplock_req = cli_smb_oplock_break_waiter_send(
3736 talloc_tos(), ev, cli1);
3737 if (oplock_req == NULL) {
3738 printf("cli_smb_oplock_break_waiter_send failed\n");
3741 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3743 open_req = cli_openx_send(
3744 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3745 if (open_req == NULL) {
3746 printf("cli_openx_send failed\n");
3749 tevent_req_set_callback(open_req, oplock4_got_open, state);
3754 while (!got_break || fnum2 == 0xffff) {
3756 ret = tevent_loop_once(ev);
3758 printf("tevent_loop_once failed: %s\n",
3764 status = cli_close(cli2, fnum2);
3765 if (!NT_STATUS_IS_OK(status)) {
3766 printf("close2 failed (%s)\n", nt_errstr(status));
3770 status = cli_close(cli1, fnum1);
3771 if (!NT_STATUS_IS_OK(status)) {
3772 printf("close1 failed (%s)\n", nt_errstr(status));
3776 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3777 if (!NT_STATUS_IS_OK(status)) {
3778 printf("unlink failed (%s)\n", nt_errstr(status));
3782 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3783 if (!NT_STATUS_IS_OK(status)) {
3784 printf("unlink failed (%s)\n", nt_errstr(status));
3788 if (!torture_close_connection(cli1)) {
3796 printf("finished oplock test 4\n");
3801 static void oplock4_got_break(struct tevent_req *req)
3803 struct oplock4_state *state = tevent_req_callback_data(
3804 req, struct oplock4_state);
3809 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3811 if (!NT_STATUS_IS_OK(status)) {
3812 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3816 *state->got_break = true;
3818 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3821 printf("cli_oplock_ack_send failed\n");
3826 static void oplock4_got_open(struct tevent_req *req)
3828 struct oplock4_state *state = tevent_req_callback_data(
3829 req, struct oplock4_state);
3832 status = cli_openx_recv(req, state->fnum2);
3833 if (!NT_STATUS_IS_OK(status)) {
3834 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3835 *state->fnum2 = 0xffff;
3840 Test delete on close semantics.
3842 static bool run_deletetest(int dummy)
3844 struct cli_state *cli1 = NULL;
3845 struct cli_state *cli2 = NULL;
3846 const char *fname = "\\delete.file";
3847 uint16_t fnum1 = (uint16_t)-1;
3848 uint16_t fnum2 = (uint16_t)-1;
3849 bool correct = false;
3852 printf("starting delete test\n");
3854 if (!torture_open_connection(&cli1, 0)) {
3858 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3860 /* Test 1 - this should delete the file on close. */
3862 cli_setatr(cli1, fname, 0, 0);
3863 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3865 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3866 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3867 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
3868 if (!NT_STATUS_IS_OK(status)) {
3869 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3873 status = cli_close(cli1, fnum1);
3874 if (!NT_STATUS_IS_OK(status)) {
3875 printf("[1] close failed (%s)\n", nt_errstr(status));
3879 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3880 if (NT_STATUS_IS_OK(status)) {
3881 printf("[1] open of %s succeeded (should fail)\n", fname);
3885 printf("first delete on close test succeeded.\n");
3887 /* Test 2 - this should delete the file on close. */
3889 cli_setatr(cli1, fname, 0, 0);
3890 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3892 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3893 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3894 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3895 if (!NT_STATUS_IS_OK(status)) {
3896 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3900 status = cli_nt_delete_on_close(cli1, fnum1, true);
3901 if (!NT_STATUS_IS_OK(status)) {
3902 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3906 status = cli_close(cli1, fnum1);
3907 if (!NT_STATUS_IS_OK(status)) {
3908 printf("[2] close failed (%s)\n", nt_errstr(status));
3912 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3913 if (NT_STATUS_IS_OK(status)) {
3914 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3915 status = cli_close(cli1, fnum1);
3916 if (!NT_STATUS_IS_OK(status)) {
3917 printf("[2] close failed (%s)\n", nt_errstr(status));
3919 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3923 printf("second delete on close test succeeded.\n");
3926 cli_setatr(cli1, fname, 0, 0);
3927 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3929 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3930 FILE_ATTRIBUTE_NORMAL,
3931 FILE_SHARE_READ|FILE_SHARE_WRITE,
3932 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3933 if (!NT_STATUS_IS_OK(status)) {
3934 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3938 /* This should fail with a sharing violation - open for delete is only compatible
3939 with SHARE_DELETE. */
3941 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3942 FILE_ATTRIBUTE_NORMAL,
3943 FILE_SHARE_READ|FILE_SHARE_WRITE,
3944 FILE_OPEN, 0, 0, &fnum2, NULL);
3945 if (NT_STATUS_IS_OK(status)) {
3946 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3950 /* This should succeed. */
3951 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3952 FILE_ATTRIBUTE_NORMAL,
3953 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3954 FILE_OPEN, 0, 0, &fnum2, NULL);
3955 if (!NT_STATUS_IS_OK(status)) {
3956 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
3960 status = cli_nt_delete_on_close(cli1, fnum1, true);
3961 if (!NT_STATUS_IS_OK(status)) {
3962 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3966 status = cli_close(cli1, fnum1);
3967 if (!NT_STATUS_IS_OK(status)) {
3968 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3972 status = cli_close(cli1, fnum2);
3973 if (!NT_STATUS_IS_OK(status)) {
3974 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3978 /* This should fail - file should no longer be there. */
3980 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3981 if (NT_STATUS_IS_OK(status)) {
3982 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3983 status = cli_close(cli1, fnum1);
3984 if (!NT_STATUS_IS_OK(status)) {
3985 printf("[3] close failed (%s)\n", nt_errstr(status));
3987 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3991 printf("third delete on close test succeeded.\n");
3994 cli_setatr(cli1, fname, 0, 0);
3995 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3997 status = cli_ntcreate(cli1, fname, 0,
3998 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3999 FILE_ATTRIBUTE_NORMAL,
4000 FILE_SHARE_READ|FILE_SHARE_WRITE,
4001 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4002 if (!NT_STATUS_IS_OK(status)) {
4003 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4007 /* This should succeed. */
4008 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4009 FILE_ATTRIBUTE_NORMAL,
4010 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4011 FILE_OPEN, 0, 0, &fnum2, NULL);
4012 if (!NT_STATUS_IS_OK(status)) {
4013 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4017 status = cli_close(cli1, fnum2);
4018 if (!NT_STATUS_IS_OK(status)) {
4019 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4023 status = cli_nt_delete_on_close(cli1, fnum1, true);
4024 if (!NT_STATUS_IS_OK(status)) {
4025 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4029 /* This should fail - no more opens once delete on close set. */
4030 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4031 FILE_ATTRIBUTE_NORMAL,
4032 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4033 FILE_OPEN, 0, 0, &fnum2, NULL);
4034 if (NT_STATUS_IS_OK(status)) {
4035 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4039 status = cli_close(cli1, fnum1);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4045 printf("fourth delete on close test succeeded.\n");
4048 cli_setatr(cli1, fname, 0, 0);
4049 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4051 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4052 if (!NT_STATUS_IS_OK(status)) {
4053 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4057 /* This should fail - only allowed on NT opens with DELETE access. */
4059 status = cli_nt_delete_on_close(cli1, fnum1, true);
4060 if (NT_STATUS_IS_OK(status)) {
4061 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4065 status = cli_close(cli1, fnum1);
4066 if (!NT_STATUS_IS_OK(status)) {
4067 printf("[5] close failed (%s)\n", nt_errstr(status));
4071 printf("fifth delete on close test succeeded.\n");
4074 cli_setatr(cli1, fname, 0, 0);
4075 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4077 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4078 FILE_ATTRIBUTE_NORMAL,
4079 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4080 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4081 if (!NT_STATUS_IS_OK(status)) {
4082 printf("[6] open of %s failed (%s)\n", fname,
4087 /* This should fail - only allowed on NT opens with DELETE access. */
4089 status = cli_nt_delete_on_close(cli1, fnum1, true);
4090 if (NT_STATUS_IS_OK(status)) {
4091 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4095 status = cli_close(cli1, fnum1);
4096 if (!NT_STATUS_IS_OK(status)) {
4097 printf("[6] close failed (%s)\n", nt_errstr(status));
4101 printf("sixth delete on close test succeeded.\n");
4104 cli_setatr(cli1, fname, 0, 0);
4105 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4107 status = cli_ntcreate(cli1, fname, 0,
4108 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4109 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4110 0, 0, &fnum1, NULL);
4111 if (!NT_STATUS_IS_OK(status)) {
4112 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4116 status = cli_nt_delete_on_close(cli1, fnum1, true);
4117 if (!NT_STATUS_IS_OK(status)) {
4118 printf("[7] setting delete_on_close on file failed !\n");
4122 status = cli_nt_delete_on_close(cli1, fnum1, false);
4123 if (!NT_STATUS_IS_OK(status)) {
4124 printf("[7] unsetting delete_on_close on file failed !\n");
4128 status = cli_close(cli1, fnum1);
4129 if (!NT_STATUS_IS_OK(status)) {
4130 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4134 /* This next open should succeed - we reset the flag. */
4135 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4136 if (!NT_STATUS_IS_OK(status)) {
4137 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4141 status = cli_close(cli1, fnum1);
4142 if (!NT_STATUS_IS_OK(status)) {
4143 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4147 printf("seventh delete on close test succeeded.\n");
4150 cli_setatr(cli1, fname, 0, 0);
4151 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4153 if (!torture_open_connection(&cli2, 1)) {
4154 printf("[8] failed to open second connection.\n");
4158 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4160 status = cli_ntcreate(cli1, fname, 0,
4161 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4162 FILE_ATTRIBUTE_NORMAL,
4163 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4164 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4165 if (!NT_STATUS_IS_OK(status)) {
4166 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4170 status = cli_ntcreate(cli2, fname, 0,
4171 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4172 FILE_ATTRIBUTE_NORMAL,
4173 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4174 FILE_OPEN, 0, 0, &fnum2, NULL);
4175 if (!NT_STATUS_IS_OK(status)) {
4176 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4180 status = cli_nt_delete_on_close(cli1, fnum1, true);
4181 if (!NT_STATUS_IS_OK(status)) {
4182 printf("[8] setting delete_on_close on file failed !\n");
4186 status = cli_close(cli1, fnum1);
4187 if (!NT_STATUS_IS_OK(status)) {
4188 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4192 status = cli_close(cli2, fnum2);
4193 if (!NT_STATUS_IS_OK(status)) {
4194 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4198 /* This should fail.. */
4199 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4200 if (NT_STATUS_IS_OK(status)) {
4201 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4205 printf("eighth delete on close test succeeded.\n");
4209 /* This should fail - we need to set DELETE_ACCESS. */
4210 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4211 FILE_ATTRIBUTE_NORMAL,
4214 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4215 if (NT_STATUS_IS_OK(status)) {
4216 printf("[9] open of %s succeeded should have failed!\n", fname);
4220 printf("ninth delete on close test succeeded.\n");
4224 status = cli_ntcreate(cli1, fname, 0,
4225 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4226 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4227 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4229 if (!NT_STATUS_IS_OK(status)) {
4230 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4234 /* This should delete the file. */
4235 status = cli_close(cli1, fnum1);
4236 if (!NT_STATUS_IS_OK(status)) {
4237 printf("[10] close failed (%s)\n", nt_errstr(status));
4241 /* This should fail.. */
4242 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4243 if (NT_STATUS_IS_OK(status)) {
4244 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4248 printf("tenth delete on close test succeeded.\n");
4252 cli_setatr(cli1, fname, 0, 0);
4253 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4255 /* Can we open a read-only file with delete access? */
4257 /* Create a readonly file. */
4258 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4259 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4260 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4261 if (!NT_STATUS_IS_OK(status)) {
4262 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4266 status = cli_close(cli1, fnum1);
4267 if (!NT_STATUS_IS_OK(status)) {
4268 printf("[11] close failed (%s)\n", nt_errstr(status));
4272 /* Now try open for delete access. */
4273 status = cli_ntcreate(cli1, fname, 0,
4274 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4276 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4277 FILE_OPEN, 0, 0, &fnum1, NULL);
4278 if (!NT_STATUS_IS_OK(status)) {
4279 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4283 cli_close(cli1, fnum1);
4285 printf("eleventh delete on close test succeeded.\n");
4289 * like test 4 but with initial delete on close
4292 cli_setatr(cli1, fname, 0, 0);
4293 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4295 status = cli_ntcreate(cli1, fname, 0,
4296 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4297 FILE_ATTRIBUTE_NORMAL,
4298 FILE_SHARE_READ|FILE_SHARE_WRITE,
4300 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4301 if (!NT_STATUS_IS_OK(status)) {
4302 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4306 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4307 FILE_ATTRIBUTE_NORMAL,
4308 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4309 FILE_OPEN, 0, 0, &fnum2, NULL);
4310 if (!NT_STATUS_IS_OK(status)) {
4311 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4315 status = cli_close(cli1, fnum2);
4316 if (!NT_STATUS_IS_OK(status)) {
4317 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4321 status = cli_nt_delete_on_close(cli1, fnum1, true);
4322 if (!NT_STATUS_IS_OK(status)) {
4323 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4327 /* This should fail - no more opens once delete on close set. */
4328 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4329 FILE_ATTRIBUTE_NORMAL,
4330 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4331 FILE_OPEN, 0, 0, &fnum2, NULL);
4332 if (NT_STATUS_IS_OK(status)) {
4333 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4337 status = cli_nt_delete_on_close(cli1, fnum1, false);
4338 if (!NT_STATUS_IS_OK(status)) {
4339 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4343 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4344 FILE_ATTRIBUTE_NORMAL,
4345 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4346 FILE_OPEN, 0, 0, &fnum2, NULL);
4347 if (!NT_STATUS_IS_OK(status)) {
4348 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4352 status = cli_close(cli1, fnum2);
4353 if (!NT_STATUS_IS_OK(status)) {
4354 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4358 status = cli_close(cli1, fnum1);
4359 if (!NT_STATUS_IS_OK(status)) {
4360 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4365 * setting delete on close on the handle does
4366 * not unset the initial delete on close...
4368 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4369 FILE_ATTRIBUTE_NORMAL,
4370 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4371 FILE_OPEN, 0, 0, &fnum2, NULL);
4372 if (NT_STATUS_IS_OK(status)) {
4373 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4375 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4376 printf("ntcreate returned %s, expected "
4377 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4382 printf("twelfth delete on close test succeeded.\n");
4385 printf("finished delete test\n");
4390 /* FIXME: This will crash if we aborted before cli2 got
4391 * intialized, because these functions don't handle
4392 * uninitialized connections. */
4394 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4395 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4396 cli_setatr(cli1, fname, 0, 0);
4397 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4399 if (cli1 && !torture_close_connection(cli1)) {
4402 if (cli2 && !torture_close_connection(cli2)) {
4410 Test wildcard delete.
4412 static bool run_wild_deletetest(int dummy)
4414 struct cli_state *cli = NULL;
4415 const char *dname = "\\WTEST";
4416 const char *fname = "\\WTEST\\A";
4417 const char *wunlink_name = "\\WTEST\\*";
4418 uint16_t fnum1 = (uint16_t)-1;
4419 bool correct = false;
4422 printf("starting wildcard delete test\n");
4424 if (!torture_open_connection(&cli, 0)) {
4428 smbXcli_conn_set_sockopt(cli->conn, sockops);
4430 cli_unlink(cli, fname, 0);
4431 cli_rmdir(cli, dname);
4432 status = cli_mkdir(cli, dname);
4433 if (!NT_STATUS_IS_OK(status)) {
4434 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4437 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4438 if (!NT_STATUS_IS_OK(status)) {
4439 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4442 status = cli_close(cli, fnum1);
4446 * Note the unlink attribute-type of zero. This should
4447 * map into FILE_ATTRIBUTE_NORMAL at the server even
4448 * on a wildcard delete.
4451 status = cli_unlink(cli, wunlink_name, 0);
4452 if (!NT_STATUS_IS_OK(status)) {
4453 printf("unlink of %s failed %s!\n",
4454 wunlink_name, nt_errstr(status));
4458 printf("finished wildcard delete test\n");
4464 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4465 cli_unlink(cli, fname, 0);
4466 cli_rmdir(cli, dname);
4468 if (cli && !torture_close_connection(cli)) {
4474 static bool run_deletetest_ln(int dummy)
4476 struct cli_state *cli;
4477 const char *fname = "\\delete1";
4478 const char *fname_ln = "\\delete1_ln";
4482 bool correct = true;
4485 printf("starting deletetest-ln\n");
4487 if (!torture_open_connection(&cli, 0)) {
4491 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4492 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4494 smbXcli_conn_set_sockopt(cli->conn, sockops);
4496 /* Create the file. */
4497 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4498 if (!NT_STATUS_IS_OK(status)) {
4499 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4503 status = cli_close(cli, fnum);
4504 if (!NT_STATUS_IS_OK(status)) {
4505 printf("close1 failed (%s)\n", nt_errstr(status));
4509 /* Now create a hardlink. */
4510 status = cli_nt_hardlink(cli, fname, fname_ln);
4511 if (!NT_STATUS_IS_OK(status)) {
4512 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4516 /* Open the original file. */
4517 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4518 FILE_ATTRIBUTE_NORMAL,
4519 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4520 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4521 if (!NT_STATUS_IS_OK(status)) {
4522 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4526 /* Unlink the hard link path. */
4527 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4528 FILE_ATTRIBUTE_NORMAL,
4529 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4530 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4531 if (!NT_STATUS_IS_OK(status)) {
4532 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4535 status = cli_nt_delete_on_close(cli, fnum1, true);
4536 if (!NT_STATUS_IS_OK(status)) {
4537 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4538 __location__, fname_ln, nt_errstr(status));
4542 status = cli_close(cli, fnum1);
4543 if (!NT_STATUS_IS_OK(status)) {
4544 printf("close %s failed (%s)\n",
4545 fname_ln, nt_errstr(status));
4549 status = cli_close(cli, fnum);
4550 if (!NT_STATUS_IS_OK(status)) {
4551 printf("close %s failed (%s)\n",
4552 fname, nt_errstr(status));
4556 /* Ensure the original file is still there. */
4557 status = cli_getatr(cli, fname, NULL, NULL, &t);
4558 if (!NT_STATUS_IS_OK(status)) {
4559 printf("%s getatr on file %s failed (%s)\n",
4566 /* Ensure the link path is gone. */
4567 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4568 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4569 printf("%s, getatr for file %s returned wrong error code %s "
4570 "- should have been deleted\n",
4572 fname_ln, nt_errstr(status));
4576 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4577 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4579 if (!torture_close_connection(cli)) {
4583 printf("finished deletetest-ln\n");
4589 print out server properties
4591 static bool run_properties(int dummy)
4593 struct cli_state *cli;
4594 bool correct = True;
4596 printf("starting properties test\n");
4600 if (!torture_open_connection(&cli, 0)) {
4604 smbXcli_conn_set_sockopt(cli->conn, sockops);
4606 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4608 if (!torture_close_connection(cli)) {
4617 /* FIRST_DESIRED_ACCESS 0xf019f */
4618 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4619 FILE_READ_EA| /* 0xf */ \
4620 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4621 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4622 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4623 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4624 /* SECOND_DESIRED_ACCESS 0xe0080 */
4625 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4626 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4627 WRITE_OWNER_ACCESS /* 0xe0000 */
4630 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4631 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4633 WRITE_OWNER_ACCESS /* */
4637 Test ntcreate calls made by xcopy
4639 static bool run_xcopy(int dummy)
4641 static struct cli_state *cli1;
4642 const char *fname = "\\test.txt";
4643 bool correct = True;
4644 uint16_t fnum1, fnum2;
4647 printf("starting xcopy test\n");
4649 if (!torture_open_connection(&cli1, 0)) {
4653 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4654 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4655 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4656 if (!NT_STATUS_IS_OK(status)) {
4657 printf("First open failed - %s\n", nt_errstr(status));
4661 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4662 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4663 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4664 if (!NT_STATUS_IS_OK(status)) {
4665 printf("second open failed - %s\n", nt_errstr(status));
4669 if (!torture_close_connection(cli1)) {
4677 Test rename on files open with share delete and no share delete.
4679 static bool run_rename(int dummy)
4681 static struct cli_state *cli1;
4682 const char *fname = "\\test.txt";
4683 const char *fname1 = "\\test1.txt";
4684 bool correct = True;
4689 printf("starting rename test\n");
4691 if (!torture_open_connection(&cli1, 0)) {
4695 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4696 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4698 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4699 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4700 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4701 if (!NT_STATUS_IS_OK(status)) {
4702 printf("First open failed - %s\n", nt_errstr(status));
4706 status = cli_rename(cli1, fname, fname1, false);
4707 if (!NT_STATUS_IS_OK(status)) {
4708 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4710 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4714 status = cli_close(cli1, fnum1);
4715 if (!NT_STATUS_IS_OK(status)) {
4716 printf("close - 1 failed (%s)\n", nt_errstr(status));
4720 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4721 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4722 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4724 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4726 FILE_SHARE_DELETE|FILE_SHARE_READ,
4728 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4729 if (!NT_STATUS_IS_OK(status)) {
4730 printf("Second open failed - %s\n", nt_errstr(status));
4734 status = cli_rename(cli1, fname, fname1, false);
4735 if (!NT_STATUS_IS_OK(status)) {
4736 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4739 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4742 status = cli_close(cli1, fnum1);
4743 if (!NT_STATUS_IS_OK(status)) {
4744 printf("close - 2 failed (%s)\n", nt_errstr(status));
4748 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4749 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4751 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4752 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4753 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4754 if (!NT_STATUS_IS_OK(status)) {
4755 printf("Third open failed - %s\n", nt_errstr(status));
4764 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4765 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4766 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4769 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4770 printf("[8] setting delete_on_close on file failed !\n");
4774 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4775 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4781 status = cli_rename(cli1, fname, fname1, false);
4782 if (!NT_STATUS_IS_OK(status)) {
4783 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4786 printf("Third rename succeeded (SHARE_NONE)\n");
4789 status = cli_close(cli1, fnum1);
4790 if (!NT_STATUS_IS_OK(status)) {
4791 printf("close - 3 failed (%s)\n", nt_errstr(status));
4795 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4796 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4800 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4801 FILE_ATTRIBUTE_NORMAL,
4802 FILE_SHARE_READ | FILE_SHARE_WRITE,
4803 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4804 if (!NT_STATUS_IS_OK(status)) {
4805 printf("Fourth open failed - %s\n", nt_errstr(status));
4809 status = cli_rename(cli1, fname, fname1, false);
4810 if (!NT_STATUS_IS_OK(status)) {
4811 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4813 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4817 status = cli_close(cli1, fnum1);
4818 if (!NT_STATUS_IS_OK(status)) {
4819 printf("close - 4 failed (%s)\n", nt_errstr(status));
4823 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4824 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4828 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4829 FILE_ATTRIBUTE_NORMAL,
4830 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4831 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4832 if (!NT_STATUS_IS_OK(status)) {
4833 printf("Fifth open failed - %s\n", nt_errstr(status));
4837 status = cli_rename(cli1, fname, fname1, false);
4838 if (!NT_STATUS_IS_OK(status)) {
4839 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4842 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4846 * Now check if the first name still exists ...
4849 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4850 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4851 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4852 printf("Opening original file after rename of open file fails: %s\n",
4856 printf("Opening original file after rename of open file works ...\n");
4857 (void)cli_close(cli1, fnum2);
4861 status = cli_close(cli1, fnum1);
4862 if (!NT_STATUS_IS_OK(status)) {
4863 printf("close - 5 failed (%s)\n", nt_errstr(status));
4867 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4868 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4869 if (!NT_STATUS_IS_OK(status)) {
4870 printf("getatr on file %s failed - %s ! \n",
4871 fname1, nt_errstr(status));
4874 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4875 printf("Renamed file %s has wrong attr 0x%x "
4876 "(should be 0x%x)\n",
4879 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4882 printf("Renamed file %s has archive bit set\n", fname1);
4886 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4887 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4889 if (!torture_close_connection(cli1)) {
4897 Test rename into a directory with an ACL denying it.
4899 static bool run_rename_access(int dummy)
4901 static struct cli_state *cli = NULL;
4902 static struct cli_state *posix_cli = NULL;
4903 const char *src = "test.txt";
4904 const char *dname = "dir";
4905 const char *dst = "dir\\test.txt";
4906 const char *dsrc = "test.dir";
4907 const char *ddst = "dir\\test.dir";
4908 uint16_t fnum = (uint16_t)-1;
4909 struct security_descriptor *sd = NULL;
4910 struct security_descriptor *newsd = NULL;
4912 TALLOC_CTX *frame = NULL;
4914 frame = talloc_stackframe();
4915 printf("starting rename access test\n");
4917 /* Windows connection. */
4918 if (!torture_open_connection(&cli, 0)) {
4922 smbXcli_conn_set_sockopt(cli->conn, sockops);
4924 /* Posix connection. */
4925 if (!torture_open_connection(&posix_cli, 0)) {
4929 smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
4931 status = torture_setup_unix_extensions(posix_cli);
4932 if (!NT_STATUS_IS_OK(status)) {
4936 /* Start with a clean slate. */
4937 cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4938 cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4939 cli_rmdir(cli, dsrc);
4940 cli_rmdir(cli, ddst);
4941 cli_rmdir(cli, dname);
4944 * Setup the destination directory with a DENY ACE to
4945 * prevent new files within it.
4947 status = cli_ntcreate(cli,
4950 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
4951 WRITE_DAC_ACCESS|FILE_READ_DATA|
4953 FILE_ATTRIBUTE_DIRECTORY,
4954 FILE_SHARE_READ|FILE_SHARE_WRITE,
4956 FILE_DIRECTORY_FILE,
4960 if (!NT_STATUS_IS_OK(status)) {
4961 printf("Create of %s - %s\n", dname, nt_errstr(status));
4965 status = cli_query_secdesc(cli,
4969 if (!NT_STATUS_IS_OK(status)) {
4970 printf("cli_query_secdesc failed for %s (%s)\n",
4971 dname, nt_errstr(status));
4975 newsd = security_descriptor_dacl_create(frame,
4980 SEC_ACE_TYPE_ACCESS_DENIED,
4981 SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
4984 if (newsd == NULL) {
4987 sd->dacl = security_acl_concatenate(frame,
4990 if (sd->dacl == NULL) {
4993 status = cli_set_secdesc(cli, fnum, sd);
4994 if (!NT_STATUS_IS_OK(status)) {
4995 printf("cli_set_secdesc failed for %s (%s)\n",
4996 dname, nt_errstr(status));
4999 status = cli_close(cli, fnum);
5000 if (!NT_STATUS_IS_OK(status)) {
5001 printf("close failed for %s (%s)\n",
5002 dname, nt_errstr(status));
5005 /* Now go around the back and chmod to 777 via POSIX. */
5006 status = cli_posix_chmod(posix_cli, dname, 0777);
5007 if (!NT_STATUS_IS_OK(status)) {
5008 printf("cli_posix_chmod failed for %s (%s)\n",
5009 dname, nt_errstr(status));
5013 /* Check we can't create a file within dname via Windows. */
5014 status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5015 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5016 cli_close(posix_cli, fnum);
5017 printf("Create of %s should be ACCESS denied, was %s\n",
5018 dst, nt_errstr(status));
5022 /* Make the sample file/directory. */
5023 status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5024 if (!NT_STATUS_IS_OK(status)) {
5025 printf("open of %s failed (%s)\n", src, nt_errstr(status));
5028 status = cli_close(cli, fnum);
5029 if (!NT_STATUS_IS_OK(status)) {
5030 printf("cli_close failed (%s)\n", nt_errstr(status));
5034 status = cli_mkdir(cli, dsrc);
5035 if (!NT_STATUS_IS_OK(status)) {
5036 printf("cli_mkdir of %s failed (%s)\n",
5037 dsrc, nt_errstr(status));
5042 * OK - renames of the new file and directory into the
5043 * dst directory should fail.
5046 status = cli_rename(cli, src, dst, false);
5047 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5048 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5049 src, dst, nt_errstr(status));
5052 status = cli_rename(cli, dsrc, ddst, false);
5053 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5054 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5055 src, dst, nt_errstr(status));
5065 torture_close_connection(posix_cli);
5069 if (fnum != (uint64_t)-1) {
5070 cli_close(cli, fnum);
5072 cli_unlink(cli, src,
5073 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5074 cli_unlink(cli, dst,
5075 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5076 cli_rmdir(cli, dsrc);
5077 cli_rmdir(cli, ddst);
5078 cli_rmdir(cli, dname);
5080 torture_close_connection(cli);
5088 Test owner rights ACE.
5090 static bool run_owner_rights(int dummy)
5092 static struct cli_state *cli = NULL;
5093 const char *fname = "owner_rights.txt";
5094 uint16_t fnum = (uint16_t)-1;
5095 struct security_descriptor *sd = NULL;
5096 struct security_descriptor *newsd = NULL;
5098 TALLOC_CTX *frame = NULL;
5100 frame = talloc_stackframe();
5101 printf("starting owner rights test\n");
5103 /* Windows connection. */
5104 if (!torture_open_connection(&cli, 0)) {
5108 smbXcli_conn_set_sockopt(cli->conn, sockops);
5110 /* Start with a clean slate. */
5111 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5113 /* Create the test file. */
5114 /* Now try and open for read and write-dac. */
5115 status = cli_ntcreate(cli,
5119 FILE_ATTRIBUTE_NORMAL,
5120 FILE_SHARE_READ|FILE_SHARE_WRITE|
5127 if (!NT_STATUS_IS_OK(status)) {
5128 printf("Create of %s - %s\n", fname, nt_errstr(status));
5132 /* Get the original SD. */
5133 status = cli_query_secdesc(cli,
5137 if (!NT_STATUS_IS_OK(status)) {
5138 printf("cli_query_secdesc failed for %s (%s)\n",
5139 fname, nt_errstr(status));
5144 * Add an "owner-rights" ACE denying WRITE_DATA,
5145 * and an "owner-rights" ACE allowing READ_DATA.
5148 newsd = security_descriptor_dacl_create(frame,
5153 SEC_ACE_TYPE_ACCESS_DENIED,
5157 SEC_ACE_TYPE_ACCESS_ALLOWED,
5161 if (newsd == NULL) {
5164 sd->dacl = security_acl_concatenate(frame,
5167 if (sd->dacl == NULL) {
5170 status = cli_set_secdesc(cli, fnum, sd);
5171 if (!NT_STATUS_IS_OK(status)) {
5172 printf("cli_set_secdesc failed for %s (%s)\n",
5173 fname, nt_errstr(status));
5176 status = cli_close(cli, fnum);
5177 if (!NT_STATUS_IS_OK(status)) {
5178 printf("close failed for %s (%s)\n",
5179 fname, nt_errstr(status));
5182 fnum = (uint16_t)-1;
5184 /* Try and open for FILE_WRITE_DATA */
5185 status = cli_ntcreate(cli,
5189 FILE_ATTRIBUTE_NORMAL,
5190 FILE_SHARE_READ|FILE_SHARE_WRITE|
5197 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5198 printf("Open of %s - %s\n", fname, nt_errstr(status));
5202 /* Now try and open for FILE_READ_DATA */
5203 status = cli_ntcreate(cli,
5207 FILE_ATTRIBUTE_NORMAL,
5208 FILE_SHARE_READ|FILE_SHARE_WRITE|
5215 if (!NT_STATUS_IS_OK(status)) {
5216 printf("Open of %s - %s\n", fname, nt_errstr(status));
5220 status = cli_close(cli, fnum);
5221 if (!NT_STATUS_IS_OK(status)) {
5222 printf("close failed for %s (%s)\n",
5223 fname, nt_errstr(status));
5227 /* Restore clean slate. */
5229 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5231 /* Create the test file. */
5232 status = cli_ntcreate(cli,
5236 FILE_ATTRIBUTE_NORMAL,
5237 FILE_SHARE_READ|FILE_SHARE_WRITE|
5244 if (!NT_STATUS_IS_OK(status)) {
5245 printf("Create of %s - %s\n", fname, nt_errstr(status));
5249 /* Get the original SD. */
5250 status = cli_query_secdesc(cli,
5254 if (!NT_STATUS_IS_OK(status)) {
5255 printf("cli_query_secdesc failed for %s (%s)\n",
5256 fname, nt_errstr(status));
5261 * Add an "owner-rights ACE denying WRITE_DATA,
5262 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5265 newsd = security_descriptor_dacl_create(frame,
5270 SEC_ACE_TYPE_ACCESS_DENIED,
5274 SEC_ACE_TYPE_ACCESS_ALLOWED,
5275 FILE_READ_DATA|FILE_WRITE_DATA,
5278 if (newsd == NULL) {
5281 sd->dacl = security_acl_concatenate(frame,
5284 if (sd->dacl == NULL) {
5287 status = cli_set_secdesc(cli, fnum, sd);
5288 if (!NT_STATUS_IS_OK(status)) {
5289 printf("cli_set_secdesc failed for %s (%s)\n",
5290 fname, nt_errstr(status));
5293 status = cli_close(cli, fnum);
5294 if (!NT_STATUS_IS_OK(status)) {
5295 printf("close failed for %s (%s)\n",
5296 fname, nt_errstr(status));
5299 fnum = (uint16_t)-1;
5301 /* Try and open for FILE_WRITE_DATA */
5302 status = cli_ntcreate(cli,
5306 FILE_ATTRIBUTE_NORMAL,
5307 FILE_SHARE_READ|FILE_SHARE_WRITE|
5314 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5315 printf("Open of %s - %s\n", fname, nt_errstr(status));
5319 /* Now try and open for FILE_READ_DATA */
5320 status = cli_ntcreate(cli,
5324 FILE_ATTRIBUTE_NORMAL,
5325 FILE_SHARE_READ|FILE_SHARE_WRITE|
5332 if (!NT_STATUS_IS_OK(status)) {
5333 printf("Open of %s - %s\n", fname, nt_errstr(status));
5337 status = cli_close(cli, fnum);
5338 if (!NT_STATUS_IS_OK(status)) {
5339 printf("close failed for %s (%s)\n",
5340 fname, nt_errstr(status));
5344 /* Restore clean slate. */
5346 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5349 /* Create the test file. */
5350 status = cli_ntcreate(cli,
5354 FILE_ATTRIBUTE_NORMAL,
5355 FILE_SHARE_READ|FILE_SHARE_WRITE|
5362 if (!NT_STATUS_IS_OK(status)) {
5363 printf("Create of %s - %s\n", fname, nt_errstr(status));
5367 /* Get the original SD. */
5368 status = cli_query_secdesc(cli,
5372 if (!NT_STATUS_IS_OK(status)) {
5373 printf("cli_query_secdesc failed for %s (%s)\n",
5374 fname, nt_errstr(status));
5379 * Add an "authenticated users" ACE allowing READ_DATA,
5380 * add an "owner-rights" denying READ_DATA,
5381 * and an "authenticated users" ACE allowing WRITE_DATA.
5384 newsd = security_descriptor_dacl_create(frame,
5388 SID_NT_AUTHENTICATED_USERS,
5389 SEC_ACE_TYPE_ACCESS_ALLOWED,
5393 SEC_ACE_TYPE_ACCESS_DENIED,
5396 SID_NT_AUTHENTICATED_USERS,
5397 SEC_ACE_TYPE_ACCESS_ALLOWED,
5401 if (newsd == NULL) {
5402 printf("newsd == NULL\n");
5405 sd->dacl = security_acl_concatenate(frame,
5408 if (sd->dacl == NULL) {
5409 printf("sd->dacl == NULL\n");
5412 status = cli_set_secdesc(cli, fnum, sd);
5413 if (!NT_STATUS_IS_OK(status)) {
5414 printf("cli_set_secdesc failed for %s (%s)\n",
5415 fname, nt_errstr(status));
5418 status = cli_close(cli, fnum);
5419 if (!NT_STATUS_IS_OK(status)) {
5420 printf("close failed for %s (%s)\n",
5421 fname, nt_errstr(status));
5424 fnum = (uint16_t)-1;
5426 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5427 status = cli_ntcreate(cli,
5430 FILE_READ_DATA|FILE_WRITE_DATA,
5431 FILE_ATTRIBUTE_NORMAL,
5432 FILE_SHARE_READ|FILE_SHARE_WRITE|
5439 if (!NT_STATUS_IS_OK(status)) {
5440 printf("Open of %s - %s\n", fname, nt_errstr(status));
5444 status = cli_close(cli, fnum);
5445 if (!NT_STATUS_IS_OK(status)) {
5446 printf("close failed for %s (%s)\n",
5447 fname, nt_errstr(status));
5451 cli_unlink(cli, fname,
5452 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5460 if (fnum != (uint16_t)-1) {
5461 cli_close(cli, fnum);
5463 cli_unlink(cli, fname,
5464 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5465 torture_close_connection(cli);
5472 static bool run_pipe_number(int dummy)
5474 struct cli_state *cli1;
5475 const char *pipe_name = "\\SPOOLSS";
5480 printf("starting pipenumber test\n");
5481 if (!torture_open_connection(&cli1, 0)) {
5485 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5487 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
5488 FILE_ATTRIBUTE_NORMAL,
5489 FILE_SHARE_READ|FILE_SHARE_WRITE,
5490 FILE_OPEN_IF, 0, 0, &fnum, NULL);
5491 if (!NT_STATUS_IS_OK(status)) {
5492 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
5496 printf("\r%6d", num_pipes);
5499 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
5500 torture_close_connection(cli1);
5505 Test open mode returns on read-only files.
5507 static bool run_opentest(int dummy)
5509 static struct cli_state *cli1;
5510 static struct cli_state *cli2;
5511 const char *fname = "\\readonly.file";
5512 uint16_t fnum1, fnum2;
5515 bool correct = True;
5519 printf("starting open test\n");
5521 if (!torture_open_connection(&cli1, 0)) {
5525 cli_setatr(cli1, fname, 0, 0);
5526 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5528 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5530 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5531 if (!NT_STATUS_IS_OK(status)) {
5532 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5536 status = cli_close(cli1, fnum1);
5537 if (!NT_STATUS_IS_OK(status)) {
5538 printf("close2 failed (%s)\n", nt_errstr(status));
5542 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
5543 if (!NT_STATUS_IS_OK(status)) {
5544 printf("cli_setatr failed (%s)\n", nt_errstr(status));
5548 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5549 if (!NT_STATUS_IS_OK(status)) {
5550 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5554 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5555 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5557 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
5558 NT_STATUS_ACCESS_DENIED)) {
5559 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5562 printf("finished open test 1\n");
5564 cli_close(cli1, fnum1);
5566 /* Now try not readonly and ensure ERRbadshare is returned. */
5568 cli_setatr(cli1, fname, 0, 0);
5570 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5571 if (!NT_STATUS_IS_OK(status)) {
5572 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5576 /* This will fail - but the error should be ERRshare. */
5577 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5579 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5580 NT_STATUS_SHARING_VIOLATION)) {
5581 printf("correct error code ERRDOS/ERRbadshare returned\n");
5584 status = cli_close(cli1, fnum1);
5585 if (!NT_STATUS_IS_OK(status)) {
5586 printf("close2 failed (%s)\n", nt_errstr(status));
5590 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5592 printf("finished open test 2\n");
5594 /* Test truncate open disposition on file opened for read. */
5595 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5596 if (!NT_STATUS_IS_OK(status)) {
5597 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5601 /* write 20 bytes. */
5603 memset(buf, '\0', 20);
5605 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5606 if (!NT_STATUS_IS_OK(status)) {
5607 printf("write failed (%s)\n", nt_errstr(status));
5611 status = cli_close(cli1, fnum1);
5612 if (!NT_STATUS_IS_OK(status)) {
5613 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5617 /* Ensure size == 20. */
5618 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5619 if (!NT_STATUS_IS_OK(status)) {
5620 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5625 printf("(3) file size != 20\n");
5629 /* Now test if we can truncate a file opened for readonly. */
5630 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5631 if (!NT_STATUS_IS_OK(status)) {
5632 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5636 status = cli_close(cli1, fnum1);
5637 if (!NT_STATUS_IS_OK(status)) {
5638 printf("close2 failed (%s)\n", nt_errstr(status));
5642 /* Ensure size == 0. */
5643 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5644 if (!NT_STATUS_IS_OK(status)) {
5645 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5650 printf("(3) file size != 0\n");
5653 printf("finished open test 3\n");
5655 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5657 printf("Do ctemp tests\n");
5658 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5659 if (!NT_STATUS_IS_OK(status)) {
5660 printf("ctemp failed (%s)\n", nt_errstr(status));
5664 printf("ctemp gave path %s\n", tmp_path);
5665 status = cli_close(cli1, fnum1);
5666 if (!NT_STATUS_IS_OK(status)) {
5667 printf("close of temp failed (%s)\n", nt_errstr(status));
5670 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5671 if (!NT_STATUS_IS_OK(status)) {
5672 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5675 /* Test the non-io opens... */
5677 if (!torture_open_connection(&cli2, 1)) {
5681 cli_setatr(cli2, fname, 0, 0);
5682 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5684 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5686 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5687 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5688 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5689 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5690 if (!NT_STATUS_IS_OK(status)) {
5691 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5695 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5696 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5697 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5698 if (!NT_STATUS_IS_OK(status)) {
5699 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5703 status = cli_close(cli1, fnum1);
5704 if (!NT_STATUS_IS_OK(status)) {
5705 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5709 status = cli_close(cli2, fnum2);
5710 if (!NT_STATUS_IS_OK(status)) {
5711 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5715 printf("non-io open test #1 passed.\n");
5717 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5719 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5721 status = cli_ntcreate(cli1, fname, 0,
5722 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5723 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5724 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5725 if (!NT_STATUS_IS_OK(status)) {
5726 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5730 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5731 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5732 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5733 if (!NT_STATUS_IS_OK(status)) {
5734 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5738 status = cli_close(cli1, fnum1);
5739 if (!NT_STATUS_IS_OK(status)) {
5740 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5744 status = cli_close(cli2, fnum2);
5745 if (!NT_STATUS_IS_OK(status)) {
5746 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5750 printf("non-io open test #2 passed.\n");
5752 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5754 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5756 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5757 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5758 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5759 if (!NT_STATUS_IS_OK(status)) {
5760 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5764 status = cli_ntcreate(cli2, fname, 0,
5765 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5766 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5767 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5768 if (!NT_STATUS_IS_OK(status)) {
5769 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5773 status = cli_close(cli1, fnum1);
5774 if (!NT_STATUS_IS_OK(status)) {
5775 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5779 status = cli_close(cli2, fnum2);
5780 if (!NT_STATUS_IS_OK(status)) {
5781 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5785 printf("non-io open test #3 passed.\n");
5787 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5789 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5791 status = cli_ntcreate(cli1, fname, 0,
5792 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5793 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5794 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5795 if (!NT_STATUS_IS_OK(status)) {
5796 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5800 status = cli_ntcreate(cli2, fname, 0,
5801 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5802 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5803 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5804 if (NT_STATUS_IS_OK(status)) {
5805 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5809 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5811 status = cli_close(cli1, fnum1);
5812 if (!NT_STATUS_IS_OK(status)) {
5813 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5817 printf("non-io open test #4 passed.\n");
5819 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5821 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5823 status = cli_ntcreate(cli1, fname, 0,
5824 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5825 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5826 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5827 if (!NT_STATUS_IS_OK(status)) {
5828 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5832 status = cli_ntcreate(cli2, fname, 0,
5833 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5834 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5835 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5836 if (!NT_STATUS_IS_OK(status)) {
5837 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5841 status = cli_close(cli1, fnum1);
5842 if (!NT_STATUS_IS_OK(status)) {
5843 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5847 status = cli_close(cli2, fnum2);
5848 if (!NT_STATUS_IS_OK(status)) {
5849 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5853 printf("non-io open test #5 passed.\n");
5855 printf("TEST #6 testing 1 non-io open, one io open\n");
5857 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5859 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5860 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5861 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5862 if (!NT_STATUS_IS_OK(status)) {
5863 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5867 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5868 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5869 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5870 if (!NT_STATUS_IS_OK(status)) {
5871 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5875 status = cli_close(cli1, fnum1);
5876 if (!NT_STATUS_IS_OK(status)) {
5877 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5881 status = cli_close(cli2, fnum2);
5882 if (!NT_STATUS_IS_OK(status)) {
5883 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5887 printf("non-io open test #6 passed.\n");
5889 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5891 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5893 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5894 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5895 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5896 if (!NT_STATUS_IS_OK(status)) {
5897 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5901 status = cli_ntcreate(cli2, fname, 0,
5902 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5903 FILE_ATTRIBUTE_NORMAL,
5904 FILE_SHARE_READ|FILE_SHARE_DELETE,
5905 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5906 if (NT_STATUS_IS_OK(status)) {
5907 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5911 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5913 status = cli_close(cli1, fnum1);
5914 if (!NT_STATUS_IS_OK(status)) {
5915 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5919 printf("non-io open test #7 passed.\n");
5921 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5923 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5924 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5925 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5926 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5927 if (!NT_STATUS_IS_OK(status)) {
5928 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5933 /* Write to ensure we have to update the file time. */
5934 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5936 if (!NT_STATUS_IS_OK(status)) {
5937 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5942 status = cli_close(cli1, fnum1);
5943 if (!NT_STATUS_IS_OK(status)) {
5944 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5950 if (!torture_close_connection(cli1)) {
5953 if (!torture_close_connection(cli2)) {
5960 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5962 uint16_t major, minor;
5963 uint32_t caplow, caphigh;
5966 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5967 printf("Server doesn't support UNIX CIFS extensions.\n");
5968 return NT_STATUS_NOT_SUPPORTED;
5971 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5973 if (!NT_STATUS_IS_OK(status)) {
5974 printf("Server didn't return UNIX CIFS extensions: %s\n",
5979 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5981 if (!NT_STATUS_IS_OK(status)) {
5982 printf("Server doesn't support setting UNIX CIFS extensions: "
5983 "%s.\n", nt_errstr(status));
5987 return NT_STATUS_OK;
5991 Test POSIX open /mkdir calls.
5993 static bool run_simple_posix_open_test(int dummy)
5995 static struct cli_state *cli1;
5996 const char *fname = "posix:file";
5997 const char *hname = "posix:hlink";
5998 const char *sname = "posix:symlink";
5999 const char *dname = "posix:dir";
6002 uint16_t fnum1 = (uint16_t)-1;
6003 SMB_STRUCT_STAT sbuf;
6004 bool correct = false;
6007 const char *fname_windows = "windows_file";
6008 uint16_t fnum2 = (uint16_t)-1;
6010 printf("Starting simple POSIX open test\n");
6012 if (!torture_open_connection(&cli1, 0)) {
6016 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6018 status = torture_setup_unix_extensions(cli1);
6019 if (!NT_STATUS_IS_OK(status)) {
6023 cli_setatr(cli1, fname, 0, 0);
6024 cli_posix_unlink(cli1, fname);
6025 cli_setatr(cli1, dname, 0, 0);
6026 cli_posix_rmdir(cli1, dname);
6027 cli_setatr(cli1, hname, 0, 0);
6028 cli_posix_unlink(cli1, hname);
6029 cli_setatr(cli1, sname, 0, 0);
6030 cli_posix_unlink(cli1, sname);
6031 cli_setatr(cli1, fname_windows, 0, 0);
6032 cli_posix_unlink(cli1, fname_windows);
6034 /* Create a directory. */
6035 status = cli_posix_mkdir(cli1, dname, 0777);
6036 if (!NT_STATUS_IS_OK(status)) {
6037 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6041 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6043 if (!NT_STATUS_IS_OK(status)) {
6044 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6048 /* Test ftruncate - set file size. */
6049 status = cli_ftruncate(cli1, fnum1, 1000);
6050 if (!NT_STATUS_IS_OK(status)) {
6051 printf("ftruncate failed (%s)\n", nt_errstr(status));
6055 /* Ensure st_size == 1000 */
6056 status = cli_posix_stat(cli1, fname, &sbuf);
6057 if (!NT_STATUS_IS_OK(status)) {
6058 printf("stat failed (%s)\n", nt_errstr(status));
6062 if (sbuf.st_ex_size != 1000) {
6063 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6067 /* Ensure st_mode == 0600 */
6068 if ((sbuf.st_ex_mode & 07777) != 0600) {
6069 printf("posix_open - bad permissions 0%o != 0600\n",
6070 (unsigned int)(sbuf.st_ex_mode & 07777));
6074 /* Test ftruncate - set file size back to zero. */
6075 status = cli_ftruncate(cli1, fnum1, 0);
6076 if (!NT_STATUS_IS_OK(status)) {
6077 printf("ftruncate failed (%s)\n", nt_errstr(status));
6081 status = cli_close(cli1, fnum1);
6082 if (!NT_STATUS_IS_OK(status)) {
6083 printf("close failed (%s)\n", nt_errstr(status));
6087 /* Now open the file again for read only. */
6088 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6089 if (!NT_STATUS_IS_OK(status)) {
6090 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
6094 /* Now unlink while open. */
6095 status = cli_posix_unlink(cli1, fname);
6096 if (!NT_STATUS_IS_OK(status)) {
6097 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6101 status = cli_close(cli1, fnum1);
6102 if (!NT_STATUS_IS_OK(status)) {
6103 printf("close(2) failed (%s)\n", nt_errstr(status));
6107 /* Ensure the file has gone. */
6108 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6109 if (NT_STATUS_IS_OK(status)) {
6110 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
6114 /* Create again to test open with O_TRUNC. */
6115 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
6116 if (!NT_STATUS_IS_OK(status)) {
6117 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6121 /* Test ftruncate - set file size. */
6122 status = cli_ftruncate(cli1, fnum1, 1000);
6123 if (!NT_STATUS_IS_OK(status)) {
6124 printf("ftruncate failed (%s)\n", nt_errstr(status));
6128 /* Ensure st_size == 1000 */
6129 status = cli_posix_stat(cli1, fname, &sbuf);
6130 if (!NT_STATUS_IS_OK(status)) {
6131 printf("stat failed (%s)\n", nt_errstr(status));
6135 if (sbuf.st_ex_size != 1000) {
6136 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6140 status = cli_close(cli1, fnum1);
6141 if (!NT_STATUS_IS_OK(status)) {
6142 printf("close(2) failed (%s)\n", nt_errstr(status));
6146 /* Re-open with O_TRUNC. */
6147 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
6148 if (!NT_STATUS_IS_OK(status)) {
6149 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6153 /* Ensure st_size == 0 */
6154 status = cli_posix_stat(cli1, fname, &sbuf);
6155 if (!NT_STATUS_IS_OK(status)) {
6156 printf("stat failed (%s)\n", nt_errstr(status));
6160 if (sbuf.st_ex_size != 0) {
6161 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
6165 status = cli_close(cli1, fnum1);
6166 if (!NT_STATUS_IS_OK(status)) {
6167 printf("close failed (%s)\n", nt_errstr(status));
6171 status = cli_posix_unlink(cli1, fname);
6172 if (!NT_STATUS_IS_OK(status)) {
6173 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6177 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
6178 if (!NT_STATUS_IS_OK(status)) {
6179 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6180 dname, nt_errstr(status));
6184 cli_close(cli1, fnum1);
6186 /* What happens when we try and POSIX open a directory for write ? */
6187 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
6188 if (NT_STATUS_IS_OK(status)) {
6189 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
6192 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
6193 NT_STATUS_FILE_IS_A_DIRECTORY)) {
6198 /* Create the file. */
6199 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6201 if (!NT_STATUS_IS_OK(status)) {
6202 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6206 /* Write some data into it. */
6207 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6209 if (!NT_STATUS_IS_OK(status)) {
6210 printf("cli_write failed: %s\n", nt_errstr(status));
6214 cli_close(cli1, fnum1);
6216 /* Now create a hardlink. */
6217 status = cli_posix_hardlink(cli1, fname, hname);
6218 if (!NT_STATUS_IS_OK(status)) {
6219 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
6223 /* Now create a symlink. */
6224 status = cli_posix_symlink(cli1, fname, sname);
6225 if (!NT_STATUS_IS_OK(status)) {
6226 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
6230 /* Open the hardlink for read. */
6231 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
6232 if (!NT_STATUS_IS_OK(status)) {
6233 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
6237 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
6238 if (!NT_STATUS_IS_OK(status)) {
6239 printf("POSIX read of %s failed (%s)\n", hname,
6242 } else if (nread != 10) {
6243 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6244 hname, (unsigned long)nread, 10);
6248 if (memcmp(buf, "TEST DATA\n", 10)) {
6249 printf("invalid data read from hardlink\n");
6253 /* Do a POSIX lock/unlock. */
6254 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
6255 if (!NT_STATUS_IS_OK(status)) {
6256 printf("POSIX lock failed %s\n", nt_errstr(status));
6260 /* Punch a hole in the locked area. */
6261 status = cli_posix_unlock(cli1, fnum1, 10, 80);
6262 if (!NT_STATUS_IS_OK(status)) {
6263 printf("POSIX unlock failed %s\n", nt_errstr(status));
6267 cli_close(cli1, fnum1);
6269 /* Open the symlink for read - this should fail. A POSIX
6270 client should not be doing opens on a symlink. */
6271 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
6272 if (NT_STATUS_IS_OK(status)) {
6273 printf("POSIX open of %s succeeded (should have failed)\n", sname);
6276 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
6277 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
6278 printf("POSIX open of %s should have failed "
6279 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6280 "failed with %s instead.\n",
6281 sname, nt_errstr(status));
6286 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
6287 if (!NT_STATUS_IS_OK(status)) {
6288 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
6292 if (strcmp(namebuf, fname) != 0) {
6293 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6294 sname, fname, namebuf);
6298 status = cli_posix_rmdir(cli1, dname);
6299 if (!NT_STATUS_IS_OK(status)) {
6300 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
6304 /* Check directory opens with a specific permission. */
6305 status = cli_posix_mkdir(cli1, dname, 0700);
6306 if (!NT_STATUS_IS_OK(status)) {
6307 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6311 /* Ensure st_mode == 0700 */
6312 status = cli_posix_stat(cli1, dname, &sbuf);
6313 if (!NT_STATUS_IS_OK(status)) {
6314 printf("stat failed (%s)\n", nt_errstr(status));
6318 if ((sbuf.st_ex_mode & 07777) != 0700) {
6319 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6320 (unsigned int)(sbuf.st_ex_mode & 07777));
6325 * Now create a Windows file, and attempt a POSIX unlink.
6326 * This should fail with a sharing violation but due to:
6328 * [Bug 9571] Unlink after open causes smbd to panic
6330 * ensure we've fixed the lock ordering violation.
6333 status = cli_ntcreate(cli1, fname_windows, 0,
6334 FILE_READ_DATA|FILE_WRITE_DATA, 0,
6335 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6337 0x0, 0x0, &fnum2, NULL);
6338 if (!NT_STATUS_IS_OK(status)) {
6339 printf("Windows create of %s failed (%s)\n", fname_windows,
6344 /* Now try posix_unlink. */
6345 status = cli_posix_unlink(cli1, fname_windows);
6346 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6347 printf("POSIX unlink of %s should fail "
6348 "with NT_STATUS_SHARING_VIOLATION "
6349 "got %s instead !\n",
6355 cli_close(cli1, fnum2);
6357 printf("Simple POSIX open test passed\n");
6362 if (fnum1 != (uint16_t)-1) {
6363 cli_close(cli1, fnum1);
6364 fnum1 = (uint16_t)-1;
6367 if (fnum2 != (uint16_t)-1) {
6368 cli_close(cli1, fnum2);
6369 fnum2 = (uint16_t)-1;
6372 cli_setatr(cli1, sname, 0, 0);
6373 cli_posix_unlink(cli1, sname);
6374 cli_setatr(cli1, hname, 0, 0);
6375 cli_posix_unlink(cli1, hname);
6376 cli_setatr(cli1, fname, 0, 0);
6377 cli_posix_unlink(cli1, fname);
6378 cli_setatr(cli1, dname, 0, 0);
6379 cli_posix_rmdir(cli1, dname);
6380 cli_setatr(cli1, fname_windows, 0, 0);
6381 cli_posix_unlink(cli1, fname_windows);
6383 if (!torture_close_connection(cli1)) {
6391 Test POSIX and Windows ACLs are rejected on symlinks.
6393 static bool run_acl_symlink_test(int dummy)
6395 static struct cli_state *cli;
6396 const char *fname = "posix_file";
6397 const char *sname = "posix_symlink";
6398 uint16_t fnum = (uint16_t)-1;
6399 bool correct = false;
6401 char *posix_acl = NULL;
6402 size_t posix_acl_len = 0;
6403 char *posix_acl_sym = NULL;
6404 size_t posix_acl_len_sym = 0;
6405 struct security_descriptor *sd = NULL;
6406 struct security_descriptor *sd_sym = NULL;
6407 TALLOC_CTX *frame = NULL;
6409 frame = talloc_stackframe();
6411 printf("Starting acl symlink test\n");
6413 if (!torture_open_connection(&cli, 0)) {
6418 smbXcli_conn_set_sockopt(cli->conn, sockops);
6420 status = torture_setup_unix_extensions(cli);
6421 if (!NT_STATUS_IS_OK(status)) {
6426 cli_setatr(cli, fname, 0, 0);
6427 cli_posix_unlink(cli, fname);
6428 cli_setatr(cli, sname, 0, 0);
6429 cli_posix_unlink(cli, sname);
6431 status = cli_ntcreate(cli,
6434 READ_CONTROL_ACCESS,
6436 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6443 if (!NT_STATUS_IS_OK(status)) {
6444 printf("cli_ntcreate of %s failed (%s)\n",
6450 /* Get the Windows ACL on the file. */
6451 status = cli_query_secdesc(cli,
6455 if (!NT_STATUS_IS_OK(status)) {
6456 printf("cli_query_secdesc failed (%s)\n",
6461 /* Get the POSIX ACL on the file. */
6462 status = cli_posix_getacl(cli,
6468 if (!NT_STATUS_IS_OK(status)) {
6469 printf("cli_posix_getacl failed (%s)\n",
6474 status = cli_close(cli, fnum);
6475 if (!NT_STATUS_IS_OK(status)) {
6476 printf("close failed (%s)\n", nt_errstr(status));
6479 fnum = (uint16_t)-1;
6481 /* Now create a symlink. */
6482 status = cli_posix_symlink(cli, fname, sname);
6483 if (!NT_STATUS_IS_OK(status)) {
6484 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6491 /* Open a handle on the symlink. */
6492 status = cli_ntcreate(cli,
6495 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
6497 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6504 if (!NT_STATUS_IS_OK(status)) {
6505 printf("cli_posix_open of %s failed (%s)\n",
6511 /* Get the Windows ACL on the symlink handle. Should fail */
6512 status = cli_query_secdesc(cli,
6517 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6518 printf("cli_query_secdesc on a symlink gave %s. "
6519 "Should be NT_STATUS_ACCESS_DENIED.\n",
6524 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6525 status = cli_posix_getacl(cli,
6531 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6532 printf("cli_posix_getacl on a symlink gave %s. "
6533 "Should be NT_STATUS_ACCESS_DENIED.\n",
6538 /* Set the Windows ACL on the symlink handle. Should fail */
6539 status = cli_set_security_descriptor(cli,
6544 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6545 printf("cli_query_secdesc on a symlink gave %s. "
6546 "Should be NT_STATUS_ACCESS_DENIED.\n",
6551 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6552 status = cli_posix_setacl(cli,
6557 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6558 printf("cli_posix_getacl on a symlink gave %s. "
6559 "Should be NT_STATUS_ACCESS_DENIED.\n",
6564 printf("ACL symlink test passed\n");
6569 if (fnum != (uint16_t)-1) {
6570 cli_close(cli, fnum);
6571 fnum = (uint16_t)-1;
6574 cli_setatr(cli, sname, 0, 0);
6575 cli_posix_unlink(cli, sname);
6576 cli_setatr(cli, fname, 0, 0);
6577 cli_posix_unlink(cli, fname);
6579 if (!torture_close_connection(cli)) {
6588 Test POSIX can delete a file containing streams.
6590 static bool run_posix_stream_delete(int dummy)
6592 struct cli_state *cli1 = NULL;
6593 struct cli_state *cli2 = NULL;
6594 const char *fname = "streamfile";
6595 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6596 uint16_t fnum1 = (uint16_t)-1;
6597 bool correct = false;
6599 TALLOC_CTX *frame = NULL;
6601 frame = talloc_stackframe();
6603 printf("Starting POSIX stream delete test\n");
6605 if (!torture_open_connection(&cli1, 0) ||
6606 !torture_open_connection(&cli2, 1)) {
6611 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6612 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6614 status = torture_setup_unix_extensions(cli2);
6615 if (!NT_STATUS_IS_OK(status)) {
6619 cli_setatr(cli1, fname, 0, 0);
6620 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6622 /* Create the file. */
6623 status = cli_ntcreate(cli1,
6626 READ_CONTROL_ACCESS,
6628 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6635 if (!NT_STATUS_IS_OK(status)) {
6636 printf("cli_ntcreate of %s failed (%s)\n",
6642 status = cli_close(cli1, fnum1);
6643 if (!NT_STATUS_IS_OK(status)) {
6644 printf("cli_close of %s failed (%s)\n",
6649 fnum1 = (uint16_t)-1;
6651 /* Now create the stream. */
6652 status = cli_ntcreate(cli1,
6657 FILE_SHARE_READ|FILE_SHARE_WRITE,
6664 if (!NT_STATUS_IS_OK(status)) {
6665 printf("cli_ntcreate of %s failed (%s)\n",
6671 /* Leave the stream handle open... */
6673 /* POSIX unlink should fail. */
6674 status = cli_posix_unlink(cli2, fname);
6675 if (NT_STATUS_IS_OK(status)) {
6676 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6681 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6682 printf("cli_posix_unlink of %s failed with (%s) "
6683 "should have been NT_STATUS_SHARING_VIOLATION\n",
6689 /* Close the stream handle. */
6690 status = cli_close(cli1, fnum1);
6691 if (!NT_STATUS_IS_OK(status)) {
6692 printf("cli_close of %s failed (%s)\n",
6697 fnum1 = (uint16_t)-1;
6699 /* POSIX unlink after stream handle closed should succeed. */
6700 status = cli_posix_unlink(cli2, fname);
6701 if (!NT_STATUS_IS_OK(status)) {
6702 printf("cli_posix_unlink of %s failed (%s)\n",
6708 printf("POSIX stream delete test passed\n");
6713 if (fnum1 != (uint16_t)-1) {
6714 cli_close(cli1, fnum1);
6715 fnum1 = (uint16_t)-1;
6718 cli_setatr(cli1, fname, 0, 0);
6719 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6721 if (!torture_close_connection(cli1)) {
6724 if (!torture_close_connection(cli2)) {
6733 Test setting EA's are rejected on symlinks.
6735 static bool run_ea_symlink_test(int dummy)
6737 static struct cli_state *cli;
6738 const char *fname = "posix_file_ea";
6739 const char *sname = "posix_symlink_ea";
6740 const char *ea_name = "testea_name";
6741 const char *ea_value = "testea_value";
6742 uint16_t fnum = (uint16_t)-1;
6743 bool correct = false;
6746 struct ea_struct *eas = NULL;
6747 TALLOC_CTX *frame = NULL;
6749 frame = talloc_stackframe();
6751 printf("Starting EA symlink test\n");
6753 if (!torture_open_connection(&cli, 0)) {
6758 smbXcli_conn_set_sockopt(cli->conn, sockops);
6760 status = torture_setup_unix_extensions(cli);
6761 if (!NT_STATUS_IS_OK(status)) {
6766 cli_setatr(cli, fname, 0, 0);
6767 cli_posix_unlink(cli, fname);
6768 cli_setatr(cli, sname, 0, 0);
6769 cli_posix_unlink(cli, sname);
6771 status = cli_ntcreate(cli,
6774 READ_CONTROL_ACCESS,
6776 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6783 if (!NT_STATUS_IS_OK(status)) {
6784 printf("cli_ntcreate of %s failed (%s)\n",
6790 status = cli_close(cli, fnum);
6791 if (!NT_STATUS_IS_OK(status)) {
6792 printf("close failed (%s)\n",
6796 fnum = (uint16_t)-1;
6798 /* Set an EA on the path. */
6799 status = cli_set_ea_path(cli,
6803 strlen(ea_value)+1);
6805 if (!NT_STATUS_IS_OK(status)) {
6806 printf("cli_set_ea_path failed (%s)\n",
6811 /* Now create a symlink. */
6812 status = cli_posix_symlink(cli, fname, sname);
6813 if (!NT_STATUS_IS_OK(status)) {
6814 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6821 /* Get the EA list on the path. Should return value set. */
6822 status = cli_get_ea_list_path(cli,
6828 if (!NT_STATUS_IS_OK(status)) {
6829 printf("cli_get_ea_list_path failed (%s)\n",
6834 /* Ensure the EA we set is there. */
6835 for (i=0; i<num_eas; i++) {
6836 if (strcmp(eas[i].name, ea_name) == 0 &&
6837 eas[i].value.length == strlen(ea_value)+1 &&
6838 memcmp(eas[i].value.data,
6840 eas[i].value.length) == 0) {
6846 printf("Didn't find EA on pathname %s\n",
6854 /* Get the EA list on the symlink. Should return empty list. */
6855 status = cli_get_ea_list_path(cli,
6861 if (!NT_STATUS_IS_OK(status)) {
6862 printf("cli_get_ea_list_path failed (%s)\n",
6868 printf("cli_get_ea_list_path failed (%s)\n",
6873 /* Set an EA on the symlink. Should fail. */
6874 status = cli_set_ea_path(cli,
6878 strlen(ea_value)+1);
6880 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6881 printf("cli_set_ea_path on a symlink gave %s. "
6882 "Should be NT_STATUS_ACCESS_DENIED.\n",
6887 printf("EA symlink test passed\n");
6892 if (fnum != (uint16_t)-1) {
6893 cli_close(cli, fnum);
6894 fnum = (uint16_t)-1;
6897 cli_setatr(cli, sname, 0, 0);
6898 cli_posix_unlink(cli, sname);
6899 cli_setatr(cli, fname, 0, 0);
6900 cli_posix_unlink(cli, fname);
6902 if (!torture_close_connection(cli)) {
6911 Test POSIX locks are OFD-locks.
6913 static bool run_posix_ofd_lock_test(int dummy)
6915 static struct cli_state *cli;
6916 const char *fname = "posix_file";
6917 uint16_t fnum1 = (uint16_t)-1;
6918 uint16_t fnum2 = (uint16_t)-1;
6919 bool correct = false;
6921 TALLOC_CTX *frame = NULL;
6923 frame = talloc_stackframe();
6925 printf("Starting POSIX ofd-lock test\n");
6927 if (!torture_open_connection(&cli, 0)) {
6932 smbXcli_conn_set_sockopt(cli->conn, sockops);
6934 status = torture_setup_unix_extensions(cli);
6935 if (!NT_STATUS_IS_OK(status)) {
6940 cli_setatr(cli, fname, 0, 0);
6941 cli_posix_unlink(cli, fname);
6943 /* Open the file twice. */
6944 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
6946 if (!NT_STATUS_IS_OK(status)) {
6947 printf("First POSIX open of %s failed\n", fname);
6951 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
6952 if (!NT_STATUS_IS_OK(status)) {
6953 printf("First POSIX open of %s failed\n", fname);
6957 /* Set a 0-50 lock on fnum1. */
6958 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6959 if (!NT_STATUS_IS_OK(status)) {
6960 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
6964 /* Set a 60-100 lock on fnum2. */
6965 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
6966 if (!NT_STATUS_IS_OK(status)) {
6967 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
6971 /* close fnum1 - 0-50 lock should go away. */
6972 status = cli_close(cli, fnum1);
6973 if (!NT_STATUS_IS_OK(status)) {
6974 printf("close failed (%s)\n",
6978 fnum1 = (uint16_t)-1;
6980 /* Change the lock context. */
6981 cli_setpid(cli, cli_getpid(cli) + 1);
6983 /* Re-open fnum1. */
6984 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
6985 if (!NT_STATUS_IS_OK(status)) {
6986 printf("Third POSIX open of %s failed\n", fname);
6990 /* 60-100 lock should still be there. */
6991 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
6992 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
6993 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
6997 /* 0-50 lock should be gone. */
6998 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6999 if (!NT_STATUS_IS_OK(status)) {
7000 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
7004 printf("POSIX OFD lock test passed\n");
7009 if (fnum1 != (uint16_t)-1) {
7010 cli_close(cli, fnum1);
7011 fnum1 = (uint16_t)-1;
7013 if (fnum2 != (uint16_t)-1) {
7014 cli_close(cli, fnum2);
7015 fnum2 = (uint16_t)-1;
7018 cli_setatr(cli, fname, 0, 0);
7019 cli_posix_unlink(cli, fname);
7021 if (!torture_close_connection(cli)) {
7029 static uint32_t open_attrs_table[] = {
7030 FILE_ATTRIBUTE_NORMAL,
7031 FILE_ATTRIBUTE_ARCHIVE,
7032 FILE_ATTRIBUTE_READONLY,
7033 FILE_ATTRIBUTE_HIDDEN,
7034 FILE_ATTRIBUTE_SYSTEM,
7036 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7037 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7038 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7039 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7040 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7041 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7043 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7044 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7045 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7046 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7049 struct trunc_open_results {
7052 uint32_t trunc_attr;
7053 uint32_t result_attr;
7056 static struct trunc_open_results attr_results[] = {
7057 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7058 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7059 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7060 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7061 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7062 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7063 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7064 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7065 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7066 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7067 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7068 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7069 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7070 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7071 { 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 },
7072 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7073 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7074 { 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 },
7075 { 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 },
7076 { 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 },
7077 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7078 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7079 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7080 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7081 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7082 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7085 static bool run_openattrtest(int dummy)
7087 static struct cli_state *cli1;
7088 const char *fname = "\\openattr.file";
7090 bool correct = True;
7092 unsigned int i, j, k, l;
7095 printf("starting open attr test\n");
7097 if (!torture_open_connection(&cli1, 0)) {
7101 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7103 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7104 cli_setatr(cli1, fname, 0, 0);
7105 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7107 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7108 open_attrs_table[i], FILE_SHARE_NONE,
7109 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7110 if (!NT_STATUS_IS_OK(status)) {
7111 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7115 status = cli_close(cli1, fnum1);
7116 if (!NT_STATUS_IS_OK(status)) {
7117 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7121 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7122 status = cli_ntcreate(cli1, fname, 0,
7123 FILE_READ_DATA|FILE_WRITE_DATA,
7124 open_attrs_table[j],
7125 FILE_SHARE_NONE, FILE_OVERWRITE,
7126 0, 0, &fnum1, NULL);
7127 if (!NT_STATUS_IS_OK(status)) {
7128 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7129 if (attr_results[l].num == k) {
7130 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7131 k, open_attrs_table[i],
7132 open_attrs_table[j],
7133 fname, NT_STATUS_V(status), nt_errstr(status));
7138 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7139 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7140 k, open_attrs_table[i], open_attrs_table[j],
7145 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7151 status = cli_close(cli1, fnum1);
7152 if (!NT_STATUS_IS_OK(status)) {
7153 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7157 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7158 if (!NT_STATUS_IS_OK(status)) {
7159 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7164 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7165 k, open_attrs_table[i], open_attrs_table[j], attr );
7168 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7169 if (attr_results[l].num == k) {
7170 if (attr != attr_results[l].result_attr ||
7171 open_attrs_table[i] != attr_results[l].init_attr ||
7172 open_attrs_table[j] != attr_results[l].trunc_attr) {
7173 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7174 open_attrs_table[i],
7175 open_attrs_table[j],
7177 attr_results[l].result_attr);
7187 cli_setatr(cli1, fname, 0, 0);
7188 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7190 printf("open attr test %s.\n", correct ? "passed" : "failed");
7192 if (!torture_close_connection(cli1)) {
7198 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7199 const char *name, void *state)
7201 int *matched = (int *)state;
7202 if (matched != NULL) {
7205 return NT_STATUS_OK;
7209 test directory listing speed
7211 static bool run_dirtest(int dummy)
7214 static struct cli_state *cli;
7216 struct timeval core_start;
7217 bool correct = True;
7220 printf("starting directory test\n");
7222 if (!torture_open_connection(&cli, 0)) {
7226 smbXcli_conn_set_sockopt(cli->conn, sockops);
7229 for (i=0;i<torture_numops;i++) {
7231 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7232 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7233 fprintf(stderr,"Failed to open %s\n", fname);
7236 cli_close(cli, fnum);
7239 core_start = timeval_current();
7242 cli_list(cli, "a*.*", 0, list_fn, &matched);
7243 printf("Matched %d\n", matched);
7246 cli_list(cli, "b*.*", 0, list_fn, &matched);
7247 printf("Matched %d\n", matched);
7250 cli_list(cli, "xyzabc", 0, list_fn, &matched);
7251 printf("Matched %d\n", matched);
7253 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7256 for (i=0;i<torture_numops;i++) {
7258 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7259 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7262 if (!torture_close_connection(cli)) {
7266 printf("finished dirtest\n");
7271 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7274 struct cli_state *pcli = (struct cli_state *)state;
7276 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7278 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7279 return NT_STATUS_OK;
7281 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7282 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7283 printf("del_fn: failed to rmdir %s\n,", fname );
7285 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7286 printf("del_fn: failed to unlink %s\n,", fname );
7288 return NT_STATUS_OK;
7293 sees what IOCTLs are supported
7295 bool torture_ioctl_test(int dummy)
7297 static struct cli_state *cli;
7298 uint16_t device, function;
7300 const char *fname = "\\ioctl.dat";
7304 if (!torture_open_connection(&cli, 0)) {
7308 printf("starting ioctl test\n");
7310 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7312 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7313 if (!NT_STATUS_IS_OK(status)) {
7314 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7318 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7319 printf("ioctl device info: %s\n", nt_errstr(status));
7321 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7322 printf("ioctl job info: %s\n", nt_errstr(status));
7324 for (device=0;device<0x100;device++) {
7325 printf("ioctl test with device = 0x%x\n", device);
7326 for (function=0;function<0x100;function++) {
7327 uint32_t code = (device<<16) | function;
7329 status = cli_raw_ioctl(cli, fnum, code, &blob);
7331 if (NT_STATUS_IS_OK(status)) {
7332 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7334 data_blob_free(&blob);
7339 if (!torture_close_connection(cli)) {
7348 tries varients of chkpath
7350 bool torture_chkpath_test(int dummy)
7352 static struct cli_state *cli;
7357 if (!torture_open_connection(&cli, 0)) {
7361 printf("starting chkpath test\n");
7363 /* cleanup from an old run */
7364 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7365 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7366 cli_rmdir(cli, "\\chkpath.dir");
7368 status = cli_mkdir(cli, "\\chkpath.dir");
7369 if (!NT_STATUS_IS_OK(status)) {
7370 printf("mkdir1 failed : %s\n", nt_errstr(status));
7374 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7375 if (!NT_STATUS_IS_OK(status)) {
7376 printf("mkdir2 failed : %s\n", nt_errstr(status));
7380 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7382 if (!NT_STATUS_IS_OK(status)) {
7383 printf("open1 failed (%s)\n", nt_errstr(status));
7386 cli_close(cli, fnum);
7388 status = cli_chkpath(cli, "\\chkpath.dir");
7389 if (!NT_STATUS_IS_OK(status)) {
7390 printf("chkpath1 failed: %s\n", nt_errstr(status));
7394 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7395 if (!NT_STATUS_IS_OK(status)) {
7396 printf("chkpath2 failed: %s\n", nt_errstr(status));
7400 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7401 if (!NT_STATUS_IS_OK(status)) {
7402 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7403 NT_STATUS_NOT_A_DIRECTORY);
7405 printf("* chkpath on a file should fail\n");
7409 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7410 if (!NT_STATUS_IS_OK(status)) {
7411 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7412 NT_STATUS_OBJECT_NAME_NOT_FOUND);
7414 printf("* chkpath on a non existent file should fail\n");
7418 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7419 if (!NT_STATUS_IS_OK(status)) {
7420 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7421 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7423 printf("* chkpath on a non existent component should fail\n");
7427 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7428 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7429 cli_rmdir(cli, "\\chkpath.dir");
7431 if (!torture_close_connection(cli)) {
7438 static bool run_eatest(int dummy)
7440 static struct cli_state *cli;
7441 const char *fname = "\\eatest.txt";
7442 bool correct = True;
7446 struct ea_struct *ea_list = NULL;
7447 TALLOC_CTX *mem_ctx = talloc_init("eatest");
7450 printf("starting eatest\n");
7452 if (!torture_open_connection(&cli, 0)) {
7453 talloc_destroy(mem_ctx);
7457 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7459 status = cli_ntcreate(cli, fname, 0,
7460 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7461 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7462 0x4044, 0, &fnum, NULL);
7463 if (!NT_STATUS_IS_OK(status)) {
7464 printf("open failed - %s\n", nt_errstr(status));
7465 talloc_destroy(mem_ctx);
7469 for (i = 0; i < 10; i++) {
7470 fstring ea_name, ea_val;
7472 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7473 memset(ea_val, (char)i+1, i+1);
7474 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7475 if (!NT_STATUS_IS_OK(status)) {
7476 printf("ea_set of name %s failed - %s\n", ea_name,
7478 talloc_destroy(mem_ctx);
7483 cli_close(cli, fnum);
7484 for (i = 0; i < 10; i++) {
7485 fstring ea_name, ea_val;
7487 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7488 memset(ea_val, (char)i+1, i+1);
7489 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7490 if (!NT_STATUS_IS_OK(status)) {
7491 printf("ea_set of name %s failed - %s\n", ea_name,
7493 talloc_destroy(mem_ctx);
7498 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7499 if (!NT_STATUS_IS_OK(status)) {
7500 printf("ea_get list failed - %s\n", nt_errstr(status));
7504 printf("num_eas = %d\n", (int)num_eas);
7506 if (num_eas != 20) {
7507 printf("Should be 20 EA's stored... failing.\n");
7511 for (i = 0; i < num_eas; i++) {
7512 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7513 dump_data(0, ea_list[i].value.data,
7514 ea_list[i].value.length);
7517 /* Setting EA's to zero length deletes them. Test this */
7518 printf("Now deleting all EA's - case indepenent....\n");
7521 cli_set_ea_path(cli, fname, "", "", 0);
7523 for (i = 0; i < 20; i++) {
7525 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7526 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7527 if (!NT_STATUS_IS_OK(status)) {
7528 printf("ea_set of name %s failed - %s\n", ea_name,
7530 talloc_destroy(mem_ctx);
7536 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7537 if (!NT_STATUS_IS_OK(status)) {
7538 printf("ea_get list failed - %s\n", nt_errstr(status));
7542 printf("num_eas = %d\n", (int)num_eas);
7543 for (i = 0; i < num_eas; i++) {
7544 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7545 dump_data(0, ea_list[i].value.data,
7546 ea_list[i].value.length);
7550 printf("deleting EA's failed.\n");
7554 /* Try and delete a non existent EA. */
7555 status = cli_set_ea_path(cli, fname, "foo", "", 0);
7556 if (!NT_STATUS_IS_OK(status)) {
7557 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7562 talloc_destroy(mem_ctx);
7563 if (!torture_close_connection(cli)) {
7570 static bool run_dirtest1(int dummy)
7573 static struct cli_state *cli;
7576 bool correct = True;
7578 printf("starting directory test\n");
7580 if (!torture_open_connection(&cli, 0)) {
7584 smbXcli_conn_set_sockopt(cli->conn, sockops);
7586 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7587 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7588 cli_rmdir(cli, "\\LISTDIR");
7589 cli_mkdir(cli, "\\LISTDIR");
7591 /* Create 1000 files and 1000 directories. */
7592 for (i=0;i<1000;i++) {
7594 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7595 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7596 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7597 0, 0, &fnum, NULL))) {
7598 fprintf(stderr,"Failed to open %s\n", fname);
7601 cli_close(cli, fnum);
7603 for (i=0;i<1000;i++) {
7605 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7606 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7607 fprintf(stderr,"Failed to open %s\n", fname);
7612 /* Now ensure that doing an old list sees both files and directories. */
7614 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7615 printf("num_seen = %d\n", num_seen );
7616 /* We should see 100 files + 1000 directories + . and .. */
7617 if (num_seen != 2002)
7620 /* Ensure if we have the "must have" bits we only see the
7624 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7625 printf("num_seen = %d\n", num_seen );
7626 if (num_seen != 1002)
7630 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7631 printf("num_seen = %d\n", num_seen );
7632 if (num_seen != 1000)
7635 /* Delete everything. */
7636 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7637 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7638 cli_rmdir(cli, "\\LISTDIR");
7641 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7642 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7643 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7646 if (!torture_close_connection(cli)) {
7650 printf("finished dirtest1\n");
7655 static bool run_error_map_extract(int dummy) {
7657 static struct cli_state *c_dos;
7658 static struct cli_state *c_nt;
7670 /* NT-Error connection */
7672 disable_spnego = true;
7673 if (!(c_nt = open_nbt_connection())) {
7674 disable_spnego = false;
7677 disable_spnego = false;
7679 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7682 if (!NT_STATUS_IS_OK(status)) {
7683 printf("%s rejected the NT-error negprot (%s)\n", host,
7689 status = cli_session_setup_anon(c_nt);
7690 if (!NT_STATUS_IS_OK(status)) {
7691 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7695 /* DOS-Error connection */
7697 disable_spnego = true;
7698 force_dos_errors = true;
7699 if (!(c_dos = open_nbt_connection())) {
7700 disable_spnego = false;
7701 force_dos_errors = false;
7704 disable_spnego = false;
7705 force_dos_errors = false;
7707 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7709 if (!NT_STATUS_IS_OK(status)) {
7710 printf("%s rejected the DOS-error negprot (%s)\n", host,
7712 cli_shutdown(c_dos);
7716 status = cli_session_setup_anon(c_dos);
7717 if (!NT_STATUS_IS_OK(status)) {
7718 printf("%s rejected the DOS-error initial session setup (%s)\n",
7719 host, nt_errstr(status));
7723 c_nt->map_dos_errors = false;
7724 c_dos->map_dos_errors = false;
7726 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7727 struct cli_credentials *user_creds = NULL;
7729 fstr_sprintf(user, "%X", error);
7731 user_creds = cli_session_creds_init(talloc_tos(),
7736 false, /* use_kerberos */
7737 false, /* fallback_after_kerberos */
7738 false, /* use_ccache */
7739 false); /* password_is_nt_hash */
7740 if (user_creds == NULL) {
7741 printf("cli_session_creds_init(%s) failed\n", user);
7745 status = cli_session_setup_creds(c_nt, user_creds);
7746 if (NT_STATUS_IS_OK(status)) {
7747 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7750 /* Case #1: 32-bit NT errors */
7751 if (!NT_STATUS_IS_DOS(status)) {
7754 printf("/** Dos error on NT connection! (%s) */\n",
7756 nt_status = NT_STATUS(0xc0000000);
7759 status = cli_session_setup_creds(c_dos, user_creds);
7760 if (NT_STATUS_IS_OK(status)) {
7761 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7764 /* Case #1: 32-bit NT errors */
7765 if (NT_STATUS_IS_DOS(status)) {
7766 printf("/** NT error on DOS connection! (%s) */\n",
7768 errnum = errclass = 0;
7770 errclass = NT_STATUS_DOS_CLASS(status);
7771 errnum = NT_STATUS_DOS_CODE(status);
7774 if (NT_STATUS_V(nt_status) != error) {
7775 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7776 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
7777 get_nt_error_c_code(talloc_tos(), nt_status));
7780 printf("\t{%s,\t%s,\t%s},\n",
7781 smb_dos_err_class(errclass),
7782 smb_dos_err_name(errclass, errnum),
7783 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7785 TALLOC_FREE(user_creds);
7790 static bool run_sesssetup_bench(int dummy)
7792 static struct cli_state *c;
7793 const char *fname = "\\file.dat";
7798 if (!torture_open_connection(&c, 0)) {
7802 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7803 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7804 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7805 if (!NT_STATUS_IS_OK(status)) {
7806 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7810 for (i=0; i<torture_numops; i++) {
7811 status = cli_session_setup_creds(c, torture_creds);
7812 if (!NT_STATUS_IS_OK(status)) {
7813 d_printf("(%s) cli_session_setup_creds failed: %s\n",
7814 __location__, nt_errstr(status));
7818 d_printf("\r%d ", (int)cli_state_get_uid(c));
7820 status = cli_ulogoff(c);
7821 if (!NT_STATUS_IS_OK(status)) {
7822 d_printf("(%s) cli_ulogoff failed: %s\n",
7823 __location__, nt_errstr(status));
7831 static bool subst_test(const char *str, const char *user, const char *domain,
7832 uid_t uid, gid_t gid, const char *expected)
7837 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7839 if (strcmp(subst, expected) != 0) {
7840 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7841 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
7850 static void chain1_open_completion(struct tevent_req *req)
7854 status = cli_openx_recv(req, &fnum);
7857 d_printf("cli_openx_recv returned %s: %d\n",
7859 NT_STATUS_IS_OK(status) ? fnum : -1);
7862 static void chain1_write_completion(struct tevent_req *req)
7866 status = cli_write_andx_recv(req, &written);
7869 d_printf("cli_write_andx_recv returned %s: %d\n",
7871 NT_STATUS_IS_OK(status) ? (int)written : -1);
7874 static void chain1_close_completion(struct tevent_req *req)
7877 bool *done = (bool *)tevent_req_callback_data_void(req);
7879 status = cli_close_recv(req);
7884 d_printf("cli_close returned %s\n", nt_errstr(status));
7887 static bool run_chain1(int dummy)
7889 struct cli_state *cli1;
7890 struct tevent_context *evt = samba_tevent_context_init(NULL);
7891 struct tevent_req *reqs[3], *smbreqs[3];
7893 const char *str = "foobar";
7896 printf("starting chain1 test\n");
7897 if (!torture_open_connection(&cli1, 0)) {
7901 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7903 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
7904 O_CREAT|O_RDWR, 0, &smbreqs[0]);
7905 if (reqs[0] == NULL) return false;
7906 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
7909 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
7910 (const uint8_t *)str, 0, strlen(str)+1,
7911 smbreqs, 1, &smbreqs[1]);
7912 if (reqs[1] == NULL) return false;
7913 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
7915 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
7916 if (reqs[2] == NULL) return false;
7917 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
7919 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7920 if (!NT_STATUS_IS_OK(status)) {
7925 tevent_loop_once(evt);
7928 torture_close_connection(cli1);
7932 static void chain2_sesssetup_completion(struct tevent_req *req)
7935 status = cli_session_setup_guest_recv(req);
7936 d_printf("sesssetup returned %s\n", nt_errstr(status));
7939 static void chain2_tcon_completion(struct tevent_req *req)
7941 bool *done = (bool *)tevent_req_callback_data_void(req);
7943 status = cli_tcon_andx_recv(req);
7944 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
7948 static bool run_chain2(int dummy)
7950 struct cli_state *cli1;
7951 struct tevent_context *evt = samba_tevent_context_init(NULL);
7952 struct tevent_req *reqs[2], *smbreqs[2];
7956 printf("starting chain2 test\n");
7957 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
7958 port_to_use, SMB_SIGNING_DEFAULT, 0);
7959 if (!NT_STATUS_IS_OK(status)) {
7963 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7965 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
7967 if (reqs[0] == NULL) return false;
7968 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
7970 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
7971 "?????", NULL, 0, &smbreqs[1]);
7972 if (reqs[1] == NULL) return false;
7973 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
7975 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7976 if (!NT_STATUS_IS_OK(status)) {
7981 tevent_loop_once(evt);
7984 torture_close_connection(cli1);
7989 struct torture_createdel_state {
7990 struct tevent_context *ev;
7991 struct cli_state *cli;
7994 static void torture_createdel_created(struct tevent_req *subreq);
7995 static void torture_createdel_closed(struct tevent_req *subreq);
7997 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
7998 struct tevent_context *ev,
7999 struct cli_state *cli,
8002 struct tevent_req *req, *subreq;
8003 struct torture_createdel_state *state;
8005 req = tevent_req_create(mem_ctx, &state,
8006 struct torture_createdel_state);
8013 subreq = cli_ntcreate_send(
8014 state, ev, cli, name, 0,
8015 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8016 FILE_ATTRIBUTE_NORMAL,
8017 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8018 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
8020 if (tevent_req_nomem(subreq, req)) {
8021 return tevent_req_post(req, ev);
8023 tevent_req_set_callback(subreq, torture_createdel_created, req);
8027 static void torture_createdel_created(struct tevent_req *subreq)
8029 struct tevent_req *req = tevent_req_callback_data(
8030 subreq, struct tevent_req);
8031 struct torture_createdel_state *state = tevent_req_data(
8032 req, struct torture_createdel_state);
8036 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8037 TALLOC_FREE(subreq);
8038 if (tevent_req_nterror(req, status)) {
8039 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8040 nt_errstr(status)));
8044 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8045 if (tevent_req_nomem(subreq, req)) {
8048 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8051 static void torture_createdel_closed(struct tevent_req *subreq)
8053 struct tevent_req *req = tevent_req_callback_data(
8054 subreq, struct tevent_req);
8057 status = cli_close_recv(subreq);
8058 if (tevent_req_nterror(req, status)) {
8059 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8062 tevent_req_done(req);
8065 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8067 return tevent_req_simple_recv_ntstatus(req);
8070 struct torture_createdels_state {
8071 struct tevent_context *ev;
8072 struct cli_state *cli;
8073 const char *base_name;
8077 struct tevent_req **reqs;
8080 static void torture_createdels_done(struct tevent_req *subreq);
8082 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8083 struct tevent_context *ev,
8084 struct cli_state *cli,
8085 const char *base_name,
8089 struct tevent_req *req;
8090 struct torture_createdels_state *state;
8093 req = tevent_req_create(mem_ctx, &state,
8094 struct torture_createdels_state);
8100 state->base_name = talloc_strdup(state, base_name);
8101 if (tevent_req_nomem(state->base_name, req)) {
8102 return tevent_req_post(req, ev);
8104 state->num_files = MAX(num_parallel, num_files);
8106 state->received = 0;
8108 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8109 if (tevent_req_nomem(state->reqs, req)) {
8110 return tevent_req_post(req, ev);
8113 for (i=0; i<num_parallel; i++) {
8116 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8118 if (tevent_req_nomem(name, req)) {
8119 return tevent_req_post(req, ev);
8121 state->reqs[i] = torture_createdel_send(
8122 state->reqs, state->ev, state->cli, name);
8123 if (tevent_req_nomem(state->reqs[i], req)) {
8124 return tevent_req_post(req, ev);
8126 name = talloc_move(state->reqs[i], &name);
8127 tevent_req_set_callback(state->reqs[i],
8128 torture_createdels_done, req);
8134 static void torture_createdels_done(struct tevent_req *subreq)
8136 struct tevent_req *req = tevent_req_callback_data(
8137 subreq, struct tevent_req);
8138 struct torture_createdels_state *state = tevent_req_data(
8139 req, struct torture_createdels_state);
8140 size_t num_parallel = talloc_array_length(state->reqs);
8145 status = torture_createdel_recv(subreq);
8146 if (!NT_STATUS_IS_OK(status)){
8147 DEBUG(10, ("torture_createdel_recv returned %s\n",
8148 nt_errstr(status)));
8149 TALLOC_FREE(subreq);
8150 tevent_req_nterror(req, status);
8154 for (i=0; i<num_parallel; i++) {
8155 if (subreq == state->reqs[i]) {
8159 if (i == num_parallel) {
8160 DEBUG(10, ("received something we did not send\n"));
8161 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8164 TALLOC_FREE(state->reqs[i]);
8166 if (state->sent >= state->num_files) {
8167 tevent_req_done(req);
8171 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8173 if (tevent_req_nomem(name, req)) {
8176 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8178 if (tevent_req_nomem(state->reqs[i], req)) {
8181 name = talloc_move(state->reqs[i], &name);
8182 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8186 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8188 return tevent_req_simple_recv_ntstatus(req);
8191 struct swallow_notify_state {
8192 struct tevent_context *ev;
8193 struct cli_state *cli;
8195 uint32_t completion_filter;
8197 bool (*fn)(uint32_t action, const char *name, void *priv);
8201 static void swallow_notify_done(struct tevent_req *subreq);
8203 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8204 struct tevent_context *ev,
8205 struct cli_state *cli,
8207 uint32_t completion_filter,
8209 bool (*fn)(uint32_t action,
8214 struct tevent_req *req, *subreq;
8215 struct swallow_notify_state *state;
8217 req = tevent_req_create(mem_ctx, &state,
8218 struct swallow_notify_state);
8225 state->completion_filter = completion_filter;
8226 state->recursive = recursive;
8230 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8231 0xffff, state->completion_filter,
8233 if (tevent_req_nomem(subreq, req)) {
8234 return tevent_req_post(req, ev);
8236 tevent_req_set_callback(subreq, swallow_notify_done, req);
8240 static void swallow_notify_done(struct tevent_req *subreq)
8242 struct tevent_req *req = tevent_req_callback_data(
8243 subreq, struct tevent_req);
8244 struct swallow_notify_state *state = tevent_req_data(
8245 req, struct swallow_notify_state);
8247 uint32_t i, num_changes;
8248 struct notify_change *changes;
8250 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8251 TALLOC_FREE(subreq);
8252 if (!NT_STATUS_IS_OK(status)) {
8253 DEBUG(10, ("cli_notify_recv returned %s\n",
8254 nt_errstr(status)));
8255 tevent_req_nterror(req, status);
8259 for (i=0; i<num_changes; i++) {
8260 state->fn(changes[i].action, changes[i].name, state->priv);
8262 TALLOC_FREE(changes);
8264 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8265 0xffff, state->completion_filter,
8267 if (tevent_req_nomem(subreq, req)) {
8270 tevent_req_set_callback(subreq, swallow_notify_done, req);
8273 static bool print_notifies(uint32_t action, const char *name, void *priv)
8275 if (DEBUGLEVEL > 5) {
8276 d_printf("%d %s\n", (int)action, name);
8281 static void notify_bench_done(struct tevent_req *req)
8283 int *num_finished = (int *)tevent_req_callback_data_void(req);
8287 static bool run_notify_bench(int dummy)
8289 const char *dname = "\\notify-bench";
8290 struct tevent_context *ev;
8293 struct tevent_req *req1;
8294 struct tevent_req *req2 = NULL;
8295 int i, num_unc_names;
8296 int num_finished = 0;
8298 printf("starting notify-bench test\n");
8300 if (use_multishare_conn) {
8302 unc_list = file_lines_load(multishare_conn_fname,
8303 &num_unc_names, 0, NULL);
8304 if (!unc_list || num_unc_names <= 0) {
8305 d_printf("Failed to load unc names list from '%s'\n",
8306 multishare_conn_fname);
8309 TALLOC_FREE(unc_list);
8314 ev = samba_tevent_context_init(talloc_tos());
8316 d_printf("tevent_context_init failed\n");
8320 for (i=0; i<num_unc_names; i++) {
8321 struct cli_state *cli;
8324 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8326 if (base_fname == NULL) {
8330 if (!torture_open_connection(&cli, i)) {
8334 status = cli_ntcreate(cli, dname, 0,
8335 MAXIMUM_ALLOWED_ACCESS,
8336 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8338 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8341 if (!NT_STATUS_IS_OK(status)) {
8342 d_printf("Could not create %s: %s\n", dname,
8347 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8348 FILE_NOTIFY_CHANGE_FILE_NAME |
8349 FILE_NOTIFY_CHANGE_DIR_NAME |
8350 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8351 FILE_NOTIFY_CHANGE_LAST_WRITE,
8352 false, print_notifies, NULL);
8354 d_printf("Could not create notify request\n");
8358 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8359 base_fname, 10, torture_numops);
8361 d_printf("Could not create createdels request\n");
8364 TALLOC_FREE(base_fname);
8366 tevent_req_set_callback(req2, notify_bench_done,
8370 while (num_finished < num_unc_names) {
8372 ret = tevent_loop_once(ev);
8374 d_printf("tevent_loop_once failed\n");
8379 if (!tevent_req_poll(req2, ev)) {
8380 d_printf("tevent_req_poll failed\n");
8383 status = torture_createdels_recv(req2);
8384 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8389 static bool run_mangle1(int dummy)
8391 struct cli_state *cli;
8392 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8396 time_t change_time, access_time, write_time;
8400 printf("starting mangle1 test\n");
8401 if (!torture_open_connection(&cli, 0)) {
8405 smbXcli_conn_set_sockopt(cli->conn, sockops);
8407 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8408 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8410 if (!NT_STATUS_IS_OK(status)) {
8411 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8414 cli_close(cli, fnum);
8416 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8417 if (!NT_STATUS_IS_OK(status)) {
8418 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8422 d_printf("alt_name: %s\n", alt_name);
8424 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8425 if (!NT_STATUS_IS_OK(status)) {
8426 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8430 cli_close(cli, fnum);
8432 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8433 &write_time, &size, &mode);
8434 if (!NT_STATUS_IS_OK(status)) {
8435 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8443 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8444 struct file_info *f,
8448 if (f->short_name == NULL) {
8449 return NT_STATUS_OK;
8452 if (strlen(f->short_name) == 0) {
8453 return NT_STATUS_OK;
8456 printf("unexpected shortname: %s\n", f->short_name);
8458 return NT_STATUS_OBJECT_NAME_INVALID;
8461 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8462 struct file_info *f,
8468 printf("name: %s\n", f->name);
8469 fstrcpy(name, f->name);
8470 return NT_STATUS_OK;
8473 static bool run_mangle_illegal(int dummy)
8475 struct cli_state *cli = NULL;
8476 struct cli_state *cli_posix = NULL;
8477 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8478 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8479 char *mangled_path = NULL;
8485 printf("starting mangle-illegal test\n");
8487 if (!torture_open_connection(&cli, 0)) {
8491 smbXcli_conn_set_sockopt(cli->conn, sockops);
8493 if (!torture_open_connection(&cli_posix, 0)) {
8497 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8499 status = torture_setup_unix_extensions(cli_posix);
8500 if (!NT_STATUS_IS_OK(status)) {
8504 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8505 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8506 if (!NT_STATUS_IS_OK(status)) {
8507 printf("mkdir1 failed : %s\n", nt_errstr(status));
8512 * Create a file with illegal NTFS characters and test that we
8513 * get a usable mangled name
8516 cli_setatr(cli_posix, illegal_fname, 0, 0);
8517 cli_posix_unlink(cli_posix, illegal_fname);
8519 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8521 if (!NT_STATUS_IS_OK(status)) {
8522 printf("POSIX create of %s failed (%s)\n",
8523 illegal_fname, nt_errstr(status));
8527 status = cli_close(cli_posix, fnum);
8528 if (!NT_STATUS_IS_OK(status)) {
8529 printf("close failed (%s)\n", nt_errstr(status));
8533 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8534 if (!NT_STATUS_IS_OK(status)) {
8535 d_printf("cli_list failed: %s\n", nt_errstr(status));
8539 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8540 if (mangled_path == NULL) {
8544 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8545 if (!NT_STATUS_IS_OK(status)) {
8546 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8547 TALLOC_FREE(mangled_path);
8550 TALLOC_FREE(mangled_path);
8551 cli_close(cli, fnum);
8553 cli_setatr(cli_posix, illegal_fname, 0, 0);
8554 cli_posix_unlink(cli_posix, illegal_fname);
8557 * Create a file with a long name and check that we got *no* short name.
8560 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8561 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8563 if (!NT_STATUS_IS_OK(status)) {
8564 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8567 cli_close(cli, fnum);
8569 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8570 if (!NT_STATUS_IS_OK(status)) {
8571 d_printf("cli_list failed\n");
8575 cli_unlink(cli, fname, 0);
8576 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8578 if (!torture_close_connection(cli_posix)) {
8582 if (!torture_close_connection(cli)) {
8589 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8591 size_t *to_pull = (size_t *)priv;
8592 size_t thistime = *to_pull;
8594 thistime = MIN(thistime, n);
8595 if (thistime == 0) {
8599 memset(buf, 0, thistime);
8600 *to_pull -= thistime;
8604 static bool run_windows_write(int dummy)
8606 struct cli_state *cli1;
8610 const char *fname = "\\writetest.txt";
8611 struct timeval start_time;
8616 printf("starting windows_write test\n");
8617 if (!torture_open_connection(&cli1, 0)) {
8621 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8622 if (!NT_STATUS_IS_OK(status)) {
8623 printf("open failed (%s)\n", nt_errstr(status));
8627 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8629 start_time = timeval_current();
8631 for (i=0; i<torture_numops; i++) {
8633 off_t start = i * torture_blocksize;
8634 size_t to_pull = torture_blocksize - 1;
8636 status = cli_writeall(cli1, fnum, 0, &c,
8637 start + torture_blocksize - 1, 1, NULL);
8638 if (!NT_STATUS_IS_OK(status)) {
8639 printf("cli_write failed: %s\n", nt_errstr(status));
8643 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8644 null_source, &to_pull);
8645 if (!NT_STATUS_IS_OK(status)) {
8646 printf("cli_push returned: %s\n", nt_errstr(status));
8651 seconds = timeval_elapsed(&start_time);
8652 kbytes = (double)torture_blocksize * torture_numops;
8655 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8656 (double)seconds, (int)(kbytes/seconds));
8660 cli_close(cli1, fnum);
8661 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8662 torture_close_connection(cli1);
8666 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8668 size_t max_pdu = 0x1FFFF;
8670 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8674 if (smb1cli_conn_signing_is_active(cli->conn)) {
8678 if (smb1cli_conn_encryption_on(cli->conn)) {
8679 max_pdu = CLI_BUFFER_SIZE;
8682 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8683 len_requested &= 0xFFFF;
8686 return MIN(len_requested,
8687 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8690 static bool check_read_call(struct cli_state *cli,
8693 size_t len_requested)
8696 struct tevent_req *subreq = NULL;
8697 ssize_t len_read = 0;
8698 size_t len_expected = 0;
8699 struct tevent_context *ev = NULL;
8701 ev = samba_tevent_context_init(talloc_tos());
8706 subreq = cli_read_andx_send(talloc_tos(),
8713 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8717 status = cli_read_andx_recv(subreq, &len_read, &buf);
8718 if (!NT_STATUS_IS_OK(status)) {
8719 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8723 TALLOC_FREE(subreq);
8726 len_expected = calc_expected_return(cli, len_requested);
8728 if (len_expected > 0x10000 && len_read == 0x10000) {
8729 /* Windows servers only return a max of 0x10000,
8730 doesn't matter if you set CAP_LARGE_READX in
8731 the client sessionsetupX call or not. */
8732 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8733 (unsigned int)len_requested);
8734 } else if (len_read != len_expected) {
8735 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8736 (unsigned int)len_requested,
8737 (unsigned int)len_read,
8738 (unsigned int)len_expected);
8741 d_printf("Correct read reply.\n");
8747 /* Test large readX variants. */
8748 static bool large_readx_tests(struct cli_state *cli,
8752 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8753 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8756 /* A read of 0x10000 should return 0x10000 bytes. */
8757 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8760 /* A read of 0x10000 should return 0x10001 bytes. */
8761 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8764 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8765 the requested number of bytes. */
8766 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8769 /* A read of 1MB should return 1MB bytes (on Samba). */
8770 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
8774 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
8777 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
8780 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
8786 static bool run_large_readx(int dummy)
8788 uint8_t *buf = NULL;
8789 struct cli_state *cli1 = NULL;
8790 struct cli_state *cli2 = NULL;
8791 bool correct = false;
8792 const char *fname = "\\large_readx.dat";
8794 uint16_t fnum1 = UINT16_MAX;
8795 uint32_t normal_caps = 0;
8796 size_t file_size = 20*1024*1024;
8797 TALLOC_CTX *frame = talloc_stackframe();
8801 enum smb_signing_setting signing_setting;
8802 enum protocol_types protocol;
8806 .signing_setting = SMB_SIGNING_IF_REQUIRED,
8807 .protocol = PROTOCOL_NT1,
8809 .name = "NT1 - SIGNING_REQUIRED",
8810 .signing_setting = SMB_SIGNING_REQUIRED,
8811 .protocol = PROTOCOL_NT1,
8815 printf("starting large_readx test\n");
8817 if (!torture_open_connection(&cli1, 0)) {
8821 normal_caps = smb1cli_conn_capabilities(cli1->conn);
8823 if (!(normal_caps & CAP_LARGE_READX)) {
8824 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8825 (unsigned int)normal_caps);
8829 /* Create a file of size 4MB. */
8830 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
8831 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8832 0, 0, &fnum1, NULL);
8834 if (!NT_STATUS_IS_OK(status)) {
8835 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8839 /* Write file_size bytes. */
8840 buf = talloc_zero_array(frame, uint8_t, file_size);
8845 status = cli_writeall(cli1,
8852 if (!NT_STATUS_IS_OK(status)) {
8853 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
8857 status = cli_close(cli1, fnum1);
8858 if (!NT_STATUS_IS_OK(status)) {
8859 d_printf("cli_close failed: %s\n", nt_errstr(status));
8865 for (i=0; i < ARRAY_SIZE(runs); i++) {
8866 enum smb_signing_setting saved_signing_setting = signing_state;
8867 uint16_t fnum2 = -1;
8870 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
8872 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
8876 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
8878 signing_state = runs[i].signing_setting;
8879 cli2 = open_nbt_connection();
8880 signing_state = saved_signing_setting;
8885 status = smbXcli_negprot(cli2->conn,
8889 if (!NT_STATUS_IS_OK(status)) {
8893 status = cli_session_setup_creds(cli2, torture_creds);
8894 if (!NT_STATUS_IS_OK(status)) {
8898 status = cli_tree_connect(cli2,
8902 if (!NT_STATUS_IS_OK(status)) {
8906 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
8908 normal_caps = smb1cli_conn_capabilities(cli2->conn);
8910 if (!(normal_caps & CAP_LARGE_READX)) {
8911 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8912 (unsigned int)normal_caps);
8917 if (force_cli_encryption(cli2, share) == false) {
8920 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
8921 uint16_t major, minor;
8922 uint32_t caplow, caphigh;
8924 status = cli_unix_extensions_version(cli2,
8927 if (!NT_STATUS_IS_OK(status)) {
8932 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
8933 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
8934 0, 0, &fnum2, NULL);
8935 if (!NT_STATUS_IS_OK(status)) {
8936 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
8940 /* All reads must return less than file_size bytes. */
8941 if (!large_readx_tests(cli2, fnum2, buf)) {
8945 status = cli_close(cli2, fnum2);
8946 if (!NT_STATUS_IS_OK(status)) {
8947 d_printf("cli_close failed: %s\n", nt_errstr(status));
8952 if (!torture_close_connection(cli2)) {
8959 printf("Success on large_readx test\n");
8964 if (!torture_close_connection(cli2)) {
8970 if (fnum1 != UINT16_MAX) {
8971 status = cli_close(cli1, fnum1);
8972 if (!NT_STATUS_IS_OK(status)) {
8973 d_printf("cli_close failed: %s\n", nt_errstr(status));
8978 status = cli_unlink(cli1, fname,
8979 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8980 if (!NT_STATUS_IS_OK(status)) {
8981 printf("unlink failed (%s)\n", nt_errstr(status));
8984 if (!torture_close_connection(cli1)) {
8991 printf("finished large_readx test\n");
8995 static bool run_cli_echo(int dummy)
8997 struct cli_state *cli;
9000 printf("starting cli_echo test\n");
9001 if (!torture_open_connection(&cli, 0)) {
9004 smbXcli_conn_set_sockopt(cli->conn, sockops);
9006 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9008 d_printf("cli_echo returned %s\n", nt_errstr(status));
9010 torture_close_connection(cli);
9011 return NT_STATUS_IS_OK(status);
9014 static bool run_uid_regression_test(int dummy)
9016 static struct cli_state *cli;
9019 bool correct = True;
9022 printf("starting uid regression test\n");
9024 if (!torture_open_connection(&cli, 0)) {
9028 smbXcli_conn_set_sockopt(cli->conn, sockops);
9030 /* Ok - now save then logoff our current user. */
9031 old_vuid = cli_state_get_uid(cli);
9033 status = cli_ulogoff(cli);
9034 if (!NT_STATUS_IS_OK(status)) {
9035 d_printf("(%s) cli_ulogoff failed: %s\n",
9036 __location__, nt_errstr(status));
9041 cli_state_set_uid(cli, old_vuid);
9043 /* Try an operation. */
9044 status = cli_mkdir(cli, "\\uid_reg_test");
9045 if (NT_STATUS_IS_OK(status)) {
9046 d_printf("(%s) cli_mkdir succeeded\n",
9051 /* Should be bad uid. */
9052 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9053 NT_STATUS_USER_SESSION_DELETED)) {
9059 old_cnum = cli_state_get_tid(cli);
9061 /* Now try a SMBtdis with the invald vuid set to zero. */
9062 cli_state_set_uid(cli, 0);
9064 /* This should succeed. */
9065 status = cli_tdis(cli);
9067 if (NT_STATUS_IS_OK(status)) {
9068 d_printf("First tdis with invalid vuid should succeed.\n");
9070 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9075 cli_state_set_uid(cli, old_vuid);
9076 cli_state_set_tid(cli, old_cnum);
9078 /* This should fail. */
9079 status = cli_tdis(cli);
9080 if (NT_STATUS_IS_OK(status)) {
9081 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9085 /* Should be bad tid. */
9086 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9087 NT_STATUS_NETWORK_NAME_DELETED)) {
9093 cli_rmdir(cli, "\\uid_reg_test");
9102 static const char *illegal_chars = "*\\/?<>|\":";
9103 static char force_shortname_chars[] = " +,.[];=\177";
9105 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9106 const char *mask, void *state)
9108 struct cli_state *pcli = (struct cli_state *)state;
9110 NTSTATUS status = NT_STATUS_OK;
9112 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9114 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9115 return NT_STATUS_OK;
9117 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9118 status = cli_rmdir(pcli, fname);
9119 if (!NT_STATUS_IS_OK(status)) {
9120 printf("del_fn: failed to rmdir %s\n,", fname );
9123 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9124 if (!NT_STATUS_IS_OK(status)) {
9125 printf("del_fn: failed to unlink %s\n,", fname );
9137 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9138 const char *name, void *state)
9140 struct sn_state *s = (struct sn_state *)state;
9144 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9145 i, finfo->name, finfo->short_name);
9148 if (strchr(force_shortname_chars, i)) {
9149 if (!finfo->short_name) {
9150 /* Shortname not created when it should be. */
9151 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9152 __location__, finfo->name, i);
9155 } else if (finfo->short_name){
9156 /* Shortname created when it should not be. */
9157 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9158 __location__, finfo->short_name, finfo->name);
9162 return NT_STATUS_OK;
9165 static bool run_shortname_test(int dummy)
9167 static struct cli_state *cli;
9168 bool correct = True;
9174 printf("starting shortname test\n");
9176 if (!torture_open_connection(&cli, 0)) {
9180 smbXcli_conn_set_sockopt(cli->conn, sockops);
9182 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9183 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9184 cli_rmdir(cli, "\\shortname");
9186 status = cli_mkdir(cli, "\\shortname");
9187 if (!NT_STATUS_IS_OK(status)) {
9188 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9189 __location__, nt_errstr(status));
9194 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9198 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9205 for (i = 32; i < 128; i++) {
9206 uint16_t fnum = (uint16_t)-1;
9210 if (strchr(illegal_chars, i)) {
9215 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9216 FILE_SHARE_READ|FILE_SHARE_WRITE,
9217 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9218 if (!NT_STATUS_IS_OK(status)) {
9219 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9220 __location__, fname, nt_errstr(status));
9224 cli_close(cli, fnum);
9227 status = cli_list(cli, "\\shortname\\test*.*", 0,
9228 shortname_list_fn, &s);
9229 if (s.matched != 1) {
9230 d_printf("(%s) failed to list %s: %s\n",
9231 __location__, fname, nt_errstr(status));
9236 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9237 if (!NT_STATUS_IS_OK(status)) {
9238 d_printf("(%s) failed to delete %s: %s\n",
9239 __location__, fname, nt_errstr(status));
9252 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9253 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9254 cli_rmdir(cli, "\\shortname");
9255 torture_close_connection(cli);
9259 static void pagedsearch_cb(struct tevent_req *req)
9262 struct tldap_message *msg;
9265 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9266 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9267 d_printf("tldap_search_paged_recv failed: %s\n",
9268 tldap_rc2string(rc));
9271 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9275 if (!tldap_entry_dn(msg, &dn)) {
9276 d_printf("tldap_entry_dn failed\n");
9279 d_printf("%s\n", dn);
9283 static bool run_tldap(int dummy)
9285 struct tldap_context *ld;
9289 struct sockaddr_storage addr;
9290 struct tevent_context *ev;
9291 struct tevent_req *req;
9295 if (!resolve_name(host, &addr, 0, false)) {
9296 d_printf("could not find host %s\n", host);
9299 status = open_socket_out(&addr, 389, 9999, &fd);
9300 if (!NT_STATUS_IS_OK(status)) {
9301 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9305 ld = tldap_context_create(talloc_tos(), fd);
9308 d_printf("tldap_context_create failed\n");
9312 rc = tldap_fetch_rootdse(ld);
9313 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9314 d_printf("tldap_fetch_rootdse failed: %s\n",
9315 tldap_errstr(talloc_tos(), ld, rc));
9319 basedn = tldap_talloc_single_attribute(
9320 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9321 if (basedn == NULL) {
9322 d_printf("no defaultNamingContext\n");
9325 d_printf("defaultNamingContext: %s\n", basedn);
9327 ev = samba_tevent_context_init(talloc_tos());
9329 d_printf("tevent_context_init failed\n");
9333 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9334 TLDAP_SCOPE_SUB, "(objectclass=*)",
9336 NULL, 0, NULL, 0, 0, 0, 0, 5);
9338 d_printf("tldap_search_paged_send failed\n");
9341 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9343 tevent_req_poll(req, ev);
9347 /* test search filters against rootDSE */
9348 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9349 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9351 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9352 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9353 talloc_tos(), NULL);
9354 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9355 d_printf("tldap_search with complex filter failed: %s\n",
9356 tldap_errstr(talloc_tos(), ld, rc));
9364 /* Torture test to ensure no regression of :
9365 https://bugzilla.samba.org/show_bug.cgi?id=7084
9368 static bool run_dir_createtime(int dummy)
9370 struct cli_state *cli;
9371 const char *dname = "\\testdir";
9372 const char *fname = "\\testdir\\testfile";
9374 struct timespec create_time;
9375 struct timespec create_time1;
9379 if (!torture_open_connection(&cli, 0)) {
9383 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9384 cli_rmdir(cli, dname);
9386 status = cli_mkdir(cli, dname);
9387 if (!NT_STATUS_IS_OK(status)) {
9388 printf("mkdir failed: %s\n", nt_errstr(status));
9392 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9394 if (!NT_STATUS_IS_OK(status)) {
9395 printf("cli_qpathinfo2 returned %s\n",
9400 /* Sleep 3 seconds, then create a file. */
9403 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9405 if (!NT_STATUS_IS_OK(status)) {
9406 printf("cli_openx failed: %s\n", nt_errstr(status));
9410 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9412 if (!NT_STATUS_IS_OK(status)) {
9413 printf("cli_qpathinfo2 (2) returned %s\n",
9418 if (timespec_compare(&create_time1, &create_time)) {
9419 printf("run_dir_createtime: create time was updated (error)\n");
9421 printf("run_dir_createtime: create time was not updated (correct)\n");
9427 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9428 cli_rmdir(cli, dname);
9429 if (!torture_close_connection(cli)) {
9436 static bool run_streamerror(int dummy)
9438 struct cli_state *cli;
9439 const char *dname = "\\testdir";
9440 const char *streamname =
9441 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9443 time_t change_time, access_time, write_time;
9445 uint16_t mode, fnum;
9448 if (!torture_open_connection(&cli, 0)) {
9452 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9453 cli_rmdir(cli, dname);
9455 status = cli_mkdir(cli, dname);
9456 if (!NT_STATUS_IS_OK(status)) {
9457 printf("mkdir failed: %s\n", nt_errstr(status));
9461 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9462 &write_time, &size, &mode);
9463 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9464 printf("pathinfo returned %s, expected "
9465 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9470 status = cli_ntcreate(cli, streamname, 0x16,
9471 FILE_READ_DATA|FILE_READ_EA|
9472 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9473 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9474 FILE_OPEN, 0, 0, &fnum, NULL);
9476 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9477 printf("ntcreate returned %s, expected "
9478 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9484 cli_rmdir(cli, dname);
9488 struct pidtest_state {
9494 static void pid_echo_done(struct tevent_req *subreq);
9496 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9497 struct tevent_context *ev,
9498 struct cli_state *cli)
9500 struct tevent_req *req, *subreq;
9501 struct pidtest_state *state;
9503 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9508 SSVAL(state->vwv, 0, 1);
9509 state->data = data_blob_const("hello", 5);
9511 subreq = smb1cli_req_send(state,
9516 0, 0, /* *_flags2 */
9518 0xDEADBEEF, /* pid */
9521 ARRAY_SIZE(state->vwv), state->vwv,
9522 state->data.length, state->data.data);
9524 if (tevent_req_nomem(subreq, req)) {
9525 return tevent_req_post(req, ev);
9527 tevent_req_set_callback(subreq, pid_echo_done, req);
9531 static void pid_echo_done(struct tevent_req *subreq)
9533 struct tevent_req *req = tevent_req_callback_data(
9534 subreq, struct tevent_req);
9535 struct pidtest_state *state = tevent_req_data(
9536 req, struct pidtest_state);
9539 uint8_t *bytes = NULL;
9540 struct iovec *recv_iov = NULL;
9541 uint8_t *phdr = NULL;
9542 uint16_t pidlow = 0;
9543 uint16_t pidhigh = 0;
9544 struct smb1cli_req_expected_response expected[] = {
9546 .status = NT_STATUS_OK,
9551 status = smb1cli_req_recv(subreq, state,
9556 NULL, /* pvwv_offset */
9559 NULL, /* pbytes_offset */
9561 expected, ARRAY_SIZE(expected));
9563 TALLOC_FREE(subreq);
9565 if (!NT_STATUS_IS_OK(status)) {
9566 tevent_req_nterror(req, status);
9570 if (num_bytes != state->data.length) {
9571 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9575 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9576 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9580 /* Check pid low/high == DEADBEEF */
9581 pidlow = SVAL(phdr, HDR_PID);
9582 if (pidlow != 0xBEEF){
9583 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9584 (unsigned int)pidlow);
9585 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9588 pidhigh = SVAL(phdr, HDR_PIDHIGH);
9589 if (pidhigh != 0xDEAD){
9590 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9591 (unsigned int)pidhigh);
9592 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9596 tevent_req_done(req);
9599 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9601 return tevent_req_simple_recv_ntstatus(req);
9604 static bool run_pidhigh(int dummy)
9606 bool success = false;
9607 struct cli_state *cli = NULL;
9609 struct tevent_context *ev = NULL;
9610 struct tevent_req *req = NULL;
9611 TALLOC_CTX *frame = talloc_stackframe();
9613 printf("starting pid high test\n");
9614 if (!torture_open_connection(&cli, 0)) {
9617 smbXcli_conn_set_sockopt(cli->conn, sockops);
9619 ev = samba_tevent_context_init(frame);
9624 req = pid_echo_send(frame, ev, cli);
9629 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
9633 status = pid_echo_recv(req);
9634 if (NT_STATUS_IS_OK(status)) {
9635 printf("pid high test ok\n");
9642 torture_close_connection(cli);
9647 Test Windows open on a bad POSIX symlink.
9649 static bool run_symlink_open_test(int dummy)
9651 static struct cli_state *cli;
9652 const char *fname = "non_existant_file";
9653 const char *sname = "dangling_symlink";
9654 uint16_t fnum = (uint16_t)-1;
9655 bool correct = false;
9657 TALLOC_CTX *frame = NULL;
9659 frame = talloc_stackframe();
9661 printf("Starting Windows bad symlink open test\n");
9663 if (!torture_open_connection(&cli, 0)) {
9668 smbXcli_conn_set_sockopt(cli->conn, sockops);
9670 status = torture_setup_unix_extensions(cli);
9671 if (!NT_STATUS_IS_OK(status)) {
9676 /* Ensure nothing exists. */
9677 cli_setatr(cli, fname, 0, 0);
9678 cli_posix_unlink(cli, fname);
9679 cli_setatr(cli, sname, 0, 0);
9680 cli_posix_unlink(cli, sname);
9682 /* Create a symlink pointing nowhere. */
9683 status = cli_posix_symlink(cli, fname, sname);
9684 if (!NT_STATUS_IS_OK(status)) {
9685 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
9692 /* Now ensure that a Windows open doesn't hang. */
9693 status = cli_ntcreate(cli,
9696 FILE_READ_DATA|FILE_WRITE_DATA,
9698 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
9706 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
9707 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
9708 * we use O_NOFOLLOW on the server or not.
9710 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
9711 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
9715 printf("cli_ntcreate of %s returned %s - should return"
9716 " either (%s) or (%s)\n",
9719 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
9720 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
9728 if (fnum != (uint16_t)-1) {
9729 cli_close(cli, fnum);
9730 fnum = (uint16_t)-1;
9733 cli_setatr(cli, sname, 0, 0);
9734 cli_posix_unlink(cli, sname);
9735 cli_setatr(cli, fname, 0, 0);
9736 cli_posix_unlink(cli, fname);
9738 if (!torture_close_connection(cli)) {
9746 static bool run_local_substitute(int dummy)
9750 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
9751 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
9752 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
9753 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
9754 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
9755 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
9756 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
9757 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
9759 /* Different captialization rules in sub_basic... */
9761 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
9767 static bool run_local_base64(int dummy)
9772 for (i=1; i<2000; i++) {
9773 DATA_BLOB blob1, blob2;
9776 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
9778 generate_random_buffer(blob1.data, blob1.length);
9780 b64 = base64_encode_data_blob(talloc_tos(), blob1);
9782 d_fprintf(stderr, "base64_encode_data_blob failed "
9783 "for %d bytes\n", i);
9786 blob2 = base64_decode_data_blob(b64);
9789 if (data_blob_cmp(&blob1, &blob2)) {
9790 d_fprintf(stderr, "data_blob_cmp failed for %d "
9794 TALLOC_FREE(blob1.data);
9795 data_blob_free(&blob2);
9800 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
9805 static bool run_local_gencache(int dummy)
9811 struct memcache *mem;
9814 mem = memcache_init(NULL, 0);
9816 d_printf("%s: memcache_init failed\n", __location__);
9819 memcache_set_global(mem);
9821 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
9822 d_printf("%s: gencache_set() failed\n", __location__);
9826 if (!gencache_get("foo", NULL, NULL, NULL)) {
9827 d_printf("%s: gencache_get() failed\n", __location__);
9831 for (i=0; i<1000000; i++) {
9832 gencache_parse("foo", parse_fn, NULL);
9835 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9836 d_printf("%s: gencache_get() failed\n", __location__);
9841 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9842 d_printf("%s: gencache_get() failed\n", __location__);
9846 if (strcmp(val, "bar") != 0) {
9847 d_printf("%s: gencache_get() returned %s, expected %s\n",
9848 __location__, val, "bar");
9855 if (!gencache_del("foo")) {
9856 d_printf("%s: gencache_del() failed\n", __location__);
9859 if (gencache_del("foo")) {
9860 d_printf("%s: second gencache_del() succeeded\n",
9865 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
9866 d_printf("%s: gencache_get() on deleted entry "
9867 "succeeded\n", __location__);
9871 blob = data_blob_string_const_null("bar");
9872 tm = time(NULL) + 60;
9874 if (!gencache_set_data_blob("foo", &blob, tm)) {
9875 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
9879 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
9880 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
9884 if (strcmp((const char *)blob.data, "bar") != 0) {
9885 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
9886 __location__, (const char *)blob.data, "bar");
9887 data_blob_free(&blob);
9891 data_blob_free(&blob);
9893 if (!gencache_del("foo")) {
9894 d_printf("%s: gencache_del() failed\n", __location__);
9897 if (gencache_del("foo")) {
9898 d_printf("%s: second gencache_del() succeeded\n",
9903 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
9904 d_printf("%s: gencache_get_data_blob() on deleted entry "
9905 "succeeded\n", __location__);
9910 blob.data = (uint8_t *)&v;
9911 blob.length = sizeof(v);
9913 if (!gencache_set_data_blob("blob", &blob, tm)) {
9914 d_printf("%s: gencache_set_data_blob() failed\n",
9918 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
9919 d_printf("%s: gencache_get succeeded\n", __location__);
9926 static bool rbt_testval(struct db_context *db, const char *key,
9929 struct db_record *rec;
9930 TDB_DATA data = string_tdb_data(value);
9935 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
9937 d_fprintf(stderr, "fetch_locked failed\n");
9940 status = dbwrap_record_store(rec, data, 0);
9941 if (!NT_STATUS_IS_OK(status)) {
9942 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
9947 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
9949 d_fprintf(stderr, "second fetch_locked failed\n");
9953 dbvalue = dbwrap_record_get_value(rec);
9954 if ((dbvalue.dsize != data.dsize)
9955 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
9956 d_fprintf(stderr, "Got wrong data back\n");
9966 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
9968 int *count2 = (int *)private_data;
9973 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
9975 int *count2 = (int *)private_data;
9977 dbwrap_record_delete(rec);
9981 static bool run_local_rbtree(int dummy)
9983 struct db_context *db;
9990 db = db_open_rbt(NULL);
9993 d_fprintf(stderr, "db_open_rbt failed\n");
9997 for (i=0; i<1000; i++) {
10000 if (asprintf(&key, "key%ld", random()) == -1) {
10003 if (asprintf(&value, "value%ld", random()) == -1) {
10008 if (!rbt_testval(db, key, value)) {
10015 if (asprintf(&value, "value%ld", random()) == -1) {
10020 if (!rbt_testval(db, key, value)) {
10031 count = 0; count2 = 0;
10032 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10034 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10035 if ((count != count2) || (count != 1000)) {
10038 count = 0; count2 = 0;
10039 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10041 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10042 if ((count != count2) || (count != 1000)) {
10045 count = 0; count2 = 0;
10046 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10048 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10049 if ((count != count2) || (count != 0)) {
10060 local test for character set functions
10062 This is a very simple test for the functionality in convert_string_error()
10064 static bool run_local_convert_string(int dummy)
10066 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10067 const char *test_strings[2] = { "March", "M\303\244rz" };
10071 for (i=0; i<2; i++) {
10072 const char *str = test_strings[i];
10073 int len = strlen(str);
10074 size_t converted_size;
10077 memset(dst, 'X', sizeof(dst));
10079 /* first try with real source length */
10080 ret = convert_string_error(CH_UNIX, CH_UTF8,
10085 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10089 if (converted_size != len) {
10090 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10091 str, len, (int)converted_size);
10095 if (strncmp(str, dst, converted_size) != 0) {
10096 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10100 if (strlen(str) != converted_size) {
10101 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10102 (int)strlen(str), (int)converted_size);
10106 if (dst[converted_size] != 'X') {
10107 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10111 /* now with srclen==-1, this causes the nul to be
10113 ret = convert_string_error(CH_UNIX, CH_UTF8,
10118 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10122 if (converted_size != len+1) {
10123 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10124 str, len, (int)converted_size);
10128 if (strncmp(str, dst, converted_size) != 0) {
10129 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10133 if (len+1 != converted_size) {
10134 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10135 len+1, (int)converted_size);
10139 if (dst[converted_size] != 'X') {
10140 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10147 TALLOC_FREE(tmp_ctx);
10150 TALLOC_FREE(tmp_ctx);
10155 struct talloc_dict_test {
10159 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
10161 int *count = (int *)priv;
10166 static bool run_local_talloc_dict(int dummy)
10168 struct talloc_dict *dict;
10169 struct talloc_dict_test *t;
10170 int key, count, res;
10173 dict = talloc_dict_init(talloc_tos());
10174 if (dict == NULL) {
10178 t = talloc(talloc_tos(), struct talloc_dict_test);
10185 ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
10191 res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
10200 if (count != res) {
10209 static bool run_local_string_to_sid(int dummy) {
10210 struct dom_sid sid;
10212 if (string_to_sid(&sid, "S--1-5-32-545")) {
10213 printf("allowing S--1-5-32-545\n");
10216 if (string_to_sid(&sid, "S-1-5-32-+545")) {
10217 printf("allowing S-1-5-32-+545\n");
10220 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")) {
10221 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10224 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10225 printf("allowing S-1-5-32-545-abc\n");
10228 if (string_to_sid(&sid, "S-300-5-32-545")) {
10229 printf("allowing S-300-5-32-545\n");
10232 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10233 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10236 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10237 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10240 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10241 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10244 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10245 printf("could not parse S-1-5-32-545\n");
10248 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10249 printf("mis-parsed S-1-5-32-545 as %s\n",
10250 sid_string_tos(&sid));
10256 static bool sid_to_string_test(const char *expected) {
10259 struct dom_sid sid;
10261 if (!string_to_sid(&sid, expected)) {
10262 printf("could not parse %s\n", expected);
10266 str = dom_sid_string(NULL, &sid);
10267 if (strcmp(str, expected)) {
10268 printf("Comparison failed (%s != %s)\n", str, expected);
10275 static bool run_local_sid_to_string(int dummy) {
10276 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10278 if (!sid_to_string_test("S-1-545"))
10280 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10285 static bool run_local_binary_to_sid(int dummy) {
10286 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10287 static const uint8_t good_binary_sid[] = {
10288 0x1, /* revision number */
10289 15, /* num auths */
10290 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10291 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10292 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10293 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10294 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10295 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10296 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10297 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10298 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10299 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10300 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10301 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10302 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10303 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10304 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10305 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10308 static const uint8_t long_binary_sid[] = {
10309 0x1, /* revision number */
10310 15, /* num auths */
10311 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10312 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10313 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10314 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10315 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10316 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10317 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10318 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10319 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10320 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10321 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10322 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10323 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10324 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10325 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10326 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10327 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10328 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10329 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10332 static const uint8_t long_binary_sid2[] = {
10333 0x1, /* revision number */
10334 32, /* num auths */
10335 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10336 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10337 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10338 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10339 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10340 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10341 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10342 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10343 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10344 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10345 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10346 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10347 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10348 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10349 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10350 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10351 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10352 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10353 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10354 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10355 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10356 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10357 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10358 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10359 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10360 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10361 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10362 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10363 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10364 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10365 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10366 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10367 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10370 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10373 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10376 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10382 /* Split a path name into filename and stream name components. Canonicalise
10383 * such that an implicit $DATA token is always explicit.
10385 * The "specification" of this function can be found in the
10386 * run_local_stream_name() function in torture.c, I've tried those
10387 * combinations against a W2k3 server.
10390 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10391 char **pbase, char **pstream)
10394 char *stream = NULL;
10395 char *sname; /* stream name */
10396 const char *stype; /* stream type */
10398 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10400 sname = strchr_m(fname, ':');
10402 if (sname == NULL) {
10403 if (pbase != NULL) {
10404 base = talloc_strdup(mem_ctx, fname);
10405 NT_STATUS_HAVE_NO_MEMORY(base);
10410 if (pbase != NULL) {
10411 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10412 NT_STATUS_HAVE_NO_MEMORY(base);
10417 stype = strchr_m(sname, ':');
10419 if (stype == NULL) {
10420 sname = talloc_strdup(mem_ctx, sname);
10424 if (strcasecmp_m(stype, ":$DATA") != 0) {
10426 * If there is an explicit stream type, so far we only
10427 * allow $DATA. Is there anything else allowed? -- vl
10429 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10431 return NT_STATUS_OBJECT_NAME_INVALID;
10433 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10437 if (sname == NULL) {
10439 return NT_STATUS_NO_MEMORY;
10442 if (sname[0] == '\0') {
10444 * no stream name, so no stream
10449 if (pstream != NULL) {
10450 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10451 if (stream == NULL) {
10452 TALLOC_FREE(sname);
10454 return NT_STATUS_NO_MEMORY;
10457 * upper-case the type field
10459 (void)strupper_m(strchr_m(stream, ':')+1);
10463 if (pbase != NULL) {
10466 if (pstream != NULL) {
10469 return NT_STATUS_OK;
10472 static bool test_stream_name(const char *fname, const char *expected_base,
10473 const char *expected_stream,
10474 NTSTATUS expected_status)
10478 char *stream = NULL;
10480 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10481 if (!NT_STATUS_EQUAL(status, expected_status)) {
10485 if (!NT_STATUS_IS_OK(status)) {
10489 if (base == NULL) goto error;
10491 if (strcmp(expected_base, base) != 0) goto error;
10493 if ((expected_stream != NULL) && (stream == NULL)) goto error;
10494 if ((expected_stream == NULL) && (stream != NULL)) goto error;
10496 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10500 TALLOC_FREE(stream);
10504 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10505 fname, expected_base ? expected_base : "<NULL>",
10506 expected_stream ? expected_stream : "<NULL>",
10507 nt_errstr(expected_status));
10508 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10509 base ? base : "<NULL>", stream ? stream : "<NULL>",
10510 nt_errstr(status));
10512 TALLOC_FREE(stream);
10516 static bool run_local_stream_name(int dummy)
10520 ret &= test_stream_name(
10521 "bla", "bla", NULL, NT_STATUS_OK);
10522 ret &= test_stream_name(
10523 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10524 ret &= test_stream_name(
10525 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10526 ret &= test_stream_name(
10527 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10528 ret &= test_stream_name(
10529 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10530 ret &= test_stream_name(
10531 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10532 ret &= test_stream_name(
10533 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10534 ret &= test_stream_name(
10535 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10540 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10542 if (a.length != b.length) {
10543 printf("a.length=%d != b.length=%d\n",
10544 (int)a.length, (int)b.length);
10547 if (memcmp(a.data, b.data, a.length) != 0) {
10548 printf("a.data and b.data differ\n");
10554 static bool run_local_memcache(int dummy)
10556 struct memcache *cache;
10558 DATA_BLOB d1, d2, d3;
10559 DATA_BLOB v1, v2, v3;
10561 TALLOC_CTX *mem_ctx;
10563 size_t size1, size2;
10566 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10568 if (cache == NULL) {
10569 printf("memcache_init failed\n");
10573 d1 = data_blob_const("d1", 2);
10574 d2 = data_blob_const("d2", 2);
10575 d3 = data_blob_const("d3", 2);
10577 k1 = data_blob_const("d1", 2);
10578 k2 = data_blob_const("d2", 2);
10580 memcache_add(cache, STAT_CACHE, k1, d1);
10581 memcache_add(cache, GETWD_CACHE, k2, d2);
10583 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10584 printf("could not find k1\n");
10587 if (!data_blob_equal(d1, v1)) {
10591 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
10592 printf("could not find k2\n");
10595 if (!data_blob_equal(d2, v2)) {
10599 memcache_add(cache, STAT_CACHE, k1, d3);
10601 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10602 printf("could not find replaced k1\n");
10605 if (!data_blob_equal(d3, v3)) {
10609 memcache_add(cache, GETWD_CACHE, k1, d1);
10611 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
10612 printf("Did find k2, should have been purged\n");
10616 TALLOC_FREE(cache);
10618 cache = memcache_init(NULL, 0);
10620 mem_ctx = talloc_init("foo");
10622 str1 = talloc_strdup(mem_ctx, "string1");
10623 str2 = talloc_strdup(mem_ctx, "string2");
10625 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10626 data_blob_string_const("torture"), &str1);
10627 size1 = talloc_total_size(cache);
10629 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10630 data_blob_string_const("torture"), &str2);
10631 size2 = talloc_total_size(cache);
10633 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
10635 if (size2 > size1) {
10636 printf("memcache leaks memory!\n");
10642 TALLOC_FREE(cache);
10646 static void wbclient_done(struct tevent_req *req)
10649 struct winbindd_response *wb_resp;
10650 int *i = (int *)tevent_req_callback_data_void(req);
10652 wbc_err = wb_trans_recv(req, req, &wb_resp);
10655 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
10658 static bool run_wbclient_multi_ping(int dummy)
10660 struct tevent_context *ev;
10661 struct wb_context **wb_ctx;
10662 struct winbindd_request wb_req;
10663 bool result = false;
10666 BlockSignals(True, SIGPIPE);
10668 ev = tevent_context_init(talloc_tos());
10673 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
10674 if (wb_ctx == NULL) {
10678 ZERO_STRUCT(wb_req);
10679 wb_req.cmd = WINBINDD_PING;
10681 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
10683 for (i=0; i<torture_nprocs; i++) {
10684 wb_ctx[i] = wb_context_init(ev, NULL);
10685 if (wb_ctx[i] == NULL) {
10688 for (j=0; j<torture_numops; j++) {
10689 struct tevent_req *req;
10690 req = wb_trans_send(ev, ev, wb_ctx[i],
10691 (j % 2) == 0, &wb_req);
10695 tevent_req_set_callback(req, wbclient_done, &i);
10701 while (i < torture_nprocs * torture_numops) {
10702 tevent_loop_once(ev);
10711 static void getaddrinfo_finished(struct tevent_req *req)
10713 char *name = (char *)tevent_req_callback_data_void(req);
10714 struct addrinfo *ainfo;
10717 res = getaddrinfo_recv(req, &ainfo);
10719 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
10722 d_printf("gai(%s) succeeded\n", name);
10723 freeaddrinfo(ainfo);
10726 static bool run_getaddrinfo_send(int dummy)
10728 TALLOC_CTX *frame = talloc_stackframe();
10729 struct fncall_context *ctx;
10730 struct tevent_context *ev;
10731 bool result = false;
10732 const char *names[4] = { "www.samba.org", "notfound.samba.org",
10733 "www.slashdot.org", "heise.de" };
10734 struct tevent_req *reqs[4];
10737 ev = samba_tevent_context_init(frame);
10742 ctx = fncall_context_init(frame, 4);
10744 for (i=0; i<ARRAY_SIZE(names); i++) {
10745 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
10747 if (reqs[i] == NULL) {
10750 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
10751 discard_const_p(void, names[i]));
10754 for (i=0; i<ARRAY_SIZE(reqs); i++) {
10755 tevent_loop_once(ev);
10760 TALLOC_FREE(frame);
10764 static bool dbtrans_inc(struct db_context *db)
10766 struct db_record *rec;
10772 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10774 printf(__location__ "fetch_lock failed\n");
10778 value = dbwrap_record_get_value(rec);
10780 if (value.dsize != sizeof(uint32_t)) {
10781 printf(__location__ "value.dsize = %d\n",
10786 memcpy(&val, value.dptr, sizeof(val));
10789 status = dbwrap_record_store(
10790 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
10791 if (!NT_STATUS_IS_OK(status)) {
10792 printf(__location__ "store failed: %s\n",
10793 nt_errstr(status));
10803 static bool run_local_dbtrans(int dummy)
10805 struct db_context *db;
10806 struct db_record *rec;
10812 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
10813 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
10816 printf("Could not open transtest.db\n");
10820 res = dbwrap_transaction_start(db);
10822 printf(__location__ "transaction_start failed\n");
10826 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10828 printf(__location__ "fetch_lock failed\n");
10832 value = dbwrap_record_get_value(rec);
10834 if (value.dptr == NULL) {
10836 status = dbwrap_record_store(
10837 rec, make_tdb_data((uint8_t *)&initial,
10840 if (!NT_STATUS_IS_OK(status)) {
10841 printf(__location__ "store returned %s\n",
10842 nt_errstr(status));
10849 res = dbwrap_transaction_commit(db);
10851 printf(__location__ "transaction_commit failed\n");
10856 uint32_t val, val2;
10859 res = dbwrap_transaction_start(db);
10861 printf(__location__ "transaction_start failed\n");
10865 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
10866 if (!NT_STATUS_IS_OK(status)) {
10867 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10868 nt_errstr(status));
10872 for (i=0; i<10; i++) {
10873 if (!dbtrans_inc(db)) {
10878 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
10879 if (!NT_STATUS_IS_OK(status)) {
10880 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10881 nt_errstr(status));
10885 if (val2 != val + 10) {
10886 printf(__location__ "val=%d, val2=%d\n",
10887 (int)val, (int)val2);
10891 printf("val2=%d\r", val2);
10893 res = dbwrap_transaction_commit(db);
10895 printf(__location__ "transaction_commit failed\n");
10905 * Just a dummy test to be run under a debugger. There's no real way
10906 * to inspect the tevent_select specific function from outside of
10910 static bool run_local_tevent_select(int dummy)
10912 struct tevent_context *ev;
10913 struct tevent_fd *fd1, *fd2;
10914 bool result = false;
10916 ev = tevent_context_init_byname(NULL, "select");
10918 d_fprintf(stderr, "tevent_context_init_byname failed\n");
10922 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
10924 d_fprintf(stderr, "tevent_add_fd failed\n");
10927 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
10929 d_fprintf(stderr, "tevent_add_fd failed\n");
10934 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
10936 d_fprintf(stderr, "tevent_add_fd failed\n");
10946 static bool run_local_hex_encode_buf(int dummy)
10952 for (i=0; i<sizeof(src); i++) {
10955 hex_encode_buf(buf, src, sizeof(src));
10956 if (strcmp(buf, "0001020304050607") != 0) {
10959 hex_encode_buf(buf, NULL, 0);
10960 if (buf[0] != '\0') {
10966 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
10988 "1001:1111:1111:1000:0:1111:1111:1111",
10997 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11011 "1001:1111:1111:1000:0:1111:1111:1111"
11014 static bool run_local_remove_duplicate_addrs2(int dummy)
11016 struct ip_service test_vector[28];
11019 /* Construct the sockaddr_storage test vector. */
11020 for (i = 0; i < 28; i++) {
11021 struct addrinfo hints;
11022 struct addrinfo *res = NULL;
11025 memset(&hints, '\0', sizeof(hints));
11026 hints.ai_flags = AI_NUMERICHOST;
11027 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11032 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11033 remove_duplicate_addrs2_test_strings_vector[i]);
11036 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11037 memcpy(&test_vector[i].ss,
11043 count = remove_duplicate_addrs2(test_vector, i);
11046 fprintf(stderr, "count wrong (%d) should be 14\n",
11051 for (i = 0; i < count; i++) {
11052 char addr[INET6_ADDRSTRLEN];
11054 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11056 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11057 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11060 remove_duplicate_addrs2_test_strings_result[i]);
11065 printf("run_local_remove_duplicate_addrs2: success\n");
11069 static bool run_local_tdb_opener(int dummy)
11075 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11076 O_RDWR|O_CREAT, 0755);
11078 perror("tdb_open failed");
11089 static bool run_local_tdb_writer(int dummy)
11095 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11097 perror("tdb_open failed");
11101 val.dptr = (uint8_t *)&v;
11102 val.dsize = sizeof(v);
11108 ret = tdb_store(t, val, val, 0);
11110 printf("%s\n", tdb_errorstr(t));
11115 data = tdb_fetch(t, val);
11116 if (data.dptr != NULL) {
11117 SAFE_FREE(data.dptr);
11123 static bool run_local_canonicalize_path(int dummy)
11125 const char *src[] = {
11132 ".././././../../../boo",
11136 const char *dst[] = {
11149 for (i = 0; src[i] != NULL; i++) {
11150 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11152 perror("talloc fail\n");
11155 if (strcmp(d, dst[i]) != 0) {
11157 "canonicalize missmatch %s -> %s != %s",
11158 src[i], d, dst[i]);
11166 static bool run_ign_bad_negprot(int dummy)
11168 struct tevent_context *ev;
11169 struct tevent_req *req;
11170 struct smbXcli_conn *conn;
11171 struct sockaddr_storage ss;
11176 printf("starting ignore bad negprot\n");
11178 ok = resolve_name(host, &ss, 0x20, true);
11180 d_fprintf(stderr, "Could not resolve name %s\n", host);
11184 status = open_socket_out(&ss, 445, 10000, &fd);
11185 if (!NT_STATUS_IS_OK(status)) {
11186 d_fprintf(stderr, "open_socket_out failed: %s\n",
11187 nt_errstr(status));
11191 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11193 if (conn == NULL) {
11194 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11198 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11199 if (NT_STATUS_IS_OK(status)) {
11200 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11204 ev = samba_tevent_context_init(talloc_tos());
11206 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11210 req = smb1cli_session_setup_nt1_send(
11211 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11212 data_blob_null, data_blob_null, 0x40,
11213 "Windows 2000 2195", "Windows 2000 5.0");
11215 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11219 ok = tevent_req_poll_ntstatus(req, ev, &status);
11221 d_fprintf(stderr, "tevent_req_poll failed\n");
11225 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11227 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11228 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11229 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11230 nt_errstr(status));
11236 printf("starting ignore bad negprot\n");
11241 static double create_procs(bool (*fn)(int), bool *result)
11244 volatile pid_t *child_status;
11245 volatile bool *child_status_out;
11248 struct timeval start;
11252 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11253 if (!child_status) {
11254 printf("Failed to setup shared memory\n");
11258 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11259 if (!child_status_out) {
11260 printf("Failed to setup result status shared memory\n");
11264 for (i = 0; i < torture_nprocs; i++) {
11265 child_status[i] = 0;
11266 child_status_out[i] = True;
11269 start = timeval_current();
11271 for (i=0;i<torture_nprocs;i++) {
11274 pid_t mypid = getpid();
11275 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11277 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11280 if (torture_open_connection(¤t_cli, i)) break;
11281 if (tries-- == 0) {
11282 printf("pid %d failed to start\n", (int)getpid());
11288 child_status[i] = getpid();
11290 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11292 child_status_out[i] = fn(i);
11299 for (i=0;i<torture_nprocs;i++) {
11300 if (child_status[i]) synccount++;
11302 if (synccount == torture_nprocs) break;
11304 } while (timeval_elapsed(&start) < 30);
11306 if (synccount != torture_nprocs) {
11307 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11309 return timeval_elapsed(&start);
11312 /* start the client load */
11313 start = timeval_current();
11315 for (i=0;i<torture_nprocs;i++) {
11316 child_status[i] = 0;
11319 printf("%d clients started\n", torture_nprocs);
11321 for (i=0;i<torture_nprocs;i++) {
11322 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11327 for (i=0;i<torture_nprocs;i++) {
11328 if (!child_status_out[i]) {
11332 return timeval_elapsed(&start);
11335 #define FLAG_MULTIPROC 1
11341 } torture_ops[] = {
11342 {"FDPASS", run_fdpasstest, 0},
11343 {"LOCK1", run_locktest1, 0},
11344 {"LOCK2", run_locktest2, 0},
11345 {"LOCK3", run_locktest3, 0},
11346 {"LOCK4", run_locktest4, 0},
11347 {"LOCK5", run_locktest5, 0},
11348 {"LOCK6", run_locktest6, 0},
11349 {"LOCK7", run_locktest7, 0},
11350 {"LOCK8", run_locktest8, 0},
11351 {"LOCK9", run_locktest9, 0},
11352 {"UNLINK", run_unlinktest, 0},
11353 {"BROWSE", run_browsetest, 0},
11354 {"ATTR", run_attrtest, 0},
11355 {"TRANS2", run_trans2test, 0},
11356 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
11357 {"TORTURE",run_torture, FLAG_MULTIPROC},
11358 {"RANDOMIPC", run_randomipc, 0},
11359 {"NEGNOWAIT", run_negprot_nowait, 0},
11360 {"NBENCH", run_nbench, 0},
11361 {"NBENCH2", run_nbench2, 0},
11362 {"OPLOCK1", run_oplock1, 0},
11363 {"OPLOCK2", run_oplock2, 0},
11364 {"OPLOCK4", run_oplock4, 0},
11365 {"DIR", run_dirtest, 0},
11366 {"DIR1", run_dirtest1, 0},
11367 {"DIR-CREATETIME", run_dir_createtime, 0},
11368 {"DENY1", torture_denytest1, 0},
11369 {"DENY2", torture_denytest2, 0},
11370 {"TCON", run_tcon_test, 0},
11371 {"TCONDEV", run_tcon_devtype_test, 0},
11372 {"RW1", run_readwritetest, 0},
11373 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
11374 {"RW3", run_readwritelarge, 0},
11375 {"RW-SIGNING", run_readwritelarge_signtest, 0},
11376 {"OPEN", run_opentest, 0},
11377 {"POSIX", run_simple_posix_open_test, 0},
11378 {"POSIX-APPEND", run_posix_append, 0},
11379 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
11380 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
11381 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
11382 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
11383 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
11384 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
11385 {"ASYNC-ECHO", run_async_echo, 0},
11386 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
11387 { "SHORTNAME-TEST", run_shortname_test, 0},
11388 { "ADDRCHANGE", run_addrchange, 0},
11390 {"OPENATTR", run_openattrtest, 0},
11392 {"XCOPY", run_xcopy, 0},
11393 {"RENAME", run_rename, 0},
11394 {"RENAME-ACCESS", run_rename_access, 0},
11395 {"OWNER-RIGHTS", run_owner_rights, 0},
11396 {"DELETE", run_deletetest, 0},
11397 {"WILDDELETE", run_wild_deletetest, 0},
11398 {"DELETE-LN", run_deletetest_ln, 0},
11399 {"PROPERTIES", run_properties, 0},
11400 {"MANGLE", torture_mangle, 0},
11401 {"MANGLE1", run_mangle1, 0},
11402 {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
11403 {"W2K", run_w2ktest, 0},
11404 {"TRANS2SCAN", torture_trans2_scan, 0},
11405 {"NTTRANSSCAN", torture_nttrans_scan, 0},
11406 {"UTABLE", torture_utable, 0},
11407 {"CASETABLE", torture_casetable, 0},
11408 {"ERRMAPEXTRACT", run_error_map_extract, 0},
11409 {"PIPE_NUMBER", run_pipe_number, 0},
11410 {"TCON2", run_tcon2_test, 0},
11411 {"IOCTL", torture_ioctl_test, 0},
11412 {"CHKPATH", torture_chkpath_test, 0},
11413 {"FDSESS", run_fdsesstest, 0},
11414 { "EATEST", run_eatest, 0},
11415 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
11416 { "CHAIN1", run_chain1, 0},
11417 { "CHAIN2", run_chain2, 0},
11418 { "CHAIN3", run_chain3, 0},
11419 { "WINDOWS-WRITE", run_windows_write, 0},
11420 { "LARGE_READX", run_large_readx, 0},
11421 { "NTTRANS-CREATE", run_nttrans_create, 0},
11422 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
11423 { "CLI_ECHO", run_cli_echo, 0},
11424 { "GETADDRINFO", run_getaddrinfo_send, 0},
11425 { "TLDAP", run_tldap },
11426 { "STREAMERROR", run_streamerror },
11427 { "NOTIFY-BENCH", run_notify_bench },
11428 { "NOTIFY-BENCH2", run_notify_bench2 },
11429 { "NOTIFY-BENCH3", run_notify_bench3 },
11430 { "BAD-NBT-SESSION", run_bad_nbt_session },
11431 { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
11432 { "SMB-ANY-CONNECT", run_smb_any_connect },
11433 { "NOTIFY-ONLINE", run_notify_online },
11434 { "SMB2-BASIC", run_smb2_basic },
11435 { "SMB2-NEGPROT", run_smb2_negprot },
11436 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
11437 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
11438 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
11439 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
11440 { "SMB2-FTRUNCATE", run_smb2_ftruncate },
11441 { "CLEANUP1", run_cleanup1 },
11442 { "CLEANUP2", run_cleanup2 },
11443 { "CLEANUP3", run_cleanup3 },
11444 { "CLEANUP4", run_cleanup4 },
11445 { "OPLOCK-CANCEL", run_oplock_cancel },
11446 { "PIDHIGH", run_pidhigh },
11447 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
11448 { "LOCAL-GENCACHE", run_local_gencache, 0},
11449 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
11450 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
11451 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2, 0 },
11452 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
11453 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
11454 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
11455 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
11456 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
11457 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
11458 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
11459 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
11460 { "LOCAL-BASE64", run_local_base64, 0},
11461 { "LOCAL-RBTREE", run_local_rbtree, 0},
11462 { "LOCAL-MEMCACHE", run_local_memcache, 0},
11463 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
11464 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
11465 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
11466 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
11467 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
11468 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
11469 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
11470 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
11471 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
11472 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
11473 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
11474 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
11475 { "local-tdb-opener", run_local_tdb_opener, 0 },
11476 { "local-tdb-writer", run_local_tdb_writer, 0 },
11477 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
11478 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
11479 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
11480 { "LOCAL-G-LOCK1", run_g_lock1, 0 },
11481 { "LOCAL-G-LOCK2", run_g_lock2, 0 },
11482 { "LOCAL-G-LOCK3", run_g_lock3, 0 },
11483 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
11484 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
11488 * dummy function to satisfy linker dependency
11490 struct tevent_context *winbind_event_context(void);
11491 struct tevent_context *winbind_event_context(void)
11496 /****************************************************************************
11497 run a specified test or "ALL"
11498 ****************************************************************************/
11499 static bool run_test(const char *name)
11502 bool result = True;
11503 bool found = False;
11506 if (strequal(name,"ALL")) {
11507 for (i=0;torture_ops[i].name;i++) {
11508 run_test(torture_ops[i].name);
11513 for (i=0;torture_ops[i].name;i++) {
11514 fstr_sprintf(randomfname, "\\XX%x",
11515 (unsigned)random());
11517 if (strequal(name, torture_ops[i].name)) {
11519 printf("Running %s\n", name);
11520 if (torture_ops[i].flags & FLAG_MULTIPROC) {
11521 t = create_procs(torture_ops[i].fn, &result);
11524 printf("TEST %s FAILED!\n", name);
11527 struct timeval start;
11528 start = timeval_current();
11529 if (!torture_ops[i].fn(0)) {
11531 printf("TEST %s FAILED!\n", name);
11533 t = timeval_elapsed(&start);
11535 printf("%s took %g secs\n\n", name, t);
11540 printf("Did not find a test named %s\n", name);
11548 static void usage(void)
11552 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11553 printf("Please use samba4 torture.\n\n");
11555 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11557 printf("\t-d debuglevel\n");
11558 printf("\t-U user%%pass\n");
11559 printf("\t-k use kerberos\n");
11560 printf("\t-N numprocs\n");
11561 printf("\t-n my_netbios_name\n");
11562 printf("\t-W workgroup\n");
11563 printf("\t-o num_operations\n");
11564 printf("\t-O socket_options\n");
11565 printf("\t-m maximum protocol\n");
11566 printf("\t-L use oplocks\n");
11567 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11568 printf("\t-A showall\n");
11569 printf("\t-p port\n");
11570 printf("\t-s seed\n");
11571 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11572 printf("\t-f filename filename to test\n");
11573 printf("\t-e encrypt\n");
11576 printf("tests are:");
11577 for (i=0;torture_ops[i].name;i++) {
11578 printf(" %s", torture_ops[i].name);
11582 printf("default test is ALL\n");
11587 /****************************************************************************
11589 ****************************************************************************/
11590 int main(int argc,char *argv[])
11596 bool correct = True;
11597 TALLOC_CTX *frame = talloc_stackframe();
11598 int seed = time(NULL);
11600 #ifdef HAVE_SETBUFFER
11601 setbuffer(stdout, NULL, 0);
11604 setup_logging("smbtorture", DEBUG_STDOUT);
11609 if (is_default_dyn_CONFIGFILE()) {
11610 if(getenv("SMB_CONF_PATH")) {
11611 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11614 lp_load_global(get_dyn_CONFIGFILE());
11621 for(p = argv[1]; *p; p++)
11625 if (strncmp(argv[1], "//", 2)) {
11629 fstrcpy(host, &argv[1][2]);
11630 p = strchr_m(&host[2],'/');
11635 fstrcpy(share, p+1);
11637 fstrcpy(myname, get_myname(talloc_tos()));
11639 fprintf(stderr, "Failed to get my hostname.\n");
11643 if (*username == 0 && getenv("LOGNAME")) {
11644 fstrcpy(username,getenv("LOGNAME"));
11650 fstrcpy(workgroup, lp_workgroup());
11652 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
11656 port_to_use = atoi(optarg);
11659 seed = atoi(optarg);
11662 fstrcpy(workgroup,optarg);
11665 lp_set_cmdline("client max protocol", optarg);
11668 torture_nprocs = atoi(optarg);
11671 torture_numops = atoi(optarg);
11674 lp_set_cmdline("log level", optarg);
11680 use_oplocks = True;
11683 local_path = optarg;
11686 torture_showall = True;
11689 fstrcpy(myname, optarg);
11692 client_txt = optarg;
11699 use_kerberos = True;
11701 d_printf("No kerberos support compiled in\n");
11707 fstrcpy(username,optarg);
11708 p = strchr_m(username,'%');
11711 fstrcpy(password, p+1);
11716 fstrcpy(multishare_conn_fname, optarg);
11717 use_multishare_conn = True;
11720 torture_blocksize = atoi(optarg);
11723 test_filename = SMB_STRDUP(optarg);
11726 printf("Unknown option %c (%d)\n", (char)opt, opt);
11731 d_printf("using seed %d\n", seed);
11735 if(use_kerberos && !gotuser) gotpass = True;
11738 char pwd[256] = {0};
11741 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
11743 fstrcpy(password, pwd);
11748 printf("host=%s share=%s user=%s myname=%s\n",
11749 host, share, username, myname);
11751 torture_creds = cli_session_creds_init(frame,
11757 false, /* fallback_after_kerberos */
11758 false, /* use_ccache */
11759 false); /* password_is_nt_hash */
11760 if (torture_creds == NULL) {
11761 d_printf("cli_session_creds_init() failed.\n");
11765 if (argc == optind) {
11766 correct = run_test("ALL");
11768 for (i=optind;i<argc;i++) {
11769 if (!run_test(argv[i])) {
11775 TALLOC_FREE(frame);