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 "libsmb/namequery.h"
24 #include "wbc_async.h"
25 #include "torture/proto.h"
26 #include "libcli/security/security.h"
28 #include "tldap_util.h"
29 #include "../librpc/gen_ndr/svcctl.h"
30 #include "../lib/util/memcache.h"
31 #include "nsswitch/winbind_client.h"
32 #include "dbwrap/dbwrap.h"
33 #include "dbwrap/dbwrap_open.h"
34 #include "dbwrap/dbwrap_rbt.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"
46 #include "lib/util/time.h"
47 #include "lib/crypto/md5.h"
52 fstring host, workgroup, share, password, username, myname;
53 struct cli_credentials *torture_creds;
54 static const char *sockops="TCP_NODELAY";
56 static int port_to_use=0;
57 int torture_numops=100;
58 int torture_blocksize=1024*1024;
59 static int procnum; /* records process count number when forking */
60 static struct cli_state *current_cli;
61 static fstring randomfname;
62 static bool use_oplocks;
63 static bool use_level_II_oplocks;
64 static const char *client_txt = "client_oplocks.txt";
65 static bool disable_spnego;
66 static bool use_kerberos;
67 static bool force_dos_errors;
68 static fstring multishare_conn_fname;
69 static bool use_multishare_conn = False;
70 static bool do_encrypt;
71 static const char *local_path = NULL;
72 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
75 bool torture_showall = False;
77 static double create_procs(bool (*fn)(int), bool *result);
79 /********************************************************************
80 Ensure a connection is encrypted.
81 ********************************************************************/
83 static bool force_cli_encryption(struct cli_state *c,
84 const char *sharename)
86 uint16_t major, minor;
87 uint32_t caplow, caphigh;
90 if (!SERVER_HAS_UNIX_CIFS(c)) {
91 d_printf("Encryption required and "
92 "server that doesn't support "
93 "UNIX extensions - failing connect\n");
97 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
99 if (!NT_STATUS_IS_OK(status)) {
100 d_printf("Encryption required and "
101 "can't get UNIX CIFS extensions "
102 "version from server: %s\n", nt_errstr(status));
106 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
107 d_printf("Encryption required and "
108 "share %s doesn't support "
109 "encryption.\n", sharename);
113 status = cli_smb1_setup_encryption(c, torture_creds);
114 if (!NT_STATUS_IS_OK(status)) {
115 d_printf("Encryption required and "
116 "setup failed with error %s.\n",
125 static struct cli_state *open_nbt_connection(void)
131 if (disable_spnego) {
132 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
136 flags |= CLI_FULL_CONNECTION_OPLOCKS;
139 if (use_level_II_oplocks) {
140 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
144 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
147 if (force_dos_errors) {
148 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
151 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
152 signing_state, flags, &c);
153 if (!NT_STATUS_IS_OK(status)) {
154 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
158 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
163 /****************************************************************************
164 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
165 ****************************************************************************/
167 static bool cli_bad_session_request(int fd,
168 struct nmb_name *calling, struct nmb_name *called)
177 uint8_t message_type;
179 struct tevent_context *ev;
180 struct tevent_req *req;
182 frame = talloc_stackframe();
184 iov[0].iov_base = len_buf;
185 iov[0].iov_len = sizeof(len_buf);
187 /* put in the destination name */
189 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
191 if (iov[1].iov_base == NULL) {
194 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
195 talloc_get_size(iov[1].iov_base));
199 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
201 if (iov[2].iov_base == NULL) {
204 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
205 talloc_get_size(iov[2].iov_base));
207 /* Deliberately corrupt the name len (first byte) */
208 *((uint8_t *)iov[2].iov_base) = 100;
210 /* send a session request (RFC 1002) */
211 /* setup the packet length
212 * Remove four bytes from the length count, since the length
213 * field in the NBT Session Service header counts the number
214 * of bytes which follow. The cli_send_smb() function knows
215 * about this and accounts for those four bytes.
219 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
220 SCVAL(len_buf,0,0x81);
222 len = write_data_iov(fd, iov, 3);
227 ev = samba_tevent_context_init(frame);
231 req = read_smb_send(frame, ev, fd);
235 if (!tevent_req_poll(req, ev)) {
238 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
245 message_type = CVAL(inbuf, 0);
246 if (message_type != 0x83) {
247 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
252 if (smb_len(inbuf) != 1) {
253 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
254 (int)smb_len(inbuf));
258 error = CVAL(inbuf, 4);
260 d_fprintf(stderr, "Expected error 0x82, got %d\n",
271 /* Insert a NULL at the first separator of the given path and return a pointer
272 * to the remainder of the string.
275 terminate_path_at_separator(char * path)
283 if ((p = strchr_m(path, '/'))) {
288 if ((p = strchr_m(path, '\\'))) {
298 parse a //server/share type UNC name
300 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
301 char **hostname, char **sharename)
305 *hostname = *sharename = NULL;
307 if (strncmp(unc_name, "\\\\", 2) &&
308 strncmp(unc_name, "//", 2)) {
312 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
313 p = terminate_path_at_separator(*hostname);
316 *sharename = talloc_strdup(mem_ctx, p);
317 terminate_path_at_separator(*sharename);
320 if (*hostname && *sharename) {
324 TALLOC_FREE(*hostname);
325 TALLOC_FREE(*sharename);
329 static bool torture_open_connection_share(struct cli_state **c,
330 const char *hostname,
331 const char *sharename,
336 status = cli_full_connection_creds(c,
346 if (!NT_STATUS_IS_OK(status)) {
347 printf("failed to open share connection: //%s/%s port:%d - %s\n",
348 hostname, sharename, port_to_use, nt_errstr(status));
352 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
355 return force_cli_encryption(*c,
361 bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
363 char **unc_list = NULL;
364 int num_unc_names = 0;
367 if (use_multishare_conn==True) {
369 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
370 if (!unc_list || num_unc_names <= 0) {
371 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
375 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
377 printf("Failed to parse UNC name %s\n",
378 unc_list[conn_index % num_unc_names]);
379 TALLOC_FREE(unc_list);
383 result = torture_open_connection_share(c, h, s, flags);
385 /* h, s were copied earlier */
386 TALLOC_FREE(unc_list);
390 return torture_open_connection_share(c, host, share, flags);
393 bool torture_open_connection(struct cli_state **c, int conn_index)
395 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
398 flags |= CLI_FULL_CONNECTION_OPLOCKS;
400 if (use_level_II_oplocks) {
401 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
404 return torture_open_connection_flags(c, conn_index, flags);
407 bool torture_init_connection(struct cli_state **pcli)
409 struct cli_state *cli;
411 cli = open_nbt_connection();
420 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
422 uint16_t old_vuid = cli_state_get_uid(cli);
426 cli_state_set_uid(cli, 0);
427 status = cli_session_setup_creds(cli, torture_creds);
428 ret = NT_STATUS_IS_OK(status);
429 *new_vuid = cli_state_get_uid(cli);
430 cli_state_set_uid(cli, old_vuid);
435 bool torture_close_connection(struct cli_state *c)
440 status = cli_tdis(c);
441 if (!NT_STATUS_IS_OK(status)) {
442 printf("tdis failed (%s)\n", nt_errstr(status));
452 /* check if the server produced the expected dos or nt error code */
453 static bool check_both_error(int line, NTSTATUS status,
454 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
456 if (NT_STATUS_IS_DOS(status)) {
460 /* Check DOS error */
461 cclass = NT_STATUS_DOS_CLASS(status);
462 num = NT_STATUS_DOS_CODE(status);
464 if (eclass != cclass || ecode != num) {
465 printf("unexpected error code class=%d code=%d\n",
466 (int)cclass, (int)num);
467 printf(" expected %d/%d %s (line=%d)\n",
468 (int)eclass, (int)ecode, nt_errstr(nterr), line);
473 if (!NT_STATUS_EQUAL(nterr, status)) {
474 printf("unexpected error code %s\n",
476 printf(" expected %s (line=%d)\n",
477 nt_errstr(nterr), line);
486 /* check if the server produced the expected error code */
487 static bool check_error(int line, NTSTATUS status,
488 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
490 if (NT_STATUS_IS_DOS(status)) {
494 /* Check DOS error */
496 cclass = NT_STATUS_DOS_CLASS(status);
497 num = NT_STATUS_DOS_CODE(status);
499 if (eclass != cclass || ecode != num) {
500 printf("unexpected error code class=%d code=%d\n",
501 (int)cclass, (int)num);
502 printf(" expected %d/%d %s (line=%d)\n",
503 (int)eclass, (int)ecode, nt_errstr(nterr),
511 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
512 printf("unexpected error code %s\n",
514 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
524 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
528 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
530 while (!NT_STATUS_IS_OK(status)) {
531 if (!check_both_error(__LINE__, status, ERRDOS,
532 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
536 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
543 static bool rw_torture(struct cli_state *c)
545 const char *lockfname = "\\torture.lck";
549 pid_t pid2, pid = getpid();
556 memset(buf, '\0', sizeof(buf));
558 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
560 if (!NT_STATUS_IS_OK(status)) {
561 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
563 if (!NT_STATUS_IS_OK(status)) {
564 printf("open of %s failed (%s)\n",
565 lockfname, nt_errstr(status));
569 for (i=0;i<torture_numops;i++) {
570 unsigned n = (unsigned)sys_random()%10;
573 printf("%d\r", i); fflush(stdout);
575 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
577 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
581 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
583 if (!NT_STATUS_IS_OK(status)) {
584 printf("open failed (%s)\n", nt_errstr(status));
589 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
591 if (!NT_STATUS_IS_OK(status)) {
592 printf("write failed (%s)\n", nt_errstr(status));
597 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
598 sizeof(pid)+(j*sizeof(buf)),
600 if (!NT_STATUS_IS_OK(status)) {
601 printf("write failed (%s)\n",
609 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
611 if (!NT_STATUS_IS_OK(status)) {
612 printf("read failed (%s)\n", nt_errstr(status));
614 } else if (nread != sizeof(pid)) {
615 printf("read/write compare failed: "
616 "recv %ld req %ld\n", (unsigned long)nread,
617 (unsigned long)sizeof(pid));
622 printf("data corruption!\n");
626 status = cli_close(c, fnum);
627 if (!NT_STATUS_IS_OK(status)) {
628 printf("close failed (%s)\n", nt_errstr(status));
632 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
633 if (!NT_STATUS_IS_OK(status)) {
634 printf("unlink failed (%s)\n", nt_errstr(status));
638 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
639 if (!NT_STATUS_IS_OK(status)) {
640 printf("unlock failed (%s)\n", nt_errstr(status));
646 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
653 static bool run_torture(int dummy)
655 struct cli_state *cli;
660 smbXcli_conn_set_sockopt(cli->conn, sockops);
662 ret = rw_torture(cli);
664 if (!torture_close_connection(cli)) {
671 static bool rw_torture3(struct cli_state *c, char *lockfname)
673 uint16_t fnum = (uint16_t)-1;
678 unsigned countprev = 0;
681 NTSTATUS status = NT_STATUS_OK;
684 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
686 SIVAL(buf, i, sys_random());
693 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
694 if (!NT_STATUS_IS_OK(status)) {
695 printf("unlink failed (%s) (normal, this file should "
696 "not exist)\n", nt_errstr(status));
699 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
701 if (!NT_STATUS_IS_OK(status)) {
702 printf("first open read/write of %s failed (%s)\n",
703 lockfname, nt_errstr(status));
709 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
711 status = cli_openx(c, lockfname, O_RDONLY,
713 if (NT_STATUS_IS_OK(status)) {
718 if (!NT_STATUS_IS_OK(status)) {
719 printf("second open read-only of %s failed (%s)\n",
720 lockfname, nt_errstr(status));
726 for (count = 0; count < sizeof(buf); count += sent)
728 if (count >= countprev) {
729 printf("%d %8d\r", i, count);
732 countprev += (sizeof(buf) / 20);
737 sent = ((unsigned)sys_random()%(20))+ 1;
738 if (sent > sizeof(buf) - count)
740 sent = sizeof(buf) - count;
743 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
745 if (!NT_STATUS_IS_OK(status)) {
746 printf("write failed (%s)\n",
753 status = cli_read(c, fnum, buf_rd+count, count,
754 sizeof(buf)-count, &sent);
755 if(!NT_STATUS_IS_OK(status)) {
756 printf("read failed offset:%d size:%ld (%s)\n",
757 count, (unsigned long)sizeof(buf)-count,
761 } else if (sent > 0) {
762 if (memcmp(buf_rd+count, buf+count, sent) != 0)
764 printf("read/write compare failed\n");
765 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
774 status = cli_close(c, fnum);
775 if (!NT_STATUS_IS_OK(status)) {
776 printf("close failed (%s)\n", nt_errstr(status));
783 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
785 const char *lockfname = "\\torture2.lck";
795 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
796 if (!NT_STATUS_IS_OK(status)) {
797 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
800 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
802 if (!NT_STATUS_IS_OK(status)) {
803 printf("first open read/write of %s failed (%s)\n",
804 lockfname, nt_errstr(status));
808 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
809 if (!NT_STATUS_IS_OK(status)) {
810 printf("second open read-only of %s failed (%s)\n",
811 lockfname, nt_errstr(status));
812 cli_close(c1, fnum1);
816 for (i = 0; i < torture_numops; i++)
818 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
820 printf("%d\r", i); fflush(stdout);
823 generate_random_buffer((unsigned char *)buf, buf_size);
825 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
827 if (!NT_STATUS_IS_OK(status)) {
828 printf("write failed (%s)\n", nt_errstr(status));
833 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
834 if(!NT_STATUS_IS_OK(status)) {
835 printf("read failed (%s)\n", nt_errstr(status));
838 } else if (bytes_read != buf_size) {
839 printf("read failed\n");
840 printf("read %ld, expected %ld\n",
841 (unsigned long)bytes_read,
842 (unsigned long)buf_size);
847 if (memcmp(buf_rd, buf, buf_size) != 0)
849 printf("read/write compare failed\n");
855 status = cli_close(c2, fnum2);
856 if (!NT_STATUS_IS_OK(status)) {
857 printf("close failed (%s)\n", nt_errstr(status));
861 status = cli_close(c1, fnum1);
862 if (!NT_STATUS_IS_OK(status)) {
863 printf("close failed (%s)\n", nt_errstr(status));
867 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
868 if (!NT_STATUS_IS_OK(status)) {
869 printf("unlink failed (%s)\n", nt_errstr(status));
876 static bool run_readwritetest(int dummy)
878 struct cli_state *cli1, *cli2;
879 bool test1, test2 = False;
881 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
884 smbXcli_conn_set_sockopt(cli1->conn, sockops);
885 smbXcli_conn_set_sockopt(cli2->conn, sockops);
887 printf("starting readwritetest\n");
889 test1 = rw_torture2(cli1, cli2);
890 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
893 test2 = rw_torture2(cli1, cli1);
894 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
897 if (!torture_close_connection(cli1)) {
901 if (!torture_close_connection(cli2)) {
905 return (test1 && test2);
908 static bool run_readwritemulti(int dummy)
910 struct cli_state *cli;
915 smbXcli_conn_set_sockopt(cli->conn, sockops);
917 printf("run_readwritemulti: fname %s\n", randomfname);
918 test = rw_torture3(cli, randomfname);
920 if (!torture_close_connection(cli)) {
927 static bool run_readwritelarge_internal(void)
929 static struct cli_state *cli1;
931 const char *lockfname = "\\large.dat";
937 if (!torture_open_connection(&cli1, 0)) {
940 smbXcli_conn_set_sockopt(cli1->conn, sockops);
941 memset(buf,'\0',sizeof(buf));
943 printf("starting readwritelarge_internal\n");
945 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
947 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
949 if (!NT_STATUS_IS_OK(status)) {
950 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
954 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
956 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
958 if (!NT_STATUS_IS_OK(status)) {
959 printf("qfileinfo failed (%s)\n", nt_errstr(status));
963 if (fsize == sizeof(buf))
964 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
965 (unsigned long)fsize);
967 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
968 (unsigned long)fsize);
972 status = cli_close(cli1, fnum1);
973 if (!NT_STATUS_IS_OK(status)) {
974 printf("close failed (%s)\n", nt_errstr(status));
978 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
979 if (!NT_STATUS_IS_OK(status)) {
980 printf("unlink failed (%s)\n", nt_errstr(status));
984 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
986 if (!NT_STATUS_IS_OK(status)) {
987 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
991 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
993 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
995 if (!NT_STATUS_IS_OK(status)) {
996 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1000 if (fsize == sizeof(buf))
1001 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1002 (unsigned long)fsize);
1004 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1005 (unsigned long)fsize);
1010 /* ToDo - set allocation. JRA */
1011 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1012 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1015 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1017 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1021 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1024 status = cli_close(cli1, fnum1);
1025 if (!NT_STATUS_IS_OK(status)) {
1026 printf("close failed (%s)\n", nt_errstr(status));
1030 if (!torture_close_connection(cli1)) {
1036 static bool run_readwritelarge(int dummy)
1038 return run_readwritelarge_internal();
1041 static bool run_readwritelarge_signtest(int dummy)
1044 signing_state = SMB_SIGNING_REQUIRED;
1045 ret = run_readwritelarge_internal();
1046 signing_state = SMB_SIGNING_DEFAULT;
1053 #define ival(s) strtol(s, NULL, 0)
1055 /* run a test that simulates an approximate netbench client load */
1056 static bool run_netbench(int client)
1058 struct cli_state *cli;
1063 const char *params[20];
1064 bool correct = True;
1070 smbXcli_conn_set_sockopt(cli->conn, sockops);
1074 slprintf(cname,sizeof(cname)-1, "client%d", client);
1076 f = fopen(client_txt, "r");
1083 while (fgets(line, sizeof(line)-1, f)) {
1087 line[strlen(line)-1] = 0;
1089 /* printf("[%d] %s\n", line_count, line); */
1091 all_string_sub(line,"client1", cname, sizeof(line));
1093 /* parse the command parameters */
1094 params[0] = strtok_r(line, " ", &saveptr);
1096 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1100 if (i < 2) continue;
1102 if (!strncmp(params[0],"SMB", 3)) {
1103 printf("ERROR: You are using a dbench 1 load file\n");
1107 if (!strcmp(params[0],"NTCreateX")) {
1108 nb_createx(params[1], ival(params[2]), ival(params[3]),
1110 } else if (!strcmp(params[0],"Close")) {
1111 nb_close(ival(params[1]));
1112 } else if (!strcmp(params[0],"Rename")) {
1113 nb_rename(params[1], params[2]);
1114 } else if (!strcmp(params[0],"Unlink")) {
1115 nb_unlink(params[1]);
1116 } else if (!strcmp(params[0],"Deltree")) {
1117 nb_deltree(params[1]);
1118 } else if (!strcmp(params[0],"Rmdir")) {
1119 nb_rmdir(params[1]);
1120 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1121 nb_qpathinfo(params[1]);
1122 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1123 nb_qfileinfo(ival(params[1]));
1124 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1125 nb_qfsinfo(ival(params[1]));
1126 } else if (!strcmp(params[0],"FIND_FIRST")) {
1127 nb_findfirst(params[1]);
1128 } else if (!strcmp(params[0],"WriteX")) {
1129 nb_writex(ival(params[1]),
1130 ival(params[2]), ival(params[3]), ival(params[4]));
1131 } else if (!strcmp(params[0],"ReadX")) {
1132 nb_readx(ival(params[1]),
1133 ival(params[2]), ival(params[3]), ival(params[4]));
1134 } else if (!strcmp(params[0],"Flush")) {
1135 nb_flush(ival(params[1]));
1137 printf("Unknown operation %s\n", params[0]);
1145 if (!torture_close_connection(cli)) {
1153 /* run a test that simulates an approximate netbench client load */
1154 static bool run_nbench(int dummy)
1157 bool correct = True;
1159 nbio_shmem(torture_nprocs);
1163 signal(SIGALRM, nb_alarm);
1165 t = create_procs(run_netbench, &correct);
1168 printf("\nThroughput %g MB/sec\n",
1169 1.0e-6 * nbio_total() / t);
1175 This test checks for two things:
1177 1) correct support for retaining locks over a close (ie. the server
1178 must not use posix semantics)
1179 2) support for lock timeouts
1181 static bool run_locktest1(int dummy)
1183 struct cli_state *cli1, *cli2;
1184 const char *fname = "\\lockt1.lck";
1185 uint16_t fnum1, fnum2, fnum3;
1187 unsigned lock_timeout;
1190 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1193 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1194 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1196 printf("starting locktest1\n");
1198 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1200 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1202 if (!NT_STATUS_IS_OK(status)) {
1203 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1207 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1213 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1214 if (!NT_STATUS_IS_OK(status)) {
1215 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1219 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1220 if (!NT_STATUS_IS_OK(status)) {
1221 printf("lock1 failed (%s)\n", nt_errstr(status));
1225 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1226 if (NT_STATUS_IS_OK(status)) {
1227 printf("lock2 succeeded! This is a locking bug\n");
1230 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1231 NT_STATUS_LOCK_NOT_GRANTED)) {
1236 lock_timeout = (1 + (random() % 20));
1237 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1239 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1240 if (NT_STATUS_IS_OK(status)) {
1241 printf("lock3 succeeded! This is a locking bug\n");
1244 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1245 NT_STATUS_FILE_LOCK_CONFLICT)) {
1251 if (ABS(t2 - t1) < lock_timeout-1) {
1252 printf("error: This server appears not to support timed lock requests\n");
1255 printf("server slept for %u seconds for a %u second timeout\n",
1256 (unsigned int)(t2-t1), lock_timeout);
1258 status = cli_close(cli1, fnum2);
1259 if (!NT_STATUS_IS_OK(status)) {
1260 printf("close1 failed (%s)\n", nt_errstr(status));
1264 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1265 if (NT_STATUS_IS_OK(status)) {
1266 printf("lock4 succeeded! This is a locking bug\n");
1269 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1270 NT_STATUS_FILE_LOCK_CONFLICT)) {
1275 status = cli_close(cli1, fnum1);
1276 if (!NT_STATUS_IS_OK(status)) {
1277 printf("close2 failed (%s)\n", nt_errstr(status));
1281 status = cli_close(cli2, fnum3);
1282 if (!NT_STATUS_IS_OK(status)) {
1283 printf("close3 failed (%s)\n", nt_errstr(status));
1287 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1288 if (!NT_STATUS_IS_OK(status)) {
1289 printf("unlink failed (%s)\n", nt_errstr(status));
1294 if (!torture_close_connection(cli1)) {
1298 if (!torture_close_connection(cli2)) {
1302 printf("Passed locktest1\n");
1307 this checks to see if a secondary tconx can use open files from an
1310 static bool run_tcon_test(int dummy)
1312 static struct cli_state *cli;
1313 const char *fname = "\\tcontest.tmp";
1315 uint32_t cnum1, cnum2, cnum3;
1316 struct smbXcli_tcon *orig_tcon = NULL;
1317 uint16_t vuid1, vuid2;
1322 memset(buf, '\0', sizeof(buf));
1324 if (!torture_open_connection(&cli, 0)) {
1327 smbXcli_conn_set_sockopt(cli->conn, sockops);
1329 printf("starting tcontest\n");
1331 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1333 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1334 if (!NT_STATUS_IS_OK(status)) {
1335 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1339 cnum1 = cli_state_get_tid(cli);
1340 vuid1 = cli_state_get_uid(cli);
1342 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1343 if (!NT_STATUS_IS_OK(status)) {
1344 printf("initial write failed (%s)", nt_errstr(status));
1348 orig_tcon = cli_state_save_tcon(cli);
1349 if (orig_tcon == NULL) {
1353 status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1354 if (!NT_STATUS_IS_OK(status)) {
1355 printf("%s refused 2nd tree connect (%s)\n", host,
1361 cnum2 = cli_state_get_tid(cli);
1362 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1363 vuid2 = cli_state_get_uid(cli) + 1;
1365 /* try a write with the wrong tid */
1366 cli_state_set_tid(cli, cnum2);
1368 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1369 if (NT_STATUS_IS_OK(status)) {
1370 printf("* server allows write with wrong TID\n");
1373 printf("server fails write with wrong TID : %s\n",
1378 /* try a write with an invalid tid */
1379 cli_state_set_tid(cli, cnum3);
1381 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1382 if (NT_STATUS_IS_OK(status)) {
1383 printf("* server allows write with invalid TID\n");
1386 printf("server fails write with invalid TID : %s\n",
1390 /* try a write with an invalid vuid */
1391 cli_state_set_uid(cli, vuid2);
1392 cli_state_set_tid(cli, cnum1);
1394 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1395 if (NT_STATUS_IS_OK(status)) {
1396 printf("* server allows write with invalid VUID\n");
1399 printf("server fails write with invalid VUID : %s\n",
1403 cli_state_set_tid(cli, cnum1);
1404 cli_state_set_uid(cli, vuid1);
1406 status = cli_close(cli, fnum1);
1407 if (!NT_STATUS_IS_OK(status)) {
1408 printf("close failed (%s)\n", nt_errstr(status));
1412 cli_state_set_tid(cli, cnum2);
1414 status = cli_tdis(cli);
1415 if (!NT_STATUS_IS_OK(status)) {
1416 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1420 cli_state_restore_tcon(cli, orig_tcon);
1422 cli_state_set_tid(cli, cnum1);
1424 if (!torture_close_connection(cli)) {
1433 checks for old style tcon support
1435 static bool run_tcon2_test(int dummy)
1437 static struct cli_state *cli;
1438 uint16_t cnum, max_xmit;
1442 if (!torture_open_connection(&cli, 0)) {
1445 smbXcli_conn_set_sockopt(cli->conn, sockops);
1447 printf("starting tcon2 test\n");
1449 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1453 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 printf("tcon2 failed : %s\n", nt_errstr(status));
1460 printf("tcon OK : max_xmit=%d cnum=%d\n",
1461 (int)max_xmit, (int)cnum);
1464 if (!torture_close_connection(cli)) {
1468 printf("Passed tcon2 test\n");
1472 static bool tcon_devtest(struct cli_state *cli,
1473 const char *myshare, const char *devtype,
1474 const char *return_devtype,
1475 NTSTATUS expected_error)
1480 status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
1482 if (NT_STATUS_IS_OK(expected_error)) {
1483 if (NT_STATUS_IS_OK(status)) {
1484 if (return_devtype != NULL &&
1485 strequal(cli->dev, return_devtype)) {
1488 printf("tconX to share %s with type %s "
1489 "succeeded but returned the wrong "
1490 "device type (got [%s] but should have got [%s])\n",
1491 myshare, devtype, cli->dev, return_devtype);
1495 printf("tconX to share %s with type %s "
1496 "should have succeeded but failed\n",
1502 if (NT_STATUS_IS_OK(status)) {
1503 printf("tconx to share %s with type %s "
1504 "should have failed but succeeded\n",
1508 if (NT_STATUS_EQUAL(status, expected_error)) {
1511 printf("Returned unexpected error\n");
1520 checks for correct tconX support
1522 static bool run_tcon_devtype_test(int dummy)
1524 static struct cli_state *cli1 = NULL;
1525 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
1529 status = cli_full_connection_creds(&cli1,
1535 NULL, /* service_type */
1540 if (!NT_STATUS_IS_OK(status)) {
1541 printf("could not open connection\n");
1545 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1548 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1551 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1554 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1557 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1560 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1563 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1566 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1569 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1572 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1578 printf("Passed tcondevtest\n");
1585 This test checks that
1587 1) the server supports multiple locking contexts on the one SMB
1588 connection, distinguished by PID.
1590 2) the server correctly fails overlapping locks made by the same PID (this
1591 goes against POSIX behaviour, which is why it is tricky to implement)
1593 3) the server denies unlock requests by an incorrect client PID
1595 static bool run_locktest2(int dummy)
1597 static struct cli_state *cli;
1598 const char *fname = "\\lockt2.lck";
1599 uint16_t fnum1, fnum2, fnum3;
1600 bool correct = True;
1603 if (!torture_open_connection(&cli, 0)) {
1607 smbXcli_conn_set_sockopt(cli->conn, sockops);
1609 printf("starting locktest2\n");
1611 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1615 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1616 if (!NT_STATUS_IS_OK(status)) {
1617 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1621 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1622 if (!NT_STATUS_IS_OK(status)) {
1623 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1629 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1630 if (!NT_STATUS_IS_OK(status)) {
1631 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1637 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1638 if (!NT_STATUS_IS_OK(status)) {
1639 printf("lock1 failed (%s)\n", nt_errstr(status));
1643 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1644 if (NT_STATUS_IS_OK(status)) {
1645 printf("WRITE lock1 succeeded! This is a locking bug\n");
1648 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1649 NT_STATUS_LOCK_NOT_GRANTED)) {
1654 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1655 if (NT_STATUS_IS_OK(status)) {
1656 printf("WRITE lock2 succeeded! This is a locking bug\n");
1659 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1660 NT_STATUS_LOCK_NOT_GRANTED)) {
1665 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1666 if (NT_STATUS_IS_OK(status)) {
1667 printf("READ lock2 succeeded! This is a locking bug\n");
1670 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1671 NT_STATUS_FILE_LOCK_CONFLICT)) {
1676 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1677 if (!NT_STATUS_IS_OK(status)) {
1678 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1681 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1682 printf("unlock at 100 succeeded! This is a locking bug\n");
1686 status = cli_unlock(cli, fnum1, 0, 4);
1687 if (NT_STATUS_IS_OK(status)) {
1688 printf("unlock1 succeeded! This is a locking bug\n");
1691 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1692 NT_STATUS_RANGE_NOT_LOCKED)) {
1697 status = cli_unlock(cli, fnum1, 0, 8);
1698 if (NT_STATUS_IS_OK(status)) {
1699 printf("unlock2 succeeded! This is a locking bug\n");
1702 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1703 NT_STATUS_RANGE_NOT_LOCKED)) {
1708 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1709 if (NT_STATUS_IS_OK(status)) {
1710 printf("lock3 succeeded! This is a locking bug\n");
1713 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1714 NT_STATUS_LOCK_NOT_GRANTED)) {
1721 status = cli_close(cli, fnum1);
1722 if (!NT_STATUS_IS_OK(status)) {
1723 printf("close1 failed (%s)\n", nt_errstr(status));
1727 status = cli_close(cli, fnum2);
1728 if (!NT_STATUS_IS_OK(status)) {
1729 printf("close2 failed (%s)\n", nt_errstr(status));
1733 status = cli_close(cli, fnum3);
1734 if (!NT_STATUS_IS_OK(status)) {
1735 printf("close3 failed (%s)\n", nt_errstr(status));
1739 if (!torture_close_connection(cli)) {
1743 printf("locktest2 finished\n");
1750 This test checks that
1752 1) the server supports the full offset range in lock requests
1754 static bool run_locktest3(int dummy)
1756 static struct cli_state *cli1, *cli2;
1757 const char *fname = "\\lockt3.lck";
1758 uint16_t fnum1, fnum2;
1761 bool correct = True;
1764 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1766 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1769 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1770 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1772 printf("starting locktest3\n");
1774 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1776 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1778 if (!NT_STATUS_IS_OK(status)) {
1779 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1783 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1784 if (!NT_STATUS_IS_OK(status)) {
1785 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1789 for (offset=i=0;i<torture_numops;i++) {
1792 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1793 if (!NT_STATUS_IS_OK(status)) {
1794 printf("lock1 %d failed (%s)\n",
1800 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1801 if (!NT_STATUS_IS_OK(status)) {
1802 printf("lock2 %d failed (%s)\n",
1809 for (offset=i=0;i<torture_numops;i++) {
1812 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1813 if (NT_STATUS_IS_OK(status)) {
1814 printf("error: lock1 %d succeeded!\n", i);
1818 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1819 if (NT_STATUS_IS_OK(status)) {
1820 printf("error: lock2 %d succeeded!\n", i);
1824 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1825 if (NT_STATUS_IS_OK(status)) {
1826 printf("error: lock3 %d succeeded!\n", i);
1830 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1831 if (NT_STATUS_IS_OK(status)) {
1832 printf("error: lock4 %d succeeded!\n", i);
1837 for (offset=i=0;i<torture_numops;i++) {
1840 status = cli_unlock(cli1, fnum1, offset-1, 1);
1841 if (!NT_STATUS_IS_OK(status)) {
1842 printf("unlock1 %d failed (%s)\n",
1848 status = cli_unlock(cli2, fnum2, offset-2, 1);
1849 if (!NT_STATUS_IS_OK(status)) {
1850 printf("unlock2 %d failed (%s)\n",
1857 status = cli_close(cli1, fnum1);
1858 if (!NT_STATUS_IS_OK(status)) {
1859 printf("close1 failed (%s)\n", nt_errstr(status));
1863 status = cli_close(cli2, fnum2);
1864 if (!NT_STATUS_IS_OK(status)) {
1865 printf("close2 failed (%s)\n", nt_errstr(status));
1869 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1870 if (!NT_STATUS_IS_OK(status)) {
1871 printf("unlink failed (%s)\n", nt_errstr(status));
1875 if (!torture_close_connection(cli1)) {
1879 if (!torture_close_connection(cli2)) {
1883 printf("finished locktest3\n");
1888 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1889 char *buf, off_t offset, size_t size,
1890 size_t *nread, size_t expect)
1895 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1897 if(!NT_STATUS_IS_OK(status)) {
1899 } else if (l_nread != expect) {
1910 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1911 printf("** "); correct = False; \
1915 looks at overlapping locks
1917 static bool run_locktest4(int dummy)
1919 static struct cli_state *cli1, *cli2;
1920 const char *fname = "\\lockt4.lck";
1921 uint16_t fnum1, fnum2, f;
1924 bool correct = True;
1927 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1931 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1932 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1934 printf("starting locktest4\n");
1936 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1938 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1939 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1941 memset(buf, 0, sizeof(buf));
1943 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1945 if (!NT_STATUS_IS_OK(status)) {
1946 printf("Failed to create file: %s\n", nt_errstr(status));
1951 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1952 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1953 EXPECTED(ret, False);
1954 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1956 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1957 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1958 EXPECTED(ret, True);
1959 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1961 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1962 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1963 EXPECTED(ret, False);
1964 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1966 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1967 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1968 EXPECTED(ret, True);
1969 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1971 ret = (cli_setpid(cli1, 1),
1972 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1973 (cli_setpid(cli1, 2),
1974 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1975 EXPECTED(ret, False);
1976 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1978 ret = (cli_setpid(cli1, 1),
1979 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1980 (cli_setpid(cli1, 2),
1981 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1982 EXPECTED(ret, True);
1983 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1985 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1986 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1987 EXPECTED(ret, True);
1988 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1990 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1991 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1992 EXPECTED(ret, False);
1993 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1995 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1996 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1997 EXPECTED(ret, False);
1998 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
2000 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
2001 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2002 EXPECTED(ret, True);
2003 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2005 ret = (cli_setpid(cli1, 1),
2006 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2007 (cli_setpid(cli1, 2),
2008 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2009 EXPECTED(ret, False);
2010 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2012 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2013 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2014 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2015 EXPECTED(ret, False);
2016 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2019 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2020 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2021 EXPECTED(ret, False);
2022 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2024 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2025 ret = NT_STATUS_IS_OK(status);
2027 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2029 ret = NT_STATUS_IS_OK(status);
2031 EXPECTED(ret, False);
2032 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2035 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2036 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2037 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2038 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2039 EXPECTED(ret, True);
2040 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2043 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2044 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2045 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2046 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2047 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2049 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2050 EXPECTED(ret, True);
2051 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2053 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2054 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2055 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2057 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2058 EXPECTED(ret, True);
2059 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2061 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2062 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2063 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2065 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2066 EXPECTED(ret, True);
2067 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2069 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2070 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2071 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2072 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2074 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2075 EXPECTED(ret, True);
2076 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2078 cli_close(cli1, fnum1);
2079 cli_close(cli2, fnum2);
2080 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2081 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2082 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2083 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2084 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2085 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2086 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2088 cli_close(cli1, fnum1);
2089 EXPECTED(ret, True);
2090 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2093 cli_close(cli1, fnum1);
2094 cli_close(cli2, fnum2);
2095 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2096 torture_close_connection(cli1);
2097 torture_close_connection(cli2);
2099 printf("finished locktest4\n");
2104 looks at lock upgrade/downgrade.
2106 static bool run_locktest5(int dummy)
2108 static struct cli_state *cli1, *cli2;
2109 const char *fname = "\\lockt5.lck";
2110 uint16_t fnum1, fnum2, fnum3;
2113 bool correct = True;
2116 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2120 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2121 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2123 printf("starting locktest5\n");
2125 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2127 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2128 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2129 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2131 memset(buf, 0, sizeof(buf));
2133 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2135 if (!NT_STATUS_IS_OK(status)) {
2136 printf("Failed to create file: %s\n", nt_errstr(status));
2141 /* Check for NT bug... */
2142 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2143 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2144 cli_close(cli1, fnum1);
2145 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2146 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2147 ret = NT_STATUS_IS_OK(status);
2148 EXPECTED(ret, True);
2149 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2150 cli_close(cli1, fnum1);
2151 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2152 cli_unlock(cli1, fnum3, 0, 1);
2154 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2155 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2156 EXPECTED(ret, True);
2157 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2159 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2160 ret = NT_STATUS_IS_OK(status);
2161 EXPECTED(ret, False);
2163 printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2165 /* Unlock the process 2 lock. */
2166 cli_unlock(cli2, fnum2, 0, 4);
2168 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2169 ret = NT_STATUS_IS_OK(status);
2170 EXPECTED(ret, False);
2172 printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
2174 /* Unlock the process 1 fnum3 lock. */
2175 cli_unlock(cli1, fnum3, 0, 4);
2177 /* Stack 2 more locks here. */
2178 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2179 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2181 EXPECTED(ret, True);
2182 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2184 /* Unlock the first process lock, then check this was the WRITE lock that was
2187 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2188 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2190 EXPECTED(ret, True);
2191 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2193 /* Unlock the process 2 lock. */
2194 cli_unlock(cli2, fnum2, 0, 4);
2196 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2198 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2199 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2200 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2202 EXPECTED(ret, True);
2203 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2205 /* Ensure the next unlock fails. */
2206 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2207 EXPECTED(ret, False);
2208 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2210 /* Ensure connection 2 can get a write lock. */
2211 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2212 ret = NT_STATUS_IS_OK(status);
2213 EXPECTED(ret, True);
2215 printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2219 cli_close(cli1, fnum1);
2220 cli_close(cli2, fnum2);
2221 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2222 if (!torture_close_connection(cli1)) {
2225 if (!torture_close_connection(cli2)) {
2229 printf("finished locktest5\n");
2235 tries the unusual lockingX locktype bits
2237 static bool run_locktest6(int dummy)
2239 static struct cli_state *cli;
2240 const char *fname[1] = { "\\lock6.txt" };
2245 if (!torture_open_connection(&cli, 0)) {
2249 smbXcli_conn_set_sockopt(cli->conn, sockops);
2251 printf("starting locktest6\n");
2254 printf("Testing %s\n", fname[i]);
2256 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2258 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2259 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2260 cli_close(cli, fnum);
2261 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2263 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2264 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2265 cli_close(cli, fnum);
2266 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2268 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2271 torture_close_connection(cli);
2273 printf("finished locktest6\n");
2277 static bool run_locktest7(int dummy)
2279 struct cli_state *cli1;
2280 const char *fname = "\\lockt7.lck";
2283 bool correct = False;
2287 if (!torture_open_connection(&cli1, 0)) {
2291 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2293 printf("starting locktest7\n");
2295 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2297 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2299 memset(buf, 0, sizeof(buf));
2301 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2303 if (!NT_STATUS_IS_OK(status)) {
2304 printf("Failed to create file: %s\n", nt_errstr(status));
2308 cli_setpid(cli1, 1);
2310 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2311 if (!NT_STATUS_IS_OK(status)) {
2312 printf("Unable to apply read lock on range 130:4, "
2313 "error was %s\n", nt_errstr(status));
2316 printf("pid1 successfully locked range 130:4 for READ\n");
2319 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2320 if (!NT_STATUS_IS_OK(status)) {
2321 printf("pid1 unable to read the range 130:4, error was %s\n",
2324 } else if (nread != 4) {
2325 printf("pid1 unable to read the range 130:4, "
2326 "recv %ld req %d\n", (unsigned long)nread, 4);
2329 printf("pid1 successfully read the range 130:4\n");
2332 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2333 if (!NT_STATUS_IS_OK(status)) {
2334 printf("pid1 unable to write to the range 130:4, error was "
2335 "%s\n", nt_errstr(status));
2336 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2337 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2341 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2345 cli_setpid(cli1, 2);
2347 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2348 if (!NT_STATUS_IS_OK(status)) {
2349 printf("pid2 unable to read the range 130:4, error was %s\n",
2352 } else if (nread != 4) {
2353 printf("pid2 unable to read the range 130:4, "
2354 "recv %ld req %d\n", (unsigned long)nread, 4);
2357 printf("pid2 successfully read the range 130:4\n");
2360 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2361 if (!NT_STATUS_IS_OK(status)) {
2362 printf("pid2 unable to write to the range 130:4, error was "
2363 "%s\n", nt_errstr(status));
2364 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2365 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2369 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2373 cli_setpid(cli1, 1);
2374 cli_unlock(cli1, fnum1, 130, 4);
2376 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2381 printf("pid1 successfully locked range 130:4 for WRITE\n");
2384 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2385 if (!NT_STATUS_IS_OK(status)) {
2386 printf("pid1 unable to read the range 130:4, error was %s\n",
2389 } else if (nread != 4) {
2390 printf("pid1 unable to read the range 130:4, "
2391 "recv %ld req %d\n", (unsigned long)nread, 4);
2394 printf("pid1 successfully read the range 130:4\n");
2397 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2398 if (!NT_STATUS_IS_OK(status)) {
2399 printf("pid1 unable to write to the range 130:4, error was "
2400 "%s\n", nt_errstr(status));
2403 printf("pid1 successfully wrote to the range 130:4\n");
2406 cli_setpid(cli1, 2);
2408 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2409 if (!NT_STATUS_IS_OK(status)) {
2410 printf("pid2 unable to read the range 130:4, error was "
2411 "%s\n", nt_errstr(status));
2412 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2413 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2417 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2418 (unsigned long)nread);
2422 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2423 if (!NT_STATUS_IS_OK(status)) {
2424 printf("pid2 unable to write to the range 130:4, error was "
2425 "%s\n", nt_errstr(status));
2426 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2427 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2431 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2435 cli_unlock(cli1, fnum1, 130, 0);
2439 cli_close(cli1, fnum1);
2440 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2441 torture_close_connection(cli1);
2443 printf("finished locktest7\n");
2448 * This demonstrates a problem with our use of GPFS share modes: A file
2449 * descriptor sitting in the pending close queue holding a GPFS share mode
2450 * blocks opening a file another time. Happens with Word 2007 temp files.
2451 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2452 * open is denied with NT_STATUS_SHARING_VIOLATION.
2455 static bool run_locktest8(int dummy)
2457 struct cli_state *cli1;
2458 const char *fname = "\\lockt8.lck";
2459 uint16_t fnum1, fnum2;
2461 bool correct = False;
2464 if (!torture_open_connection(&cli1, 0)) {
2468 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2470 printf("starting locktest8\n");
2472 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2474 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2476 if (!NT_STATUS_IS_OK(status)) {
2477 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2481 memset(buf, 0, sizeof(buf));
2483 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2484 if (!NT_STATUS_IS_OK(status)) {
2485 d_fprintf(stderr, "cli_openx second time returned %s\n",
2490 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2491 if (!NT_STATUS_IS_OK(status)) {
2492 printf("Unable to apply read lock on range 1:1, error was "
2493 "%s\n", nt_errstr(status));
2497 status = cli_close(cli1, fnum1);
2498 if (!NT_STATUS_IS_OK(status)) {
2499 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2503 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2504 if (!NT_STATUS_IS_OK(status)) {
2505 d_fprintf(stderr, "cli_openx third time returned %s\n",
2513 cli_close(cli1, fnum1);
2514 cli_close(cli1, fnum2);
2515 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2516 torture_close_connection(cli1);
2518 printf("finished locktest8\n");
2523 * This test is designed to be run in conjunction with
2524 * external NFS or POSIX locks taken in the filesystem.
2525 * It checks that the smbd server will block until the
2526 * lock is released and then acquire it. JRA.
2529 static bool got_alarm;
2530 static struct cli_state *alarm_cli;
2532 static void alarm_handler(int dummy)
2537 static void alarm_handler_parent(int dummy)
2539 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2542 static void do_local_lock(int read_fd, int write_fd)
2547 const char *local_pathname = NULL;
2550 local_pathname = talloc_asprintf(talloc_tos(),
2551 "%s/lockt9.lck", local_path);
2552 if (!local_pathname) {
2553 printf("child: alloc fail\n");
2557 unlink(local_pathname);
2558 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2560 printf("child: open of %s failed %s.\n",
2561 local_pathname, strerror(errno));
2565 /* Now take a fcntl lock. */
2566 lock.l_type = F_WRLCK;
2567 lock.l_whence = SEEK_SET;
2570 lock.l_pid = getpid();
2572 ret = fcntl(fd,F_SETLK,&lock);
2574 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2575 local_pathname, strerror(errno));
2578 printf("child: got lock 0:4 on file %s.\n",
2583 CatchSignal(SIGALRM, alarm_handler);
2585 /* Signal the parent. */
2586 if (write(write_fd, &c, 1) != 1) {
2587 printf("child: start signal fail %s.\n",
2594 /* Wait for the parent to be ready. */
2595 if (read(read_fd, &c, 1) != 1) {
2596 printf("child: reply signal fail %s.\n",
2604 printf("child: released lock 0:4 on file %s.\n",
2610 static bool run_locktest9(int dummy)
2612 struct cli_state *cli1;
2613 const char *fname = "\\lockt9.lck";
2615 bool correct = False;
2616 int pipe_in[2], pipe_out[2];
2620 struct timeval start;
2624 printf("starting locktest9\n");
2626 if (local_path == NULL) {
2627 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2631 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2636 if (child_pid == -1) {
2640 if (child_pid == 0) {
2642 do_local_lock(pipe_out[0], pipe_in[1]);
2652 ret = read(pipe_in[0], &c, 1);
2654 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2659 if (!torture_open_connection(&cli1, 0)) {
2663 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2665 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2667 if (!NT_STATUS_IS_OK(status)) {
2668 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2672 /* Ensure the child has the lock. */
2673 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2674 if (NT_STATUS_IS_OK(status)) {
2675 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2678 d_printf("Child has the lock.\n");
2681 /* Tell the child to wait 5 seconds then exit. */
2682 ret = write(pipe_out[1], &c, 1);
2684 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2689 /* Wait 20 seconds for the lock. */
2691 CatchSignal(SIGALRM, alarm_handler_parent);
2694 start = timeval_current();
2696 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2697 if (!NT_STATUS_IS_OK(status)) {
2698 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2699 "%s\n", nt_errstr(status));
2704 seconds = timeval_elapsed(&start);
2706 printf("Parent got the lock after %.2f seconds.\n",
2709 status = cli_close(cli1, fnum);
2710 if (!NT_STATUS_IS_OK(status)) {
2711 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2718 cli_close(cli1, fnum);
2719 torture_close_connection(cli1);
2723 printf("finished locktest9\n");
2728 test whether fnums and tids open on one VC are available on another (a major
2731 static bool run_fdpasstest(int dummy)
2733 struct cli_state *cli1, *cli2;
2734 const char *fname = "\\fdpass.tst";
2739 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2742 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2743 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2745 printf("starting fdpasstest\n");
2747 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2749 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2751 if (!NT_STATUS_IS_OK(status)) {
2752 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2756 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2758 if (!NT_STATUS_IS_OK(status)) {
2759 printf("write failed (%s)\n", nt_errstr(status));
2763 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2764 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2765 cli_setpid(cli2, cli_getpid(cli1));
2767 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2768 printf("read succeeded! nasty security hole [%s]\n", buf);
2772 cli_close(cli1, fnum1);
2773 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2775 torture_close_connection(cli1);
2776 torture_close_connection(cli2);
2778 printf("finished fdpasstest\n");
2782 static bool run_fdsesstest(int dummy)
2784 struct cli_state *cli;
2786 uint16_t saved_vuid;
2788 uint32_t saved_cnum;
2789 const char *fname = "\\fdsess.tst";
2790 const char *fname1 = "\\fdsess1.tst";
2797 if (!torture_open_connection(&cli, 0))
2799 smbXcli_conn_set_sockopt(cli->conn, sockops);
2801 if (!torture_cli_session_setup2(cli, &new_vuid))
2804 saved_cnum = cli_state_get_tid(cli);
2805 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
2807 new_cnum = cli_state_get_tid(cli);
2808 cli_state_set_tid(cli, saved_cnum);
2810 printf("starting fdsesstest\n");
2812 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2813 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2815 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2816 if (!NT_STATUS_IS_OK(status)) {
2817 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2821 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2823 if (!NT_STATUS_IS_OK(status)) {
2824 printf("write failed (%s)\n", nt_errstr(status));
2828 saved_vuid = cli_state_get_uid(cli);
2829 cli_state_set_uid(cli, new_vuid);
2831 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2832 printf("read succeeded with different vuid! "
2833 "nasty security hole [%s]\n", buf);
2836 /* Try to open a file with different vuid, samba cnum. */
2837 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2838 printf("create with different vuid, same cnum succeeded.\n");
2839 cli_close(cli, fnum2);
2840 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2842 printf("create with different vuid, same cnum failed.\n");
2843 printf("This will cause problems with service clients.\n");
2847 cli_state_set_uid(cli, saved_vuid);
2849 /* Try with same vuid, different cnum. */
2850 cli_state_set_tid(cli, new_cnum);
2852 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2853 printf("read succeeded with different cnum![%s]\n", buf);
2857 cli_state_set_tid(cli, saved_cnum);
2858 cli_close(cli, fnum1);
2859 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2861 torture_close_connection(cli);
2863 printf("finished fdsesstest\n");
2868 This test checks that
2870 1) the server does not allow an unlink on a file that is open
2872 static bool run_unlinktest(int dummy)
2874 struct cli_state *cli;
2875 const char *fname = "\\unlink.tst";
2877 bool correct = True;
2880 if (!torture_open_connection(&cli, 0)) {
2884 smbXcli_conn_set_sockopt(cli->conn, sockops);
2886 printf("starting unlink test\n");
2888 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2892 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2893 if (!NT_STATUS_IS_OK(status)) {
2894 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2898 status = cli_unlink(cli, fname,
2899 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2900 if (NT_STATUS_IS_OK(status)) {
2901 printf("error: server allowed unlink on an open file\n");
2904 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2905 NT_STATUS_SHARING_VIOLATION);
2908 cli_close(cli, fnum);
2909 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2911 if (!torture_close_connection(cli)) {
2915 printf("unlink test finished\n");
2922 test how many open files this server supports on the one socket
2924 static bool run_maxfidtest(int dummy)
2926 struct cli_state *cli;
2928 uint16_t fnums[0x11000];
2931 bool correct = True;
2937 printf("failed to connect\n");
2941 smbXcli_conn_set_sockopt(cli->conn, sockops);
2943 for (i=0; i<0x11000; i++) {
2944 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2945 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2947 if (!NT_STATUS_IS_OK(status)) {
2948 printf("open of %s failed (%s)\n",
2949 fname, nt_errstr(status));
2950 printf("maximum fnum is %d\n", i);
2958 printf("cleaning up\n");
2960 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2961 cli_close(cli, fnums[i]);
2963 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2964 if (!NT_STATUS_IS_OK(status)) {
2965 printf("unlink of %s failed (%s)\n",
2966 fname, nt_errstr(status));
2973 printf("maxfid test finished\n");
2974 if (!torture_close_connection(cli)) {
2980 /* generate a random buffer */
2981 static void rand_buf(char *buf, int len)
2984 *buf = (char)sys_random();
2989 /* send smb negprot commands, not reading the response */
2990 static bool run_negprot_nowait(int dummy)
2992 struct tevent_context *ev;
2994 struct cli_state *cli;
2995 bool correct = True;
2997 printf("starting negprot nowait test\n");
2999 ev = samba_tevent_context_init(talloc_tos());
3004 if (!(cli = open_nbt_connection())) {
3009 for (i=0;i<50000;i++) {
3010 struct tevent_req *req;
3012 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3013 PROTOCOL_CORE, PROTOCOL_NT1, 0);
3018 if (!tevent_req_poll(req, ev)) {
3019 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3027 if (torture_close_connection(cli)) {
3031 printf("finished negprot nowait test\n");
3036 /* send smb negprot commands, not reading the response */
3037 static bool run_bad_nbt_session(int dummy)
3039 struct nmb_name called, calling;
3040 struct sockaddr_storage ss;
3045 printf("starting bad nbt session test\n");
3047 make_nmb_name(&calling, myname, 0x0);
3048 make_nmb_name(&called , host, 0x20);
3050 if (!resolve_name(host, &ss, 0x20, true)) {
3051 d_fprintf(stderr, "Could not resolve name %s\n", host);
3055 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3056 if (!NT_STATUS_IS_OK(status)) {
3057 d_fprintf(stderr, "open_socket_out failed: %s\n",
3062 ret = cli_bad_session_request(fd, &calling, &called);
3065 d_fprintf(stderr, "open_socket_out failed: %s\n",
3070 printf("finished bad nbt session test\n");
3074 /* send random IPC commands */
3075 static bool run_randomipc(int dummy)
3077 char *rparam = NULL;
3079 unsigned int rdrcnt,rprcnt;
3081 int api, param_len, i;
3082 struct cli_state *cli;
3083 bool correct = True;
3086 printf("starting random ipc test\n");
3088 if (!torture_open_connection(&cli, 0)) {
3092 for (i=0;i<count;i++) {
3093 api = sys_random() % 500;
3094 param_len = (sys_random() % 64);
3096 rand_buf(param, param_len);
3101 param, param_len, 8,
3102 NULL, 0, CLI_BUFFER_SIZE,
3106 printf("%d/%d\r", i,count);
3109 printf("%d/%d\n", i, count);
3111 if (!torture_close_connection(cli)) {
3118 printf("finished random ipc test\n");
3125 static void browse_callback(const char *sname, uint32_t stype,
3126 const char *comment, void *state)
3128 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3134 This test checks the browse list code
3137 static bool run_browsetest(int dummy)
3139 static struct cli_state *cli;
3140 bool correct = True;
3142 printf("starting browse test\n");
3144 if (!torture_open_connection(&cli, 0)) {
3148 printf("domain list:\n");
3149 cli_NetServerEnum(cli, cli->server_domain,
3150 SV_TYPE_DOMAIN_ENUM,
3151 browse_callback, NULL);
3153 printf("machine list:\n");
3154 cli_NetServerEnum(cli, cli->server_domain,
3156 browse_callback, NULL);
3158 if (!torture_close_connection(cli)) {
3162 printf("browse test finished\n");
3168 static bool check_attributes(struct cli_state *cli,
3170 uint16_t expected_attrs)
3173 NTSTATUS status = cli_getatr(cli,
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("cli_getatr failed with %s\n",
3183 if (attrs != expected_attrs) {
3184 printf("Attributes incorrect 0x%x, should be 0x%x\n",
3185 (unsigned int)attrs,
3186 (unsigned int)expected_attrs);
3193 This checks how the getatr calls works
3195 static bool run_attrtest(int dummy)
3197 struct cli_state *cli;
3200 const char *fname = "\\attrib123456789.tst";
3201 bool correct = True;
3204 printf("starting attrib test\n");
3206 if (!torture_open_connection(&cli, 0)) {
3210 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3211 cli_openx(cli, fname,
3212 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3213 cli_close(cli, fnum);
3215 status = cli_getatr(cli, fname, NULL, NULL, &t);
3216 if (!NT_STATUS_IS_OK(status)) {
3217 printf("getatr failed (%s)\n", nt_errstr(status));
3221 if (labs(t - time(NULL)) > 60*60*24*10) {
3222 printf("ERROR: SMBgetatr bug. time is %s",
3228 t2 = t-60*60*24; /* 1 day ago */
3230 status = cli_setatr(cli, fname, 0, t2);
3231 if (!NT_STATUS_IS_OK(status)) {
3232 printf("setatr failed (%s)\n", nt_errstr(status));
3236 status = cli_getatr(cli, fname, NULL, NULL, &t);
3237 if (!NT_STATUS_IS_OK(status)) {
3238 printf("getatr failed (%s)\n", nt_errstr(status));
3243 printf("ERROR: getatr/setatr bug. times are\n%s",
3245 printf("%s", ctime(&t2));
3249 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3251 /* Check cli_setpathinfo_basic() */
3252 /* Re-create the file. */
3253 status = cli_openx(cli, fname,
3254 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3255 if (!NT_STATUS_IS_OK(status)) {
3256 printf("Failed to recreate %s (%s)\n",
3257 fname, nt_errstr(status));
3260 cli_close(cli, fnum);
3262 status = cli_setpathinfo_basic(cli,
3268 FILE_ATTRIBUTE_SYSTEM |
3269 FILE_ATTRIBUTE_HIDDEN |
3270 FILE_ATTRIBUTE_READONLY);
3271 if (!NT_STATUS_IS_OK(status)) {
3272 printf("cli_setpathinfo_basic failed with %s\n",
3277 /* Check attributes are correct. */
3278 correct = check_attributes(cli,
3280 FILE_ATTRIBUTE_SYSTEM |
3281 FILE_ATTRIBUTE_HIDDEN |
3282 FILE_ATTRIBUTE_READONLY);
3283 if (correct == false) {
3287 /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
3288 status = cli_setpathinfo_basic(cli,
3294 FILE_ATTRIBUTE_NORMAL);
3295 if (!NT_STATUS_IS_OK(status)) {
3296 printf("cli_setpathinfo_basic failed with %s\n",
3301 /* Check attributes are correct. */
3302 correct = check_attributes(cli,
3304 FILE_ATTRIBUTE_SYSTEM |
3305 FILE_ATTRIBUTE_HIDDEN |
3306 FILE_ATTRIBUTE_READONLY);
3307 if (correct == false) {
3311 /* Setting to (uint16_t)-1 should also be ignored. */
3312 status = cli_setpathinfo_basic(cli,
3319 if (!NT_STATUS_IS_OK(status)) {
3320 printf("cli_setpathinfo_basic failed with %s\n",
3325 /* Check attributes are correct. */
3326 correct = check_attributes(cli,
3328 FILE_ATTRIBUTE_SYSTEM |
3329 FILE_ATTRIBUTE_HIDDEN |
3330 FILE_ATTRIBUTE_READONLY);
3331 if (correct == false) {
3335 /* Setting to 0 should clear them all. */
3336 status = cli_setpathinfo_basic(cli,
3343 if (!NT_STATUS_IS_OK(status)) {
3344 printf("cli_setpathinfo_basic failed with %s\n",
3349 /* Check attributes are correct. */
3350 correct = check_attributes(cli,
3352 FILE_ATTRIBUTE_NORMAL);
3353 if (correct == false) {
3361 FILE_ATTRIBUTE_SYSTEM |
3362 FILE_ATTRIBUTE_HIDDEN|
3363 FILE_ATTRIBUTE_READONLY);
3365 if (!torture_close_connection(cli)) {
3369 printf("attrib test finished\n");
3376 This checks a couple of trans2 calls
3378 static bool run_trans2test(int dummy)
3380 struct cli_state *cli;
3383 time_t c_time, a_time, m_time;
3384 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3385 const char *fname = "\\trans2.tst";
3386 const char *dname = "\\trans2";
3387 const char *fname2 = "\\trans2\\trans2.tst";
3389 bool correct = True;
3393 printf("starting trans2 test\n");
3395 if (!torture_open_connection(&cli, 0)) {
3399 status = cli_get_fs_attr_info(cli, &fs_attr);
3400 if (!NT_STATUS_IS_OK(status)) {
3401 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3406 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3407 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3408 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3409 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3410 if (!NT_STATUS_IS_OK(status)) {
3411 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3415 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3416 if (!NT_STATUS_IS_OK(status)) {
3417 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3420 else if (strcmp(pname, fname)) {
3421 printf("qfilename gave different name? [%s] [%s]\n",
3426 cli_close(cli, fnum);
3430 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3431 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3433 if (!NT_STATUS_IS_OK(status)) {
3434 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3437 cli_close(cli, fnum);
3439 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3441 if (!NT_STATUS_IS_OK(status)) {
3442 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3445 time_t t = time(NULL);
3447 if (c_time != m_time) {
3448 printf("create time=%s", ctime(&c_time));
3449 printf("modify time=%s", ctime(&m_time));
3450 printf("This system appears to have sticky create times\n");
3452 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3453 printf("access time=%s", ctime(&a_time));
3454 printf("This system appears to set a midnight access time\n");
3458 if (labs(m_time - t) > 60*60*24*7) {
3459 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3465 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3466 cli_openx(cli, fname,
3467 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3468 cli_close(cli, fnum);
3469 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3470 &m_time_ts, &size, NULL, NULL);
3471 if (!NT_STATUS_IS_OK(status)) {
3472 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3475 if (w_time_ts.tv_sec < 60*60*24*2) {
3476 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3477 printf("This system appears to set a initial 0 write time\n");
3482 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3485 /* check if the server updates the directory modification time
3486 when creating a new file */
3487 status = cli_mkdir(cli, dname);
3488 if (!NT_STATUS_IS_OK(status)) {
3489 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3493 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3494 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3495 if (!NT_STATUS_IS_OK(status)) {
3496 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3500 cli_openx(cli, fname2,
3501 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3502 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3503 cli_close(cli, fnum);
3504 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3505 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3506 if (!NT_STATUS_IS_OK(status)) {
3507 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3510 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3512 printf("This system does not update directory modification times\n");
3516 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3517 cli_rmdir(cli, dname);
3519 if (!torture_close_connection(cli)) {
3523 printf("trans2 test finished\n");
3529 This checks new W2K calls.
3532 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3534 uint8_t *buf = NULL;
3538 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3539 CLI_BUFFER_SIZE, NULL, &buf, &len);
3540 if (!NT_STATUS_IS_OK(status)) {
3541 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3544 printf("qfileinfo: level %d, len = %u\n", level, len);
3545 dump_data(0, (uint8_t *)buf, len);
3552 static bool run_w2ktest(int dummy)
3554 struct cli_state *cli;
3556 const char *fname = "\\w2ktest\\w2k.tst";
3558 bool correct = True;
3560 printf("starting w2k test\n");
3562 if (!torture_open_connection(&cli, 0)) {
3566 cli_openx(cli, fname,
3567 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3569 for (level = 1004; level < 1040; level++) {
3570 new_trans(cli, fnum, level);
3573 cli_close(cli, fnum);
3575 if (!torture_close_connection(cli)) {
3579 printf("w2k test finished\n");
3586 this is a harness for some oplock tests
3588 static bool run_oplock1(int dummy)
3590 struct cli_state *cli1;
3591 const char *fname = "\\lockt1.lck";
3593 bool correct = True;
3596 printf("starting oplock test 1\n");
3598 if (!torture_open_connection(&cli1, 0)) {
3602 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3604 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3606 cli1->use_oplocks = True;
3608 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3610 if (!NT_STATUS_IS_OK(status)) {
3611 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3615 cli1->use_oplocks = False;
3617 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3618 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3620 status = cli_close(cli1, fnum1);
3621 if (!NT_STATUS_IS_OK(status)) {
3622 printf("close2 failed (%s)\n", nt_errstr(status));
3626 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3627 if (!NT_STATUS_IS_OK(status)) {
3628 printf("unlink failed (%s)\n", nt_errstr(status));
3632 if (!torture_close_connection(cli1)) {
3636 printf("finished oplock test 1\n");
3641 static bool run_oplock2(int dummy)
3643 struct cli_state *cli1, *cli2;
3644 const char *fname = "\\lockt2.lck";
3645 uint16_t fnum1, fnum2;
3646 int saved_use_oplocks = use_oplocks;
3648 bool correct = True;
3649 volatile bool *shared_correct;
3653 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3654 *shared_correct = True;
3656 use_level_II_oplocks = True;
3659 printf("starting oplock test 2\n");
3661 if (!torture_open_connection(&cli1, 0)) {
3662 use_level_II_oplocks = False;
3663 use_oplocks = saved_use_oplocks;
3667 if (!torture_open_connection(&cli2, 1)) {
3668 use_level_II_oplocks = False;
3669 use_oplocks = saved_use_oplocks;
3673 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3675 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3676 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3678 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3680 if (!NT_STATUS_IS_OK(status)) {
3681 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3685 /* Don't need the globals any more. */
3686 use_level_II_oplocks = False;
3687 use_oplocks = saved_use_oplocks;
3691 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3692 if (!NT_STATUS_IS_OK(status)) {
3693 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3694 *shared_correct = False;
3700 status = cli_close(cli2, fnum2);
3701 if (!NT_STATUS_IS_OK(status)) {
3702 printf("close2 failed (%s)\n", nt_errstr(status));
3703 *shared_correct = False;
3711 /* Ensure cli1 processes the break. Empty file should always return 0
3713 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3714 if (!NT_STATUS_IS_OK(status)) {
3715 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3717 } else if (nread != 0) {
3718 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3719 (unsigned long)nread, 0);
3723 /* Should now be at level II. */
3724 /* Test if sending a write locks causes a break to none. */
3725 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3726 if (!NT_STATUS_IS_OK(status)) {
3727 printf("lock failed (%s)\n", nt_errstr(status));
3731 cli_unlock(cli1, fnum1, 0, 4);
3735 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3736 if (!NT_STATUS_IS_OK(status)) {
3737 printf("lock failed (%s)\n", nt_errstr(status));
3741 cli_unlock(cli1, fnum1, 0, 4);
3745 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3747 status = cli_close(cli1, fnum1);
3748 if (!NT_STATUS_IS_OK(status)) {
3749 printf("close1 failed (%s)\n", nt_errstr(status));
3755 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3756 if (!NT_STATUS_IS_OK(status)) {
3757 printf("unlink failed (%s)\n", nt_errstr(status));
3761 if (!torture_close_connection(cli1)) {
3765 if (!*shared_correct) {
3769 printf("finished oplock test 2\n");
3774 struct oplock4_state {
3775 struct tevent_context *ev;
3776 struct cli_state *cli;
3781 static void oplock4_got_break(struct tevent_req *req);
3782 static void oplock4_got_open(struct tevent_req *req);
3784 static bool run_oplock4(int dummy)
3786 struct tevent_context *ev;
3787 struct cli_state *cli1, *cli2;
3788 struct tevent_req *oplock_req, *open_req;
3789 const char *fname = "\\lockt4.lck";
3790 const char *fname_ln = "\\lockt4_ln.lck";
3791 uint16_t fnum1, fnum2;
3792 int saved_use_oplocks = use_oplocks;
3794 bool correct = true;
3798 struct oplock4_state *state;
3800 printf("starting oplock test 4\n");
3802 if (!torture_open_connection(&cli1, 0)) {
3803 use_level_II_oplocks = false;
3804 use_oplocks = saved_use_oplocks;
3808 if (!torture_open_connection(&cli2, 1)) {
3809 use_level_II_oplocks = false;
3810 use_oplocks = saved_use_oplocks;
3814 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3815 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3817 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3818 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3820 /* Create the file. */
3821 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3823 if (!NT_STATUS_IS_OK(status)) {
3824 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3828 status = cli_close(cli1, fnum1);
3829 if (!NT_STATUS_IS_OK(status)) {
3830 printf("close1 failed (%s)\n", nt_errstr(status));
3834 /* Now create a hardlink. */
3835 status = cli_nt_hardlink(cli1, fname, fname_ln);
3836 if (!NT_STATUS_IS_OK(status)) {
3837 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3841 /* Prove that opening hardlinks cause deny modes to conflict. */
3842 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3843 if (!NT_STATUS_IS_OK(status)) {
3844 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3848 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3849 if (NT_STATUS_IS_OK(status)) {
3850 printf("open of %s succeeded - should fail with sharing violation.\n",
3855 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3856 printf("open of %s should fail with sharing violation. Got %s\n",
3857 fname_ln, nt_errstr(status));
3861 status = cli_close(cli1, fnum1);
3862 if (!NT_STATUS_IS_OK(status)) {
3863 printf("close1 failed (%s)\n", nt_errstr(status));
3867 cli1->use_oplocks = true;
3868 cli2->use_oplocks = true;
3870 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3871 if (!NT_STATUS_IS_OK(status)) {
3872 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3876 ev = samba_tevent_context_init(talloc_tos());
3878 printf("tevent_context_init failed\n");
3882 state = talloc(ev, struct oplock4_state);
3883 if (state == NULL) {
3884 printf("talloc failed\n");
3889 state->got_break = &got_break;
3890 state->fnum2 = &fnum2;
3892 oplock_req = cli_smb_oplock_break_waiter_send(
3893 talloc_tos(), ev, cli1);
3894 if (oplock_req == NULL) {
3895 printf("cli_smb_oplock_break_waiter_send failed\n");
3898 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3900 open_req = cli_openx_send(
3901 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3902 if (open_req == NULL) {
3903 printf("cli_openx_send failed\n");
3906 tevent_req_set_callback(open_req, oplock4_got_open, state);
3911 while (!got_break || fnum2 == 0xffff) {
3913 ret = tevent_loop_once(ev);
3915 printf("tevent_loop_once failed: %s\n",
3921 status = cli_close(cli2, fnum2);
3922 if (!NT_STATUS_IS_OK(status)) {
3923 printf("close2 failed (%s)\n", nt_errstr(status));
3927 status = cli_close(cli1, fnum1);
3928 if (!NT_STATUS_IS_OK(status)) {
3929 printf("close1 failed (%s)\n", nt_errstr(status));
3933 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 printf("unlink failed (%s)\n", nt_errstr(status));
3939 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3940 if (!NT_STATUS_IS_OK(status)) {
3941 printf("unlink failed (%s)\n", nt_errstr(status));
3945 if (!torture_close_connection(cli1)) {
3953 printf("finished oplock test 4\n");
3958 static void oplock4_got_break(struct tevent_req *req)
3960 struct oplock4_state *state = tevent_req_callback_data(
3961 req, struct oplock4_state);
3966 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3968 if (!NT_STATUS_IS_OK(status)) {
3969 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3973 *state->got_break = true;
3975 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3978 printf("cli_oplock_ack_send failed\n");
3983 static void oplock4_got_open(struct tevent_req *req)
3985 struct oplock4_state *state = tevent_req_callback_data(
3986 req, struct oplock4_state);
3989 status = cli_openx_recv(req, state->fnum2);
3990 if (!NT_STATUS_IS_OK(status)) {
3991 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3992 *state->fnum2 = 0xffff;
3997 Test delete on close semantics.
3999 static bool run_deletetest(int dummy)
4001 struct cli_state *cli1 = NULL;
4002 struct cli_state *cli2 = NULL;
4003 const char *fname = "\\delete.file";
4004 uint16_t fnum1 = (uint16_t)-1;
4005 uint16_t fnum2 = (uint16_t)-1;
4006 bool correct = false;
4009 printf("starting delete test\n");
4011 if (!torture_open_connection(&cli1, 0)) {
4015 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4017 /* Test 1 - this should delete the file on close. */
4019 cli_setatr(cli1, fname, 0, 0);
4020 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4022 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4023 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4024 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4025 if (!NT_STATUS_IS_OK(status)) {
4026 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
4030 status = cli_close(cli1, fnum1);
4031 if (!NT_STATUS_IS_OK(status)) {
4032 printf("[1] close failed (%s)\n", nt_errstr(status));
4036 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
4037 if (NT_STATUS_IS_OK(status)) {
4038 printf("[1] open of %s succeeded (should fail)\n", fname);
4042 printf("first delete on close test succeeded.\n");
4044 /* Test 2 - this should delete the file on close. */
4046 cli_setatr(cli1, fname, 0, 0);
4047 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4049 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4050 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4051 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4052 if (!NT_STATUS_IS_OK(status)) {
4053 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
4057 status = cli_nt_delete_on_close(cli1, fnum1, true);
4058 if (!NT_STATUS_IS_OK(status)) {
4059 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
4063 status = cli_close(cli1, fnum1);
4064 if (!NT_STATUS_IS_OK(status)) {
4065 printf("[2] close failed (%s)\n", nt_errstr(status));
4069 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4070 if (NT_STATUS_IS_OK(status)) {
4071 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
4072 status = cli_close(cli1, fnum1);
4073 if (!NT_STATUS_IS_OK(status)) {
4074 printf("[2] close failed (%s)\n", nt_errstr(status));
4076 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4080 printf("second delete on close test succeeded.\n");
4083 cli_setatr(cli1, fname, 0, 0);
4084 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4086 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4087 FILE_ATTRIBUTE_NORMAL,
4088 FILE_SHARE_READ|FILE_SHARE_WRITE,
4089 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4090 if (!NT_STATUS_IS_OK(status)) {
4091 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
4095 /* This should fail with a sharing violation - open for delete is only compatible
4096 with SHARE_DELETE. */
4098 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4099 FILE_ATTRIBUTE_NORMAL,
4100 FILE_SHARE_READ|FILE_SHARE_WRITE,
4101 FILE_OPEN, 0, 0, &fnum2, NULL);
4102 if (NT_STATUS_IS_OK(status)) {
4103 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4107 /* This should succeed. */
4108 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4109 FILE_ATTRIBUTE_NORMAL,
4110 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4111 FILE_OPEN, 0, 0, &fnum2, NULL);
4112 if (!NT_STATUS_IS_OK(status)) {
4113 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
4117 status = cli_nt_delete_on_close(cli1, fnum1, true);
4118 if (!NT_STATUS_IS_OK(status)) {
4119 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4123 status = cli_close(cli1, fnum1);
4124 if (!NT_STATUS_IS_OK(status)) {
4125 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4129 status = cli_close(cli1, fnum2);
4130 if (!NT_STATUS_IS_OK(status)) {
4131 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4135 /* This should fail - file should no longer be there. */
4137 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4138 if (NT_STATUS_IS_OK(status)) {
4139 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4140 status = cli_close(cli1, fnum1);
4141 if (!NT_STATUS_IS_OK(status)) {
4142 printf("[3] close failed (%s)\n", nt_errstr(status));
4144 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4148 printf("third delete on close test succeeded.\n");
4151 cli_setatr(cli1, fname, 0, 0);
4152 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4154 status = cli_ntcreate(cli1, fname, 0,
4155 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4156 FILE_ATTRIBUTE_NORMAL,
4157 FILE_SHARE_READ|FILE_SHARE_WRITE,
4158 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4159 if (!NT_STATUS_IS_OK(status)) {
4160 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4164 /* This should succeed. */
4165 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4166 FILE_ATTRIBUTE_NORMAL,
4167 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4168 FILE_OPEN, 0, 0, &fnum2, NULL);
4169 if (!NT_STATUS_IS_OK(status)) {
4170 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4174 status = cli_close(cli1, fnum2);
4175 if (!NT_STATUS_IS_OK(status)) {
4176 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4180 status = cli_nt_delete_on_close(cli1, fnum1, true);
4181 if (!NT_STATUS_IS_OK(status)) {
4182 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4186 /* This should fail - no more opens once delete on close set. */
4187 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4188 FILE_ATTRIBUTE_NORMAL,
4189 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4190 FILE_OPEN, 0, 0, &fnum2, NULL);
4191 if (NT_STATUS_IS_OK(status)) {
4192 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4196 status = cli_close(cli1, fnum1);
4197 if (!NT_STATUS_IS_OK(status)) {
4198 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4202 printf("fourth delete on close test succeeded.\n");
4205 cli_setatr(cli1, fname, 0, 0);
4206 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4208 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4209 if (!NT_STATUS_IS_OK(status)) {
4210 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4214 /* This should fail - only allowed on NT opens with DELETE access. */
4216 status = cli_nt_delete_on_close(cli1, fnum1, true);
4217 if (NT_STATUS_IS_OK(status)) {
4218 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4222 status = cli_close(cli1, fnum1);
4223 if (!NT_STATUS_IS_OK(status)) {
4224 printf("[5] close failed (%s)\n", nt_errstr(status));
4228 printf("fifth delete on close test succeeded.\n");
4231 cli_setatr(cli1, fname, 0, 0);
4232 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4234 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4235 FILE_ATTRIBUTE_NORMAL,
4236 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4237 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4238 if (!NT_STATUS_IS_OK(status)) {
4239 printf("[6] open of %s failed (%s)\n", fname,
4244 /* This should fail - only allowed on NT opens with DELETE access. */
4246 status = cli_nt_delete_on_close(cli1, fnum1, true);
4247 if (NT_STATUS_IS_OK(status)) {
4248 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4252 status = cli_close(cli1, fnum1);
4253 if (!NT_STATUS_IS_OK(status)) {
4254 printf("[6] close failed (%s)\n", nt_errstr(status));
4258 printf("sixth delete on close test succeeded.\n");
4261 cli_setatr(cli1, fname, 0, 0);
4262 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4264 status = cli_ntcreate(cli1, fname, 0,
4265 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4266 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4267 0, 0, &fnum1, NULL);
4268 if (!NT_STATUS_IS_OK(status)) {
4269 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4273 status = cli_nt_delete_on_close(cli1, fnum1, true);
4274 if (!NT_STATUS_IS_OK(status)) {
4275 printf("[7] setting delete_on_close on file failed !\n");
4279 status = cli_nt_delete_on_close(cli1, fnum1, false);
4280 if (!NT_STATUS_IS_OK(status)) {
4281 printf("[7] unsetting delete_on_close on file failed !\n");
4285 status = cli_close(cli1, fnum1);
4286 if (!NT_STATUS_IS_OK(status)) {
4287 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4291 /* This next open should succeed - we reset the flag. */
4292 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4293 if (!NT_STATUS_IS_OK(status)) {
4294 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4298 status = cli_close(cli1, fnum1);
4299 if (!NT_STATUS_IS_OK(status)) {
4300 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4304 printf("seventh delete on close test succeeded.\n");
4307 cli_setatr(cli1, fname, 0, 0);
4308 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4310 if (!torture_open_connection(&cli2, 1)) {
4311 printf("[8] failed to open second connection.\n");
4315 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4317 status = cli_ntcreate(cli1, fname, 0,
4318 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4319 FILE_ATTRIBUTE_NORMAL,
4320 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4321 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4322 if (!NT_STATUS_IS_OK(status)) {
4323 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4327 status = cli_ntcreate(cli2, fname, 0,
4328 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_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("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4337 status = cli_nt_delete_on_close(cli1, fnum1, true);
4338 if (!NT_STATUS_IS_OK(status)) {
4339 printf("[8] setting delete_on_close on file failed !\n");
4343 status = cli_close(cli1, fnum1);
4344 if (!NT_STATUS_IS_OK(status)) {
4345 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4349 status = cli_close(cli2, fnum2);
4350 if (!NT_STATUS_IS_OK(status)) {
4351 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4355 /* This should fail.. */
4356 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4357 if (NT_STATUS_IS_OK(status)) {
4358 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4362 printf("eighth delete on close test succeeded.\n");
4366 /* This should fail - we need to set DELETE_ACCESS. */
4367 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4368 FILE_ATTRIBUTE_NORMAL,
4371 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4372 if (NT_STATUS_IS_OK(status)) {
4373 printf("[9] open of %s succeeded should have failed!\n", fname);
4377 printf("ninth delete on close test succeeded.\n");
4381 status = cli_ntcreate(cli1, fname, 0,
4382 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4383 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4384 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4386 if (!NT_STATUS_IS_OK(status)) {
4387 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4391 /* This should delete the file. */
4392 status = cli_close(cli1, fnum1);
4393 if (!NT_STATUS_IS_OK(status)) {
4394 printf("[10] close failed (%s)\n", nt_errstr(status));
4398 /* This should fail.. */
4399 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4400 if (NT_STATUS_IS_OK(status)) {
4401 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4405 printf("tenth delete on close test succeeded.\n");
4409 cli_setatr(cli1, fname, 0, 0);
4410 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4412 /* Can we open a read-only file with delete access? */
4414 /* Create a readonly file. */
4415 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4416 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4417 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4418 if (!NT_STATUS_IS_OK(status)) {
4419 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4423 status = cli_close(cli1, fnum1);
4424 if (!NT_STATUS_IS_OK(status)) {
4425 printf("[11] close failed (%s)\n", nt_errstr(status));
4429 /* Now try open for delete access. */
4430 status = cli_ntcreate(cli1, fname, 0,
4431 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4433 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4434 FILE_OPEN, 0, 0, &fnum1, NULL);
4435 if (!NT_STATUS_IS_OK(status)) {
4436 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4440 cli_close(cli1, fnum1);
4442 printf("eleventh delete on close test succeeded.\n");
4446 * like test 4 but with initial delete on close
4449 cli_setatr(cli1, fname, 0, 0);
4450 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4452 status = cli_ntcreate(cli1, fname, 0,
4453 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4454 FILE_ATTRIBUTE_NORMAL,
4455 FILE_SHARE_READ|FILE_SHARE_WRITE,
4457 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4458 if (!NT_STATUS_IS_OK(status)) {
4459 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4463 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4464 FILE_ATTRIBUTE_NORMAL,
4465 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4466 FILE_OPEN, 0, 0, &fnum2, NULL);
4467 if (!NT_STATUS_IS_OK(status)) {
4468 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4472 status = cli_close(cli1, fnum2);
4473 if (!NT_STATUS_IS_OK(status)) {
4474 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4478 status = cli_nt_delete_on_close(cli1, fnum1, true);
4479 if (!NT_STATUS_IS_OK(status)) {
4480 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4484 /* This should fail - no more opens once delete on close set. */
4485 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4486 FILE_ATTRIBUTE_NORMAL,
4487 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4488 FILE_OPEN, 0, 0, &fnum2, NULL);
4489 if (NT_STATUS_IS_OK(status)) {
4490 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4494 status = cli_nt_delete_on_close(cli1, fnum1, false);
4495 if (!NT_STATUS_IS_OK(status)) {
4496 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4500 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4501 FILE_ATTRIBUTE_NORMAL,
4502 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4503 FILE_OPEN, 0, 0, &fnum2, NULL);
4504 if (!NT_STATUS_IS_OK(status)) {
4505 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4509 status = cli_close(cli1, fnum2);
4510 if (!NT_STATUS_IS_OK(status)) {
4511 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4515 status = cli_close(cli1, fnum1);
4516 if (!NT_STATUS_IS_OK(status)) {
4517 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4522 * setting delete on close on the handle does
4523 * not unset the initial delete on close...
4525 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4526 FILE_ATTRIBUTE_NORMAL,
4527 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4528 FILE_OPEN, 0, 0, &fnum2, NULL);
4529 if (NT_STATUS_IS_OK(status)) {
4530 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4532 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4533 printf("ntcreate returned %s, expected "
4534 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4539 printf("twelfth delete on close test succeeded.\n");
4542 printf("finished delete test\n");
4547 /* FIXME: This will crash if we aborted before cli2 got
4548 * intialized, because these functions don't handle
4549 * uninitialized connections. */
4551 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4552 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4553 cli_setatr(cli1, fname, 0, 0);
4554 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4556 if (cli1 && !torture_close_connection(cli1)) {
4559 if (cli2 && !torture_close_connection(cli2)) {
4566 Exercise delete on close semantics - use on the PRINT1 share in torture
4569 static bool run_delete_print_test(int dummy)
4571 struct cli_state *cli1 = NULL;
4572 const char *fname = "print_delete.file";
4573 uint16_t fnum1 = (uint16_t)-1;
4574 bool correct = false;
4575 const char *buf = "print file data\n";
4578 printf("starting print delete test\n");
4580 if (!torture_open_connection(&cli1, 0)) {
4584 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4586 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4587 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4588 0, 0, &fnum1, NULL);
4589 if (!NT_STATUS_IS_OK(status)) {
4590 printf("open of %s failed (%s)\n",
4596 status = cli_writeall(cli1,
4599 (const uint8_t *)buf,
4601 strlen(buf), /* size */
4603 if (!NT_STATUS_IS_OK(status)) {
4604 printf("writing print file data failed (%s)\n",
4609 status = cli_nt_delete_on_close(cli1, fnum1, true);
4610 if (!NT_STATUS_IS_OK(status)) {
4611 printf("setting delete_on_close failed (%s)\n",
4616 status = cli_close(cli1, fnum1);
4617 if (!NT_STATUS_IS_OK(status)) {
4618 printf("close failed (%s)\n", nt_errstr(status));
4622 printf("finished print delete test\n");
4628 if (fnum1 != (uint16_t)-1) {
4629 cli_close(cli1, fnum1);
4632 if (cli1 && !torture_close_connection(cli1)) {
4639 Test wildcard delete.
4641 static bool run_wild_deletetest(int dummy)
4643 struct cli_state *cli = NULL;
4644 const char *dname = "\\WTEST";
4645 const char *fname = "\\WTEST\\A";
4646 const char *wunlink_name = "\\WTEST\\*";
4647 uint16_t fnum1 = (uint16_t)-1;
4648 bool correct = false;
4651 printf("starting wildcard delete test\n");
4653 if (!torture_open_connection(&cli, 0)) {
4657 smbXcli_conn_set_sockopt(cli->conn, sockops);
4659 cli_unlink(cli, fname, 0);
4660 cli_rmdir(cli, dname);
4661 status = cli_mkdir(cli, dname);
4662 if (!NT_STATUS_IS_OK(status)) {
4663 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4666 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4667 if (!NT_STATUS_IS_OK(status)) {
4668 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4671 status = cli_close(cli, fnum1);
4675 * Note the unlink attribute-type of zero. This should
4676 * map into FILE_ATTRIBUTE_NORMAL at the server even
4677 * on a wildcard delete.
4680 status = cli_unlink(cli, wunlink_name, 0);
4681 if (!NT_STATUS_IS_OK(status)) {
4682 printf("unlink of %s failed %s!\n",
4683 wunlink_name, nt_errstr(status));
4687 printf("finished wildcard delete test\n");
4693 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4694 cli_unlink(cli, fname, 0);
4695 cli_rmdir(cli, dname);
4697 if (cli && !torture_close_connection(cli)) {
4703 static bool run_deletetest_ln(int dummy)
4705 struct cli_state *cli;
4706 const char *fname = "\\delete1";
4707 const char *fname_ln = "\\delete1_ln";
4711 bool correct = true;
4714 printf("starting deletetest-ln\n");
4716 if (!torture_open_connection(&cli, 0)) {
4720 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4721 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4723 smbXcli_conn_set_sockopt(cli->conn, sockops);
4725 /* Create the file. */
4726 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4727 if (!NT_STATUS_IS_OK(status)) {
4728 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4732 status = cli_close(cli, fnum);
4733 if (!NT_STATUS_IS_OK(status)) {
4734 printf("close1 failed (%s)\n", nt_errstr(status));
4738 /* Now create a hardlink. */
4739 status = cli_nt_hardlink(cli, fname, fname_ln);
4740 if (!NT_STATUS_IS_OK(status)) {
4741 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4745 /* Open the original file. */
4746 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4747 FILE_ATTRIBUTE_NORMAL,
4748 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4749 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4750 if (!NT_STATUS_IS_OK(status)) {
4751 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4755 /* Unlink the hard link path. */
4756 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4757 FILE_ATTRIBUTE_NORMAL,
4758 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4759 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4760 if (!NT_STATUS_IS_OK(status)) {
4761 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4764 status = cli_nt_delete_on_close(cli, fnum1, true);
4765 if (!NT_STATUS_IS_OK(status)) {
4766 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4767 __location__, fname_ln, nt_errstr(status));
4771 status = cli_close(cli, fnum1);
4772 if (!NT_STATUS_IS_OK(status)) {
4773 printf("close %s failed (%s)\n",
4774 fname_ln, nt_errstr(status));
4778 status = cli_close(cli, fnum);
4779 if (!NT_STATUS_IS_OK(status)) {
4780 printf("close %s failed (%s)\n",
4781 fname, nt_errstr(status));
4785 /* Ensure the original file is still there. */
4786 status = cli_getatr(cli, fname, NULL, NULL, &t);
4787 if (!NT_STATUS_IS_OK(status)) {
4788 printf("%s getatr on file %s failed (%s)\n",
4795 /* Ensure the link path is gone. */
4796 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4797 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4798 printf("%s, getatr for file %s returned wrong error code %s "
4799 "- should have been deleted\n",
4801 fname_ln, nt_errstr(status));
4805 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4806 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4808 if (!torture_close_connection(cli)) {
4812 printf("finished deletetest-ln\n");
4818 print out server properties
4820 static bool run_properties(int dummy)
4822 struct cli_state *cli;
4823 bool correct = True;
4825 printf("starting properties test\n");
4829 if (!torture_open_connection(&cli, 0)) {
4833 smbXcli_conn_set_sockopt(cli->conn, sockops);
4835 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4837 if (!torture_close_connection(cli)) {
4846 /* FIRST_DESIRED_ACCESS 0xf019f */
4847 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4848 FILE_READ_EA| /* 0xf */ \
4849 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4850 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4851 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4852 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4853 /* SECOND_DESIRED_ACCESS 0xe0080 */
4854 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4855 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4856 WRITE_OWNER_ACCESS /* 0xe0000 */
4859 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4860 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4862 WRITE_OWNER_ACCESS /* */
4866 Test ntcreate calls made by xcopy
4868 static bool run_xcopy(int dummy)
4870 static struct cli_state *cli1;
4871 const char *fname = "\\test.txt";
4872 bool correct = True;
4873 uint16_t fnum1, fnum2;
4876 printf("starting xcopy test\n");
4878 if (!torture_open_connection(&cli1, 0)) {
4882 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4883 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4884 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4885 if (!NT_STATUS_IS_OK(status)) {
4886 printf("First open failed - %s\n", nt_errstr(status));
4890 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4891 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4892 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4893 if (!NT_STATUS_IS_OK(status)) {
4894 printf("second open failed - %s\n", nt_errstr(status));
4898 if (!torture_close_connection(cli1)) {
4906 Test rename on files open with share delete and no share delete.
4908 static bool run_rename(int dummy)
4910 static struct cli_state *cli1;
4911 const char *fname = "\\test.txt";
4912 const char *fname1 = "\\test1.txt";
4913 bool correct = True;
4918 printf("starting rename test\n");
4920 if (!torture_open_connection(&cli1, 0)) {
4924 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4925 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4927 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4928 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4929 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4930 if (!NT_STATUS_IS_OK(status)) {
4931 printf("First open failed - %s\n", nt_errstr(status));
4935 status = cli_rename(cli1, fname, fname1, false);
4936 if (!NT_STATUS_IS_OK(status)) {
4937 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4939 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4943 status = cli_close(cli1, fnum1);
4944 if (!NT_STATUS_IS_OK(status)) {
4945 printf("close - 1 failed (%s)\n", nt_errstr(status));
4949 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4950 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4951 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4953 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4955 FILE_SHARE_DELETE|FILE_SHARE_READ,
4957 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4958 if (!NT_STATUS_IS_OK(status)) {
4959 printf("Second open failed - %s\n", nt_errstr(status));
4963 status = cli_rename(cli1, fname, fname1, false);
4964 if (!NT_STATUS_IS_OK(status)) {
4965 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4968 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4971 status = cli_close(cli1, fnum1);
4972 if (!NT_STATUS_IS_OK(status)) {
4973 printf("close - 2 failed (%s)\n", nt_errstr(status));
4977 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4978 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4980 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4981 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4982 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4983 if (!NT_STATUS_IS_OK(status)) {
4984 printf("Third open failed - %s\n", nt_errstr(status));
4993 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4994 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4995 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4998 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4999 printf("[8] setting delete_on_close on file failed !\n");
5003 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
5004 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
5010 status = cli_rename(cli1, fname, fname1, false);
5011 if (!NT_STATUS_IS_OK(status)) {
5012 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
5015 printf("Third rename succeeded (SHARE_NONE)\n");
5018 status = cli_close(cli1, fnum1);
5019 if (!NT_STATUS_IS_OK(status)) {
5020 printf("close - 3 failed (%s)\n", nt_errstr(status));
5024 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5025 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5029 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5030 FILE_ATTRIBUTE_NORMAL,
5031 FILE_SHARE_READ | FILE_SHARE_WRITE,
5032 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5033 if (!NT_STATUS_IS_OK(status)) {
5034 printf("Fourth open failed - %s\n", nt_errstr(status));
5038 status = cli_rename(cli1, fname, fname1, false);
5039 if (!NT_STATUS_IS_OK(status)) {
5040 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
5042 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
5046 status = cli_close(cli1, fnum1);
5047 if (!NT_STATUS_IS_OK(status)) {
5048 printf("close - 4 failed (%s)\n", nt_errstr(status));
5052 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5053 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5057 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5058 FILE_ATTRIBUTE_NORMAL,
5059 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5060 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5061 if (!NT_STATUS_IS_OK(status)) {
5062 printf("Fifth open failed - %s\n", nt_errstr(status));
5066 status = cli_rename(cli1, fname, fname1, false);
5067 if (!NT_STATUS_IS_OK(status)) {
5068 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
5071 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
5075 * Now check if the first name still exists ...
5078 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
5079 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5080 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
5081 printf("Opening original file after rename of open file fails: %s\n",
5085 printf("Opening original file after rename of open file works ...\n");
5086 (void)cli_close(cli1, fnum2);
5090 status = cli_close(cli1, fnum1);
5091 if (!NT_STATUS_IS_OK(status)) {
5092 printf("close - 5 failed (%s)\n", nt_errstr(status));
5096 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
5097 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
5098 if (!NT_STATUS_IS_OK(status)) {
5099 printf("getatr on file %s failed - %s ! \n",
5100 fname1, nt_errstr(status));
5103 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
5104 printf("Renamed file %s has wrong attr 0x%x "
5105 "(should be 0x%x)\n",
5108 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
5111 printf("Renamed file %s has archive bit set\n", fname1);
5115 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5116 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5118 if (!torture_close_connection(cli1)) {
5126 Test rename into a directory with an ACL denying it.
5128 static bool run_rename_access(int dummy)
5130 static struct cli_state *cli = NULL;
5131 static struct cli_state *posix_cli = NULL;
5132 const char *src = "test.txt";
5133 const char *dname = "dir";
5134 const char *dst = "dir\\test.txt";
5135 const char *dsrc = "test.dir";
5136 const char *ddst = "dir\\test.dir";
5137 uint16_t fnum = (uint16_t)-1;
5138 struct security_descriptor *sd = NULL;
5139 struct security_descriptor *newsd = NULL;
5141 TALLOC_CTX *frame = NULL;
5143 frame = talloc_stackframe();
5144 printf("starting rename access test\n");
5146 /* Windows connection. */
5147 if (!torture_open_connection(&cli, 0)) {
5151 smbXcli_conn_set_sockopt(cli->conn, sockops);
5153 /* Posix connection. */
5154 if (!torture_open_connection(&posix_cli, 0)) {
5158 smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
5160 status = torture_setup_unix_extensions(posix_cli);
5161 if (!NT_STATUS_IS_OK(status)) {
5165 /* Start with a clean slate. */
5166 cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5167 cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5168 cli_rmdir(cli, dsrc);
5169 cli_rmdir(cli, ddst);
5170 cli_rmdir(cli, dname);
5173 * Setup the destination directory with a DENY ACE to
5174 * prevent new files within it.
5176 status = cli_ntcreate(cli,
5179 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
5180 WRITE_DAC_ACCESS|FILE_READ_DATA|
5182 FILE_ATTRIBUTE_DIRECTORY,
5183 FILE_SHARE_READ|FILE_SHARE_WRITE,
5185 FILE_DIRECTORY_FILE,
5189 if (!NT_STATUS_IS_OK(status)) {
5190 printf("Create of %s - %s\n", dname, nt_errstr(status));
5194 status = cli_query_secdesc(cli,
5198 if (!NT_STATUS_IS_OK(status)) {
5199 printf("cli_query_secdesc failed for %s (%s)\n",
5200 dname, nt_errstr(status));
5204 newsd = security_descriptor_dacl_create(frame,
5209 SEC_ACE_TYPE_ACCESS_DENIED,
5210 SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
5213 if (newsd == NULL) {
5216 sd->dacl = security_acl_concatenate(frame,
5219 if (sd->dacl == NULL) {
5222 status = cli_set_secdesc(cli, fnum, sd);
5223 if (!NT_STATUS_IS_OK(status)) {
5224 printf("cli_set_secdesc failed for %s (%s)\n",
5225 dname, nt_errstr(status));
5228 status = cli_close(cli, fnum);
5229 if (!NT_STATUS_IS_OK(status)) {
5230 printf("close failed for %s (%s)\n",
5231 dname, nt_errstr(status));
5234 /* Now go around the back and chmod to 777 via POSIX. */
5235 status = cli_posix_chmod(posix_cli, dname, 0777);
5236 if (!NT_STATUS_IS_OK(status)) {
5237 printf("cli_posix_chmod failed for %s (%s)\n",
5238 dname, nt_errstr(status));
5242 /* Check we can't create a file within dname via Windows. */
5243 status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5244 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5245 cli_close(posix_cli, fnum);
5246 printf("Create of %s should be ACCESS denied, was %s\n",
5247 dst, nt_errstr(status));
5251 /* Make the sample file/directory. */
5252 status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5253 if (!NT_STATUS_IS_OK(status)) {
5254 printf("open of %s failed (%s)\n", src, nt_errstr(status));
5257 status = cli_close(cli, fnum);
5258 if (!NT_STATUS_IS_OK(status)) {
5259 printf("cli_close failed (%s)\n", nt_errstr(status));
5263 status = cli_mkdir(cli, dsrc);
5264 if (!NT_STATUS_IS_OK(status)) {
5265 printf("cli_mkdir of %s failed (%s)\n",
5266 dsrc, nt_errstr(status));
5271 * OK - renames of the new file and directory into the
5272 * dst directory should fail.
5275 status = cli_rename(cli, src, dst, false);
5276 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5277 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5278 src, dst, nt_errstr(status));
5281 status = cli_rename(cli, dsrc, ddst, false);
5282 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5283 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5284 src, dst, nt_errstr(status));
5294 torture_close_connection(posix_cli);
5298 if (fnum != (uint16_t)-1) {
5299 cli_close(cli, fnum);
5301 cli_unlink(cli, src,
5302 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5303 cli_unlink(cli, dst,
5304 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5305 cli_rmdir(cli, dsrc);
5306 cli_rmdir(cli, ddst);
5307 cli_rmdir(cli, dname);
5309 torture_close_connection(cli);
5317 Test owner rights ACE.
5319 static bool run_owner_rights(int dummy)
5321 static struct cli_state *cli = NULL;
5322 const char *fname = "owner_rights.txt";
5323 uint16_t fnum = (uint16_t)-1;
5324 struct security_descriptor *sd = NULL;
5325 struct security_descriptor *newsd = NULL;
5327 TALLOC_CTX *frame = NULL;
5329 frame = talloc_stackframe();
5330 printf("starting owner rights test\n");
5332 /* Windows connection. */
5333 if (!torture_open_connection(&cli, 0)) {
5337 smbXcli_conn_set_sockopt(cli->conn, sockops);
5339 /* Start with a clean slate. */
5340 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5342 /* Create the test file. */
5343 /* Now try and open for read and write-dac. */
5344 status = cli_ntcreate(cli,
5348 FILE_ATTRIBUTE_NORMAL,
5349 FILE_SHARE_READ|FILE_SHARE_WRITE|
5356 if (!NT_STATUS_IS_OK(status)) {
5357 printf("Create of %s - %s\n", fname, nt_errstr(status));
5361 /* Get the original SD. */
5362 status = cli_query_secdesc(cli,
5366 if (!NT_STATUS_IS_OK(status)) {
5367 printf("cli_query_secdesc failed for %s (%s)\n",
5368 fname, nt_errstr(status));
5373 * Add an "owner-rights" ACE denying WRITE_DATA,
5374 * and an "owner-rights" ACE allowing READ_DATA.
5377 newsd = security_descriptor_dacl_create(frame,
5382 SEC_ACE_TYPE_ACCESS_DENIED,
5386 SEC_ACE_TYPE_ACCESS_ALLOWED,
5390 if (newsd == NULL) {
5393 sd->dacl = security_acl_concatenate(frame,
5396 if (sd->dacl == NULL) {
5399 status = cli_set_secdesc(cli, fnum, sd);
5400 if (!NT_STATUS_IS_OK(status)) {
5401 printf("cli_set_secdesc failed for %s (%s)\n",
5402 fname, nt_errstr(status));
5405 status = cli_close(cli, fnum);
5406 if (!NT_STATUS_IS_OK(status)) {
5407 printf("close failed for %s (%s)\n",
5408 fname, nt_errstr(status));
5411 fnum = (uint16_t)-1;
5413 /* Try and open for FILE_WRITE_DATA */
5414 status = cli_ntcreate(cli,
5418 FILE_ATTRIBUTE_NORMAL,
5419 FILE_SHARE_READ|FILE_SHARE_WRITE|
5426 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5427 printf("Open of %s - %s\n", fname, nt_errstr(status));
5431 /* Now try and open for FILE_READ_DATA */
5432 status = cli_ntcreate(cli,
5436 FILE_ATTRIBUTE_NORMAL,
5437 FILE_SHARE_READ|FILE_SHARE_WRITE|
5444 if (!NT_STATUS_IS_OK(status)) {
5445 printf("Open of %s - %s\n", fname, nt_errstr(status));
5449 status = cli_close(cli, fnum);
5450 if (!NT_STATUS_IS_OK(status)) {
5451 printf("close failed for %s (%s)\n",
5452 fname, nt_errstr(status));
5456 /* Restore clean slate. */
5458 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5460 /* Create the test file. */
5461 status = cli_ntcreate(cli,
5465 FILE_ATTRIBUTE_NORMAL,
5466 FILE_SHARE_READ|FILE_SHARE_WRITE|
5473 if (!NT_STATUS_IS_OK(status)) {
5474 printf("Create of %s - %s\n", fname, nt_errstr(status));
5478 /* Get the original SD. */
5479 status = cli_query_secdesc(cli,
5483 if (!NT_STATUS_IS_OK(status)) {
5484 printf("cli_query_secdesc failed for %s (%s)\n",
5485 fname, nt_errstr(status));
5490 * Add an "owner-rights ACE denying WRITE_DATA,
5491 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5494 newsd = security_descriptor_dacl_create(frame,
5499 SEC_ACE_TYPE_ACCESS_DENIED,
5503 SEC_ACE_TYPE_ACCESS_ALLOWED,
5504 FILE_READ_DATA|FILE_WRITE_DATA,
5507 if (newsd == NULL) {
5510 sd->dacl = security_acl_concatenate(frame,
5513 if (sd->dacl == NULL) {
5516 status = cli_set_secdesc(cli, fnum, sd);
5517 if (!NT_STATUS_IS_OK(status)) {
5518 printf("cli_set_secdesc failed for %s (%s)\n",
5519 fname, nt_errstr(status));
5522 status = cli_close(cli, fnum);
5523 if (!NT_STATUS_IS_OK(status)) {
5524 printf("close failed for %s (%s)\n",
5525 fname, nt_errstr(status));
5528 fnum = (uint16_t)-1;
5530 /* Try and open for FILE_WRITE_DATA */
5531 status = cli_ntcreate(cli,
5535 FILE_ATTRIBUTE_NORMAL,
5536 FILE_SHARE_READ|FILE_SHARE_WRITE|
5543 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5544 printf("Open of %s - %s\n", fname, nt_errstr(status));
5548 /* Now try and open for FILE_READ_DATA */
5549 status = cli_ntcreate(cli,
5553 FILE_ATTRIBUTE_NORMAL,
5554 FILE_SHARE_READ|FILE_SHARE_WRITE|
5561 if (!NT_STATUS_IS_OK(status)) {
5562 printf("Open of %s - %s\n", fname, nt_errstr(status));
5566 status = cli_close(cli, fnum);
5567 if (!NT_STATUS_IS_OK(status)) {
5568 printf("close failed for %s (%s)\n",
5569 fname, nt_errstr(status));
5573 /* Restore clean slate. */
5575 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5578 /* Create the test file. */
5579 status = cli_ntcreate(cli,
5583 FILE_ATTRIBUTE_NORMAL,
5584 FILE_SHARE_READ|FILE_SHARE_WRITE|
5591 if (!NT_STATUS_IS_OK(status)) {
5592 printf("Create of %s - %s\n", fname, nt_errstr(status));
5596 /* Get the original SD. */
5597 status = cli_query_secdesc(cli,
5601 if (!NT_STATUS_IS_OK(status)) {
5602 printf("cli_query_secdesc failed for %s (%s)\n",
5603 fname, nt_errstr(status));
5608 * Add an "authenticated users" ACE allowing READ_DATA,
5609 * add an "owner-rights" denying READ_DATA,
5610 * and an "authenticated users" ACE allowing WRITE_DATA.
5613 newsd = security_descriptor_dacl_create(frame,
5617 SID_NT_AUTHENTICATED_USERS,
5618 SEC_ACE_TYPE_ACCESS_ALLOWED,
5622 SEC_ACE_TYPE_ACCESS_DENIED,
5625 SID_NT_AUTHENTICATED_USERS,
5626 SEC_ACE_TYPE_ACCESS_ALLOWED,
5630 if (newsd == NULL) {
5631 printf("newsd == NULL\n");
5634 sd->dacl = security_acl_concatenate(frame,
5637 if (sd->dacl == NULL) {
5638 printf("sd->dacl == NULL\n");
5641 status = cli_set_secdesc(cli, fnum, sd);
5642 if (!NT_STATUS_IS_OK(status)) {
5643 printf("cli_set_secdesc failed for %s (%s)\n",
5644 fname, nt_errstr(status));
5647 status = cli_close(cli, fnum);
5648 if (!NT_STATUS_IS_OK(status)) {
5649 printf("close failed for %s (%s)\n",
5650 fname, nt_errstr(status));
5653 fnum = (uint16_t)-1;
5655 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5656 status = cli_ntcreate(cli,
5659 FILE_READ_DATA|FILE_WRITE_DATA,
5660 FILE_ATTRIBUTE_NORMAL,
5661 FILE_SHARE_READ|FILE_SHARE_WRITE|
5668 if (!NT_STATUS_IS_OK(status)) {
5669 printf("Open of %s - %s\n", fname, nt_errstr(status));
5673 status = cli_close(cli, fnum);
5674 if (!NT_STATUS_IS_OK(status)) {
5675 printf("close failed for %s (%s)\n",
5676 fname, nt_errstr(status));
5680 cli_unlink(cli, fname,
5681 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5689 if (fnum != (uint16_t)-1) {
5690 cli_close(cli, fnum);
5692 cli_unlink(cli, fname,
5693 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5694 torture_close_connection(cli);
5701 static bool run_pipe_number(int dummy)
5703 struct cli_state *cli1;
5704 const char *pipe_name = "\\SPOOLSS";
5709 printf("starting pipenumber test\n");
5710 if (!torture_open_connection(&cli1, 0)) {
5714 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5716 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
5717 FILE_ATTRIBUTE_NORMAL,
5718 FILE_SHARE_READ|FILE_SHARE_WRITE,
5719 FILE_OPEN_IF, 0, 0, &fnum, NULL);
5720 if (!NT_STATUS_IS_OK(status)) {
5721 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
5725 printf("\r%6d", num_pipes);
5728 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
5729 torture_close_connection(cli1);
5734 Test open mode returns on read-only files.
5736 static bool run_opentest(int dummy)
5738 static struct cli_state *cli1;
5739 static struct cli_state *cli2;
5740 const char *fname = "\\readonly.file";
5741 uint16_t fnum1, fnum2;
5744 bool correct = True;
5748 printf("starting open test\n");
5750 if (!torture_open_connection(&cli1, 0)) {
5754 cli_setatr(cli1, fname, 0, 0);
5755 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5757 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5759 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5760 if (!NT_STATUS_IS_OK(status)) {
5761 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5765 status = cli_close(cli1, fnum1);
5766 if (!NT_STATUS_IS_OK(status)) {
5767 printf("close2 failed (%s)\n", nt_errstr(status));
5771 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
5772 if (!NT_STATUS_IS_OK(status)) {
5773 printf("cli_setatr failed (%s)\n", nt_errstr(status));
5777 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5778 if (!NT_STATUS_IS_OK(status)) {
5779 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5783 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5784 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5786 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
5787 NT_STATUS_ACCESS_DENIED)) {
5788 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5791 printf("finished open test 1\n");
5793 cli_close(cli1, fnum1);
5795 /* Now try not readonly and ensure ERRbadshare is returned. */
5797 cli_setatr(cli1, fname, 0, 0);
5799 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5800 if (!NT_STATUS_IS_OK(status)) {
5801 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5805 /* This will fail - but the error should be ERRshare. */
5806 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5808 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5809 NT_STATUS_SHARING_VIOLATION)) {
5810 printf("correct error code ERRDOS/ERRbadshare returned\n");
5813 status = cli_close(cli1, fnum1);
5814 if (!NT_STATUS_IS_OK(status)) {
5815 printf("close2 failed (%s)\n", nt_errstr(status));
5819 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5821 printf("finished open test 2\n");
5823 /* Test truncate open disposition on file opened for read. */
5824 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5825 if (!NT_STATUS_IS_OK(status)) {
5826 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5830 /* write 20 bytes. */
5832 memset(buf, '\0', 20);
5834 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5835 if (!NT_STATUS_IS_OK(status)) {
5836 printf("write failed (%s)\n", nt_errstr(status));
5840 status = cli_close(cli1, fnum1);
5841 if (!NT_STATUS_IS_OK(status)) {
5842 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5846 /* Ensure size == 20. */
5847 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5848 if (!NT_STATUS_IS_OK(status)) {
5849 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5854 printf("(3) file size != 20\n");
5858 /* Now test if we can truncate a file opened for readonly. */
5859 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5860 if (!NT_STATUS_IS_OK(status)) {
5861 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5865 status = cli_close(cli1, fnum1);
5866 if (!NT_STATUS_IS_OK(status)) {
5867 printf("close2 failed (%s)\n", nt_errstr(status));
5871 /* Ensure size == 0. */
5872 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5873 if (!NT_STATUS_IS_OK(status)) {
5874 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5879 printf("(3) file size != 0\n");
5882 printf("finished open test 3\n");
5884 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5886 printf("Do ctemp tests\n");
5887 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5888 if (!NT_STATUS_IS_OK(status)) {
5889 printf("ctemp failed (%s)\n", nt_errstr(status));
5893 printf("ctemp gave path %s\n", tmp_path);
5894 status = cli_close(cli1, fnum1);
5895 if (!NT_STATUS_IS_OK(status)) {
5896 printf("close of temp failed (%s)\n", nt_errstr(status));
5899 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5900 if (!NT_STATUS_IS_OK(status)) {
5901 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5904 /* Test the non-io opens... */
5906 if (!torture_open_connection(&cli2, 1)) {
5910 cli_setatr(cli2, fname, 0, 0);
5911 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5913 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5915 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5916 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5917 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5918 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5919 if (!NT_STATUS_IS_OK(status)) {
5920 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5924 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5925 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5926 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5927 if (!NT_STATUS_IS_OK(status)) {
5928 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5932 status = cli_close(cli1, fnum1);
5933 if (!NT_STATUS_IS_OK(status)) {
5934 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5938 status = cli_close(cli2, fnum2);
5939 if (!NT_STATUS_IS_OK(status)) {
5940 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5944 printf("non-io open test #1 passed.\n");
5946 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5948 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5950 status = cli_ntcreate(cli1, fname, 0,
5951 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5952 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5953 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5954 if (!NT_STATUS_IS_OK(status)) {
5955 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5959 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5960 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5961 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5962 if (!NT_STATUS_IS_OK(status)) {
5963 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5967 status = cli_close(cli1, fnum1);
5968 if (!NT_STATUS_IS_OK(status)) {
5969 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5973 status = cli_close(cli2, fnum2);
5974 if (!NT_STATUS_IS_OK(status)) {
5975 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5979 printf("non-io open test #2 passed.\n");
5981 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5983 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5985 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5986 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5987 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5988 if (!NT_STATUS_IS_OK(status)) {
5989 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5993 status = cli_ntcreate(cli2, fname, 0,
5994 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5995 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5996 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5997 if (!NT_STATUS_IS_OK(status)) {
5998 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6002 status = cli_close(cli1, fnum1);
6003 if (!NT_STATUS_IS_OK(status)) {
6004 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6008 status = cli_close(cli2, fnum2);
6009 if (!NT_STATUS_IS_OK(status)) {
6010 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6014 printf("non-io open test #3 passed.\n");
6016 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6018 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
6020 status = cli_ntcreate(cli1, fname, 0,
6021 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6022 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6023 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6024 if (!NT_STATUS_IS_OK(status)) {
6025 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6029 status = cli_ntcreate(cli2, fname, 0,
6030 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6031 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6032 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6033 if (NT_STATUS_IS_OK(status)) {
6034 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
6038 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
6040 status = cli_close(cli1, fnum1);
6041 if (!NT_STATUS_IS_OK(status)) {
6042 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6046 printf("non-io open test #4 passed.\n");
6048 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6050 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
6052 status = cli_ntcreate(cli1, fname, 0,
6053 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6054 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
6055 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6056 if (!NT_STATUS_IS_OK(status)) {
6057 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6061 status = cli_ntcreate(cli2, fname, 0,
6062 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6063 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
6064 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6065 if (!NT_STATUS_IS_OK(status)) {
6066 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6070 status = cli_close(cli1, fnum1);
6071 if (!NT_STATUS_IS_OK(status)) {
6072 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6076 status = cli_close(cli2, fnum2);
6077 if (!NT_STATUS_IS_OK(status)) {
6078 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6082 printf("non-io open test #5 passed.\n");
6084 printf("TEST #6 testing 1 non-io open, one io open\n");
6086 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6088 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6089 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6090 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6091 if (!NT_STATUS_IS_OK(status)) {
6092 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6096 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
6097 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6098 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6099 if (!NT_STATUS_IS_OK(status)) {
6100 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6104 status = cli_close(cli1, fnum1);
6105 if (!NT_STATUS_IS_OK(status)) {
6106 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6110 status = cli_close(cli2, fnum2);
6111 if (!NT_STATUS_IS_OK(status)) {
6112 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6116 printf("non-io open test #6 passed.\n");
6118 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
6120 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6122 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6123 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6124 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6125 if (!NT_STATUS_IS_OK(status)) {
6126 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6130 status = cli_ntcreate(cli2, fname, 0,
6131 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6132 FILE_ATTRIBUTE_NORMAL,
6133 FILE_SHARE_READ|FILE_SHARE_DELETE,
6134 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6135 if (NT_STATUS_IS_OK(status)) {
6136 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
6140 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
6142 status = cli_close(cli1, fnum1);
6143 if (!NT_STATUS_IS_OK(status)) {
6144 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6148 printf("non-io open test #7 passed.\n");
6150 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6152 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
6153 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
6154 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6155 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6156 if (!NT_STATUS_IS_OK(status)) {
6157 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
6162 /* Write to ensure we have to update the file time. */
6163 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6165 if (!NT_STATUS_IS_OK(status)) {
6166 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
6171 status = cli_close(cli1, fnum1);
6172 if (!NT_STATUS_IS_OK(status)) {
6173 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
6179 if (!torture_close_connection(cli1)) {
6182 if (!torture_close_connection(cli2)) {
6189 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
6191 uint16_t major, minor;
6192 uint32_t caplow, caphigh;
6195 if (!SERVER_HAS_UNIX_CIFS(cli)) {
6196 printf("Server doesn't support UNIX CIFS extensions.\n");
6197 return NT_STATUS_NOT_SUPPORTED;
6200 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
6202 if (!NT_STATUS_IS_OK(status)) {
6203 printf("Server didn't return UNIX CIFS extensions: %s\n",
6208 status = cli_set_unix_extensions_capabilities(cli, major, minor,
6210 if (!NT_STATUS_IS_OK(status)) {
6211 printf("Server doesn't support setting UNIX CIFS extensions: "
6212 "%s.\n", nt_errstr(status));
6216 return NT_STATUS_OK;
6220 Test POSIX open /mkdir calls.
6222 static bool run_simple_posix_open_test(int dummy)
6224 static struct cli_state *cli1;
6225 const char *fname = "posix:file";
6226 const char *hname = "posix:hlink";
6227 const char *sname = "posix:symlink";
6228 const char *dname = "posix:dir";
6231 uint16_t fnum1 = (uint16_t)-1;
6232 SMB_STRUCT_STAT sbuf;
6233 bool correct = false;
6236 const char *fname_windows = "windows_file";
6237 uint16_t fnum2 = (uint16_t)-1;
6239 printf("Starting simple POSIX open test\n");
6241 if (!torture_open_connection(&cli1, 0)) {
6245 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6247 status = torture_setup_unix_extensions(cli1);
6248 if (!NT_STATUS_IS_OK(status)) {
6252 cli_setatr(cli1, fname, 0, 0);
6253 cli_posix_unlink(cli1, fname);
6254 cli_setatr(cli1, dname, 0, 0);
6255 cli_posix_rmdir(cli1, dname);
6256 cli_setatr(cli1, hname, 0, 0);
6257 cli_posix_unlink(cli1, hname);
6258 cli_setatr(cli1, sname, 0, 0);
6259 cli_posix_unlink(cli1, sname);
6260 cli_setatr(cli1, fname_windows, 0, 0);
6261 cli_posix_unlink(cli1, fname_windows);
6263 /* Create a directory. */
6264 status = cli_posix_mkdir(cli1, dname, 0777);
6265 if (!NT_STATUS_IS_OK(status)) {
6266 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6270 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6272 if (!NT_STATUS_IS_OK(status)) {
6273 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6277 /* Test ftruncate - set file size. */
6278 status = cli_ftruncate(cli1, fnum1, 1000);
6279 if (!NT_STATUS_IS_OK(status)) {
6280 printf("ftruncate failed (%s)\n", nt_errstr(status));
6284 /* Ensure st_size == 1000 */
6285 status = cli_posix_stat(cli1, fname, &sbuf);
6286 if (!NT_STATUS_IS_OK(status)) {
6287 printf("stat failed (%s)\n", nt_errstr(status));
6291 if (sbuf.st_ex_size != 1000) {
6292 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6296 /* Ensure st_mode == 0600 */
6297 if ((sbuf.st_ex_mode & 07777) != 0600) {
6298 printf("posix_open - bad permissions 0%o != 0600\n",
6299 (unsigned int)(sbuf.st_ex_mode & 07777));
6303 /* Test ftruncate - set file size back to zero. */
6304 status = cli_ftruncate(cli1, fnum1, 0);
6305 if (!NT_STATUS_IS_OK(status)) {
6306 printf("ftruncate failed (%s)\n", nt_errstr(status));
6310 status = cli_close(cli1, fnum1);
6311 if (!NT_STATUS_IS_OK(status)) {
6312 printf("close failed (%s)\n", nt_errstr(status));
6316 /* Now open the file again for read only. */
6317 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6318 if (!NT_STATUS_IS_OK(status)) {
6319 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
6323 /* Now unlink while open. */
6324 status = cli_posix_unlink(cli1, fname);
6325 if (!NT_STATUS_IS_OK(status)) {
6326 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6330 status = cli_close(cli1, fnum1);
6331 if (!NT_STATUS_IS_OK(status)) {
6332 printf("close(2) failed (%s)\n", nt_errstr(status));
6336 /* Ensure the file has gone. */
6337 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6338 if (NT_STATUS_IS_OK(status)) {
6339 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
6343 /* Create again to test open with O_TRUNC. */
6344 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
6345 if (!NT_STATUS_IS_OK(status)) {
6346 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6350 /* Test ftruncate - set file size. */
6351 status = cli_ftruncate(cli1, fnum1, 1000);
6352 if (!NT_STATUS_IS_OK(status)) {
6353 printf("ftruncate failed (%s)\n", nt_errstr(status));
6357 /* Ensure st_size == 1000 */
6358 status = cli_posix_stat(cli1, fname, &sbuf);
6359 if (!NT_STATUS_IS_OK(status)) {
6360 printf("stat failed (%s)\n", nt_errstr(status));
6364 if (sbuf.st_ex_size != 1000) {
6365 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6369 status = cli_close(cli1, fnum1);
6370 if (!NT_STATUS_IS_OK(status)) {
6371 printf("close(2) failed (%s)\n", nt_errstr(status));
6375 /* Re-open with O_TRUNC. */
6376 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
6377 if (!NT_STATUS_IS_OK(status)) {
6378 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6382 /* Ensure st_size == 0 */
6383 status = cli_posix_stat(cli1, fname, &sbuf);
6384 if (!NT_STATUS_IS_OK(status)) {
6385 printf("stat failed (%s)\n", nt_errstr(status));
6389 if (sbuf.st_ex_size != 0) {
6390 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
6394 status = cli_close(cli1, fnum1);
6395 if (!NT_STATUS_IS_OK(status)) {
6396 printf("close failed (%s)\n", nt_errstr(status));
6400 status = cli_posix_unlink(cli1, fname);
6401 if (!NT_STATUS_IS_OK(status)) {
6402 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6406 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
6407 if (!NT_STATUS_IS_OK(status)) {
6408 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6409 dname, nt_errstr(status));
6413 cli_close(cli1, fnum1);
6415 /* What happens when we try and POSIX open a directory for write ? */
6416 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
6417 if (NT_STATUS_IS_OK(status)) {
6418 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
6421 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
6422 NT_STATUS_FILE_IS_A_DIRECTORY)) {
6427 /* Create the file. */
6428 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6430 if (!NT_STATUS_IS_OK(status)) {
6431 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6435 /* Write some data into it. */
6436 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6438 if (!NT_STATUS_IS_OK(status)) {
6439 printf("cli_write failed: %s\n", nt_errstr(status));
6443 cli_close(cli1, fnum1);
6445 /* Now create a hardlink. */
6446 status = cli_posix_hardlink(cli1, fname, hname);
6447 if (!NT_STATUS_IS_OK(status)) {
6448 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
6452 /* Now create a symlink. */
6453 status = cli_posix_symlink(cli1, fname, sname);
6454 if (!NT_STATUS_IS_OK(status)) {
6455 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
6459 /* Open the hardlink for read. */
6460 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
6461 if (!NT_STATUS_IS_OK(status)) {
6462 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
6466 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
6467 if (!NT_STATUS_IS_OK(status)) {
6468 printf("POSIX read of %s failed (%s)\n", hname,
6471 } else if (nread != 10) {
6472 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6473 hname, (unsigned long)nread, 10);
6477 if (memcmp(buf, "TEST DATA\n", 10)) {
6478 printf("invalid data read from hardlink\n");
6482 /* Do a POSIX lock/unlock. */
6483 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
6484 if (!NT_STATUS_IS_OK(status)) {
6485 printf("POSIX lock failed %s\n", nt_errstr(status));
6489 /* Punch a hole in the locked area. */
6490 status = cli_posix_unlock(cli1, fnum1, 10, 80);
6491 if (!NT_STATUS_IS_OK(status)) {
6492 printf("POSIX unlock failed %s\n", nt_errstr(status));
6496 cli_close(cli1, fnum1);
6498 /* Open the symlink for read - this should fail. A POSIX
6499 client should not be doing opens on a symlink. */
6500 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
6501 if (NT_STATUS_IS_OK(status)) {
6502 printf("POSIX open of %s succeeded (should have failed)\n", sname);
6505 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
6506 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
6507 printf("POSIX open of %s should have failed "
6508 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6509 "failed with %s instead.\n",
6510 sname, nt_errstr(status));
6515 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
6516 if (!NT_STATUS_IS_OK(status)) {
6517 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
6521 if (strcmp(namebuf, fname) != 0) {
6522 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6523 sname, fname, namebuf);
6527 status = cli_posix_rmdir(cli1, dname);
6528 if (!NT_STATUS_IS_OK(status)) {
6529 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
6533 /* Check directory opens with a specific permission. */
6534 status = cli_posix_mkdir(cli1, dname, 0700);
6535 if (!NT_STATUS_IS_OK(status)) {
6536 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6540 /* Ensure st_mode == 0700 */
6541 status = cli_posix_stat(cli1, dname, &sbuf);
6542 if (!NT_STATUS_IS_OK(status)) {
6543 printf("stat failed (%s)\n", nt_errstr(status));
6547 if ((sbuf.st_ex_mode & 07777) != 0700) {
6548 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6549 (unsigned int)(sbuf.st_ex_mode & 07777));
6554 * Now create a Windows file, and attempt a POSIX unlink.
6555 * This should fail with a sharing violation but due to:
6557 * [Bug 9571] Unlink after open causes smbd to panic
6559 * ensure we've fixed the lock ordering violation.
6562 status = cli_ntcreate(cli1, fname_windows, 0,
6563 FILE_READ_DATA|FILE_WRITE_DATA, 0,
6564 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6566 0x0, 0x0, &fnum2, NULL);
6567 if (!NT_STATUS_IS_OK(status)) {
6568 printf("Windows create of %s failed (%s)\n", fname_windows,
6573 /* Now try posix_unlink. */
6574 status = cli_posix_unlink(cli1, fname_windows);
6575 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6576 printf("POSIX unlink of %s should fail "
6577 "with NT_STATUS_SHARING_VIOLATION "
6578 "got %s instead !\n",
6584 cli_close(cli1, fnum2);
6586 printf("Simple POSIX open test passed\n");
6591 if (fnum1 != (uint16_t)-1) {
6592 cli_close(cli1, fnum1);
6593 fnum1 = (uint16_t)-1;
6596 if (fnum2 != (uint16_t)-1) {
6597 cli_close(cli1, fnum2);
6598 fnum2 = (uint16_t)-1;
6601 cli_setatr(cli1, sname, 0, 0);
6602 cli_posix_unlink(cli1, sname);
6603 cli_setatr(cli1, hname, 0, 0);
6604 cli_posix_unlink(cli1, hname);
6605 cli_setatr(cli1, fname, 0, 0);
6606 cli_posix_unlink(cli1, fname);
6607 cli_setatr(cli1, dname, 0, 0);
6608 cli_posix_rmdir(cli1, dname);
6609 cli_setatr(cli1, fname_windows, 0, 0);
6610 cli_posix_unlink(cli1, fname_windows);
6612 if (!torture_close_connection(cli1)) {
6620 Test POSIX and Windows ACLs are rejected on symlinks.
6622 static bool run_acl_symlink_test(int dummy)
6624 static struct cli_state *cli;
6625 const char *fname = "posix_file";
6626 const char *sname = "posix_symlink";
6627 uint16_t fnum = (uint16_t)-1;
6628 bool correct = false;
6630 char *posix_acl = NULL;
6631 size_t posix_acl_len = 0;
6632 char *posix_acl_sym = NULL;
6633 size_t posix_acl_len_sym = 0;
6634 struct security_descriptor *sd = NULL;
6635 struct security_descriptor *sd_sym = NULL;
6636 TALLOC_CTX *frame = NULL;
6638 frame = talloc_stackframe();
6640 printf("Starting acl symlink test\n");
6642 if (!torture_open_connection(&cli, 0)) {
6647 smbXcli_conn_set_sockopt(cli->conn, sockops);
6649 status = torture_setup_unix_extensions(cli);
6650 if (!NT_STATUS_IS_OK(status)) {
6655 cli_setatr(cli, fname, 0, 0);
6656 cli_posix_unlink(cli, fname);
6657 cli_setatr(cli, sname, 0, 0);
6658 cli_posix_unlink(cli, sname);
6660 status = cli_ntcreate(cli,
6663 READ_CONTROL_ACCESS,
6665 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6672 if (!NT_STATUS_IS_OK(status)) {
6673 printf("cli_ntcreate of %s failed (%s)\n",
6679 /* Get the Windows ACL on the file. */
6680 status = cli_query_secdesc(cli,
6684 if (!NT_STATUS_IS_OK(status)) {
6685 printf("cli_query_secdesc failed (%s)\n",
6690 /* Get the POSIX ACL on the file. */
6691 status = cli_posix_getacl(cli,
6697 if (!NT_STATUS_IS_OK(status)) {
6698 printf("cli_posix_getacl failed (%s)\n",
6703 status = cli_close(cli, fnum);
6704 if (!NT_STATUS_IS_OK(status)) {
6705 printf("close failed (%s)\n", nt_errstr(status));
6708 fnum = (uint16_t)-1;
6710 /* Now create a symlink. */
6711 status = cli_posix_symlink(cli, fname, sname);
6712 if (!NT_STATUS_IS_OK(status)) {
6713 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6720 /* Open a handle on the symlink. */
6721 status = cli_ntcreate(cli,
6724 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
6726 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6733 if (!NT_STATUS_IS_OK(status)) {
6734 printf("cli_posix_open of %s failed (%s)\n",
6740 /* Get the Windows ACL on the symlink handle. Should fail */
6741 status = cli_query_secdesc(cli,
6746 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6747 printf("cli_query_secdesc on a symlink gave %s. "
6748 "Should be NT_STATUS_ACCESS_DENIED.\n",
6753 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6754 status = cli_posix_getacl(cli,
6760 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6761 printf("cli_posix_getacl on a symlink gave %s. "
6762 "Should be NT_STATUS_ACCESS_DENIED.\n",
6767 /* Set the Windows ACL on the symlink handle. Should fail */
6768 status = cli_set_security_descriptor(cli,
6773 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6774 printf("cli_query_secdesc on a symlink gave %s. "
6775 "Should be NT_STATUS_ACCESS_DENIED.\n",
6780 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6781 status = cli_posix_setacl(cli,
6786 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6787 printf("cli_posix_getacl on a symlink gave %s. "
6788 "Should be NT_STATUS_ACCESS_DENIED.\n",
6793 printf("ACL symlink test passed\n");
6798 if (fnum != (uint16_t)-1) {
6799 cli_close(cli, fnum);
6800 fnum = (uint16_t)-1;
6803 cli_setatr(cli, sname, 0, 0);
6804 cli_posix_unlink(cli, sname);
6805 cli_setatr(cli, fname, 0, 0);
6806 cli_posix_unlink(cli, fname);
6808 if (!torture_close_connection(cli)) {
6817 Test POSIX can delete a file containing streams.
6819 static bool run_posix_stream_delete(int dummy)
6821 struct cli_state *cli1 = NULL;
6822 struct cli_state *cli2 = NULL;
6823 const char *fname = "streamfile";
6824 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6825 uint16_t fnum1 = (uint16_t)-1;
6826 bool correct = false;
6828 TALLOC_CTX *frame = NULL;
6830 frame = talloc_stackframe();
6832 printf("Starting POSIX stream delete test\n");
6834 if (!torture_open_connection(&cli1, 0) ||
6835 !torture_open_connection(&cli2, 1)) {
6840 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6841 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6843 status = torture_setup_unix_extensions(cli2);
6844 if (!NT_STATUS_IS_OK(status)) {
6848 cli_setatr(cli1, fname, 0, 0);
6849 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6851 /* Create the file. */
6852 status = cli_ntcreate(cli1,
6855 READ_CONTROL_ACCESS,
6857 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6864 if (!NT_STATUS_IS_OK(status)) {
6865 printf("cli_ntcreate of %s failed (%s)\n",
6871 status = cli_close(cli1, fnum1);
6872 if (!NT_STATUS_IS_OK(status)) {
6873 printf("cli_close of %s failed (%s)\n",
6878 fnum1 = (uint16_t)-1;
6880 /* Now create the stream. */
6881 status = cli_ntcreate(cli1,
6886 FILE_SHARE_READ|FILE_SHARE_WRITE,
6893 if (!NT_STATUS_IS_OK(status)) {
6894 printf("cli_ntcreate of %s failed (%s)\n",
6900 /* Leave the stream handle open... */
6902 /* POSIX unlink should fail. */
6903 status = cli_posix_unlink(cli2, fname);
6904 if (NT_STATUS_IS_OK(status)) {
6905 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6910 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6911 printf("cli_posix_unlink of %s failed with (%s) "
6912 "should have been NT_STATUS_SHARING_VIOLATION\n",
6918 /* Close the stream handle. */
6919 status = cli_close(cli1, fnum1);
6920 if (!NT_STATUS_IS_OK(status)) {
6921 printf("cli_close of %s failed (%s)\n",
6926 fnum1 = (uint16_t)-1;
6928 /* POSIX unlink after stream handle closed should succeed. */
6929 status = cli_posix_unlink(cli2, fname);
6930 if (!NT_STATUS_IS_OK(status)) {
6931 printf("cli_posix_unlink of %s failed (%s)\n",
6937 printf("POSIX stream delete test passed\n");
6942 if (fnum1 != (uint16_t)-1) {
6943 cli_close(cli1, fnum1);
6944 fnum1 = (uint16_t)-1;
6947 cli_setatr(cli1, fname, 0, 0);
6948 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6950 if (!torture_close_connection(cli1)) {
6953 if (!torture_close_connection(cli2)) {
6962 Test setting EA's are rejected on symlinks.
6964 static bool run_ea_symlink_test(int dummy)
6966 static struct cli_state *cli;
6967 const char *fname = "posix_file_ea";
6968 const char *sname = "posix_symlink_ea";
6969 const char *ea_name = "testea_name";
6970 const char *ea_value = "testea_value";
6971 uint16_t fnum = (uint16_t)-1;
6972 bool correct = false;
6975 struct ea_struct *eas = NULL;
6976 TALLOC_CTX *frame = NULL;
6978 frame = talloc_stackframe();
6980 printf("Starting EA symlink test\n");
6982 if (!torture_open_connection(&cli, 0)) {
6987 smbXcli_conn_set_sockopt(cli->conn, sockops);
6989 status = torture_setup_unix_extensions(cli);
6990 if (!NT_STATUS_IS_OK(status)) {
6995 cli_setatr(cli, fname, 0, 0);
6996 cli_posix_unlink(cli, fname);
6997 cli_setatr(cli, sname, 0, 0);
6998 cli_posix_unlink(cli, sname);
7000 status = cli_ntcreate(cli,
7003 READ_CONTROL_ACCESS,
7005 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7012 if (!NT_STATUS_IS_OK(status)) {
7013 printf("cli_ntcreate of %s failed (%s)\n",
7019 status = cli_close(cli, fnum);
7020 if (!NT_STATUS_IS_OK(status)) {
7021 printf("close failed (%s)\n",
7025 fnum = (uint16_t)-1;
7027 /* Set an EA on the path. */
7028 status = cli_set_ea_path(cli,
7032 strlen(ea_value)+1);
7034 if (!NT_STATUS_IS_OK(status)) {
7035 printf("cli_set_ea_path failed (%s)\n",
7040 /* Now create a symlink. */
7041 status = cli_posix_symlink(cli, fname, sname);
7042 if (!NT_STATUS_IS_OK(status)) {
7043 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
7050 /* Get the EA list on the path. Should return value set. */
7051 status = cli_get_ea_list_path(cli,
7057 if (!NT_STATUS_IS_OK(status)) {
7058 printf("cli_get_ea_list_path failed (%s)\n",
7063 /* Ensure the EA we set is there. */
7064 for (i=0; i<num_eas; i++) {
7065 if (strcmp(eas[i].name, ea_name) == 0 &&
7066 eas[i].value.length == strlen(ea_value)+1 &&
7067 memcmp(eas[i].value.data,
7069 eas[i].value.length) == 0) {
7075 printf("Didn't find EA on pathname %s\n",
7083 /* Get the EA list on the symlink. Should return empty list. */
7084 status = cli_get_ea_list_path(cli,
7090 if (!NT_STATUS_IS_OK(status)) {
7091 printf("cli_get_ea_list_path failed (%s)\n",
7097 printf("cli_get_ea_list_path failed (%s)\n",
7102 /* Set an EA on the symlink. Should fail. */
7103 status = cli_set_ea_path(cli,
7107 strlen(ea_value)+1);
7109 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7110 printf("cli_set_ea_path on a symlink gave %s. "
7111 "Should be NT_STATUS_ACCESS_DENIED.\n",
7116 printf("EA symlink test passed\n");
7121 if (fnum != (uint16_t)-1) {
7122 cli_close(cli, fnum);
7123 fnum = (uint16_t)-1;
7126 cli_setatr(cli, sname, 0, 0);
7127 cli_posix_unlink(cli, sname);
7128 cli_setatr(cli, fname, 0, 0);
7129 cli_posix_unlink(cli, fname);
7131 if (!torture_close_connection(cli)) {
7140 Test POSIX locks are OFD-locks.
7142 static bool run_posix_ofd_lock_test(int dummy)
7144 static struct cli_state *cli;
7145 const char *fname = "posix_file";
7146 uint16_t fnum1 = (uint16_t)-1;
7147 uint16_t fnum2 = (uint16_t)-1;
7148 bool correct = false;
7150 TALLOC_CTX *frame = NULL;
7152 frame = talloc_stackframe();
7154 printf("Starting POSIX ofd-lock test\n");
7156 if (!torture_open_connection(&cli, 0)) {
7161 smbXcli_conn_set_sockopt(cli->conn, sockops);
7163 status = torture_setup_unix_extensions(cli);
7164 if (!NT_STATUS_IS_OK(status)) {
7169 cli_setatr(cli, fname, 0, 0);
7170 cli_posix_unlink(cli, fname);
7172 /* Open the file twice. */
7173 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
7175 if (!NT_STATUS_IS_OK(status)) {
7176 printf("First POSIX open of %s failed\n", fname);
7180 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
7181 if (!NT_STATUS_IS_OK(status)) {
7182 printf("First POSIX open of %s failed\n", fname);
7186 /* Set a 0-50 lock on fnum1. */
7187 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7188 if (!NT_STATUS_IS_OK(status)) {
7189 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
7193 /* Set a 60-100 lock on fnum2. */
7194 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
7195 if (!NT_STATUS_IS_OK(status)) {
7196 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
7200 /* close fnum1 - 0-50 lock should go away. */
7201 status = cli_close(cli, fnum1);
7202 if (!NT_STATUS_IS_OK(status)) {
7203 printf("close failed (%s)\n",
7207 fnum1 = (uint16_t)-1;
7209 /* Change the lock context. */
7210 cli_setpid(cli, cli_getpid(cli) + 1);
7212 /* Re-open fnum1. */
7213 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
7214 if (!NT_STATUS_IS_OK(status)) {
7215 printf("Third POSIX open of %s failed\n", fname);
7219 /* 60-100 lock should still be there. */
7220 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
7221 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
7222 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
7226 /* 0-50 lock should be gone. */
7227 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7228 if (!NT_STATUS_IS_OK(status)) {
7229 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
7233 printf("POSIX OFD lock test passed\n");
7238 if (fnum1 != (uint16_t)-1) {
7239 cli_close(cli, fnum1);
7240 fnum1 = (uint16_t)-1;
7242 if (fnum2 != (uint16_t)-1) {
7243 cli_close(cli, fnum2);
7244 fnum2 = (uint16_t)-1;
7247 cli_setatr(cli, fname, 0, 0);
7248 cli_posix_unlink(cli, fname);
7250 if (!torture_close_connection(cli)) {
7258 static uint32_t open_attrs_table[] = {
7259 FILE_ATTRIBUTE_NORMAL,
7260 FILE_ATTRIBUTE_ARCHIVE,
7261 FILE_ATTRIBUTE_READONLY,
7262 FILE_ATTRIBUTE_HIDDEN,
7263 FILE_ATTRIBUTE_SYSTEM,
7265 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7266 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7267 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7268 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7269 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7270 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7272 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7273 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7274 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7275 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7278 struct trunc_open_results {
7281 uint32_t trunc_attr;
7282 uint32_t result_attr;
7285 static struct trunc_open_results attr_results[] = {
7286 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7287 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7288 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7289 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7290 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7291 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7292 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7293 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7294 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7295 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7296 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7297 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7298 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7299 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7300 { 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 },
7301 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7302 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7303 { 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 },
7304 { 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 },
7305 { 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 },
7306 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7307 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7308 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7309 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7310 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7311 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7314 static bool run_openattrtest(int dummy)
7316 static struct cli_state *cli1;
7317 const char *fname = "\\openattr.file";
7319 bool correct = True;
7321 unsigned int i, j, k, l;
7324 printf("starting open attr test\n");
7326 if (!torture_open_connection(&cli1, 0)) {
7330 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7332 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7333 cli_setatr(cli1, fname, 0, 0);
7334 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7336 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7337 open_attrs_table[i], FILE_SHARE_NONE,
7338 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7339 if (!NT_STATUS_IS_OK(status)) {
7340 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7344 status = cli_close(cli1, fnum1);
7345 if (!NT_STATUS_IS_OK(status)) {
7346 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7350 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7351 status = cli_ntcreate(cli1, fname, 0,
7352 FILE_READ_DATA|FILE_WRITE_DATA,
7353 open_attrs_table[j],
7354 FILE_SHARE_NONE, FILE_OVERWRITE,
7355 0, 0, &fnum1, NULL);
7356 if (!NT_STATUS_IS_OK(status)) {
7357 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7358 if (attr_results[l].num == k) {
7359 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7360 k, open_attrs_table[i],
7361 open_attrs_table[j],
7362 fname, NT_STATUS_V(status), nt_errstr(status));
7367 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7368 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7369 k, open_attrs_table[i], open_attrs_table[j],
7374 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7380 status = cli_close(cli1, fnum1);
7381 if (!NT_STATUS_IS_OK(status)) {
7382 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7386 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7387 if (!NT_STATUS_IS_OK(status)) {
7388 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7393 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7394 k, open_attrs_table[i], open_attrs_table[j], attr );
7397 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7398 if (attr_results[l].num == k) {
7399 if (attr != attr_results[l].result_attr ||
7400 open_attrs_table[i] != attr_results[l].init_attr ||
7401 open_attrs_table[j] != attr_results[l].trunc_attr) {
7402 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7403 open_attrs_table[i],
7404 open_attrs_table[j],
7406 attr_results[l].result_attr);
7416 cli_setatr(cli1, fname, 0, 0);
7417 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7419 printf("open attr test %s.\n", correct ? "passed" : "failed");
7421 if (!torture_close_connection(cli1)) {
7427 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7428 const char *name, void *state)
7430 int *matched = (int *)state;
7431 if (matched != NULL) {
7434 return NT_STATUS_OK;
7438 test directory listing speed
7440 static bool run_dirtest(int dummy)
7443 static struct cli_state *cli;
7445 struct timeval core_start;
7446 bool correct = True;
7449 printf("starting directory test\n");
7451 if (!torture_open_connection(&cli, 0)) {
7455 smbXcli_conn_set_sockopt(cli->conn, sockops);
7458 for (i=0;i<torture_numops;i++) {
7460 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7461 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7462 fprintf(stderr,"Failed to open %s\n", fname);
7465 cli_close(cli, fnum);
7468 core_start = timeval_current();
7471 cli_list(cli, "a*.*", 0, list_fn, &matched);
7472 printf("Matched %d\n", matched);
7475 cli_list(cli, "b*.*", 0, list_fn, &matched);
7476 printf("Matched %d\n", matched);
7479 cli_list(cli, "xyzabc", 0, list_fn, &matched);
7480 printf("Matched %d\n", matched);
7482 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7485 for (i=0;i<torture_numops;i++) {
7487 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7488 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7491 if (!torture_close_connection(cli)) {
7495 printf("finished dirtest\n");
7500 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7503 struct cli_state *pcli = (struct cli_state *)state;
7505 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7507 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7508 return NT_STATUS_OK;
7510 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7511 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7512 printf("del_fn: failed to rmdir %s\n,", fname );
7514 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7515 printf("del_fn: failed to unlink %s\n,", fname );
7517 return NT_STATUS_OK;
7522 sees what IOCTLs are supported
7524 bool torture_ioctl_test(int dummy)
7526 static struct cli_state *cli;
7527 uint16_t device, function;
7529 const char *fname = "\\ioctl.dat";
7533 if (!torture_open_connection(&cli, 0)) {
7537 printf("starting ioctl test\n");
7539 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7541 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7542 if (!NT_STATUS_IS_OK(status)) {
7543 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7547 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7548 printf("ioctl device info: %s\n", nt_errstr(status));
7550 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7551 printf("ioctl job info: %s\n", nt_errstr(status));
7553 for (device=0;device<0x100;device++) {
7554 printf("ioctl test with device = 0x%x\n", device);
7555 for (function=0;function<0x100;function++) {
7556 uint32_t code = (device<<16) | function;
7558 status = cli_raw_ioctl(cli, fnum, code, &blob);
7560 if (NT_STATUS_IS_OK(status)) {
7561 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7563 data_blob_free(&blob);
7568 if (!torture_close_connection(cli)) {
7577 tries varients of chkpath
7579 bool torture_chkpath_test(int dummy)
7581 static struct cli_state *cli;
7586 if (!torture_open_connection(&cli, 0)) {
7590 printf("starting chkpath test\n");
7592 /* cleanup from an old run */
7593 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7594 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7595 cli_rmdir(cli, "\\chkpath.dir");
7597 status = cli_mkdir(cli, "\\chkpath.dir");
7598 if (!NT_STATUS_IS_OK(status)) {
7599 printf("mkdir1 failed : %s\n", nt_errstr(status));
7603 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7604 if (!NT_STATUS_IS_OK(status)) {
7605 printf("mkdir2 failed : %s\n", nt_errstr(status));
7609 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7611 if (!NT_STATUS_IS_OK(status)) {
7612 printf("open1 failed (%s)\n", nt_errstr(status));
7615 cli_close(cli, fnum);
7617 status = cli_chkpath(cli, "\\chkpath.dir");
7618 if (!NT_STATUS_IS_OK(status)) {
7619 printf("chkpath1 failed: %s\n", nt_errstr(status));
7623 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7624 if (!NT_STATUS_IS_OK(status)) {
7625 printf("chkpath2 failed: %s\n", nt_errstr(status));
7629 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7630 if (!NT_STATUS_IS_OK(status)) {
7631 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7632 NT_STATUS_NOT_A_DIRECTORY);
7634 printf("* chkpath on a file should fail\n");
7638 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7639 if (!NT_STATUS_IS_OK(status)) {
7640 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7641 NT_STATUS_OBJECT_NAME_NOT_FOUND);
7643 printf("* chkpath on a non existent file should fail\n");
7647 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7648 if (!NT_STATUS_IS_OK(status)) {
7649 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7650 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7652 printf("* chkpath on a non existent component should fail\n");
7656 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7657 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7658 cli_rmdir(cli, "\\chkpath.dir");
7660 if (!torture_close_connection(cli)) {
7667 static bool run_eatest(int dummy)
7669 static struct cli_state *cli;
7670 const char *fname = "\\eatest.txt";
7671 bool correct = True;
7675 struct ea_struct *ea_list = NULL;
7676 TALLOC_CTX *mem_ctx = talloc_init("eatest");
7679 printf("starting eatest\n");
7681 if (!torture_open_connection(&cli, 0)) {
7682 talloc_destroy(mem_ctx);
7686 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7688 status = cli_ntcreate(cli, fname, 0,
7689 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7690 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7691 0x4044, 0, &fnum, NULL);
7692 if (!NT_STATUS_IS_OK(status)) {
7693 printf("open failed - %s\n", nt_errstr(status));
7694 talloc_destroy(mem_ctx);
7698 for (i = 0; i < 10; i++) {
7699 fstring ea_name, ea_val;
7701 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7702 memset(ea_val, (char)i+1, i+1);
7703 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7704 if (!NT_STATUS_IS_OK(status)) {
7705 printf("ea_set of name %s failed - %s\n", ea_name,
7707 talloc_destroy(mem_ctx);
7712 cli_close(cli, fnum);
7713 for (i = 0; i < 10; i++) {
7714 fstring ea_name, ea_val;
7716 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7717 memset(ea_val, (char)i+1, i+1);
7718 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7719 if (!NT_STATUS_IS_OK(status)) {
7720 printf("ea_set of name %s failed - %s\n", ea_name,
7722 talloc_destroy(mem_ctx);
7727 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7728 if (!NT_STATUS_IS_OK(status)) {
7729 printf("ea_get list failed - %s\n", nt_errstr(status));
7733 printf("num_eas = %d\n", (int)num_eas);
7735 if (num_eas != 20) {
7736 printf("Should be 20 EA's stored... failing.\n");
7740 for (i = 0; i < num_eas; i++) {
7741 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7742 dump_data(0, ea_list[i].value.data,
7743 ea_list[i].value.length);
7746 /* Setting EA's to zero length deletes them. Test this */
7747 printf("Now deleting all EA's - case indepenent....\n");
7750 cli_set_ea_path(cli, fname, "", "", 0);
7752 for (i = 0; i < 20; i++) {
7754 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7755 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7756 if (!NT_STATUS_IS_OK(status)) {
7757 printf("ea_set of name %s failed - %s\n", ea_name,
7759 talloc_destroy(mem_ctx);
7765 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7766 if (!NT_STATUS_IS_OK(status)) {
7767 printf("ea_get list failed - %s\n", nt_errstr(status));
7771 printf("num_eas = %d\n", (int)num_eas);
7772 for (i = 0; i < num_eas; i++) {
7773 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7774 dump_data(0, ea_list[i].value.data,
7775 ea_list[i].value.length);
7779 printf("deleting EA's failed.\n");
7783 /* Try and delete a non existent EA. */
7784 status = cli_set_ea_path(cli, fname, "foo", "", 0);
7785 if (!NT_STATUS_IS_OK(status)) {
7786 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7791 talloc_destroy(mem_ctx);
7792 if (!torture_close_connection(cli)) {
7799 static bool run_dirtest1(int dummy)
7802 static struct cli_state *cli;
7805 bool correct = True;
7807 printf("starting directory test\n");
7809 if (!torture_open_connection(&cli, 0)) {
7813 smbXcli_conn_set_sockopt(cli->conn, sockops);
7815 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7816 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7817 cli_rmdir(cli, "\\LISTDIR");
7818 cli_mkdir(cli, "\\LISTDIR");
7820 /* Create 1000 files and 1000 directories. */
7821 for (i=0;i<1000;i++) {
7823 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7824 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7825 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7826 0, 0, &fnum, NULL))) {
7827 fprintf(stderr,"Failed to open %s\n", fname);
7830 cli_close(cli, fnum);
7832 for (i=0;i<1000;i++) {
7834 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7835 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7836 fprintf(stderr,"Failed to open %s\n", fname);
7841 /* Now ensure that doing an old list sees both files and directories. */
7843 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7844 printf("num_seen = %d\n", num_seen );
7845 /* We should see 100 files + 1000 directories + . and .. */
7846 if (num_seen != 2002)
7849 /* Ensure if we have the "must have" bits we only see the
7853 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7854 printf("num_seen = %d\n", num_seen );
7855 if (num_seen != 1002)
7859 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7860 printf("num_seen = %d\n", num_seen );
7861 if (num_seen != 1000)
7864 /* Delete everything. */
7865 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7866 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7867 cli_rmdir(cli, "\\LISTDIR");
7870 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7871 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7872 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7875 if (!torture_close_connection(cli)) {
7879 printf("finished dirtest1\n");
7884 static bool run_error_map_extract(int dummy) {
7886 static struct cli_state *c_dos;
7887 static struct cli_state *c_nt;
7899 /* NT-Error connection */
7901 disable_spnego = true;
7902 if (!(c_nt = open_nbt_connection())) {
7903 disable_spnego = false;
7906 disable_spnego = false;
7908 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7911 if (!NT_STATUS_IS_OK(status)) {
7912 printf("%s rejected the NT-error negprot (%s)\n", host,
7918 status = cli_session_setup_anon(c_nt);
7919 if (!NT_STATUS_IS_OK(status)) {
7920 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7924 /* DOS-Error connection */
7926 disable_spnego = true;
7927 force_dos_errors = true;
7928 if (!(c_dos = open_nbt_connection())) {
7929 disable_spnego = false;
7930 force_dos_errors = false;
7933 disable_spnego = false;
7934 force_dos_errors = false;
7936 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7938 if (!NT_STATUS_IS_OK(status)) {
7939 printf("%s rejected the DOS-error negprot (%s)\n", host,
7941 cli_shutdown(c_dos);
7945 status = cli_session_setup_anon(c_dos);
7946 if (!NT_STATUS_IS_OK(status)) {
7947 printf("%s rejected the DOS-error initial session setup (%s)\n",
7948 host, nt_errstr(status));
7952 c_nt->map_dos_errors = false;
7953 c_dos->map_dos_errors = false;
7955 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7956 struct cli_credentials *user_creds = NULL;
7958 fstr_sprintf(user, "%X", error);
7960 user_creds = cli_session_creds_init(talloc_tos(),
7965 false, /* use_kerberos */
7966 false, /* fallback_after_kerberos */
7967 false, /* use_ccache */
7968 false); /* password_is_nt_hash */
7969 if (user_creds == NULL) {
7970 printf("cli_session_creds_init(%s) failed\n", user);
7974 status = cli_session_setup_creds(c_nt, user_creds);
7975 if (NT_STATUS_IS_OK(status)) {
7976 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7979 /* Case #1: 32-bit NT errors */
7980 if (!NT_STATUS_IS_DOS(status)) {
7983 printf("/** Dos error on NT connection! (%s) */\n",
7985 nt_status = NT_STATUS(0xc0000000);
7988 status = cli_session_setup_creds(c_dos, user_creds);
7989 if (NT_STATUS_IS_OK(status)) {
7990 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7993 /* Case #1: 32-bit NT errors */
7994 if (NT_STATUS_IS_DOS(status)) {
7995 printf("/** NT error on DOS connection! (%s) */\n",
7997 errnum = errclass = 0;
7999 errclass = NT_STATUS_DOS_CLASS(status);
8000 errnum = NT_STATUS_DOS_CODE(status);
8003 if (NT_STATUS_V(nt_status) != error) {
8004 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
8005 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
8006 get_nt_error_c_code(talloc_tos(), nt_status));
8009 printf("\t{%s,\t%s,\t%s},\n",
8010 smb_dos_err_class(errclass),
8011 smb_dos_err_name(errclass, errnum),
8012 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
8014 TALLOC_FREE(user_creds);
8019 static bool run_sesssetup_bench(int dummy)
8021 static struct cli_state *c;
8022 const char *fname = "\\file.dat";
8027 if (!torture_open_connection(&c, 0)) {
8031 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8032 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8033 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
8034 if (!NT_STATUS_IS_OK(status)) {
8035 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8039 for (i=0; i<torture_numops; i++) {
8040 status = cli_session_setup_creds(c, torture_creds);
8041 if (!NT_STATUS_IS_OK(status)) {
8042 d_printf("(%s) cli_session_setup_creds failed: %s\n",
8043 __location__, nt_errstr(status));
8047 d_printf("\r%d ", (int)cli_state_get_uid(c));
8049 status = cli_ulogoff(c);
8050 if (!NT_STATUS_IS_OK(status)) {
8051 d_printf("(%s) cli_ulogoff failed: %s\n",
8052 __location__, nt_errstr(status));
8060 static bool subst_test(const char *str, const char *user, const char *domain,
8061 uid_t uid, gid_t gid, const char *expected)
8066 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
8068 if (strcmp(subst, expected) != 0) {
8069 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
8070 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
8079 static void chain1_open_completion(struct tevent_req *req)
8083 status = cli_openx_recv(req, &fnum);
8086 d_printf("cli_openx_recv returned %s: %d\n",
8088 NT_STATUS_IS_OK(status) ? fnum : -1);
8091 static void chain1_write_completion(struct tevent_req *req)
8095 status = cli_write_andx_recv(req, &written);
8098 d_printf("cli_write_andx_recv returned %s: %d\n",
8100 NT_STATUS_IS_OK(status) ? (int)written : -1);
8103 static void chain1_close_completion(struct tevent_req *req)
8106 bool *done = (bool *)tevent_req_callback_data_void(req);
8108 status = cli_close_recv(req);
8113 d_printf("cli_close returned %s\n", nt_errstr(status));
8116 static bool run_chain1(int dummy)
8118 struct cli_state *cli1;
8119 struct tevent_context *evt = samba_tevent_context_init(NULL);
8120 struct tevent_req *reqs[3], *smbreqs[3];
8122 const char *str = "foobar";
8125 printf("starting chain1 test\n");
8126 if (!torture_open_connection(&cli1, 0)) {
8130 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8132 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
8133 O_CREAT|O_RDWR, 0, &smbreqs[0]);
8134 if (reqs[0] == NULL) return false;
8135 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
8138 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
8139 (const uint8_t *)str, 0, strlen(str)+1,
8140 smbreqs, 1, &smbreqs[1]);
8141 if (reqs[1] == NULL) return false;
8142 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
8144 reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
8145 if (reqs[2] == NULL) return false;
8146 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
8148 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8149 if (!NT_STATUS_IS_OK(status)) {
8154 tevent_loop_once(evt);
8157 torture_close_connection(cli1);
8161 static void chain2_sesssetup_completion(struct tevent_req *req)
8164 status = cli_session_setup_guest_recv(req);
8165 d_printf("sesssetup returned %s\n", nt_errstr(status));
8168 static void chain2_tcon_completion(struct tevent_req *req)
8170 bool *done = (bool *)tevent_req_callback_data_void(req);
8172 status = cli_tcon_andx_recv(req);
8173 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
8177 static bool run_chain2(int dummy)
8179 struct cli_state *cli1;
8180 struct tevent_context *evt = samba_tevent_context_init(NULL);
8181 struct tevent_req *reqs[2], *smbreqs[2];
8184 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
8186 printf("starting chain2 test\n");
8187 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
8188 port_to_use, SMB_SIGNING_DEFAULT, flags);
8189 if (!NT_STATUS_IS_OK(status)) {
8193 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8195 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
8197 if (reqs[0] == NULL) return false;
8198 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
8200 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
8201 "?????", NULL, 0, &smbreqs[1]);
8202 if (reqs[1] == NULL) return false;
8203 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
8205 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8206 if (!NT_STATUS_IS_OK(status)) {
8211 tevent_loop_once(evt);
8214 torture_close_connection(cli1);
8219 struct torture_createdel_state {
8220 struct tevent_context *ev;
8221 struct cli_state *cli;
8224 static void torture_createdel_created(struct tevent_req *subreq);
8225 static void torture_createdel_closed(struct tevent_req *subreq);
8227 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8228 struct tevent_context *ev,
8229 struct cli_state *cli,
8232 struct tevent_req *req, *subreq;
8233 struct torture_createdel_state *state;
8235 req = tevent_req_create(mem_ctx, &state,
8236 struct torture_createdel_state);
8243 subreq = cli_ntcreate_send(
8244 state, ev, cli, name, 0,
8245 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8246 FILE_ATTRIBUTE_NORMAL,
8247 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8248 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
8250 if (tevent_req_nomem(subreq, req)) {
8251 return tevent_req_post(req, ev);
8253 tevent_req_set_callback(subreq, torture_createdel_created, req);
8257 static void torture_createdel_created(struct tevent_req *subreq)
8259 struct tevent_req *req = tevent_req_callback_data(
8260 subreq, struct tevent_req);
8261 struct torture_createdel_state *state = tevent_req_data(
8262 req, struct torture_createdel_state);
8266 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8267 TALLOC_FREE(subreq);
8268 if (tevent_req_nterror(req, status)) {
8269 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8270 nt_errstr(status)));
8274 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8275 if (tevent_req_nomem(subreq, req)) {
8278 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8281 static void torture_createdel_closed(struct tevent_req *subreq)
8283 struct tevent_req *req = tevent_req_callback_data(
8284 subreq, struct tevent_req);
8287 status = cli_close_recv(subreq);
8288 if (tevent_req_nterror(req, status)) {
8289 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8292 tevent_req_done(req);
8295 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8297 return tevent_req_simple_recv_ntstatus(req);
8300 struct torture_createdels_state {
8301 struct tevent_context *ev;
8302 struct cli_state *cli;
8303 const char *base_name;
8307 struct tevent_req **reqs;
8310 static void torture_createdels_done(struct tevent_req *subreq);
8312 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8313 struct tevent_context *ev,
8314 struct cli_state *cli,
8315 const char *base_name,
8319 struct tevent_req *req;
8320 struct torture_createdels_state *state;
8323 req = tevent_req_create(mem_ctx, &state,
8324 struct torture_createdels_state);
8330 state->base_name = talloc_strdup(state, base_name);
8331 if (tevent_req_nomem(state->base_name, req)) {
8332 return tevent_req_post(req, ev);
8334 state->num_files = MAX(num_parallel, num_files);
8336 state->received = 0;
8338 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8339 if (tevent_req_nomem(state->reqs, req)) {
8340 return tevent_req_post(req, ev);
8343 for (i=0; i<num_parallel; i++) {
8346 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8348 if (tevent_req_nomem(name, req)) {
8349 return tevent_req_post(req, ev);
8351 state->reqs[i] = torture_createdel_send(
8352 state->reqs, state->ev, state->cli, name);
8353 if (tevent_req_nomem(state->reqs[i], req)) {
8354 return tevent_req_post(req, ev);
8356 name = talloc_move(state->reqs[i], &name);
8357 tevent_req_set_callback(state->reqs[i],
8358 torture_createdels_done, req);
8364 static void torture_createdels_done(struct tevent_req *subreq)
8366 struct tevent_req *req = tevent_req_callback_data(
8367 subreq, struct tevent_req);
8368 struct torture_createdels_state *state = tevent_req_data(
8369 req, struct torture_createdels_state);
8370 size_t num_parallel = talloc_array_length(state->reqs);
8375 status = torture_createdel_recv(subreq);
8376 if (!NT_STATUS_IS_OK(status)){
8377 DEBUG(10, ("torture_createdel_recv returned %s\n",
8378 nt_errstr(status)));
8379 TALLOC_FREE(subreq);
8380 tevent_req_nterror(req, status);
8384 for (i=0; i<num_parallel; i++) {
8385 if (subreq == state->reqs[i]) {
8389 if (i == num_parallel) {
8390 DEBUG(10, ("received something we did not send\n"));
8391 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8394 TALLOC_FREE(state->reqs[i]);
8396 if (state->sent >= state->num_files) {
8397 tevent_req_done(req);
8401 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8403 if (tevent_req_nomem(name, req)) {
8406 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8408 if (tevent_req_nomem(state->reqs[i], req)) {
8411 name = talloc_move(state->reqs[i], &name);
8412 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8416 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8418 return tevent_req_simple_recv_ntstatus(req);
8421 struct swallow_notify_state {
8422 struct tevent_context *ev;
8423 struct cli_state *cli;
8425 uint32_t completion_filter;
8427 bool (*fn)(uint32_t action, const char *name, void *priv);
8431 static void swallow_notify_done(struct tevent_req *subreq);
8433 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8434 struct tevent_context *ev,
8435 struct cli_state *cli,
8437 uint32_t completion_filter,
8439 bool (*fn)(uint32_t action,
8444 struct tevent_req *req, *subreq;
8445 struct swallow_notify_state *state;
8447 req = tevent_req_create(mem_ctx, &state,
8448 struct swallow_notify_state);
8455 state->completion_filter = completion_filter;
8456 state->recursive = recursive;
8460 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8461 0xffff, state->completion_filter,
8463 if (tevent_req_nomem(subreq, req)) {
8464 return tevent_req_post(req, ev);
8466 tevent_req_set_callback(subreq, swallow_notify_done, req);
8470 static void swallow_notify_done(struct tevent_req *subreq)
8472 struct tevent_req *req = tevent_req_callback_data(
8473 subreq, struct tevent_req);
8474 struct swallow_notify_state *state = tevent_req_data(
8475 req, struct swallow_notify_state);
8477 uint32_t i, num_changes;
8478 struct notify_change *changes;
8480 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8481 TALLOC_FREE(subreq);
8482 if (!NT_STATUS_IS_OK(status)) {
8483 DEBUG(10, ("cli_notify_recv returned %s\n",
8484 nt_errstr(status)));
8485 tevent_req_nterror(req, status);
8489 for (i=0; i<num_changes; i++) {
8490 state->fn(changes[i].action, changes[i].name, state->priv);
8492 TALLOC_FREE(changes);
8494 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8495 0xffff, state->completion_filter,
8497 if (tevent_req_nomem(subreq, req)) {
8500 tevent_req_set_callback(subreq, swallow_notify_done, req);
8503 static bool print_notifies(uint32_t action, const char *name, void *priv)
8505 if (DEBUGLEVEL > 5) {
8506 d_printf("%d %s\n", (int)action, name);
8511 static void notify_bench_done(struct tevent_req *req)
8513 int *num_finished = (int *)tevent_req_callback_data_void(req);
8517 static bool run_notify_bench(int dummy)
8519 const char *dname = "\\notify-bench";
8520 struct tevent_context *ev;
8523 struct tevent_req *req1;
8524 struct tevent_req *req2 = NULL;
8525 int i, num_unc_names;
8526 int num_finished = 0;
8528 printf("starting notify-bench test\n");
8530 if (use_multishare_conn) {
8532 unc_list = file_lines_load(multishare_conn_fname,
8533 &num_unc_names, 0, NULL);
8534 if (!unc_list || num_unc_names <= 0) {
8535 d_printf("Failed to load unc names list from '%s'\n",
8536 multishare_conn_fname);
8539 TALLOC_FREE(unc_list);
8544 ev = samba_tevent_context_init(talloc_tos());
8546 d_printf("tevent_context_init failed\n");
8550 for (i=0; i<num_unc_names; i++) {
8551 struct cli_state *cli;
8554 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8556 if (base_fname == NULL) {
8560 if (!torture_open_connection(&cli, i)) {
8564 status = cli_ntcreate(cli, dname, 0,
8565 MAXIMUM_ALLOWED_ACCESS,
8566 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8568 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8571 if (!NT_STATUS_IS_OK(status)) {
8572 d_printf("Could not create %s: %s\n", dname,
8577 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8578 FILE_NOTIFY_CHANGE_FILE_NAME |
8579 FILE_NOTIFY_CHANGE_DIR_NAME |
8580 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8581 FILE_NOTIFY_CHANGE_LAST_WRITE,
8582 false, print_notifies, NULL);
8584 d_printf("Could not create notify request\n");
8588 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8589 base_fname, 10, torture_numops);
8591 d_printf("Could not create createdels request\n");
8594 TALLOC_FREE(base_fname);
8596 tevent_req_set_callback(req2, notify_bench_done,
8600 while (num_finished < num_unc_names) {
8602 ret = tevent_loop_once(ev);
8604 d_printf("tevent_loop_once failed\n");
8609 if (!tevent_req_poll(req2, ev)) {
8610 d_printf("tevent_req_poll failed\n");
8613 status = torture_createdels_recv(req2);
8614 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8619 static bool run_mangle1(int dummy)
8621 struct cli_state *cli;
8622 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8626 time_t change_time, access_time, write_time;
8630 printf("starting mangle1 test\n");
8631 if (!torture_open_connection(&cli, 0)) {
8635 smbXcli_conn_set_sockopt(cli->conn, sockops);
8637 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8638 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8640 if (!NT_STATUS_IS_OK(status)) {
8641 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8644 cli_close(cli, fnum);
8646 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8647 if (!NT_STATUS_IS_OK(status)) {
8648 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8652 d_printf("alt_name: %s\n", alt_name);
8654 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8655 if (!NT_STATUS_IS_OK(status)) {
8656 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8660 cli_close(cli, fnum);
8662 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8663 &write_time, &size, &mode);
8664 if (!NT_STATUS_IS_OK(status)) {
8665 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8673 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8674 struct file_info *f,
8678 if (f->short_name == NULL) {
8679 return NT_STATUS_OK;
8682 if (strlen(f->short_name) == 0) {
8683 return NT_STATUS_OK;
8686 printf("unexpected shortname: %s\n", f->short_name);
8688 return NT_STATUS_OBJECT_NAME_INVALID;
8691 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8692 struct file_info *f,
8698 printf("name: %s\n", f->name);
8699 fstrcpy(name, f->name);
8700 return NT_STATUS_OK;
8703 static bool run_mangle_illegal(int dummy)
8705 struct cli_state *cli = NULL;
8706 struct cli_state *cli_posix = NULL;
8707 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8708 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8709 char *mangled_path = NULL;
8715 printf("starting mangle-illegal test\n");
8717 if (!torture_open_connection(&cli, 0)) {
8721 smbXcli_conn_set_sockopt(cli->conn, sockops);
8723 if (!torture_open_connection(&cli_posix, 0)) {
8727 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8729 status = torture_setup_unix_extensions(cli_posix);
8730 if (!NT_STATUS_IS_OK(status)) {
8734 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8735 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8736 if (!NT_STATUS_IS_OK(status)) {
8737 printf("mkdir1 failed : %s\n", nt_errstr(status));
8742 * Create a file with illegal NTFS characters and test that we
8743 * get a usable mangled name
8746 cli_setatr(cli_posix, illegal_fname, 0, 0);
8747 cli_posix_unlink(cli_posix, illegal_fname);
8749 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8751 if (!NT_STATUS_IS_OK(status)) {
8752 printf("POSIX create of %s failed (%s)\n",
8753 illegal_fname, nt_errstr(status));
8757 status = cli_close(cli_posix, fnum);
8758 if (!NT_STATUS_IS_OK(status)) {
8759 printf("close failed (%s)\n", nt_errstr(status));
8763 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8764 if (!NT_STATUS_IS_OK(status)) {
8765 d_printf("cli_list failed: %s\n", nt_errstr(status));
8769 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8770 if (mangled_path == NULL) {
8774 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8775 if (!NT_STATUS_IS_OK(status)) {
8776 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8777 TALLOC_FREE(mangled_path);
8780 TALLOC_FREE(mangled_path);
8781 cli_close(cli, fnum);
8783 cli_setatr(cli_posix, illegal_fname, 0, 0);
8784 cli_posix_unlink(cli_posix, illegal_fname);
8787 * Create a file with a long name and check that we got *no* short name.
8790 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8791 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8793 if (!NT_STATUS_IS_OK(status)) {
8794 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8797 cli_close(cli, fnum);
8799 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8800 if (!NT_STATUS_IS_OK(status)) {
8801 d_printf("cli_list failed\n");
8805 cli_unlink(cli, fname, 0);
8806 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8808 if (!torture_close_connection(cli_posix)) {
8812 if (!torture_close_connection(cli)) {
8819 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8821 size_t *to_pull = (size_t *)priv;
8822 size_t thistime = *to_pull;
8824 thistime = MIN(thistime, n);
8825 if (thistime == 0) {
8829 memset(buf, 0, thistime);
8830 *to_pull -= thistime;
8834 static bool run_windows_write(int dummy)
8836 struct cli_state *cli1;
8840 const char *fname = "\\writetest.txt";
8841 struct timeval start_time;
8846 printf("starting windows_write test\n");
8847 if (!torture_open_connection(&cli1, 0)) {
8851 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8852 if (!NT_STATUS_IS_OK(status)) {
8853 printf("open failed (%s)\n", nt_errstr(status));
8857 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8859 start_time = timeval_current();
8861 for (i=0; i<torture_numops; i++) {
8863 off_t start = i * torture_blocksize;
8864 size_t to_pull = torture_blocksize - 1;
8866 status = cli_writeall(cli1, fnum, 0, &c,
8867 start + torture_blocksize - 1, 1, NULL);
8868 if (!NT_STATUS_IS_OK(status)) {
8869 printf("cli_write failed: %s\n", nt_errstr(status));
8873 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8874 null_source, &to_pull);
8875 if (!NT_STATUS_IS_OK(status)) {
8876 printf("cli_push returned: %s\n", nt_errstr(status));
8881 seconds = timeval_elapsed(&start_time);
8882 kbytes = (double)torture_blocksize * torture_numops;
8885 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8886 (double)seconds, (int)(kbytes/seconds));
8890 cli_close(cli1, fnum);
8891 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8892 torture_close_connection(cli1);
8896 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8898 size_t max_pdu = 0x1FFFF;
8900 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8904 if (smb1cli_conn_signing_is_active(cli->conn)) {
8908 if (smb1cli_conn_encryption_on(cli->conn)) {
8909 max_pdu = CLI_BUFFER_SIZE;
8912 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8913 len_requested &= 0xFFFF;
8916 return MIN(len_requested,
8917 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8920 static bool check_read_call(struct cli_state *cli,
8923 size_t len_requested)
8926 struct tevent_req *subreq = NULL;
8927 ssize_t len_read = 0;
8928 size_t len_expected = 0;
8929 struct tevent_context *ev = NULL;
8931 ev = samba_tevent_context_init(talloc_tos());
8936 subreq = cli_read_andx_send(talloc_tos(),
8943 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8947 status = cli_read_andx_recv(subreq, &len_read, &buf);
8948 if (!NT_STATUS_IS_OK(status)) {
8949 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8953 TALLOC_FREE(subreq);
8956 len_expected = calc_expected_return(cli, len_requested);
8958 if (len_expected > 0x10000 && len_read == 0x10000) {
8959 /* Windows servers only return a max of 0x10000,
8960 doesn't matter if you set CAP_LARGE_READX in
8961 the client sessionsetupX call or not. */
8962 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8963 (unsigned int)len_requested);
8964 } else if (len_read != len_expected) {
8965 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8966 (unsigned int)len_requested,
8967 (unsigned int)len_read,
8968 (unsigned int)len_expected);
8971 d_printf("Correct read reply.\n");
8977 /* Test large readX variants. */
8978 static bool large_readx_tests(struct cli_state *cli,
8982 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8983 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8986 /* A read of 0x10000 should return 0x10000 bytes. */
8987 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8990 /* A read of 0x10000 should return 0x10001 bytes. */
8991 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8994 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8995 the requested number of bytes. */
8996 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8999 /* A read of 1MB should return 1MB bytes (on Samba). */
9000 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
9004 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
9007 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
9010 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
9016 static bool run_large_readx(int dummy)
9018 uint8_t *buf = NULL;
9019 struct cli_state *cli1 = NULL;
9020 struct cli_state *cli2 = NULL;
9021 bool correct = false;
9022 const char *fname = "\\large_readx.dat";
9024 uint16_t fnum1 = UINT16_MAX;
9025 uint32_t normal_caps = 0;
9026 size_t file_size = 20*1024*1024;
9027 TALLOC_CTX *frame = talloc_stackframe();
9031 enum smb_signing_setting signing_setting;
9032 enum protocol_types protocol;
9036 .signing_setting = SMB_SIGNING_IF_REQUIRED,
9037 .protocol = PROTOCOL_NT1,
9039 .name = "NT1 - SIGNING_REQUIRED",
9040 .signing_setting = SMB_SIGNING_REQUIRED,
9041 .protocol = PROTOCOL_NT1,
9045 printf("starting large_readx test\n");
9047 if (!torture_open_connection(&cli1, 0)) {
9051 normal_caps = smb1cli_conn_capabilities(cli1->conn);
9053 if (!(normal_caps & CAP_LARGE_READX)) {
9054 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9055 (unsigned int)normal_caps);
9059 /* Create a file of size 4MB. */
9060 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
9061 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9062 0, 0, &fnum1, NULL);
9064 if (!NT_STATUS_IS_OK(status)) {
9065 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
9069 /* Write file_size bytes. */
9070 buf = talloc_zero_array(frame, uint8_t, file_size);
9075 status = cli_writeall(cli1,
9082 if (!NT_STATUS_IS_OK(status)) {
9083 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9087 status = cli_close(cli1, fnum1);
9088 if (!NT_STATUS_IS_OK(status)) {
9089 d_printf("cli_close failed: %s\n", nt_errstr(status));
9095 for (i=0; i < ARRAY_SIZE(runs); i++) {
9096 enum smb_signing_setting saved_signing_setting = signing_state;
9097 uint16_t fnum2 = -1;
9100 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
9102 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
9106 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
9108 signing_state = runs[i].signing_setting;
9109 cli2 = open_nbt_connection();
9110 signing_state = saved_signing_setting;
9115 status = smbXcli_negprot(cli2->conn,
9119 if (!NT_STATUS_IS_OK(status)) {
9123 status = cli_session_setup_creds(cli2, torture_creds);
9124 if (!NT_STATUS_IS_OK(status)) {
9128 status = cli_tree_connect(cli2,
9132 if (!NT_STATUS_IS_OK(status)) {
9136 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
9138 normal_caps = smb1cli_conn_capabilities(cli2->conn);
9140 if (!(normal_caps & CAP_LARGE_READX)) {
9141 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9142 (unsigned int)normal_caps);
9147 if (force_cli_encryption(cli2, share) == false) {
9150 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
9151 uint16_t major, minor;
9152 uint32_t caplow, caphigh;
9154 status = cli_unix_extensions_version(cli2,
9157 if (!NT_STATUS_IS_OK(status)) {
9162 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
9163 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
9164 0, 0, &fnum2, NULL);
9165 if (!NT_STATUS_IS_OK(status)) {
9166 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
9170 /* All reads must return less than file_size bytes. */
9171 if (!large_readx_tests(cli2, fnum2, buf)) {
9175 status = cli_close(cli2, fnum2);
9176 if (!NT_STATUS_IS_OK(status)) {
9177 d_printf("cli_close failed: %s\n", nt_errstr(status));
9182 if (!torture_close_connection(cli2)) {
9189 printf("Success on large_readx test\n");
9194 if (!torture_close_connection(cli2)) {
9200 if (fnum1 != UINT16_MAX) {
9201 status = cli_close(cli1, fnum1);
9202 if (!NT_STATUS_IS_OK(status)) {
9203 d_printf("cli_close failed: %s\n", nt_errstr(status));
9208 status = cli_unlink(cli1, fname,
9209 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9210 if (!NT_STATUS_IS_OK(status)) {
9211 printf("unlink failed (%s)\n", nt_errstr(status));
9214 if (!torture_close_connection(cli1)) {
9221 printf("finished large_readx test\n");
9225 static bool run_cli_echo(int dummy)
9227 struct cli_state *cli;
9230 printf("starting cli_echo test\n");
9231 if (!torture_open_connection(&cli, 0)) {
9234 smbXcli_conn_set_sockopt(cli->conn, sockops);
9236 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9238 d_printf("cli_echo returned %s\n", nt_errstr(status));
9240 torture_close_connection(cli);
9241 return NT_STATUS_IS_OK(status);
9244 static int splice_status(off_t written, void *priv)
9249 static bool run_cli_splice(int dummy)
9251 uint8_t *buf = NULL;
9252 struct cli_state *cli1 = NULL;
9253 bool correct = false;
9254 const char *fname_src = "\\splice_src.dat";
9255 const char *fname_dst = "\\splice_dst.dat";
9257 uint16_t fnum1 = UINT16_MAX;
9258 uint16_t fnum2 = UINT16_MAX;
9259 size_t file_size = 2*1024*1024;
9260 size_t splice_size = 1*1024*1024 + 713;
9262 uint8_t digest1[16], digest2[16];
9265 TALLOC_CTX *frame = talloc_stackframe();
9267 printf("starting cli_splice test\n");
9269 if (!torture_open_connection(&cli1, 0)) {
9273 cli_unlink(cli1, fname_src,
9274 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9275 cli_unlink(cli1, fname_dst,
9276 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9279 status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
9280 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9281 0, 0, &fnum1, NULL);
9283 if (!NT_STATUS_IS_OK(status)) {
9284 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
9288 /* Write file_size bytes - must be bigger than splice_size. */
9289 buf = talloc_zero_array(frame, uint8_t, file_size);
9291 d_printf("talloc_fail\n");
9295 /* Fill it with random numbers. */
9296 generate_random_buffer(buf, file_size);
9298 /* MD5 the first 1MB + 713 bytes. */
9300 MD5Update(&md5_ctx, buf, splice_size);
9301 MD5Final(digest1, &md5_ctx);
9303 status = cli_writeall(cli1,
9310 if (!NT_STATUS_IS_OK(status)) {
9311 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9315 status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
9316 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9317 0, 0, &fnum2, NULL);
9319 if (!NT_STATUS_IS_OK(status)) {
9320 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
9324 /* Now splice 1MB + 713 bytes. */
9325 status = cli_splice(cli1,
9336 if (!NT_STATUS_IS_OK(status)) {
9337 d_printf("cli_splice failed: %s\n", nt_errstr(status));
9341 /* Clear the old buffer. */
9342 memset(buf, '\0', file_size);
9344 /* Read the new file. */
9345 status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
9346 if (!NT_STATUS_IS_OK(status)) {
9347 d_printf("cli_read failed: %s\n", nt_errstr(status));
9350 if (nread != splice_size) {
9351 d_printf("bad read of 0x%x, should be 0x%x\n",
9352 (unsigned int)nread,
9353 (unsigned int)splice_size);
9357 /* MD5 the first 1MB + 713 bytes. */
9359 MD5Update(&md5_ctx, buf, splice_size);
9360 MD5Final(digest2, &md5_ctx);
9362 /* Must be the same. */
9363 if (memcmp(digest1, digest2, 16) != 0) {
9364 d_printf("bad MD5 compare\n");
9369 printf("Success on cli_splice test\n");
9374 if (fnum1 != UINT16_MAX) {
9375 cli_close(cli1, fnum1);
9377 if (fnum2 != UINT16_MAX) {
9378 cli_close(cli1, fnum2);
9381 cli_unlink(cli1, fname_src,
9382 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9383 cli_unlink(cli1, fname_dst,
9384 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9386 if (!torture_close_connection(cli1)) {
9395 static bool run_uid_regression_test(int dummy)
9397 static struct cli_state *cli;
9400 bool correct = True;
9401 struct smbXcli_tcon *orig_tcon = NULL;
9404 printf("starting uid regression test\n");
9406 if (!torture_open_connection(&cli, 0)) {
9410 smbXcli_conn_set_sockopt(cli->conn, sockops);
9412 /* Ok - now save then logoff our current user. */
9413 old_vuid = cli_state_get_uid(cli);
9415 status = cli_ulogoff(cli);
9416 if (!NT_STATUS_IS_OK(status)) {
9417 d_printf("(%s) cli_ulogoff failed: %s\n",
9418 __location__, nt_errstr(status));
9423 cli_state_set_uid(cli, old_vuid);
9425 /* Try an operation. */
9426 status = cli_mkdir(cli, "\\uid_reg_test");
9427 if (NT_STATUS_IS_OK(status)) {
9428 d_printf("(%s) cli_mkdir succeeded\n",
9433 /* Should be bad uid. */
9434 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9435 NT_STATUS_USER_SESSION_DELETED)) {
9441 old_cnum = cli_state_get_tid(cli);
9442 orig_tcon = cli_state_save_tcon(cli);
9443 if (orig_tcon == NULL) {
9448 /* Now try a SMBtdis with the invald vuid set to zero. */
9449 cli_state_set_uid(cli, 0);
9451 /* This should succeed. */
9452 status = cli_tdis(cli);
9454 if (NT_STATUS_IS_OK(status)) {
9455 d_printf("First tdis with invalid vuid should succeed.\n");
9457 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9459 cli_state_restore_tcon(cli, orig_tcon);
9463 cli_state_restore_tcon(cli, orig_tcon);
9464 cli_state_set_uid(cli, old_vuid);
9465 cli_state_set_tid(cli, old_cnum);
9467 /* This should fail. */
9468 status = cli_tdis(cli);
9469 if (NT_STATUS_IS_OK(status)) {
9470 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9474 /* Should be bad tid. */
9475 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9476 NT_STATUS_NETWORK_NAME_DELETED)) {
9482 cli_rmdir(cli, "\\uid_reg_test");
9491 static const char *illegal_chars = "*\\/?<>|\":";
9492 static char force_shortname_chars[] = " +,.[];=\177";
9494 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9495 const char *mask, void *state)
9497 struct cli_state *pcli = (struct cli_state *)state;
9499 NTSTATUS status = NT_STATUS_OK;
9501 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9503 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9504 return NT_STATUS_OK;
9506 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9507 status = cli_rmdir(pcli, fname);
9508 if (!NT_STATUS_IS_OK(status)) {
9509 printf("del_fn: failed to rmdir %s\n,", fname );
9512 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9513 if (!NT_STATUS_IS_OK(status)) {
9514 printf("del_fn: failed to unlink %s\n,", fname );
9526 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9527 const char *name, void *state)
9529 struct sn_state *s = (struct sn_state *)state;
9533 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9534 i, finfo->name, finfo->short_name);
9537 if (strchr(force_shortname_chars, i)) {
9538 if (!finfo->short_name) {
9539 /* Shortname not created when it should be. */
9540 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9541 __location__, finfo->name, i);
9544 } else if (finfo->short_name){
9545 /* Shortname created when it should not be. */
9546 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9547 __location__, finfo->short_name, finfo->name);
9551 return NT_STATUS_OK;
9554 static bool run_shortname_test(int dummy)
9556 static struct cli_state *cli;
9557 bool correct = True;
9563 printf("starting shortname test\n");
9565 if (!torture_open_connection(&cli, 0)) {
9569 smbXcli_conn_set_sockopt(cli->conn, sockops);
9571 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9572 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9573 cli_rmdir(cli, "\\shortname");
9575 status = cli_mkdir(cli, "\\shortname");
9576 if (!NT_STATUS_IS_OK(status)) {
9577 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9578 __location__, nt_errstr(status));
9583 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9587 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9594 for (i = 32; i < 128; i++) {
9595 uint16_t fnum = (uint16_t)-1;
9599 if (strchr(illegal_chars, i)) {
9604 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9605 FILE_SHARE_READ|FILE_SHARE_WRITE,
9606 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9607 if (!NT_STATUS_IS_OK(status)) {
9608 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9609 __location__, fname, nt_errstr(status));
9613 cli_close(cli, fnum);
9616 status = cli_list(cli, "\\shortname\\test*.*", 0,
9617 shortname_list_fn, &s);
9618 if (s.matched != 1) {
9619 d_printf("(%s) failed to list %s: %s\n",
9620 __location__, fname, nt_errstr(status));
9625 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9626 if (!NT_STATUS_IS_OK(status)) {
9627 d_printf("(%s) failed to delete %s: %s\n",
9628 __location__, fname, nt_errstr(status));
9641 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9642 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9643 cli_rmdir(cli, "\\shortname");
9644 torture_close_connection(cli);
9648 static void pagedsearch_cb(struct tevent_req *req)
9651 struct tldap_message *msg;
9654 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9655 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9656 d_printf("tldap_search_paged_recv failed: %s\n",
9657 tldap_rc2string(rc));
9660 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9664 if (!tldap_entry_dn(msg, &dn)) {
9665 d_printf("tldap_entry_dn failed\n");
9668 d_printf("%s\n", dn);
9672 static bool run_tldap(int dummy)
9674 struct tldap_context *ld;
9678 struct sockaddr_storage addr;
9679 struct tevent_context *ev;
9680 struct tevent_req *req;
9684 if (!resolve_name(host, &addr, 0, false)) {
9685 d_printf("could not find host %s\n", host);
9688 status = open_socket_out(&addr, 389, 9999, &fd);
9689 if (!NT_STATUS_IS_OK(status)) {
9690 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9694 ld = tldap_context_create(talloc_tos(), fd);
9697 d_printf("tldap_context_create failed\n");
9701 rc = tldap_fetch_rootdse(ld);
9702 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9703 d_printf("tldap_fetch_rootdse failed: %s\n",
9704 tldap_errstr(talloc_tos(), ld, rc));
9708 basedn = tldap_talloc_single_attribute(
9709 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9710 if (basedn == NULL) {
9711 d_printf("no defaultNamingContext\n");
9714 d_printf("defaultNamingContext: %s\n", basedn);
9716 ev = samba_tevent_context_init(talloc_tos());
9718 d_printf("tevent_context_init failed\n");
9722 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9723 TLDAP_SCOPE_SUB, "(objectclass=*)",
9725 NULL, 0, NULL, 0, 0, 0, 0, 5);
9727 d_printf("tldap_search_paged_send failed\n");
9730 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9732 tevent_req_poll(req, ev);
9736 /* test search filters against rootDSE */
9737 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9738 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9740 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9741 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9742 talloc_tos(), NULL);
9743 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9744 d_printf("tldap_search with complex filter failed: %s\n",
9745 tldap_errstr(talloc_tos(), ld, rc));
9753 /* Torture test to ensure no regression of :
9754 https://bugzilla.samba.org/show_bug.cgi?id=7084
9757 static bool run_dir_createtime(int dummy)
9759 struct cli_state *cli;
9760 const char *dname = "\\testdir";
9761 const char *fname = "\\testdir\\testfile";
9763 struct timespec create_time;
9764 struct timespec create_time1;
9768 if (!torture_open_connection(&cli, 0)) {
9772 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9773 cli_rmdir(cli, dname);
9775 status = cli_mkdir(cli, dname);
9776 if (!NT_STATUS_IS_OK(status)) {
9777 printf("mkdir failed: %s\n", nt_errstr(status));
9781 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9783 if (!NT_STATUS_IS_OK(status)) {
9784 printf("cli_qpathinfo2 returned %s\n",
9789 /* Sleep 3 seconds, then create a file. */
9792 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9794 if (!NT_STATUS_IS_OK(status)) {
9795 printf("cli_openx failed: %s\n", nt_errstr(status));
9799 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9801 if (!NT_STATUS_IS_OK(status)) {
9802 printf("cli_qpathinfo2 (2) returned %s\n",
9807 if (timespec_compare(&create_time1, &create_time)) {
9808 printf("run_dir_createtime: create time was updated (error)\n");
9810 printf("run_dir_createtime: create time was not updated (correct)\n");
9816 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9817 cli_rmdir(cli, dname);
9818 if (!torture_close_connection(cli)) {
9825 static bool run_streamerror(int dummy)
9827 struct cli_state *cli;
9828 const char *dname = "\\testdir";
9829 const char *streamname =
9830 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9832 time_t change_time, access_time, write_time;
9834 uint16_t mode, fnum;
9837 if (!torture_open_connection(&cli, 0)) {
9841 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9842 cli_rmdir(cli, dname);
9844 status = cli_mkdir(cli, dname);
9845 if (!NT_STATUS_IS_OK(status)) {
9846 printf("mkdir failed: %s\n", nt_errstr(status));
9850 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9851 &write_time, &size, &mode);
9852 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9853 printf("pathinfo returned %s, expected "
9854 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9859 status = cli_ntcreate(cli, streamname, 0x16,
9860 FILE_READ_DATA|FILE_READ_EA|
9861 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9862 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9863 FILE_OPEN, 0, 0, &fnum, NULL);
9865 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9866 printf("ntcreate returned %s, expected "
9867 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9873 cli_rmdir(cli, dname);
9877 struct pidtest_state {
9883 static void pid_echo_done(struct tevent_req *subreq);
9885 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9886 struct tevent_context *ev,
9887 struct cli_state *cli)
9889 struct tevent_req *req, *subreq;
9890 struct pidtest_state *state;
9892 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9897 SSVAL(state->vwv, 0, 1);
9898 state->data = data_blob_const("hello", 5);
9900 subreq = smb1cli_req_send(state,
9905 0, 0, /* *_flags2 */
9907 0xDEADBEEF, /* pid */
9910 ARRAY_SIZE(state->vwv), state->vwv,
9911 state->data.length, state->data.data);
9913 if (tevent_req_nomem(subreq, req)) {
9914 return tevent_req_post(req, ev);
9916 tevent_req_set_callback(subreq, pid_echo_done, req);
9920 static void pid_echo_done(struct tevent_req *subreq)
9922 struct tevent_req *req = tevent_req_callback_data(
9923 subreq, struct tevent_req);
9924 struct pidtest_state *state = tevent_req_data(
9925 req, struct pidtest_state);
9928 uint8_t *bytes = NULL;
9929 struct iovec *recv_iov = NULL;
9930 uint8_t *phdr = NULL;
9931 uint16_t pidlow = 0;
9932 uint16_t pidhigh = 0;
9933 struct smb1cli_req_expected_response expected[] = {
9935 .status = NT_STATUS_OK,
9940 status = smb1cli_req_recv(subreq, state,
9945 NULL, /* pvwv_offset */
9948 NULL, /* pbytes_offset */
9950 expected, ARRAY_SIZE(expected));
9952 TALLOC_FREE(subreq);
9954 if (!NT_STATUS_IS_OK(status)) {
9955 tevent_req_nterror(req, status);
9959 if (num_bytes != state->data.length) {
9960 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9964 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9965 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9969 /* Check pid low/high == DEADBEEF */
9970 pidlow = SVAL(phdr, HDR_PID);
9971 if (pidlow != 0xBEEF){
9972 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9973 (unsigned int)pidlow);
9974 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9977 pidhigh = SVAL(phdr, HDR_PIDHIGH);
9978 if (pidhigh != 0xDEAD){
9979 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9980 (unsigned int)pidhigh);
9981 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9985 tevent_req_done(req);
9988 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9990 return tevent_req_simple_recv_ntstatus(req);
9993 static bool run_pidhigh(int dummy)
9995 bool success = false;
9996 struct cli_state *cli = NULL;
9998 struct tevent_context *ev = NULL;
9999 struct tevent_req *req = NULL;
10000 TALLOC_CTX *frame = talloc_stackframe();
10002 printf("starting pid high test\n");
10003 if (!torture_open_connection(&cli, 0)) {
10006 smbXcli_conn_set_sockopt(cli->conn, sockops);
10008 ev = samba_tevent_context_init(frame);
10013 req = pid_echo_send(frame, ev, cli);
10018 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
10022 status = pid_echo_recv(req);
10023 if (NT_STATUS_IS_OK(status)) {
10024 printf("pid high test ok\n");
10030 TALLOC_FREE(frame);
10031 torture_close_connection(cli);
10036 Test Windows open on a bad POSIX symlink.
10038 static bool run_symlink_open_test(int dummy)
10040 static struct cli_state *cli;
10041 const char *fname = "non_existant_file";
10042 const char *sname = "dangling_symlink";
10043 uint16_t fnum = (uint16_t)-1;
10044 bool correct = false;
10046 TALLOC_CTX *frame = NULL;
10048 frame = talloc_stackframe();
10050 printf("Starting Windows bad symlink open test\n");
10052 if (!torture_open_connection(&cli, 0)) {
10053 TALLOC_FREE(frame);
10057 smbXcli_conn_set_sockopt(cli->conn, sockops);
10059 status = torture_setup_unix_extensions(cli);
10060 if (!NT_STATUS_IS_OK(status)) {
10061 TALLOC_FREE(frame);
10065 /* Ensure nothing exists. */
10066 cli_setatr(cli, fname, 0, 0);
10067 cli_posix_unlink(cli, fname);
10068 cli_setatr(cli, sname, 0, 0);
10069 cli_posix_unlink(cli, sname);
10071 /* Create a symlink pointing nowhere. */
10072 status = cli_posix_symlink(cli, fname, sname);
10073 if (!NT_STATUS_IS_OK(status)) {
10074 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
10077 nt_errstr(status));
10081 /* Now ensure that a Windows open doesn't hang. */
10082 status = cli_ntcreate(cli,
10085 FILE_READ_DATA|FILE_WRITE_DATA,
10087 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
10095 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
10096 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
10097 * we use O_NOFOLLOW on the server or not.
10099 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
10100 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
10104 printf("cli_ntcreate of %s returned %s - should return"
10105 " either (%s) or (%s)\n",
10108 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
10109 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
10117 if (fnum != (uint16_t)-1) {
10118 cli_close(cli, fnum);
10119 fnum = (uint16_t)-1;
10122 cli_setatr(cli, sname, 0, 0);
10123 cli_posix_unlink(cli, sname);
10124 cli_setatr(cli, fname, 0, 0);
10125 cli_posix_unlink(cli, fname);
10127 if (!torture_close_connection(cli)) {
10131 TALLOC_FREE(frame);
10136 * Only testing minimal time strings, as the others
10137 * need (locale-dependent) guessing at what strftime does and
10138 * even may differ in builds.
10140 static bool timesubst_test(void)
10142 TALLOC_CTX *ctx = NULL;
10143 /* Sa 23. Dez 04:33:20 CET 2017 */
10144 const struct timeval tv = { 1514000000, 123 };
10145 const char* expect_minimal = "20171223_033320";
10146 const char* expect_minus = "20171223_033320_000123";
10148 char *env_tz, *orig_tz = NULL;
10149 bool result = true;
10151 ctx = talloc_new(NULL);
10153 env_tz = getenv("TZ");
10155 orig_tz = talloc_strdup(ctx, env_tz);
10157 setenv("TZ", "UTC", 1);
10159 s = minimal_timeval_string(ctx, &tv, false);
10161 if(!s || strcmp(s, expect_minimal)) {
10162 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
10163 "[%s]\n", s ? s : "<nil>", expect_minimal);
10167 s = minimal_timeval_string(ctx, &tv, true);
10168 if(!s || strcmp(s, expect_minus)) {
10169 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
10170 "[%s]\n", s ? s : "<nil>", expect_minus);
10176 setenv("TZ", orig_tz, 1);
10183 static bool run_local_substitute(int dummy)
10187 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
10188 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
10189 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
10190 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
10191 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
10192 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
10193 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
10194 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
10195 ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
10196 /* Substitution depends on current time, so better test the underlying
10197 formatting function. At least covers %t. */
10198 ok &= timesubst_test();
10200 /* Different captialization rules in sub_basic... */
10202 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
10208 static bool run_local_base64(int dummy)
10213 for (i=1; i<2000; i++) {
10214 DATA_BLOB blob1, blob2;
10217 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
10219 generate_random_buffer(blob1.data, blob1.length);
10221 b64 = base64_encode_data_blob(talloc_tos(), blob1);
10223 d_fprintf(stderr, "base64_encode_data_blob failed "
10224 "for %d bytes\n", i);
10227 blob2 = base64_decode_data_blob(b64);
10230 if (data_blob_cmp(&blob1, &blob2)) {
10231 d_fprintf(stderr, "data_blob_cmp failed for %d "
10235 TALLOC_FREE(blob1.data);
10236 data_blob_free(&blob2);
10241 static void parse_fn(const struct gencache_timeout *t,
10243 void *private_data)
10248 static bool run_local_gencache(int dummy)
10254 struct memcache *mem;
10257 mem = memcache_init(NULL, 0);
10259 d_printf("%s: memcache_init failed\n", __location__);
10262 memcache_set_global(mem);
10264 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
10265 d_printf("%s: gencache_set() failed\n", __location__);
10269 if (!gencache_get("foo", NULL, NULL, NULL)) {
10270 d_printf("%s: gencache_get() failed\n", __location__);
10274 for (i=0; i<1000000; i++) {
10275 gencache_parse("foo", parse_fn, NULL);
10278 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10279 d_printf("%s: gencache_get() failed\n", __location__);
10284 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10285 d_printf("%s: gencache_get() failed\n", __location__);
10289 if (strcmp(val, "bar") != 0) {
10290 d_printf("%s: gencache_get() returned %s, expected %s\n",
10291 __location__, val, "bar");
10298 if (!gencache_del("foo")) {
10299 d_printf("%s: gencache_del() failed\n", __location__);
10302 if (gencache_del("foo")) {
10303 d_printf("%s: second gencache_del() succeeded\n",
10308 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
10309 d_printf("%s: gencache_get() on deleted entry "
10310 "succeeded\n", __location__);
10314 blob = data_blob_string_const_null("bar");
10315 tm = time(NULL) + 60;
10317 if (!gencache_set_data_blob("foo", blob, tm)) {
10318 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
10322 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10323 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
10327 if (strcmp((const char *)blob.data, "bar") != 0) {
10328 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10329 __location__, (const char *)blob.data, "bar");
10330 data_blob_free(&blob);
10334 data_blob_free(&blob);
10336 if (!gencache_del("foo")) {
10337 d_printf("%s: gencache_del() failed\n", __location__);
10340 if (gencache_del("foo")) {
10341 d_printf("%s: second gencache_del() succeeded\n",
10346 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10347 d_printf("%s: gencache_get_data_blob() on deleted entry "
10348 "succeeded\n", __location__);
10353 blob.data = (uint8_t *)&v;
10354 blob.length = sizeof(v);
10356 if (!gencache_set_data_blob("blob", blob, tm)) {
10357 d_printf("%s: gencache_set_data_blob() failed\n",
10361 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
10362 d_printf("%s: gencache_get succeeded\n", __location__);
10369 static bool rbt_testval(struct db_context *db, const char *key,
10372 struct db_record *rec;
10373 TDB_DATA data = string_tdb_data(value);
10378 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10380 d_fprintf(stderr, "fetch_locked failed\n");
10383 status = dbwrap_record_store(rec, data, 0);
10384 if (!NT_STATUS_IS_OK(status)) {
10385 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
10390 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10392 d_fprintf(stderr, "second fetch_locked failed\n");
10396 dbvalue = dbwrap_record_get_value(rec);
10397 if ((dbvalue.dsize != data.dsize)
10398 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
10399 d_fprintf(stderr, "Got wrong data back\n");
10409 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
10411 int *count2 = (int *)private_data;
10416 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
10418 int *count2 = (int *)private_data;
10420 dbwrap_record_delete(rec);
10424 static bool run_local_rbtree(int dummy)
10426 struct db_context *db;
10433 db = db_open_rbt(NULL);
10436 d_fprintf(stderr, "db_open_rbt failed\n");
10440 for (i=0; i<1000; i++) {
10443 if (asprintf(&key, "key%ld", random()) == -1) {
10446 if (asprintf(&value, "value%ld", random()) == -1) {
10451 if (!rbt_testval(db, key, value)) {
10458 if (asprintf(&value, "value%ld", random()) == -1) {
10463 if (!rbt_testval(db, key, value)) {
10474 count = 0; count2 = 0;
10475 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10477 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10478 if ((count != count2) || (count != 1000)) {
10481 count = 0; count2 = 0;
10482 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10484 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10485 if ((count != count2) || (count != 1000)) {
10488 count = 0; count2 = 0;
10489 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10491 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10492 if ((count != count2) || (count != 0)) {
10503 local test for character set functions
10505 This is a very simple test for the functionality in convert_string_error()
10507 static bool run_local_convert_string(int dummy)
10509 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10510 const char *test_strings[2] = { "March", "M\303\244rz" };
10514 for (i=0; i<2; i++) {
10515 const char *str = test_strings[i];
10516 int len = strlen(str);
10517 size_t converted_size;
10520 memset(dst, 'X', sizeof(dst));
10522 /* first try with real source length */
10523 ret = convert_string_error(CH_UNIX, CH_UTF8,
10528 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10532 if (converted_size != len) {
10533 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10534 str, len, (int)converted_size);
10538 if (strncmp(str, dst, converted_size) != 0) {
10539 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10543 if (strlen(str) != converted_size) {
10544 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10545 (int)strlen(str), (int)converted_size);
10549 if (dst[converted_size] != 'X') {
10550 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10554 /* now with srclen==-1, this causes the nul to be
10556 ret = convert_string_error(CH_UNIX, CH_UTF8,
10561 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10565 if (converted_size != len+1) {
10566 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10567 str, len, (int)converted_size);
10571 if (strncmp(str, dst, converted_size) != 0) {
10572 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10576 if (len+1 != converted_size) {
10577 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10578 len+1, (int)converted_size);
10582 if (dst[converted_size] != 'X') {
10583 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10590 TALLOC_FREE(tmp_ctx);
10593 TALLOC_FREE(tmp_ctx);
10597 static bool run_local_string_to_sid(int dummy) {
10598 struct dom_sid sid;
10600 if (string_to_sid(&sid, "S--1-5-32-545")) {
10601 printf("allowing S--1-5-32-545\n");
10604 if (string_to_sid(&sid, "S-1-5-32-+545")) {
10605 printf("allowing S-1-5-32-+545\n");
10608 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")) {
10609 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10612 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10613 printf("allowing S-1-5-32-545-abc\n");
10616 if (string_to_sid(&sid, "S-300-5-32-545")) {
10617 printf("allowing S-300-5-32-545\n");
10620 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10621 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10624 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10625 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10628 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10629 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10632 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10633 printf("could not parse S-1-5-32-545\n");
10636 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10637 printf("mis-parsed S-1-5-32-545 as %s\n",
10638 sid_string_tos(&sid));
10644 static bool sid_to_string_test(const char *expected) {
10647 struct dom_sid sid;
10649 if (!string_to_sid(&sid, expected)) {
10650 printf("could not parse %s\n", expected);
10654 str = dom_sid_string(NULL, &sid);
10655 if (strcmp(str, expected)) {
10656 printf("Comparison failed (%s != %s)\n", str, expected);
10663 static bool run_local_sid_to_string(int dummy) {
10664 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10666 if (!sid_to_string_test("S-1-545"))
10668 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10673 static bool run_local_binary_to_sid(int dummy) {
10674 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10675 static const uint8_t good_binary_sid[] = {
10676 0x1, /* revision number */
10677 15, /* num auths */
10678 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10679 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10680 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10681 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10682 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10683 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10684 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10685 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10686 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10687 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10688 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10689 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10690 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10691 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10692 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10693 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10696 static const uint8_t long_binary_sid[] = {
10697 0x1, /* revision number */
10698 15, /* num auths */
10699 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10700 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10701 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10702 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10703 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10704 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10705 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10706 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10707 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10708 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10709 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10710 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10711 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10712 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10713 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10714 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10715 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10716 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10717 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10720 static const uint8_t long_binary_sid2[] = {
10721 0x1, /* revision number */
10722 32, /* num auths */
10723 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10724 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10725 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10726 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10727 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10728 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10729 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10730 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10731 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10732 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10733 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10734 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10735 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10736 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10737 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10738 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10739 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10740 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10741 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10742 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10743 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10744 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10745 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10746 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10747 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10748 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10749 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10750 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10751 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10752 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10753 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10754 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10755 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10758 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10761 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10764 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10770 /* Split a path name into filename and stream name components. Canonicalise
10771 * such that an implicit $DATA token is always explicit.
10773 * The "specification" of this function can be found in the
10774 * run_local_stream_name() function in torture.c, I've tried those
10775 * combinations against a W2k3 server.
10778 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10779 char **pbase, char **pstream)
10782 char *stream = NULL;
10783 char *sname; /* stream name */
10784 const char *stype; /* stream type */
10786 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10788 sname = strchr_m(fname, ':');
10790 if (sname == NULL) {
10791 if (pbase != NULL) {
10792 base = talloc_strdup(mem_ctx, fname);
10793 NT_STATUS_HAVE_NO_MEMORY(base);
10798 if (pbase != NULL) {
10799 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10800 NT_STATUS_HAVE_NO_MEMORY(base);
10805 stype = strchr_m(sname, ':');
10807 if (stype == NULL) {
10808 sname = talloc_strdup(mem_ctx, sname);
10812 if (strcasecmp_m(stype, ":$DATA") != 0) {
10814 * If there is an explicit stream type, so far we only
10815 * allow $DATA. Is there anything else allowed? -- vl
10817 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10819 return NT_STATUS_OBJECT_NAME_INVALID;
10821 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10825 if (sname == NULL) {
10827 return NT_STATUS_NO_MEMORY;
10830 if (sname[0] == '\0') {
10832 * no stream name, so no stream
10837 if (pstream != NULL) {
10838 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10839 if (stream == NULL) {
10840 TALLOC_FREE(sname);
10842 return NT_STATUS_NO_MEMORY;
10845 * upper-case the type field
10847 (void)strupper_m(strchr_m(stream, ':')+1);
10851 if (pbase != NULL) {
10854 if (pstream != NULL) {
10857 return NT_STATUS_OK;
10860 static bool test_stream_name(const char *fname, const char *expected_base,
10861 const char *expected_stream,
10862 NTSTATUS expected_status)
10866 char *stream = NULL;
10868 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10869 if (!NT_STATUS_EQUAL(status, expected_status)) {
10873 if (!NT_STATUS_IS_OK(status)) {
10877 if (base == NULL) goto error;
10879 if (strcmp(expected_base, base) != 0) goto error;
10881 if ((expected_stream != NULL) && (stream == NULL)) goto error;
10882 if ((expected_stream == NULL) && (stream != NULL)) goto error;
10884 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10888 TALLOC_FREE(stream);
10892 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10893 fname, expected_base ? expected_base : "<NULL>",
10894 expected_stream ? expected_stream : "<NULL>",
10895 nt_errstr(expected_status));
10896 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10897 base ? base : "<NULL>", stream ? stream : "<NULL>",
10898 nt_errstr(status));
10900 TALLOC_FREE(stream);
10904 static bool run_local_stream_name(int dummy)
10908 ret &= test_stream_name(
10909 "bla", "bla", NULL, NT_STATUS_OK);
10910 ret &= test_stream_name(
10911 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10912 ret &= test_stream_name(
10913 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10914 ret &= test_stream_name(
10915 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10916 ret &= test_stream_name(
10917 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10918 ret &= test_stream_name(
10919 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10920 ret &= test_stream_name(
10921 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10922 ret &= test_stream_name(
10923 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10928 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10930 if (a.length != b.length) {
10931 printf("a.length=%d != b.length=%d\n",
10932 (int)a.length, (int)b.length);
10935 if (memcmp(a.data, b.data, a.length) != 0) {
10936 printf("a.data and b.data differ\n");
10942 static bool run_local_memcache(int dummy)
10944 struct memcache *cache;
10945 DATA_BLOB k1, k2, k3;
10949 TALLOC_CTX *mem_ctx;
10954 size_t size1, size2;
10957 mem_ctx = talloc_init("foo");
10958 if (mem_ctx == NULL) {
10962 /* STAT_CACHE TESTS */
10964 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10966 if (cache == NULL) {
10967 printf("memcache_init failed\n");
10971 d1 = data_blob_const("d1", 2);
10972 d3 = data_blob_const("d3", 2);
10974 k1 = data_blob_const("d1", 2);
10975 k2 = data_blob_const("d2", 2);
10976 k3 = data_blob_const("d3", 2);
10978 memcache_add(cache, STAT_CACHE, k1, d1);
10980 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10981 printf("could not find k1\n");
10984 if (!data_blob_equal(d1, v1)) {
10988 memcache_add(cache, STAT_CACHE, k1, d3);
10990 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10991 printf("could not find replaced k1\n");
10994 if (!data_blob_equal(d3, v3)) {
10998 TALLOC_FREE(cache);
11000 /* GETWD_CACHE TESTS */
11001 str1 = talloc_strdup(mem_ctx, "string1");
11002 if (str1 == NULL) {
11005 ptr2 = str1; /* Keep an alias for comparison. */
11007 str2 = talloc_strdup(mem_ctx, "string2");
11008 if (str2 == NULL) {
11012 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
11013 if (cache == NULL) {
11014 printf("memcache_init failed\n");
11018 memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
11019 /* str1 == NULL now. */
11020 ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
11021 if (ptr1 == NULL) {
11022 printf("could not find k2\n");
11025 if (ptr1 != ptr2) {
11026 printf("fetch of k2 got wrong string\n");
11030 /* Add a blob to ensure k2 gets purged. */
11031 d3 = data_blob_talloc_zero(mem_ctx, 180);
11032 memcache_add(cache, STAT_CACHE, k3, d3);
11034 ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
11035 if (ptr2 != NULL) {
11036 printf("Did find k2, should have been purged\n");
11040 TALLOC_FREE(cache);
11041 TALLOC_FREE(mem_ctx);
11043 mem_ctx = talloc_init("foo");
11044 if (mem_ctx == NULL) {
11048 cache = memcache_init(NULL, 0);
11049 if (cache == NULL) {
11053 str1 = talloc_strdup(mem_ctx, "string1");
11054 if (str1 == NULL) {
11057 str2 = talloc_strdup(mem_ctx, "string2");
11058 if (str2 == NULL) {
11061 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
11062 data_blob_string_const("torture"), &str1);
11063 size1 = talloc_total_size(cache);
11065 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
11066 data_blob_string_const("torture"), &str2);
11067 size2 = talloc_total_size(cache);
11069 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
11071 if (size2 > size1) {
11072 printf("memcache leaks memory!\n");
11078 TALLOC_FREE(cache);
11082 static void wbclient_done(struct tevent_req *req)
11085 struct winbindd_response *wb_resp;
11086 int *i = (int *)tevent_req_callback_data_void(req);
11088 wbc_err = wb_trans_recv(req, req, &wb_resp);
11091 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
11094 static bool run_wbclient_multi_ping(int dummy)
11096 struct tevent_context *ev;
11097 struct wb_context **wb_ctx;
11098 struct winbindd_request wb_req;
11099 bool result = false;
11102 BlockSignals(True, SIGPIPE);
11104 ev = tevent_context_init(talloc_tos());
11109 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
11110 if (wb_ctx == NULL) {
11114 ZERO_STRUCT(wb_req);
11115 wb_req.cmd = WINBINDD_PING;
11117 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
11119 for (i=0; i<torture_nprocs; i++) {
11120 wb_ctx[i] = wb_context_init(ev, NULL);
11121 if (wb_ctx[i] == NULL) {
11124 for (j=0; j<torture_numops; j++) {
11125 struct tevent_req *req;
11126 req = wb_trans_send(ev, ev, wb_ctx[i],
11127 (j % 2) == 0, &wb_req);
11131 tevent_req_set_callback(req, wbclient_done, &i);
11137 while (i < torture_nprocs * torture_numops) {
11138 tevent_loop_once(ev);
11147 static bool dbtrans_inc(struct db_context *db)
11149 struct db_record *rec;
11155 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11157 printf(__location__ "fetch_lock failed\n");
11161 value = dbwrap_record_get_value(rec);
11163 if (value.dsize != sizeof(uint32_t)) {
11164 printf(__location__ "value.dsize = %d\n",
11169 memcpy(&val, value.dptr, sizeof(val));
11172 status = dbwrap_record_store(
11173 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
11174 if (!NT_STATUS_IS_OK(status)) {
11175 printf(__location__ "store failed: %s\n",
11176 nt_errstr(status));
11186 static bool run_local_dbtrans(int dummy)
11188 struct db_context *db;
11189 struct db_record *rec;
11195 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
11196 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
11199 printf("Could not open transtest.db\n");
11203 res = dbwrap_transaction_start(db);
11205 printf(__location__ "transaction_start failed\n");
11209 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11211 printf(__location__ "fetch_lock failed\n");
11215 value = dbwrap_record_get_value(rec);
11217 if (value.dptr == NULL) {
11219 status = dbwrap_record_store(
11220 rec, make_tdb_data((uint8_t *)&initial,
11223 if (!NT_STATUS_IS_OK(status)) {
11224 printf(__location__ "store returned %s\n",
11225 nt_errstr(status));
11232 res = dbwrap_transaction_commit(db);
11234 printf(__location__ "transaction_commit failed\n");
11239 uint32_t val, val2;
11242 res = dbwrap_transaction_start(db);
11244 printf(__location__ "transaction_start failed\n");
11248 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
11249 if (!NT_STATUS_IS_OK(status)) {
11250 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11251 nt_errstr(status));
11255 for (i=0; i<10; i++) {
11256 if (!dbtrans_inc(db)) {
11261 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
11262 if (!NT_STATUS_IS_OK(status)) {
11263 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11264 nt_errstr(status));
11268 if (val2 != val + 10) {
11269 printf(__location__ "val=%d, val2=%d\n",
11270 (int)val, (int)val2);
11274 printf("val2=%d\r", val2);
11276 res = dbwrap_transaction_commit(db);
11278 printf(__location__ "transaction_commit failed\n");
11288 * Just a dummy test to be run under a debugger. There's no real way
11289 * to inspect the tevent_poll specific function from outside of
11293 static bool run_local_tevent_poll(int dummy)
11295 struct tevent_context *ev;
11296 struct tevent_fd *fd1, *fd2;
11297 bool result = false;
11299 ev = tevent_context_init_byname(NULL, "poll");
11301 d_fprintf(stderr, "tevent_context_init_byname failed\n");
11305 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
11307 d_fprintf(stderr, "tevent_add_fd failed\n");
11310 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
11312 d_fprintf(stderr, "tevent_add_fd failed\n");
11317 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
11319 d_fprintf(stderr, "tevent_add_fd failed\n");
11329 static bool run_local_hex_encode_buf(int dummy)
11335 for (i=0; i<sizeof(src); i++) {
11338 hex_encode_buf(buf, src, sizeof(src));
11339 if (strcmp(buf, "0001020304050607") != 0) {
11342 hex_encode_buf(buf, NULL, 0);
11343 if (buf[0] != '\0') {
11349 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11371 "1001:1111:1111:1000:0:1111:1111:1111",
11380 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11394 "1001:1111:1111:1000:0:1111:1111:1111"
11397 static bool run_local_remove_duplicate_addrs2(int dummy)
11399 struct ip_service test_vector[28];
11402 /* Construct the sockaddr_storage test vector. */
11403 for (i = 0; i < 28; i++) {
11404 struct addrinfo hints;
11405 struct addrinfo *res = NULL;
11408 memset(&hints, '\0', sizeof(hints));
11409 hints.ai_flags = AI_NUMERICHOST;
11410 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11415 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11416 remove_duplicate_addrs2_test_strings_vector[i]);
11419 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11420 memcpy(&test_vector[i].ss,
11426 count = remove_duplicate_addrs2(test_vector, i);
11429 fprintf(stderr, "count wrong (%d) should be 14\n",
11434 for (i = 0; i < count; i++) {
11435 char addr[INET6_ADDRSTRLEN];
11437 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11439 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11440 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11443 remove_duplicate_addrs2_test_strings_result[i]);
11448 printf("run_local_remove_duplicate_addrs2: success\n");
11452 static bool run_local_tdb_opener(int dummy)
11458 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11459 O_RDWR|O_CREAT, 0755);
11461 perror("tdb_open failed");
11472 static bool run_local_tdb_writer(int dummy)
11478 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11480 perror("tdb_open failed");
11484 val.dptr = (uint8_t *)&v;
11485 val.dsize = sizeof(v);
11491 ret = tdb_store(t, val, val, 0);
11493 printf("%s\n", tdb_errorstr(t));
11498 data = tdb_fetch(t, val);
11499 if (data.dptr != NULL) {
11500 SAFE_FREE(data.dptr);
11506 static bool run_local_canonicalize_path(int dummy)
11508 const char *src[] = {
11515 ".././././../../../boo",
11519 const char *dst[] = {
11532 for (i = 0; src[i] != NULL; i++) {
11533 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11535 perror("talloc fail\n");
11538 if (strcmp(d, dst[i]) != 0) {
11540 "canonicalize mismatch %s -> %s != %s",
11541 src[i], d, dst[i]);
11549 static bool run_ign_bad_negprot(int dummy)
11551 struct tevent_context *ev;
11552 struct tevent_req *req;
11553 struct smbXcli_conn *conn;
11554 struct sockaddr_storage ss;
11559 printf("starting ignore bad negprot\n");
11561 ok = resolve_name(host, &ss, 0x20, true);
11563 d_fprintf(stderr, "Could not resolve name %s\n", host);
11567 status = open_socket_out(&ss, 445, 10000, &fd);
11568 if (!NT_STATUS_IS_OK(status)) {
11569 d_fprintf(stderr, "open_socket_out failed: %s\n",
11570 nt_errstr(status));
11574 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11576 if (conn == NULL) {
11577 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11581 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11582 if (NT_STATUS_IS_OK(status)) {
11583 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11587 ev = samba_tevent_context_init(talloc_tos());
11589 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11593 req = smb1cli_session_setup_nt1_send(
11594 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11595 data_blob_null, data_blob_null, 0x40,
11596 "Windows 2000 2195", "Windows 2000 5.0");
11598 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11602 ok = tevent_req_poll_ntstatus(req, ev, &status);
11604 d_fprintf(stderr, "tevent_req_poll failed\n");
11608 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11610 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11611 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11612 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11613 nt_errstr(status));
11619 printf("starting ignore bad negprot\n");
11624 static double create_procs(bool (*fn)(int), bool *result)
11627 volatile pid_t *child_status;
11628 volatile bool *child_status_out;
11631 struct timeval start;
11635 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11636 if (!child_status) {
11637 printf("Failed to setup shared memory\n");
11641 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11642 if (!child_status_out) {
11643 printf("Failed to setup result status shared memory\n");
11647 for (i = 0; i < torture_nprocs; i++) {
11648 child_status[i] = 0;
11649 child_status_out[i] = True;
11652 start = timeval_current();
11654 for (i=0;i<torture_nprocs;i++) {
11657 pid_t mypid = getpid();
11658 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11660 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11663 if (torture_open_connection(¤t_cli, i)) break;
11664 if (tries-- == 0) {
11665 printf("pid %d failed to start\n", (int)getpid());
11671 child_status[i] = getpid();
11673 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11675 child_status_out[i] = fn(i);
11682 for (i=0;i<torture_nprocs;i++) {
11683 if (child_status[i]) synccount++;
11685 if (synccount == torture_nprocs) break;
11687 } while (timeval_elapsed(&start) < 30);
11689 if (synccount != torture_nprocs) {
11690 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11692 return timeval_elapsed(&start);
11695 /* start the client load */
11696 start = timeval_current();
11698 for (i=0;i<torture_nprocs;i++) {
11699 child_status[i] = 0;
11702 printf("%d clients started\n", torture_nprocs);
11704 for (i=0;i<torture_nprocs;i++) {
11705 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11710 for (i=0;i<torture_nprocs;i++) {
11711 if (!child_status_out[i]) {
11715 return timeval_elapsed(&start);
11718 #define FLAG_MULTIPROC 1
11724 } torture_ops[] = {
11725 {"FDPASS", run_fdpasstest, 0},
11726 {"LOCK1", run_locktest1, 0},
11727 {"LOCK2", run_locktest2, 0},
11728 {"LOCK3", run_locktest3, 0},
11729 {"LOCK4", run_locktest4, 0},
11730 {"LOCK5", run_locktest5, 0},
11731 {"LOCK6", run_locktest6, 0},
11732 {"LOCK7", run_locktest7, 0},
11733 {"LOCK8", run_locktest8, 0},
11734 {"LOCK9", run_locktest9, 0},
11735 {"UNLINK", run_unlinktest, 0},
11736 {"BROWSE", run_browsetest, 0},
11737 {"ATTR", run_attrtest, 0},
11738 {"TRANS2", run_trans2test, 0},
11739 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
11740 {"TORTURE",run_torture, FLAG_MULTIPROC},
11741 {"RANDOMIPC", run_randomipc, 0},
11742 {"NEGNOWAIT", run_negprot_nowait, 0},
11743 {"NBENCH", run_nbench, 0},
11744 {"NBENCH2", run_nbench2, 0},
11745 {"OPLOCK1", run_oplock1, 0},
11746 {"OPLOCK2", run_oplock2, 0},
11747 {"OPLOCK4", run_oplock4, 0},
11748 {"DIR", run_dirtest, 0},
11749 {"DIR1", run_dirtest1, 0},
11750 {"DIR-CREATETIME", run_dir_createtime, 0},
11751 {"DENY1", torture_denytest1, 0},
11752 {"DENY2", torture_denytest2, 0},
11753 {"TCON", run_tcon_test, 0},
11754 {"TCONDEV", run_tcon_devtype_test, 0},
11755 {"RW1", run_readwritetest, 0},
11756 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
11757 {"RW3", run_readwritelarge, 0},
11758 {"RW-SIGNING", run_readwritelarge_signtest, 0},
11759 {"OPEN", run_opentest, 0},
11760 {"POSIX", run_simple_posix_open_test, 0},
11761 {"POSIX-APPEND", run_posix_append, 0},
11762 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
11763 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
11764 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
11765 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
11766 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
11767 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
11768 {"ASYNC-ECHO", run_async_echo, 0},
11769 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
11770 { "SHORTNAME-TEST", run_shortname_test, 0},
11771 { "ADDRCHANGE", run_addrchange, 0},
11773 {"OPENATTR", run_openattrtest, 0},
11775 {"XCOPY", run_xcopy, 0},
11776 {"RENAME", run_rename, 0},
11777 {"RENAME-ACCESS", run_rename_access, 0},
11778 {"OWNER-RIGHTS", run_owner_rights, 0},
11779 {"DELETE", run_deletetest, 0},
11780 {"DELETE-PRINT", run_delete_print_test, 0},
11781 {"WILDDELETE", run_wild_deletetest, 0},
11782 {"DELETE-LN", run_deletetest_ln, 0},
11783 {"PROPERTIES", run_properties, 0},
11784 {"MANGLE", torture_mangle, 0},
11785 {"MANGLE1", run_mangle1, 0},
11786 {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
11787 {"W2K", run_w2ktest, 0},
11788 {"TRANS2SCAN", torture_trans2_scan, 0},
11789 {"NTTRANSSCAN", torture_nttrans_scan, 0},
11790 {"UTABLE", torture_utable, 0},
11791 {"CASETABLE", torture_casetable, 0},
11792 {"ERRMAPEXTRACT", run_error_map_extract, 0},
11793 {"PIPE_NUMBER", run_pipe_number, 0},
11794 {"TCON2", run_tcon2_test, 0},
11795 {"IOCTL", torture_ioctl_test, 0},
11796 {"CHKPATH", torture_chkpath_test, 0},
11797 {"FDSESS", run_fdsesstest, 0},
11798 { "EATEST", run_eatest, 0},
11799 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
11800 { "CHAIN1", run_chain1, 0},
11801 { "CHAIN2", run_chain2, 0},
11802 { "CHAIN3", run_chain3, 0},
11803 { "WINDOWS-WRITE", run_windows_write, 0},
11804 { "LARGE_READX", run_large_readx, 0},
11805 { "NTTRANS-CREATE", run_nttrans_create, 0},
11806 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
11807 { "CLI_ECHO", run_cli_echo, 0},
11808 { "CLI_SPLICE", run_cli_splice, 0},
11809 { "TLDAP", run_tldap },
11810 { "STREAMERROR", run_streamerror },
11811 { "NOTIFY-BENCH", run_notify_bench },
11812 { "NOTIFY-BENCH2", run_notify_bench2 },
11813 { "NOTIFY-BENCH3", run_notify_bench3 },
11814 { "BAD-NBT-SESSION", run_bad_nbt_session },
11815 { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
11816 { "SMB-ANY-CONNECT", run_smb_any_connect },
11817 { "NOTIFY-ONLINE", run_notify_online },
11818 { "SMB2-BASIC", run_smb2_basic },
11819 { "SMB2-NEGPROT", run_smb2_negprot },
11820 { "SMB2-ANONYMOUS", run_smb2_anonymous },
11821 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
11822 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
11823 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
11824 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
11825 { "SMB2-FTRUNCATE", run_smb2_ftruncate },
11826 { "SMB2-DIR-FSYNC", run_smb2_dir_fsync },
11827 { "CLEANUP1", run_cleanup1 },
11828 { "CLEANUP2", run_cleanup2 },
11829 { "CLEANUP3", run_cleanup3 },
11830 { "CLEANUP4", run_cleanup4 },
11831 { "OPLOCK-CANCEL", run_oplock_cancel },
11832 { "PIDHIGH", run_pidhigh },
11833 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
11834 { "LOCAL-GENCACHE", run_local_gencache, 0},
11835 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
11836 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2, 0 },
11837 { "LOCAL-DBWRAP-DO-LOCKED1", run_dbwrap_do_locked1, 0 },
11838 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
11839 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
11840 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
11841 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
11842 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
11843 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
11844 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
11845 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
11846 { "LOCAL-MESSAGING-SEND-ALL", run_messaging_send_all, 0 },
11847 { "LOCAL-BASE64", run_local_base64, 0},
11848 { "LOCAL-RBTREE", run_local_rbtree, 0},
11849 { "LOCAL-MEMCACHE", run_local_memcache, 0},
11850 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
11851 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
11852 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
11853 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
11854 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
11855 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
11856 { "LOCAL-TEVENT-POLL", run_local_tevent_poll, 0},
11857 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
11858 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
11859 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
11860 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
11861 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
11862 { "local-tdb-opener", run_local_tdb_opener, 0 },
11863 { "local-tdb-writer", run_local_tdb_writer, 0 },
11864 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
11865 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
11866 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
11867 { "LOCAL-G-LOCK1", run_g_lock1, 0 },
11868 { "LOCAL-G-LOCK2", run_g_lock2, 0 },
11869 { "LOCAL-G-LOCK3", run_g_lock3, 0 },
11870 { "LOCAL-G-LOCK4", run_g_lock4, 0 },
11871 { "LOCAL-G-LOCK5", run_g_lock5, 0 },
11872 { "LOCAL-G-LOCK6", run_g_lock6, 0 },
11873 { "LOCAL-G-LOCK-PING-PONG", run_g_lock_ping_pong, 0 },
11874 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
11875 { "LOCAL-NAMEMAP-CACHE1", run_local_namemap_cache1, 0 },
11876 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
11879 /****************************************************************************
11880 run a specified test or "ALL"
11881 ****************************************************************************/
11882 static bool run_test(const char *name)
11885 bool result = True;
11886 bool found = False;
11889 if (strequal(name,"ALL")) {
11890 for (i=0;torture_ops[i].name;i++) {
11891 run_test(torture_ops[i].name);
11896 for (i=0;torture_ops[i].name;i++) {
11897 fstr_sprintf(randomfname, "\\XX%x",
11898 (unsigned)random());
11900 if (strequal(name, torture_ops[i].name)) {
11902 printf("Running %s\n", name);
11903 if (torture_ops[i].flags & FLAG_MULTIPROC) {
11904 t = create_procs(torture_ops[i].fn, &result);
11907 printf("TEST %s FAILED!\n", name);
11910 struct timeval start;
11911 start = timeval_current();
11912 if (!torture_ops[i].fn(0)) {
11914 printf("TEST %s FAILED!\n", name);
11916 t = timeval_elapsed(&start);
11918 printf("%s took %g secs\n\n", name, t);
11923 printf("Did not find a test named %s\n", name);
11931 static void usage(void)
11935 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11936 printf("Please use samba4 torture.\n\n");
11938 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11940 printf("\t-d debuglevel\n");
11941 printf("\t-U user%%pass\n");
11942 printf("\t-k use kerberos\n");
11943 printf("\t-N numprocs\n");
11944 printf("\t-n my_netbios_name\n");
11945 printf("\t-W workgroup\n");
11946 printf("\t-o num_operations\n");
11947 printf("\t-O socket_options\n");
11948 printf("\t-m maximum protocol\n");
11949 printf("\t-L use oplocks\n");
11950 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11951 printf("\t-A showall\n");
11952 printf("\t-p port\n");
11953 printf("\t-s seed\n");
11954 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11955 printf("\t-f filename filename to test\n");
11956 printf("\t-e encrypt\n");
11959 printf("tests are:");
11960 for (i=0;torture_ops[i].name;i++) {
11961 printf(" %s", torture_ops[i].name);
11965 printf("default test is ALL\n");
11970 /****************************************************************************
11972 ****************************************************************************/
11973 int main(int argc,char *argv[])
11979 bool correct = True;
11980 TALLOC_CTX *frame = talloc_stackframe();
11981 int seed = time(NULL);
11983 #ifdef HAVE_SETBUFFER
11984 setbuffer(stdout, NULL, 0);
11987 setup_logging("smbtorture", DEBUG_STDOUT);
11992 if (is_default_dyn_CONFIGFILE()) {
11993 if(getenv("SMB_CONF_PATH")) {
11994 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11997 lp_load_global(get_dyn_CONFIGFILE());
12004 for(p = argv[1]; *p; p++)
12008 if (strncmp(argv[1], "//", 2)) {
12012 fstrcpy(host, &argv[1][2]);
12013 p = strchr_m(&host[2],'/');
12018 fstrcpy(share, p+1);
12020 fstrcpy(myname, get_myname(talloc_tos()));
12022 fprintf(stderr, "Failed to get my hostname.\n");
12026 if (*username == 0 && getenv("LOGNAME")) {
12027 fstrcpy(username,getenv("LOGNAME"));
12033 fstrcpy(workgroup, lp_workgroup());
12035 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
12039 port_to_use = atoi(optarg);
12042 seed = atoi(optarg);
12045 fstrcpy(workgroup,optarg);
12048 lp_set_cmdline("client max protocol", optarg);
12051 torture_nprocs = atoi(optarg);
12054 torture_numops = atoi(optarg);
12057 lp_set_cmdline("log level", optarg);
12063 use_oplocks = True;
12066 local_path = optarg;
12069 torture_showall = True;
12072 fstrcpy(myname, optarg);
12075 client_txt = optarg;
12082 use_kerberos = True;
12084 d_printf("No kerberos support compiled in\n");
12090 fstrcpy(username,optarg);
12091 p = strchr_m(username,'%');
12094 fstrcpy(password, p+1);
12099 fstrcpy(multishare_conn_fname, optarg);
12100 use_multishare_conn = True;
12103 torture_blocksize = atoi(optarg);
12106 test_filename = SMB_STRDUP(optarg);
12109 printf("Unknown option %c (%d)\n", (char)opt, opt);
12114 d_printf("using seed %d\n", seed);
12118 if(use_kerberos && !gotuser) gotpass = True;
12121 char pwd[256] = {0};
12124 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
12126 fstrcpy(password, pwd);
12131 printf("host=%s share=%s user=%s myname=%s\n",
12132 host, share, username, myname);
12134 torture_creds = cli_session_creds_init(frame,
12140 false, /* fallback_after_kerberos */
12141 false, /* use_ccache */
12142 false); /* password_is_nt_hash */
12143 if (torture_creds == NULL) {
12144 d_printf("cli_session_creds_init() failed.\n");
12148 if (argc == optind) {
12149 correct = run_test("ALL");
12151 for (i=optind;i<argc;i++) {
12152 if (!run_test(argv[i])) {
12158 TALLOC_FREE(frame);