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/gencache.h"
48 #include "lib/util/sys_rw.h"
50 #include <gnutls/gnutls.h>
51 #include <gnutls/crypto.h>
56 fstring host, workgroup, share, password, username, myname;
57 struct cli_credentials *torture_creds;
58 static const char *sockops="TCP_NODELAY";
60 static int port_to_use=0;
61 int torture_numops=100;
62 int torture_blocksize=1024*1024;
63 static int procnum; /* records process count number when forking */
64 static struct cli_state *current_cli;
65 static fstring randomfname;
66 static bool use_oplocks;
67 static bool use_level_II_oplocks;
68 static const char *client_txt = "client_oplocks.txt";
69 static bool disable_spnego;
70 static bool use_kerberos;
71 static bool force_dos_errors;
72 static fstring multishare_conn_fname;
73 static bool use_multishare_conn = False;
74 static bool do_encrypt;
75 static const char *local_path = NULL;
76 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
79 bool torture_showall = False;
81 static double create_procs(bool (*fn)(int), bool *result);
83 /********************************************************************
84 Ensure a connection is encrypted.
85 ********************************************************************/
87 static bool force_cli_encryption(struct cli_state *c,
88 const char *sharename)
90 uint16_t major, minor;
91 uint32_t caplow, caphigh;
94 if (!SERVER_HAS_UNIX_CIFS(c)) {
95 d_printf("Encryption required and "
96 "server that doesn't support "
97 "UNIX extensions - failing connect\n");
101 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
103 if (!NT_STATUS_IS_OK(status)) {
104 d_printf("Encryption required and "
105 "can't get UNIX CIFS extensions "
106 "version from server: %s\n", nt_errstr(status));
110 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
111 d_printf("Encryption required and "
112 "share %s doesn't support "
113 "encryption.\n", sharename);
117 status = cli_smb1_setup_encryption(c, torture_creds);
118 if (!NT_STATUS_IS_OK(status)) {
119 d_printf("Encryption required and "
120 "setup failed with error %s.\n",
129 static struct cli_state *open_nbt_connection(void)
135 if (disable_spnego) {
136 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
140 flags |= CLI_FULL_CONNECTION_OPLOCKS;
143 if (use_level_II_oplocks) {
144 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
148 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
151 if (force_dos_errors) {
152 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
155 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
156 signing_state, flags, &c);
157 if (!NT_STATUS_IS_OK(status)) {
158 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
162 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
167 /****************************************************************************
168 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
169 ****************************************************************************/
171 static bool cli_bad_session_request(int fd,
172 struct nmb_name *calling, struct nmb_name *called)
181 uint8_t message_type;
183 struct tevent_context *ev;
184 struct tevent_req *req;
186 frame = talloc_stackframe();
188 iov[0].iov_base = len_buf;
189 iov[0].iov_len = sizeof(len_buf);
191 /* put in the destination name */
193 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
195 if (iov[1].iov_base == NULL) {
198 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
199 talloc_get_size(iov[1].iov_base));
203 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
205 if (iov[2].iov_base == NULL) {
208 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
209 talloc_get_size(iov[2].iov_base));
211 /* Deliberately corrupt the name len (first byte) */
212 *((uint8_t *)iov[2].iov_base) = 100;
214 /* send a session request (RFC 1002) */
215 /* setup the packet length
216 * Remove four bytes from the length count, since the length
217 * field in the NBT Session Service header counts the number
218 * of bytes which follow. The cli_send_smb() function knows
219 * about this and accounts for those four bytes.
223 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
224 SCVAL(len_buf,0,0x81);
226 len = write_data_iov(fd, iov, 3);
231 ev = samba_tevent_context_init(frame);
235 req = read_smb_send(frame, ev, fd);
239 if (!tevent_req_poll(req, ev)) {
242 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
249 message_type = CVAL(inbuf, 0);
250 if (message_type != 0x83) {
251 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
256 if (smb_len(inbuf) != 1) {
257 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
258 (int)smb_len(inbuf));
262 error = CVAL(inbuf, 4);
264 d_fprintf(stderr, "Expected error 0x82, got %d\n",
275 /* Insert a NULL at the first separator of the given path and return a pointer
276 * to the remainder of the string.
279 terminate_path_at_separator(char * path)
287 if ((p = strchr_m(path, '/'))) {
292 if ((p = strchr_m(path, '\\'))) {
302 parse a //server/share type UNC name
304 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
305 char **hostname, char **sharename)
309 *hostname = *sharename = NULL;
311 if (strncmp(unc_name, "\\\\", 2) &&
312 strncmp(unc_name, "//", 2)) {
316 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
317 p = terminate_path_at_separator(*hostname);
320 *sharename = talloc_strdup(mem_ctx, p);
321 terminate_path_at_separator(*sharename);
324 if (*hostname && *sharename) {
328 TALLOC_FREE(*hostname);
329 TALLOC_FREE(*sharename);
333 static bool torture_open_connection_share(struct cli_state **c,
334 const char *hostname,
335 const char *sharename,
340 status = cli_full_connection_creds(c,
350 if (!NT_STATUS_IS_OK(status)) {
351 printf("failed to open share connection: //%s/%s port:%d - %s\n",
352 hostname, sharename, port_to_use, nt_errstr(status));
356 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
359 return force_cli_encryption(*c,
365 bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
367 char **unc_list = NULL;
368 int num_unc_names = 0;
371 if (use_multishare_conn==True) {
373 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
374 if (!unc_list || num_unc_names <= 0) {
375 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
379 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
381 printf("Failed to parse UNC name %s\n",
382 unc_list[conn_index % num_unc_names]);
383 TALLOC_FREE(unc_list);
387 result = torture_open_connection_share(c, h, s, flags);
389 /* h, s were copied earlier */
390 TALLOC_FREE(unc_list);
394 return torture_open_connection_share(c, host, share, flags);
397 bool torture_open_connection(struct cli_state **c, int conn_index)
399 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
402 flags |= CLI_FULL_CONNECTION_OPLOCKS;
404 if (use_level_II_oplocks) {
405 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
408 return torture_open_connection_flags(c, conn_index, flags);
411 bool torture_init_connection(struct cli_state **pcli)
413 struct cli_state *cli;
415 cli = open_nbt_connection();
424 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
426 uint16_t old_vuid = cli_state_get_uid(cli);
430 cli_state_set_uid(cli, 0);
431 status = cli_session_setup_creds(cli, torture_creds);
432 ret = NT_STATUS_IS_OK(status);
433 *new_vuid = cli_state_get_uid(cli);
434 cli_state_set_uid(cli, old_vuid);
439 bool torture_close_connection(struct cli_state *c)
444 status = cli_tdis(c);
445 if (!NT_STATUS_IS_OK(status)) {
446 printf("tdis failed (%s)\n", nt_errstr(status));
456 /* check if the server produced the expected dos or nt error code */
457 static bool check_both_error(int line, NTSTATUS status,
458 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
460 if (NT_STATUS_IS_DOS(status)) {
464 /* Check DOS error */
465 cclass = NT_STATUS_DOS_CLASS(status);
466 num = NT_STATUS_DOS_CODE(status);
468 if (eclass != cclass || ecode != num) {
469 printf("unexpected error code class=%d code=%d\n",
470 (int)cclass, (int)num);
471 printf(" expected %d/%d %s (line=%d)\n",
472 (int)eclass, (int)ecode, nt_errstr(nterr), line);
477 if (!NT_STATUS_EQUAL(nterr, status)) {
478 printf("unexpected error code %s\n",
480 printf(" expected %s (line=%d)\n",
481 nt_errstr(nterr), line);
490 /* check if the server produced the expected error code */
491 static bool check_error(int line, NTSTATUS status,
492 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
494 if (NT_STATUS_IS_DOS(status)) {
498 /* Check DOS error */
500 cclass = NT_STATUS_DOS_CLASS(status);
501 num = NT_STATUS_DOS_CODE(status);
503 if (eclass != cclass || ecode != num) {
504 printf("unexpected error code class=%d code=%d\n",
505 (int)cclass, (int)num);
506 printf(" expected %d/%d %s (line=%d)\n",
507 (int)eclass, (int)ecode, nt_errstr(nterr),
515 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
516 printf("unexpected error code %s\n",
518 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
528 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
532 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
534 while (!NT_STATUS_IS_OK(status)) {
535 if (!check_both_error(__LINE__, status, ERRDOS,
536 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
540 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
547 static bool rw_torture(struct cli_state *c)
549 const char *lockfname = "\\torture.lck";
553 pid_t pid2, pid = getpid();
560 memset(buf, '\0', sizeof(buf));
562 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
564 if (!NT_STATUS_IS_OK(status)) {
565 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
567 if (!NT_STATUS_IS_OK(status)) {
568 printf("open of %s failed (%s)\n",
569 lockfname, nt_errstr(status));
573 for (i=0;i<torture_numops;i++) {
574 unsigned n = (unsigned)sys_random()%10;
577 printf("%d\r", i); fflush(stdout);
579 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
581 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
585 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
587 if (!NT_STATUS_IS_OK(status)) {
588 printf("open failed (%s)\n", nt_errstr(status));
593 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
595 if (!NT_STATUS_IS_OK(status)) {
596 printf("write failed (%s)\n", nt_errstr(status));
601 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
602 sizeof(pid)+(j*sizeof(buf)),
604 if (!NT_STATUS_IS_OK(status)) {
605 printf("write failed (%s)\n",
613 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
615 if (!NT_STATUS_IS_OK(status)) {
616 printf("read failed (%s)\n", nt_errstr(status));
618 } else if (nread != sizeof(pid)) {
619 printf("read/write compare failed: "
620 "recv %ld req %ld\n", (unsigned long)nread,
621 (unsigned long)sizeof(pid));
626 printf("data corruption!\n");
630 status = cli_close(c, fnum);
631 if (!NT_STATUS_IS_OK(status)) {
632 printf("close failed (%s)\n", nt_errstr(status));
636 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
637 if (!NT_STATUS_IS_OK(status)) {
638 printf("unlink failed (%s)\n", nt_errstr(status));
642 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
643 if (!NT_STATUS_IS_OK(status)) {
644 printf("unlock failed (%s)\n", nt_errstr(status));
650 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
657 static bool run_torture(int dummy)
659 struct cli_state *cli;
664 smbXcli_conn_set_sockopt(cli->conn, sockops);
666 ret = rw_torture(cli);
668 if (!torture_close_connection(cli)) {
675 static bool rw_torture3(struct cli_state *c, char *lockfname)
677 uint16_t fnum = (uint16_t)-1;
682 unsigned countprev = 0;
685 NTSTATUS status = NT_STATUS_OK;
688 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
690 SIVAL(buf, i, sys_random());
697 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
698 if (!NT_STATUS_IS_OK(status)) {
699 printf("unlink failed (%s) (normal, this file should "
700 "not exist)\n", nt_errstr(status));
703 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
705 if (!NT_STATUS_IS_OK(status)) {
706 printf("first open read/write of %s failed (%s)\n",
707 lockfname, nt_errstr(status));
713 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
715 status = cli_openx(c, lockfname, O_RDONLY,
717 if (NT_STATUS_IS_OK(status)) {
722 if (!NT_STATUS_IS_OK(status)) {
723 printf("second open read-only of %s failed (%s)\n",
724 lockfname, nt_errstr(status));
730 for (count = 0; count < sizeof(buf); count += sent)
732 if (count >= countprev) {
733 printf("%d %8d\r", i, count);
736 countprev += (sizeof(buf) / 20);
741 sent = ((unsigned)sys_random()%(20))+ 1;
742 if (sent > sizeof(buf) - count)
744 sent = sizeof(buf) - count;
747 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
749 if (!NT_STATUS_IS_OK(status)) {
750 printf("write failed (%s)\n",
757 status = cli_read(c, fnum, buf_rd+count, count,
758 sizeof(buf)-count, &sent);
759 if(!NT_STATUS_IS_OK(status)) {
760 printf("read failed offset:%d size:%ld (%s)\n",
761 count, (unsigned long)sizeof(buf)-count,
765 } else if (sent > 0) {
766 if (memcmp(buf_rd+count, buf+count, sent) != 0)
768 printf("read/write compare failed\n");
769 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
778 status = cli_close(c, fnum);
779 if (!NT_STATUS_IS_OK(status)) {
780 printf("close failed (%s)\n", nt_errstr(status));
787 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
789 const char *lockfname = "\\torture2.lck";
799 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
800 if (!NT_STATUS_IS_OK(status)) {
801 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
804 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
806 if (!NT_STATUS_IS_OK(status)) {
807 printf("first open read/write of %s failed (%s)\n",
808 lockfname, nt_errstr(status));
812 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
813 if (!NT_STATUS_IS_OK(status)) {
814 printf("second open read-only of %s failed (%s)\n",
815 lockfname, nt_errstr(status));
816 cli_close(c1, fnum1);
820 for (i = 0; i < torture_numops; i++)
822 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
824 printf("%d\r", i); fflush(stdout);
827 generate_random_buffer((unsigned char *)buf, buf_size);
829 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
831 if (!NT_STATUS_IS_OK(status)) {
832 printf("write failed (%s)\n", nt_errstr(status));
837 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
838 if(!NT_STATUS_IS_OK(status)) {
839 printf("read failed (%s)\n", nt_errstr(status));
842 } else if (bytes_read != buf_size) {
843 printf("read failed\n");
844 printf("read %ld, expected %ld\n",
845 (unsigned long)bytes_read,
846 (unsigned long)buf_size);
851 if (memcmp(buf_rd, buf, buf_size) != 0)
853 printf("read/write compare failed\n");
859 status = cli_close(c2, fnum2);
860 if (!NT_STATUS_IS_OK(status)) {
861 printf("close failed (%s)\n", nt_errstr(status));
865 status = cli_close(c1, fnum1);
866 if (!NT_STATUS_IS_OK(status)) {
867 printf("close failed (%s)\n", nt_errstr(status));
871 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
872 if (!NT_STATUS_IS_OK(status)) {
873 printf("unlink failed (%s)\n", nt_errstr(status));
880 static bool run_readwritetest(int dummy)
882 struct cli_state *cli1, *cli2;
883 bool test1, test2 = False;
885 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
888 smbXcli_conn_set_sockopt(cli1->conn, sockops);
889 smbXcli_conn_set_sockopt(cli2->conn, sockops);
891 printf("starting readwritetest\n");
893 test1 = rw_torture2(cli1, cli2);
894 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
897 test2 = rw_torture2(cli1, cli1);
898 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
901 if (!torture_close_connection(cli1)) {
905 if (!torture_close_connection(cli2)) {
909 return (test1 && test2);
912 static bool run_readwritemulti(int dummy)
914 struct cli_state *cli;
919 smbXcli_conn_set_sockopt(cli->conn, sockops);
921 printf("run_readwritemulti: fname %s\n", randomfname);
922 test = rw_torture3(cli, randomfname);
924 if (!torture_close_connection(cli)) {
931 static bool run_readwritelarge_internal(void)
933 static struct cli_state *cli1;
935 const char *lockfname = "\\large.dat";
941 if (!torture_open_connection(&cli1, 0)) {
944 smbXcli_conn_set_sockopt(cli1->conn, sockops);
945 memset(buf,'\0',sizeof(buf));
947 printf("starting readwritelarge_internal\n");
949 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
951 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
953 if (!NT_STATUS_IS_OK(status)) {
954 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
958 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
960 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
962 if (!NT_STATUS_IS_OK(status)) {
963 printf("qfileinfo failed (%s)\n", nt_errstr(status));
967 if (fsize == sizeof(buf))
968 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
969 (unsigned long)fsize);
971 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
972 (unsigned long)fsize);
976 status = cli_close(cli1, fnum1);
977 if (!NT_STATUS_IS_OK(status)) {
978 printf("close failed (%s)\n", nt_errstr(status));
982 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
983 if (!NT_STATUS_IS_OK(status)) {
984 printf("unlink failed (%s)\n", nt_errstr(status));
988 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
990 if (!NT_STATUS_IS_OK(status)) {
991 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
995 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
997 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
999 if (!NT_STATUS_IS_OK(status)) {
1000 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1004 if (fsize == sizeof(buf))
1005 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1006 (unsigned long)fsize);
1008 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1009 (unsigned long)fsize);
1014 /* ToDo - set allocation. JRA */
1015 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1016 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1019 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1021 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1025 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1028 status = cli_close(cli1, fnum1);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 printf("close failed (%s)\n", nt_errstr(status));
1034 if (!torture_close_connection(cli1)) {
1040 static bool run_readwritelarge(int dummy)
1042 return run_readwritelarge_internal();
1045 static bool run_readwritelarge_signtest(int dummy)
1048 signing_state = SMB_SIGNING_REQUIRED;
1049 ret = run_readwritelarge_internal();
1050 signing_state = SMB_SIGNING_DEFAULT;
1057 #define ival(s) strtol(s, NULL, 0)
1059 /* run a test that simulates an approximate netbench client load */
1060 static bool run_netbench(int client)
1062 struct cli_state *cli;
1067 const char *params[20];
1068 bool correct = True;
1074 smbXcli_conn_set_sockopt(cli->conn, sockops);
1078 slprintf(cname,sizeof(cname)-1, "client%d", client);
1080 f = fopen(client_txt, "r");
1087 while (fgets(line, sizeof(line)-1, f)) {
1091 line[strlen(line)-1] = 0;
1093 /* printf("[%d] %s\n", line_count, line); */
1095 all_string_sub(line,"client1", cname, sizeof(line));
1097 /* parse the command parameters */
1098 params[0] = strtok_r(line, " ", &saveptr);
1100 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1104 if (i < 2) continue;
1106 if (!strncmp(params[0],"SMB", 3)) {
1107 printf("ERROR: You are using a dbench 1 load file\n");
1111 if (!strcmp(params[0],"NTCreateX")) {
1112 nb_createx(params[1], ival(params[2]), ival(params[3]),
1114 } else if (!strcmp(params[0],"Close")) {
1115 nb_close(ival(params[1]));
1116 } else if (!strcmp(params[0],"Rename")) {
1117 nb_rename(params[1], params[2]);
1118 } else if (!strcmp(params[0],"Unlink")) {
1119 nb_unlink(params[1]);
1120 } else if (!strcmp(params[0],"Deltree")) {
1121 nb_deltree(params[1]);
1122 } else if (!strcmp(params[0],"Rmdir")) {
1123 nb_rmdir(params[1]);
1124 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1125 nb_qpathinfo(params[1]);
1126 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1127 nb_qfileinfo(ival(params[1]));
1128 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1129 nb_qfsinfo(ival(params[1]));
1130 } else if (!strcmp(params[0],"FIND_FIRST")) {
1131 nb_findfirst(params[1]);
1132 } else if (!strcmp(params[0],"WriteX")) {
1133 nb_writex(ival(params[1]),
1134 ival(params[2]), ival(params[3]), ival(params[4]));
1135 } else if (!strcmp(params[0],"ReadX")) {
1136 nb_readx(ival(params[1]),
1137 ival(params[2]), ival(params[3]), ival(params[4]));
1138 } else if (!strcmp(params[0],"Flush")) {
1139 nb_flush(ival(params[1]));
1141 printf("Unknown operation %s\n", params[0]);
1149 if (!torture_close_connection(cli)) {
1157 /* run a test that simulates an approximate netbench client load */
1158 static bool run_nbench(int dummy)
1161 bool correct = True;
1163 nbio_shmem(torture_nprocs);
1167 signal(SIGALRM, nb_alarm);
1169 t = create_procs(run_netbench, &correct);
1172 printf("\nThroughput %g MB/sec\n",
1173 1.0e-6 * nbio_total() / t);
1179 This test checks for two things:
1181 1) correct support for retaining locks over a close (ie. the server
1182 must not use posix semantics)
1183 2) support for lock timeouts
1185 static bool run_locktest1(int dummy)
1187 struct cli_state *cli1, *cli2;
1188 const char *fname = "\\lockt1.lck";
1189 uint16_t fnum1, fnum2, fnum3;
1191 unsigned lock_timeout;
1194 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1197 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1198 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1200 printf("starting locktest1\n");
1202 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1204 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1206 if (!NT_STATUS_IS_OK(status)) {
1207 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1211 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1217 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1218 if (!NT_STATUS_IS_OK(status)) {
1219 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1223 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1224 if (!NT_STATUS_IS_OK(status)) {
1225 printf("lock1 failed (%s)\n", nt_errstr(status));
1229 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1230 if (NT_STATUS_IS_OK(status)) {
1231 printf("lock2 succeeded! This is a locking bug\n");
1234 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1235 NT_STATUS_LOCK_NOT_GRANTED)) {
1240 lock_timeout = (1 + (random() % 20));
1241 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1243 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1244 if (NT_STATUS_IS_OK(status)) {
1245 printf("lock3 succeeded! This is a locking bug\n");
1248 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1249 NT_STATUS_FILE_LOCK_CONFLICT)) {
1255 if (ABS(t2 - t1) < lock_timeout-1) {
1256 printf("error: This server appears not to support timed lock requests\n");
1259 printf("server slept for %u seconds for a %u second timeout\n",
1260 (unsigned int)(t2-t1), lock_timeout);
1262 status = cli_close(cli1, fnum2);
1263 if (!NT_STATUS_IS_OK(status)) {
1264 printf("close1 failed (%s)\n", nt_errstr(status));
1268 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1269 if (NT_STATUS_IS_OK(status)) {
1270 printf("lock4 succeeded! This is a locking bug\n");
1273 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1274 NT_STATUS_FILE_LOCK_CONFLICT)) {
1279 status = cli_close(cli1, fnum1);
1280 if (!NT_STATUS_IS_OK(status)) {
1281 printf("close2 failed (%s)\n", nt_errstr(status));
1285 status = cli_close(cli2, fnum3);
1286 if (!NT_STATUS_IS_OK(status)) {
1287 printf("close3 failed (%s)\n", nt_errstr(status));
1291 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1292 if (!NT_STATUS_IS_OK(status)) {
1293 printf("unlink failed (%s)\n", nt_errstr(status));
1298 if (!torture_close_connection(cli1)) {
1302 if (!torture_close_connection(cli2)) {
1306 printf("Passed locktest1\n");
1311 this checks to see if a secondary tconx can use open files from an
1314 static bool run_tcon_test(int dummy)
1316 static struct cli_state *cli;
1317 const char *fname = "\\tcontest.tmp";
1319 uint32_t cnum1, cnum2, cnum3;
1320 struct smbXcli_tcon *orig_tcon = NULL;
1321 uint16_t vuid1, vuid2;
1326 memset(buf, '\0', sizeof(buf));
1328 if (!torture_open_connection(&cli, 0)) {
1331 smbXcli_conn_set_sockopt(cli->conn, sockops);
1333 printf("starting tcontest\n");
1335 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1337 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1343 cnum1 = cli_state_get_tid(cli);
1344 vuid1 = cli_state_get_uid(cli);
1346 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1347 if (!NT_STATUS_IS_OK(status)) {
1348 printf("initial write failed (%s)", nt_errstr(status));
1352 orig_tcon = cli_state_save_tcon(cli);
1353 if (orig_tcon == NULL) {
1357 status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1358 if (!NT_STATUS_IS_OK(status)) {
1359 printf("%s refused 2nd tree connect (%s)\n", host,
1365 cnum2 = cli_state_get_tid(cli);
1366 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1367 vuid2 = cli_state_get_uid(cli) + 1;
1369 /* try a write with the wrong tid */
1370 cli_state_set_tid(cli, cnum2);
1372 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1373 if (NT_STATUS_IS_OK(status)) {
1374 printf("* server allows write with wrong TID\n");
1377 printf("server fails write with wrong TID : %s\n",
1382 /* try a write with an invalid tid */
1383 cli_state_set_tid(cli, cnum3);
1385 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1386 if (NT_STATUS_IS_OK(status)) {
1387 printf("* server allows write with invalid TID\n");
1390 printf("server fails write with invalid TID : %s\n",
1394 /* try a write with an invalid vuid */
1395 cli_state_set_uid(cli, vuid2);
1396 cli_state_set_tid(cli, cnum1);
1398 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1399 if (NT_STATUS_IS_OK(status)) {
1400 printf("* server allows write with invalid VUID\n");
1403 printf("server fails write with invalid VUID : %s\n",
1407 cli_state_set_tid(cli, cnum1);
1408 cli_state_set_uid(cli, vuid1);
1410 status = cli_close(cli, fnum1);
1411 if (!NT_STATUS_IS_OK(status)) {
1412 printf("close failed (%s)\n", nt_errstr(status));
1416 cli_state_set_tid(cli, cnum2);
1418 status = cli_tdis(cli);
1419 if (!NT_STATUS_IS_OK(status)) {
1420 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1424 cli_state_restore_tcon(cli, orig_tcon);
1426 cli_state_set_tid(cli, cnum1);
1428 if (!torture_close_connection(cli)) {
1437 checks for old style tcon support
1439 static bool run_tcon2_test(int dummy)
1441 static struct cli_state *cli;
1442 uint16_t cnum, max_xmit;
1446 if (!torture_open_connection(&cli, 0)) {
1449 smbXcli_conn_set_sockopt(cli->conn, sockops);
1451 printf("starting tcon2 test\n");
1453 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1457 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1461 if (!NT_STATUS_IS_OK(status)) {
1462 printf("tcon2 failed : %s\n", nt_errstr(status));
1464 printf("tcon OK : max_xmit=%d cnum=%d\n",
1465 (int)max_xmit, (int)cnum);
1468 if (!torture_close_connection(cli)) {
1472 printf("Passed tcon2 test\n");
1476 static bool tcon_devtest(struct cli_state *cli,
1477 const char *myshare, const char *devtype,
1478 const char *return_devtype,
1479 NTSTATUS expected_error)
1484 status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
1486 if (NT_STATUS_IS_OK(expected_error)) {
1487 if (NT_STATUS_IS_OK(status)) {
1488 if (return_devtype != NULL &&
1489 strequal(cli->dev, return_devtype)) {
1492 printf("tconX to share %s with type %s "
1493 "succeeded but returned the wrong "
1494 "device type (got [%s] but should have got [%s])\n",
1495 myshare, devtype, cli->dev, return_devtype);
1499 printf("tconX to share %s with type %s "
1500 "should have succeeded but failed\n",
1506 if (NT_STATUS_IS_OK(status)) {
1507 printf("tconx to share %s with type %s "
1508 "should have failed but succeeded\n",
1512 if (NT_STATUS_EQUAL(status, expected_error)) {
1515 printf("Returned unexpected error\n");
1524 checks for correct tconX support
1526 static bool run_tcon_devtype_test(int dummy)
1528 static struct cli_state *cli1 = NULL;
1529 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
1533 status = cli_full_connection_creds(&cli1,
1539 NULL, /* service_type */
1544 if (!NT_STATUS_IS_OK(status)) {
1545 printf("could not open connection\n");
1549 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1552 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1555 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1558 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1561 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1564 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1567 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1570 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1573 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1576 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1582 printf("Passed tcondevtest\n");
1589 This test checks that
1591 1) the server supports multiple locking contexts on the one SMB
1592 connection, distinguished by PID.
1594 2) the server correctly fails overlapping locks made by the same PID (this
1595 goes against POSIX behaviour, which is why it is tricky to implement)
1597 3) the server denies unlock requests by an incorrect client PID
1599 static bool run_locktest2(int dummy)
1601 static struct cli_state *cli;
1602 const char *fname = "\\lockt2.lck";
1603 uint16_t fnum1, fnum2, fnum3;
1604 bool correct = True;
1607 if (!torture_open_connection(&cli, 0)) {
1611 smbXcli_conn_set_sockopt(cli->conn, sockops);
1613 printf("starting locktest2\n");
1615 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1619 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1620 if (!NT_STATUS_IS_OK(status)) {
1621 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1625 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1626 if (!NT_STATUS_IS_OK(status)) {
1627 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1633 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1634 if (!NT_STATUS_IS_OK(status)) {
1635 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1641 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1642 if (!NT_STATUS_IS_OK(status)) {
1643 printf("lock1 failed (%s)\n", nt_errstr(status));
1647 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1648 if (NT_STATUS_IS_OK(status)) {
1649 printf("WRITE lock1 succeeded! This is a locking bug\n");
1652 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1653 NT_STATUS_LOCK_NOT_GRANTED)) {
1658 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1659 if (NT_STATUS_IS_OK(status)) {
1660 printf("WRITE lock2 succeeded! This is a locking bug\n");
1663 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1664 NT_STATUS_LOCK_NOT_GRANTED)) {
1669 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1670 if (NT_STATUS_IS_OK(status)) {
1671 printf("READ lock2 succeeded! This is a locking bug\n");
1674 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1675 NT_STATUS_FILE_LOCK_CONFLICT)) {
1680 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1681 if (!NT_STATUS_IS_OK(status)) {
1682 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1685 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1686 printf("unlock at 100 succeeded! This is a locking bug\n");
1690 status = cli_unlock(cli, fnum1, 0, 4);
1691 if (NT_STATUS_IS_OK(status)) {
1692 printf("unlock1 succeeded! This is a locking bug\n");
1695 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1696 NT_STATUS_RANGE_NOT_LOCKED)) {
1701 status = cli_unlock(cli, fnum1, 0, 8);
1702 if (NT_STATUS_IS_OK(status)) {
1703 printf("unlock2 succeeded! This is a locking bug\n");
1706 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1707 NT_STATUS_RANGE_NOT_LOCKED)) {
1712 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1713 if (NT_STATUS_IS_OK(status)) {
1714 printf("lock3 succeeded! This is a locking bug\n");
1717 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1718 NT_STATUS_LOCK_NOT_GRANTED)) {
1725 status = cli_close(cli, fnum1);
1726 if (!NT_STATUS_IS_OK(status)) {
1727 printf("close1 failed (%s)\n", nt_errstr(status));
1731 status = cli_close(cli, fnum2);
1732 if (!NT_STATUS_IS_OK(status)) {
1733 printf("close2 failed (%s)\n", nt_errstr(status));
1737 status = cli_close(cli, fnum3);
1738 if (!NT_STATUS_IS_OK(status)) {
1739 printf("close3 failed (%s)\n", nt_errstr(status));
1743 if (!torture_close_connection(cli)) {
1747 printf("locktest2 finished\n");
1754 This test checks that
1756 1) the server supports the full offset range in lock requests
1758 static bool run_locktest3(int dummy)
1760 static struct cli_state *cli1, *cli2;
1761 const char *fname = "\\lockt3.lck";
1762 uint16_t fnum1, fnum2;
1765 bool correct = True;
1768 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1770 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1773 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1774 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1776 printf("starting locktest3\n");
1778 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1780 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1782 if (!NT_STATUS_IS_OK(status)) {
1783 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1787 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1788 if (!NT_STATUS_IS_OK(status)) {
1789 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1793 for (offset=i=0;i<torture_numops;i++) {
1796 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1797 if (!NT_STATUS_IS_OK(status)) {
1798 printf("lock1 %d failed (%s)\n",
1804 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1805 if (!NT_STATUS_IS_OK(status)) {
1806 printf("lock2 %d failed (%s)\n",
1813 for (offset=i=0;i<torture_numops;i++) {
1816 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1817 if (NT_STATUS_IS_OK(status)) {
1818 printf("error: lock1 %d succeeded!\n", i);
1822 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1823 if (NT_STATUS_IS_OK(status)) {
1824 printf("error: lock2 %d succeeded!\n", i);
1828 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1829 if (NT_STATUS_IS_OK(status)) {
1830 printf("error: lock3 %d succeeded!\n", i);
1834 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1835 if (NT_STATUS_IS_OK(status)) {
1836 printf("error: lock4 %d succeeded!\n", i);
1841 for (offset=i=0;i<torture_numops;i++) {
1844 status = cli_unlock(cli1, fnum1, offset-1, 1);
1845 if (!NT_STATUS_IS_OK(status)) {
1846 printf("unlock1 %d failed (%s)\n",
1852 status = cli_unlock(cli2, fnum2, offset-2, 1);
1853 if (!NT_STATUS_IS_OK(status)) {
1854 printf("unlock2 %d failed (%s)\n",
1861 status = cli_close(cli1, fnum1);
1862 if (!NT_STATUS_IS_OK(status)) {
1863 printf("close1 failed (%s)\n", nt_errstr(status));
1867 status = cli_close(cli2, fnum2);
1868 if (!NT_STATUS_IS_OK(status)) {
1869 printf("close2 failed (%s)\n", nt_errstr(status));
1873 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1874 if (!NT_STATUS_IS_OK(status)) {
1875 printf("unlink failed (%s)\n", nt_errstr(status));
1879 if (!torture_close_connection(cli1)) {
1883 if (!torture_close_connection(cli2)) {
1887 printf("finished locktest3\n");
1892 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1893 char *buf, off_t offset, size_t size,
1894 size_t *nread, size_t expect)
1899 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1901 if(!NT_STATUS_IS_OK(status)) {
1903 } else if (l_nread != expect) {
1914 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1915 printf("** "); correct = False; \
1919 looks at overlapping locks
1921 static bool run_locktest4(int dummy)
1923 static struct cli_state *cli1, *cli2;
1924 const char *fname = "\\lockt4.lck";
1925 uint16_t fnum1, fnum2, f;
1928 bool correct = True;
1931 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1935 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1936 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1938 printf("starting locktest4\n");
1940 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1942 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1943 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1945 memset(buf, 0, sizeof(buf));
1947 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1949 if (!NT_STATUS_IS_OK(status)) {
1950 printf("Failed to create file: %s\n", nt_errstr(status));
1955 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1956 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1957 EXPECTED(ret, False);
1958 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1960 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1961 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1962 EXPECTED(ret, True);
1963 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1965 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1966 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1967 EXPECTED(ret, False);
1968 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1970 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1971 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1972 EXPECTED(ret, True);
1973 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1975 ret = (cli_setpid(cli1, 1),
1976 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1977 (cli_setpid(cli1, 2),
1978 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1979 EXPECTED(ret, False);
1980 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1982 ret = (cli_setpid(cli1, 1),
1983 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1984 (cli_setpid(cli1, 2),
1985 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1986 EXPECTED(ret, True);
1987 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1989 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1990 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1991 EXPECTED(ret, True);
1992 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1994 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1995 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1996 EXPECTED(ret, False);
1997 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1999 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
2000 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
2001 EXPECTED(ret, False);
2002 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
2004 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
2005 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2006 EXPECTED(ret, True);
2007 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2009 ret = (cli_setpid(cli1, 1),
2010 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2011 (cli_setpid(cli1, 2),
2012 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2013 EXPECTED(ret, False);
2014 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2016 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2017 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2018 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2019 EXPECTED(ret, False);
2020 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2023 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2024 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2025 EXPECTED(ret, False);
2026 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2028 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2029 ret = NT_STATUS_IS_OK(status);
2031 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2033 ret = NT_STATUS_IS_OK(status);
2035 EXPECTED(ret, False);
2036 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2039 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2040 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2041 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2042 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2043 EXPECTED(ret, True);
2044 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2047 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2048 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2049 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2050 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2051 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2053 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2054 EXPECTED(ret, True);
2055 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2057 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2058 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2059 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2061 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2062 EXPECTED(ret, True);
2063 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2065 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2066 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2067 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2069 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2070 EXPECTED(ret, True);
2071 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2073 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2074 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2075 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2076 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2078 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2079 EXPECTED(ret, True);
2080 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2082 cli_close(cli1, fnum1);
2083 cli_close(cli2, fnum2);
2084 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2085 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2086 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2087 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2088 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2089 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2090 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2092 cli_close(cli1, fnum1);
2093 EXPECTED(ret, True);
2094 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2097 cli_close(cli1, fnum1);
2098 cli_close(cli2, fnum2);
2099 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2100 torture_close_connection(cli1);
2101 torture_close_connection(cli2);
2103 printf("finished locktest4\n");
2108 looks at lock upgrade/downgrade.
2110 static bool run_locktest5(int dummy)
2112 static struct cli_state *cli1, *cli2;
2113 const char *fname = "\\lockt5.lck";
2114 uint16_t fnum1, fnum2, fnum3;
2117 bool correct = True;
2120 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2124 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2125 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2127 printf("starting locktest5\n");
2129 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2131 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2132 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2133 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2135 memset(buf, 0, sizeof(buf));
2137 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2139 if (!NT_STATUS_IS_OK(status)) {
2140 printf("Failed to create file: %s\n", nt_errstr(status));
2145 /* Check for NT bug... */
2146 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2147 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2148 cli_close(cli1, fnum1);
2149 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2150 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2151 ret = NT_STATUS_IS_OK(status);
2152 EXPECTED(ret, True);
2153 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2154 cli_close(cli1, fnum1);
2155 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2156 cli_unlock(cli1, fnum3, 0, 1);
2158 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2159 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2160 EXPECTED(ret, True);
2161 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2163 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2164 ret = NT_STATUS_IS_OK(status);
2165 EXPECTED(ret, False);
2167 printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2169 /* Unlock the process 2 lock. */
2170 cli_unlock(cli2, fnum2, 0, 4);
2172 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2173 ret = NT_STATUS_IS_OK(status);
2174 EXPECTED(ret, False);
2176 printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
2178 /* Unlock the process 1 fnum3 lock. */
2179 cli_unlock(cli1, fnum3, 0, 4);
2181 /* Stack 2 more locks here. */
2182 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2183 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2185 EXPECTED(ret, True);
2186 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2188 /* Unlock the first process lock, then check this was the WRITE lock that was
2191 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2192 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2194 EXPECTED(ret, True);
2195 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2197 /* Unlock the process 2 lock. */
2198 cli_unlock(cli2, fnum2, 0, 4);
2200 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2202 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2203 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2204 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2206 EXPECTED(ret, True);
2207 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2209 /* Ensure the next unlock fails. */
2210 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2211 EXPECTED(ret, False);
2212 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2214 /* Ensure connection 2 can get a write lock. */
2215 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2216 ret = NT_STATUS_IS_OK(status);
2217 EXPECTED(ret, True);
2219 printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2223 cli_close(cli1, fnum1);
2224 cli_close(cli2, fnum2);
2225 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2226 if (!torture_close_connection(cli1)) {
2229 if (!torture_close_connection(cli2)) {
2233 printf("finished locktest5\n");
2239 tries the unusual lockingX locktype bits
2241 static bool run_locktest6(int dummy)
2243 static struct cli_state *cli;
2244 const char *fname[1] = { "\\lock6.txt" };
2249 if (!torture_open_connection(&cli, 0)) {
2253 smbXcli_conn_set_sockopt(cli->conn, sockops);
2255 printf("starting locktest6\n");
2258 printf("Testing %s\n", fname[i]);
2260 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2262 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2263 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2264 cli_close(cli, fnum);
2265 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2267 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2268 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2269 cli_close(cli, fnum);
2270 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2272 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2275 torture_close_connection(cli);
2277 printf("finished locktest6\n");
2281 static bool run_locktest7(int dummy)
2283 struct cli_state *cli1;
2284 const char *fname = "\\lockt7.lck";
2287 bool correct = False;
2291 if (!torture_open_connection(&cli1, 0)) {
2295 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2297 printf("starting locktest7\n");
2299 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2301 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2303 memset(buf, 0, sizeof(buf));
2305 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2307 if (!NT_STATUS_IS_OK(status)) {
2308 printf("Failed to create file: %s\n", nt_errstr(status));
2312 cli_setpid(cli1, 1);
2314 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2315 if (!NT_STATUS_IS_OK(status)) {
2316 printf("Unable to apply read lock on range 130:4, "
2317 "error was %s\n", nt_errstr(status));
2320 printf("pid1 successfully locked range 130:4 for READ\n");
2323 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2324 if (!NT_STATUS_IS_OK(status)) {
2325 printf("pid1 unable to read the range 130:4, error was %s\n",
2328 } else if (nread != 4) {
2329 printf("pid1 unable to read the range 130:4, "
2330 "recv %ld req %d\n", (unsigned long)nread, 4);
2333 printf("pid1 successfully read the range 130:4\n");
2336 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2337 if (!NT_STATUS_IS_OK(status)) {
2338 printf("pid1 unable to write to the range 130:4, error was "
2339 "%s\n", nt_errstr(status));
2340 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2341 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2345 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2349 cli_setpid(cli1, 2);
2351 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2352 if (!NT_STATUS_IS_OK(status)) {
2353 printf("pid2 unable to read the range 130:4, error was %s\n",
2356 } else if (nread != 4) {
2357 printf("pid2 unable to read the range 130:4, "
2358 "recv %ld req %d\n", (unsigned long)nread, 4);
2361 printf("pid2 successfully read the range 130:4\n");
2364 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2365 if (!NT_STATUS_IS_OK(status)) {
2366 printf("pid2 unable to write to the range 130:4, error was "
2367 "%s\n", nt_errstr(status));
2368 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2369 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2373 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2377 cli_setpid(cli1, 1);
2378 cli_unlock(cli1, fnum1, 130, 4);
2380 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2381 if (!NT_STATUS_IS_OK(status)) {
2382 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2385 printf("pid1 successfully locked range 130:4 for WRITE\n");
2388 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2389 if (!NT_STATUS_IS_OK(status)) {
2390 printf("pid1 unable to read the range 130:4, error was %s\n",
2393 } else if (nread != 4) {
2394 printf("pid1 unable to read the range 130:4, "
2395 "recv %ld req %d\n", (unsigned long)nread, 4);
2398 printf("pid1 successfully read the range 130:4\n");
2401 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2402 if (!NT_STATUS_IS_OK(status)) {
2403 printf("pid1 unable to write to the range 130:4, error was "
2404 "%s\n", nt_errstr(status));
2407 printf("pid1 successfully wrote to the range 130:4\n");
2410 cli_setpid(cli1, 2);
2412 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 printf("pid2 unable to read the range 130:4, error was "
2415 "%s\n", nt_errstr(status));
2416 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2417 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2421 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2422 (unsigned long)nread);
2426 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2427 if (!NT_STATUS_IS_OK(status)) {
2428 printf("pid2 unable to write to the range 130:4, error was "
2429 "%s\n", nt_errstr(status));
2430 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2431 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2435 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2439 cli_unlock(cli1, fnum1, 130, 0);
2443 cli_close(cli1, fnum1);
2444 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2445 torture_close_connection(cli1);
2447 printf("finished locktest7\n");
2452 * This demonstrates a problem with our use of GPFS share modes: A file
2453 * descriptor sitting in the pending close queue holding a GPFS share mode
2454 * blocks opening a file another time. Happens with Word 2007 temp files.
2455 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2456 * open is denied with NT_STATUS_SHARING_VIOLATION.
2459 static bool run_locktest8(int dummy)
2461 struct cli_state *cli1;
2462 const char *fname = "\\lockt8.lck";
2463 uint16_t fnum1, fnum2;
2465 bool correct = False;
2468 if (!torture_open_connection(&cli1, 0)) {
2472 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2474 printf("starting locktest8\n");
2476 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2478 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2480 if (!NT_STATUS_IS_OK(status)) {
2481 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2485 memset(buf, 0, sizeof(buf));
2487 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2488 if (!NT_STATUS_IS_OK(status)) {
2489 d_fprintf(stderr, "cli_openx second time returned %s\n",
2494 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2495 if (!NT_STATUS_IS_OK(status)) {
2496 printf("Unable to apply read lock on range 1:1, error was "
2497 "%s\n", nt_errstr(status));
2501 status = cli_close(cli1, fnum1);
2502 if (!NT_STATUS_IS_OK(status)) {
2503 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2507 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2508 if (!NT_STATUS_IS_OK(status)) {
2509 d_fprintf(stderr, "cli_openx third time returned %s\n",
2517 cli_close(cli1, fnum1);
2518 cli_close(cli1, fnum2);
2519 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2520 torture_close_connection(cli1);
2522 printf("finished locktest8\n");
2527 * This test is designed to be run in conjunction with
2528 * external NFS or POSIX locks taken in the filesystem.
2529 * It checks that the smbd server will block until the
2530 * lock is released and then acquire it. JRA.
2533 static bool got_alarm;
2534 static struct cli_state *alarm_cli;
2536 static void alarm_handler(int dummy)
2541 static void alarm_handler_parent(int dummy)
2543 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2546 static void do_local_lock(int read_fd, int write_fd)
2551 const char *local_pathname = NULL;
2554 local_pathname = talloc_asprintf(talloc_tos(),
2555 "%s/lockt9.lck", local_path);
2556 if (!local_pathname) {
2557 printf("child: alloc fail\n");
2561 unlink(local_pathname);
2562 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2564 printf("child: open of %s failed %s.\n",
2565 local_pathname, strerror(errno));
2569 /* Now take a fcntl lock. */
2570 lock.l_type = F_WRLCK;
2571 lock.l_whence = SEEK_SET;
2574 lock.l_pid = getpid();
2576 ret = fcntl(fd,F_SETLK,&lock);
2578 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2579 local_pathname, strerror(errno));
2582 printf("child: got lock 0:4 on file %s.\n",
2587 CatchSignal(SIGALRM, alarm_handler);
2589 /* Signal the parent. */
2590 if (write(write_fd, &c, 1) != 1) {
2591 printf("child: start signal fail %s.\n",
2598 /* Wait for the parent to be ready. */
2599 if (read(read_fd, &c, 1) != 1) {
2600 printf("child: reply signal fail %s.\n",
2608 printf("child: released lock 0:4 on file %s.\n",
2614 static bool run_locktest9(int dummy)
2616 struct cli_state *cli1;
2617 const char *fname = "\\lockt9.lck";
2619 bool correct = False;
2620 int pipe_in[2], pipe_out[2];
2624 struct timeval start;
2628 printf("starting locktest9\n");
2630 if (local_path == NULL) {
2631 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2635 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2640 if (child_pid == -1) {
2644 if (child_pid == 0) {
2646 do_local_lock(pipe_out[0], pipe_in[1]);
2656 ret = read(pipe_in[0], &c, 1);
2658 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2663 if (!torture_open_connection(&cli1, 0)) {
2667 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2669 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2671 if (!NT_STATUS_IS_OK(status)) {
2672 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2676 /* Ensure the child has the lock. */
2677 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2678 if (NT_STATUS_IS_OK(status)) {
2679 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2682 d_printf("Child has the lock.\n");
2685 /* Tell the child to wait 5 seconds then exit. */
2686 ret = write(pipe_out[1], &c, 1);
2688 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2693 /* Wait 20 seconds for the lock. */
2695 CatchSignal(SIGALRM, alarm_handler_parent);
2698 start = timeval_current();
2700 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2701 if (!NT_STATUS_IS_OK(status)) {
2702 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2703 "%s\n", nt_errstr(status));
2708 seconds = timeval_elapsed(&start);
2710 printf("Parent got the lock after %.2f seconds.\n",
2713 status = cli_close(cli1, fnum);
2714 if (!NT_STATUS_IS_OK(status)) {
2715 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2722 cli_close(cli1, fnum);
2723 torture_close_connection(cli1);
2727 printf("finished locktest9\n");
2731 struct locktest10_state {
2736 static void locktest10_lockingx_done(struct tevent_req *subreq);
2737 static void locktest10_read_andx_done(struct tevent_req *subreq);
2739 static bool run_locktest10(int dummy)
2741 struct tevent_context *ev = NULL;
2742 struct cli_state *cli1 = NULL;
2743 struct cli_state *cli2 = NULL;
2744 struct smb1_lock_element lck = { 0 };
2745 struct tevent_req *reqs[2] = { NULL };
2746 struct tevent_req *smbreqs[2] = { NULL };
2747 const char fname[] = "\\lockt10.lck";
2748 uint16_t fnum1, fnum2;
2752 struct locktest10_state state = { .ok = true };
2755 printf("starting locktest10\n");
2757 ev = samba_tevent_context_init(NULL);
2759 d_fprintf(stderr, "samba_tevent_context_init failed\n");
2763 ok = torture_open_connection(&cli1, 0);
2767 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2769 ok = torture_open_connection(&cli2, 1);
2773 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2775 status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
2776 if (!NT_STATUS_IS_OK(status)) {
2778 "cli_openx failed: %s\n",
2783 status = cli_writeall(cli1, fnum1, 0, &data, 0, sizeof(data), NULL);
2784 if (!NT_STATUS_IS_OK(status)) {
2786 "cli_writeall failed: %s\n",
2791 status = cli_openx(cli2, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
2792 if (!NT_STATUS_IS_OK(status)) {
2794 "cli_openx failed: %s\n",
2799 status = cli_locktype(
2800 cli2, fnum2, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
2801 if (!NT_STATUS_IS_OK(status)) {
2803 "cli_locktype failed: %s\n",
2808 lck = (struct smb1_lock_element) {
2809 .pid = cli_getpid(cli1), .offset = 0, .length = 1,
2812 reqs[0] = cli_lockingx_create(
2814 ev, /* tevent_context */
2817 LOCKING_ANDX_EXCLUSIVE_LOCK, /* typeoflock */
2818 0, /* newoplocklevel */
2820 0, /* num_unlocks */
2824 &smbreqs[0]); /* psmbreq */
2825 if (reqs[0] == NULL) {
2826 d_fprintf(stderr, "cli_lockingx_create failed\n");
2829 tevent_req_set_callback(reqs[0], locktest10_lockingx_done, &state);
2831 reqs[1] = cli_read_andx_create(
2838 &smbreqs[1]); /* psmbreq */
2839 if (reqs[1] == NULL) {
2840 d_fprintf(stderr, "cli_read_andx_create failed\n");
2843 tevent_req_set_callback(reqs[1], locktest10_read_andx_done, &state);
2845 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
2846 if (!NT_STATUS_IS_OK(status)) {
2848 "smb1cli_req_chain_submit failed: %s\n",
2853 while (!state.done) {
2854 tevent_loop_once(ev);
2857 torture_close_connection(cli1);
2866 static void locktest10_lockingx_done(struct tevent_req *subreq)
2868 struct locktest10_state *state = tevent_req_callback_data_void(subreq);
2871 status = cli_lockingx_recv(subreq);
2872 TALLOC_FREE(subreq);
2874 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2875 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
2880 static void locktest10_read_andx_done(struct tevent_req *subreq)
2882 struct locktest10_state *state = tevent_req_callback_data_void(subreq);
2883 ssize_t received = -1;
2884 uint8_t *rcvbuf = NULL;
2887 status = cli_read_andx_recv(subreq, &received, &rcvbuf);
2889 if (!NT_STATUS_EQUAL(status, NT_STATUS_REQUEST_ABORTED)) {
2890 d_printf("cli_read_andx returned %s\n", nt_errstr(status));
2895 TALLOC_FREE(subreq);
2898 static bool run_locktest11(int dummy)
2900 struct cli_state *cli1;
2901 const char *fname = "\\lockt11.lck";
2906 if (!torture_open_connection(&cli1, 0)) {
2910 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2912 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2914 status = cli_openx(cli1, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum);
2915 if (!NT_STATUS_IS_OK(status)) {
2917 "cli_openx returned %s\n",
2923 * Test that LOCKING_ANDX_CANCEL_LOCK without any locks
2924 * returns NT_STATUS_OK
2927 status = cli_lockingx(
2930 LOCKING_ANDX_CANCEL_LOCK, /* typeoflock */
2931 0, /* newoplocklevel */
2933 0, /* num_unlocks */
2938 if (!NT_STATUS_IS_OK(status)) {
2939 d_printf("cli_lockingX returned %s\n", nt_errstr(status));
2945 cli_close(cli1, fnum);
2946 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2951 struct deferred_close_state {
2952 struct tevent_context *ev;
2953 struct cli_state *cli;
2957 static void deferred_close_waited(struct tevent_req *subreq);
2958 static void deferred_close_done(struct tevent_req *subreq);
2960 static struct tevent_req *deferred_close_send(
2961 TALLOC_CTX *mem_ctx,
2962 struct tevent_context *ev,
2964 struct cli_state *cli,
2967 struct tevent_req *req = NULL, *subreq = NULL;
2968 struct deferred_close_state *state = NULL;
2969 struct timeval wakeup_time = timeval_current_ofs(wait_secs, 0);
2971 req = tevent_req_create(
2972 mem_ctx, &state, struct deferred_close_state);
2980 subreq = tevent_wakeup_send(state, state->ev, wakeup_time);
2981 if (tevent_req_nomem(subreq, req)) {
2982 return tevent_req_post(req, ev);
2984 tevent_req_set_callback(subreq, deferred_close_waited, req);
2988 static void deferred_close_waited(struct tevent_req *subreq)
2990 struct tevent_req *req = tevent_req_callback_data(
2991 subreq, struct tevent_req);
2992 struct deferred_close_state *state = tevent_req_data(
2993 req, struct deferred_close_state);
2996 ok = tevent_wakeup_recv(subreq);
2997 TALLOC_FREE(subreq);
2999 tevent_req_oom(req);
3003 subreq = cli_close_send(state, state->ev, state->cli, state->fnum);
3004 if (tevent_req_nomem(subreq, req)) {
3007 tevent_req_set_callback(subreq, deferred_close_done, req);
3010 static void deferred_close_done(struct tevent_req *subreq)
3012 NTSTATUS status = cli_close_recv(subreq);
3013 tevent_req_simple_finish_ntstatus(subreq, status);
3016 static NTSTATUS deferred_close_recv(struct tevent_req *req)
3018 return tevent_req_simple_recv_ntstatus(req);
3021 struct lockread_state {
3022 struct smb1_lock_element lck;
3023 struct tevent_req *reqs[2];
3024 struct tevent_req *smbreqs[2];
3025 NTSTATUS lock_status;
3026 NTSTATUS read_status;
3030 static void lockread_lockingx_done(struct tevent_req *subreq);
3031 static void lockread_read_andx_done(struct tevent_req *subreq);
3033 static struct tevent_req *lockread_send(
3034 TALLOC_CTX *mem_ctx,
3035 struct tevent_context *ev,
3036 struct cli_state *cli,
3039 struct tevent_req *req = NULL;
3040 struct lockread_state *state = NULL;
3043 req = tevent_req_create(mem_ctx, &state, struct lockread_state);
3048 state->lck = (struct smb1_lock_element) {
3049 .pid = cli_getpid(cli), .offset = 0, .length = 1,
3052 state->reqs[0] = cli_lockingx_create(
3054 ev, /* tevent_context */
3057 LOCKING_ANDX_EXCLUSIVE_LOCK, /* typeoflock */
3058 0, /* newoplocklevel */
3059 10000, /* timeout */
3060 0, /* num_unlocks */
3063 &state->lck, /* locks */
3064 &state->smbreqs[0]); /* psmbreq */
3065 if (tevent_req_nomem(state->reqs[0], req)) {
3066 return tevent_req_post(req, ev);
3068 tevent_req_set_callback(
3069 state->reqs[0], lockread_lockingx_done, req);
3071 state->reqs[1] = cli_read_andx_create(
3078 &state->smbreqs[1]); /* psmbreq */
3079 if (tevent_req_nomem(state->reqs[1], req)) {
3080 return tevent_req_post(req, ev);
3082 tevent_req_set_callback(
3083 state->reqs[1], lockread_read_andx_done, req);
3085 status = smb1cli_req_chain_submit(state->smbreqs, 2);
3086 if (tevent_req_nterror(req, status)) {
3087 return tevent_req_post(req, ev);
3092 static void lockread_lockingx_done(struct tevent_req *subreq)
3094 struct tevent_req *req = tevent_req_callback_data(
3095 subreq, struct tevent_req);
3096 struct lockread_state *state = tevent_req_data(
3097 req, struct lockread_state);
3098 state->lock_status = cli_lockingx_recv(subreq);
3099 TALLOC_FREE(subreq);
3101 "lockingx returned %s\n",
3102 nt_errstr(state->lock_status));
3105 static void lockread_read_andx_done(struct tevent_req *subreq)
3107 struct tevent_req *req = tevent_req_callback_data(
3108 subreq, struct tevent_req);
3109 struct lockread_state *state = tevent_req_data(
3110 req, struct lockread_state);
3111 ssize_t received = -1;
3112 uint8_t *rcvbuf = NULL;
3114 state->read_status = cli_read_andx_recv(subreq, &received, &rcvbuf);
3117 "read returned %s\n",
3118 nt_errstr(state->read_status));
3120 if (!NT_STATUS_IS_OK(state->read_status)) {
3121 TALLOC_FREE(subreq);
3122 tevent_req_done(req);
3127 state->readbuf = talloc_memdup(state, rcvbuf, received);
3128 TALLOC_FREE(subreq);
3129 if (tevent_req_nomem(state->readbuf, req)) {
3133 TALLOC_FREE(subreq);
3134 tevent_req_done(req);
3137 static NTSTATUS lockread_recv(
3138 struct tevent_req *req,
3139 NTSTATUS *lock_status,
3140 NTSTATUS *read_status,
3141 TALLOC_CTX *mem_ctx,
3144 struct lockread_state *state = tevent_req_data(
3145 req, struct lockread_state);
3148 if (tevent_req_is_nterror(req, &status)) {
3152 *lock_status = state->lock_status;
3153 *read_status = state->read_status;
3154 if (state->readbuf != NULL) {
3155 *read_buf = talloc_move(mem_ctx, &state->readbuf);
3160 return NT_STATUS_OK;
3163 struct lock12_state {
3167 static void lock12_closed(struct tevent_req *subreq);
3168 static void lock12_read(struct tevent_req *subreq);
3170 static struct tevent_req *lock12_send(
3171 TALLOC_CTX *mem_ctx,
3172 struct tevent_context *ev,
3173 struct cli_state *cli,
3177 struct tevent_req *req = NULL, *subreq = NULL;
3178 struct lock12_state *state = NULL;
3180 req = tevent_req_create(mem_ctx, &state, struct lock12_state);
3185 subreq = deferred_close_send(state, ev, 1, cli, fnum1);
3186 if (tevent_req_nomem(subreq, req)) {
3187 return tevent_req_post(req, ev);
3189 tevent_req_set_callback(subreq, lock12_closed, req);
3191 subreq = lockread_send(state, ev, cli, fnum2);
3192 if (tevent_req_nomem(subreq, req)) {
3193 return tevent_req_post(req, ev);
3195 tevent_req_set_callback(subreq, lock12_read, req);
3200 static void lock12_closed(struct tevent_req *subreq)
3202 struct tevent_req *req = tevent_req_callback_data(
3203 subreq, struct tevent_req);
3206 status = deferred_close_recv(subreq);
3207 TALLOC_FREE(subreq);
3208 DBG_DEBUG("close returned %s\n", nt_errstr(status));
3209 if (tevent_req_nterror(req, status)) {
3214 static void lock12_read(struct tevent_req *subreq)
3216 struct tevent_req *req = tevent_req_callback_data(
3217 subreq, struct tevent_req);
3218 struct lock12_state *state = tevent_req_data(
3219 req, struct lock12_state);
3220 NTSTATUS status, lock_status, read_status;
3221 uint8_t *buf = NULL;
3223 status = lockread_recv(
3224 subreq, &lock_status, &read_status, state, &buf);
3225 TALLOC_FREE(subreq);
3226 if (tevent_req_nterror(req, status) ||
3227 tevent_req_nterror(req, lock_status) ||
3228 tevent_req_nterror(req, read_status)) {
3231 tevent_req_done(req);
3234 static NTSTATUS lock12_recv(struct tevent_req *req)
3239 if (tevent_req_is_nterror(req, &status)) {
3242 return NT_STATUS_OK;
3245 static bool run_locktest12(int dummy)
3247 struct tevent_context *ev = NULL;
3248 struct tevent_req *req = NULL;
3249 struct cli_state *cli = NULL;
3250 const char fname[] = "\\lockt12.lck";
3251 uint16_t fnum1, fnum2;
3257 printf("starting locktest12\n");
3259 ev = samba_tevent_context_init(NULL);
3261 d_fprintf(stderr, "samba_tevent_context_init failed\n");
3265 ok = torture_open_connection(&cli, 0);
3269 smbXcli_conn_set_sockopt(cli->conn, sockops);
3271 status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
3272 if (!NT_STATUS_IS_OK(status)) {
3274 "cli_openx failed: %s\n",
3279 status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
3280 if (!NT_STATUS_IS_OK(status)) {
3282 "cli_openx failed: %s\n",
3287 status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
3288 if (!NT_STATUS_IS_OK(status)) {
3290 "cli_writeall failed: %s\n",
3295 status = cli_locktype(
3296 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
3297 if (!NT_STATUS_IS_OK(status)) {
3299 "cli_locktype failed: %s\n",
3304 req = lock12_send(ev, ev, cli, fnum1, fnum2);
3306 d_fprintf(stderr, "lock12_send failed\n");
3310 ok = tevent_req_poll_ntstatus(req, ev, &status);
3312 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
3316 if (!NT_STATUS_IS_OK(status)) {
3318 "tevent_req_poll_ntstatus returned %s\n",
3323 status = lock12_recv(req);
3324 if (!NT_STATUS_IS_OK(status)) {
3325 d_fprintf(stderr, "lock12 returned %s\n", nt_errstr(status));
3331 torture_close_connection(cli);
3335 struct lock_ntcancel_state {
3336 struct timeval start;
3337 struct smb1_lock_element lck;
3338 struct tevent_req *subreq;
3341 static void lock_ntcancel_waited(struct tevent_req *subreq);
3342 static void lock_ntcancel_done(struct tevent_req *subreq);
3344 static struct tevent_req *lock_ntcancel_send(
3345 TALLOC_CTX *mem_ctx,
3346 struct tevent_context *ev,
3347 struct cli_state *cli,
3350 struct tevent_req *req = NULL, *subreq = NULL;
3351 struct lock_ntcancel_state *state = NULL;
3353 req = tevent_req_create(mem_ctx, &state, struct lock_ntcancel_state);
3357 state->lck = (struct smb1_lock_element) {
3358 .pid = cli_getpid(cli), .offset = 0, .length = 1,
3360 state->start = timeval_current();
3362 state->subreq = cli_lockingx_send(
3363 state, /* mem_ctx */
3364 ev, /* tevent_context */
3367 LOCKING_ANDX_EXCLUSIVE_LOCK, /* typeoflock */
3368 0, /* newoplocklevel */
3369 10000, /* timeout */
3370 0, /* num_unlocks */
3373 &state->lck); /* locks */
3374 if (tevent_req_nomem(state->subreq, req)) {
3375 return tevent_req_post(req, ev);
3377 tevent_req_set_callback(state->subreq, lock_ntcancel_done, req);
3379 subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(1, 0));
3380 if (tevent_req_nomem(subreq, req)) {
3381 return tevent_req_post(req, ev);
3383 tevent_req_set_callback(subreq, lock_ntcancel_waited, req);
3387 static void lock_ntcancel_waited(struct tevent_req *subreq)
3389 struct tevent_req *req = tevent_req_callback_data(
3390 subreq, struct tevent_req);
3391 struct lock_ntcancel_state *state = tevent_req_data(
3392 req, struct lock_ntcancel_state);
3395 ok = tevent_wakeup_recv(subreq);
3396 TALLOC_FREE(subreq);
3398 tevent_req_oom(req);
3402 ok = tevent_req_cancel(state->subreq);
3404 d_fprintf(stderr, "Could not cancel subreq\n");
3405 tevent_req_oom(req);
3410 static void lock_ntcancel_done(struct tevent_req *subreq)
3412 struct tevent_req *req = tevent_req_callback_data(
3413 subreq, struct tevent_req);
3414 struct lock_ntcancel_state *state = tevent_req_data(
3415 req, struct lock_ntcancel_state);
3419 status = cli_lockingx_recv(subreq);
3420 TALLOC_FREE(subreq);
3422 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
3423 d_printf("cli_lockingx returned %s\n", nt_errstr(status));
3424 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
3428 elapsed = timeval_elapsed(&state->start);
3431 d_printf("cli_lockingx was too slow, cancel did not work\n");
3432 tevent_req_nterror(req, NT_STATUS_UNSUCCESSFUL);
3436 tevent_req_done(req);
3439 static NTSTATUS lock_ntcancel_recv(struct tevent_req *req)
3441 return tevent_req_simple_recv_ntstatus(req);
3444 static bool run_locktest13(int dummy)
3446 struct tevent_context *ev = NULL;
3447 struct tevent_req *req = NULL;
3448 struct cli_state *cli = NULL;
3449 const char fname[] = "\\lockt13.lck";
3450 uint16_t fnum1, fnum2;
3456 printf("starting locktest13\n");
3458 ev = samba_tevent_context_init(NULL);
3460 d_fprintf(stderr, "samba_tevent_context_init failed\n");
3464 ok = torture_open_connection(&cli, 0);
3468 smbXcli_conn_set_sockopt(cli->conn, sockops);
3470 status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum1);
3471 if (!NT_STATUS_IS_OK(status)) {
3473 "cli_openx failed: %s\n",
3478 status = cli_openx(cli, fname, O_CREAT|O_RDWR, DENY_NONE, &fnum2);
3479 if (!NT_STATUS_IS_OK(status)) {
3481 "cli_openx failed: %s\n",
3486 status = cli_writeall(cli, fnum1, 0, &data, 0, sizeof(data), NULL);
3487 if (!NT_STATUS_IS_OK(status)) {
3489 "cli_writeall failed: %s\n",
3494 status = cli_locktype(
3495 cli, fnum1, 0, 1, 0, LOCKING_ANDX_EXCLUSIVE_LOCK);
3496 if (!NT_STATUS_IS_OK(status)) {
3498 "cli_locktype failed: %s\n",
3503 req = lock_ntcancel_send(ev, ev, cli, fnum2);
3505 d_fprintf(stderr, "lock_ntcancel_send failed\n");
3509 ok = tevent_req_poll_ntstatus(req, ev, &status);
3511 d_fprintf(stderr, "tevent_req_poll_ntstatus failed\n");
3515 if (!NT_STATUS_IS_OK(status)) {
3517 "tevent_req_poll_ntstatus returned %s\n",
3522 status = lock_ntcancel_recv(req);
3523 if (!NT_STATUS_IS_OK(status)) {
3525 "lock_ntcancel returned %s\n",
3532 torture_close_connection(cli);
3537 test whether fnums and tids open on one VC are available on another (a major
3540 static bool run_fdpasstest(int dummy)
3542 struct cli_state *cli1, *cli2;
3543 const char *fname = "\\fdpass.tst";
3548 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
3551 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3552 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3554 printf("starting fdpasstest\n");
3556 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3558 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3560 if (!NT_STATUS_IS_OK(status)) {
3561 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3565 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
3567 if (!NT_STATUS_IS_OK(status)) {
3568 printf("write failed (%s)\n", nt_errstr(status));
3572 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
3573 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
3574 cli_setpid(cli2, cli_getpid(cli1));
3576 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
3577 printf("read succeeded! nasty security hole [%s]\n", buf);
3581 cli_close(cli1, fnum1);
3582 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3584 torture_close_connection(cli1);
3585 torture_close_connection(cli2);
3587 printf("finished fdpasstest\n");
3591 static bool run_fdsesstest(int dummy)
3593 struct cli_state *cli;
3595 uint16_t saved_vuid;
3597 uint32_t saved_cnum;
3598 const char *fname = "\\fdsess.tst";
3599 const char *fname1 = "\\fdsess1.tst";
3606 if (!torture_open_connection(&cli, 0))
3608 smbXcli_conn_set_sockopt(cli->conn, sockops);
3610 if (!torture_cli_session_setup2(cli, &new_vuid))
3613 saved_cnum = cli_state_get_tid(cli);
3614 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
3616 new_cnum = cli_state_get_tid(cli);
3617 cli_state_set_tid(cli, saved_cnum);
3619 printf("starting fdsesstest\n");
3621 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3622 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3624 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
3625 if (!NT_STATUS_IS_OK(status)) {
3626 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3630 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
3632 if (!NT_STATUS_IS_OK(status)) {
3633 printf("write failed (%s)\n", nt_errstr(status));
3637 saved_vuid = cli_state_get_uid(cli);
3638 cli_state_set_uid(cli, new_vuid);
3640 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
3641 printf("read succeeded with different vuid! "
3642 "nasty security hole [%s]\n", buf);
3645 /* Try to open a file with different vuid, samba cnum. */
3646 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
3647 printf("create with different vuid, same cnum succeeded.\n");
3648 cli_close(cli, fnum2);
3649 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3651 printf("create with different vuid, same cnum failed.\n");
3652 printf("This will cause problems with service clients.\n");
3656 cli_state_set_uid(cli, saved_vuid);
3658 /* Try with same vuid, different cnum. */
3659 cli_state_set_tid(cli, new_cnum);
3661 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
3662 printf("read succeeded with different cnum![%s]\n", buf);
3666 cli_state_set_tid(cli, saved_cnum);
3667 cli_close(cli, fnum1);
3668 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3670 torture_close_connection(cli);
3672 printf("finished fdsesstest\n");
3677 This test checks that
3679 1) the server does not allow an unlink on a file that is open
3681 static bool run_unlinktest(int dummy)
3683 struct cli_state *cli;
3684 const char *fname = "\\unlink.tst";
3686 bool correct = True;
3689 if (!torture_open_connection(&cli, 0)) {
3693 smbXcli_conn_set_sockopt(cli->conn, sockops);
3695 printf("starting unlink test\n");
3697 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3701 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
3702 if (!NT_STATUS_IS_OK(status)) {
3703 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3707 status = cli_unlink(cli, fname,
3708 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3709 if (NT_STATUS_IS_OK(status)) {
3710 printf("error: server allowed unlink on an open file\n");
3713 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
3714 NT_STATUS_SHARING_VIOLATION);
3717 cli_close(cli, fnum);
3718 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3720 if (!torture_close_connection(cli)) {
3724 printf("unlink test finished\n");
3731 test how many open files this server supports on the one socket
3733 static bool run_maxfidtest(int dummy)
3735 struct cli_state *cli;
3737 uint16_t fnums[0x11000];
3740 bool correct = True;
3746 printf("failed to connect\n");
3750 smbXcli_conn_set_sockopt(cli->conn, sockops);
3752 for (i=0; i<0x11000; i++) {
3753 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
3754 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
3756 if (!NT_STATUS_IS_OK(status)) {
3757 printf("open of %s failed (%s)\n",
3758 fname, nt_errstr(status));
3759 printf("maximum fnum is %d\n", i);
3767 printf("cleaning up\n");
3769 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
3770 cli_close(cli, fnums[i]);
3772 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3773 if (!NT_STATUS_IS_OK(status)) {
3774 printf("unlink of %s failed (%s)\n",
3775 fname, nt_errstr(status));
3782 printf("maxfid test finished\n");
3783 if (!torture_close_connection(cli)) {
3789 /* generate a random buffer */
3790 static void rand_buf(char *buf, int len)
3793 *buf = (char)sys_random();
3798 /* send smb negprot commands, not reading the response */
3799 static bool run_negprot_nowait(int dummy)
3801 struct tevent_context *ev;
3803 struct cli_state *cli;
3804 bool correct = True;
3806 printf("starting negprot nowait test\n");
3808 ev = samba_tevent_context_init(talloc_tos());
3813 if (!(cli = open_nbt_connection())) {
3818 for (i=0;i<50000;i++) {
3819 struct tevent_req *req;
3821 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3822 PROTOCOL_CORE, PROTOCOL_NT1, 0);
3827 if (!tevent_req_poll(req, ev)) {
3828 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3836 if (torture_close_connection(cli)) {
3840 printf("finished negprot nowait test\n");
3845 /* send smb negprot commands, not reading the response */
3846 static bool run_bad_nbt_session(int dummy)
3848 struct nmb_name called, calling;
3849 struct sockaddr_storage ss;
3854 printf("starting bad nbt session test\n");
3856 make_nmb_name(&calling, myname, 0x0);
3857 make_nmb_name(&called , host, 0x20);
3859 if (!resolve_name(host, &ss, 0x20, true)) {
3860 d_fprintf(stderr, "Could not resolve name %s\n", host);
3864 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3865 if (!NT_STATUS_IS_OK(status)) {
3866 d_fprintf(stderr, "open_socket_out failed: %s\n",
3871 ret = cli_bad_session_request(fd, &calling, &called);
3874 d_fprintf(stderr, "open_socket_out failed: %s\n",
3879 printf("finished bad nbt session test\n");
3883 /* send random IPC commands */
3884 static bool run_randomipc(int dummy)
3886 char *rparam = NULL;
3888 unsigned int rdrcnt,rprcnt;
3890 int api, param_len, i;
3891 struct cli_state *cli;
3892 bool correct = True;
3895 printf("starting random ipc test\n");
3897 if (!torture_open_connection(&cli, 0)) {
3901 for (i=0;i<count;i++) {
3902 api = sys_random() % 500;
3903 param_len = (sys_random() % 64);
3905 rand_buf(param, param_len);
3910 param, param_len, 8,
3911 NULL, 0, CLI_BUFFER_SIZE,
3915 printf("%d/%d\r", i,count);
3918 printf("%d/%d\n", i, count);
3920 if (!torture_close_connection(cli)) {
3927 printf("finished random ipc test\n");
3934 static void browse_callback(const char *sname, uint32_t stype,
3935 const char *comment, void *state)
3937 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3943 This test checks the browse list code
3946 static bool run_browsetest(int dummy)
3948 static struct cli_state *cli;
3949 bool correct = True;
3951 printf("starting browse test\n");
3953 if (!torture_open_connection(&cli, 0)) {
3957 printf("domain list:\n");
3958 cli_NetServerEnum(cli, cli->server_domain,
3959 SV_TYPE_DOMAIN_ENUM,
3960 browse_callback, NULL);
3962 printf("machine list:\n");
3963 cli_NetServerEnum(cli, cli->server_domain,
3965 browse_callback, NULL);
3967 if (!torture_close_connection(cli)) {
3971 printf("browse test finished\n");
3977 static bool check_attributes(struct cli_state *cli,
3979 uint16_t expected_attrs)
3982 NTSTATUS status = cli_getatr(cli,
3987 if (!NT_STATUS_IS_OK(status)) {
3988 printf("cli_getatr failed with %s\n",
3992 if (attrs != expected_attrs) {
3993 printf("Attributes incorrect 0x%x, should be 0x%x\n",
3994 (unsigned int)attrs,
3995 (unsigned int)expected_attrs);
4002 This checks how the getatr calls works
4004 static bool run_attrtest(int dummy)
4006 struct cli_state *cli;
4009 const char *fname = "\\attrib123456789.tst";
4010 bool correct = True;
4013 printf("starting attrib test\n");
4015 if (!torture_open_connection(&cli, 0)) {
4019 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4020 cli_openx(cli, fname,
4021 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
4022 cli_close(cli, fnum);
4024 status = cli_getatr(cli, fname, NULL, NULL, &t);
4025 if (!NT_STATUS_IS_OK(status)) {
4026 printf("getatr failed (%s)\n", nt_errstr(status));
4030 if (labs(t - time(NULL)) > 60*60*24*10) {
4031 printf("ERROR: SMBgetatr bug. time is %s",
4037 t2 = t-60*60*24; /* 1 day ago */
4039 status = cli_setatr(cli, fname, 0, t2);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 printf("setatr failed (%s)\n", nt_errstr(status));
4045 status = cli_getatr(cli, fname, NULL, NULL, &t);
4046 if (!NT_STATUS_IS_OK(status)) {
4047 printf("getatr failed (%s)\n", nt_errstr(status));
4052 printf("ERROR: getatr/setatr bug. times are\n%s",
4054 printf("%s", ctime(&t2));
4058 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4060 /* Check cli_setpathinfo_basic() */
4061 /* Re-create the file. */
4062 status = cli_openx(cli, fname,
4063 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
4064 if (!NT_STATUS_IS_OK(status)) {
4065 printf("Failed to recreate %s (%s)\n",
4066 fname, nt_errstr(status));
4069 cli_close(cli, fnum);
4071 status = cli_setpathinfo_basic(cli,
4077 FILE_ATTRIBUTE_SYSTEM |
4078 FILE_ATTRIBUTE_HIDDEN |
4079 FILE_ATTRIBUTE_READONLY);
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("cli_setpathinfo_basic failed with %s\n",
4086 /* Check attributes are correct. */
4087 correct = check_attributes(cli,
4089 FILE_ATTRIBUTE_SYSTEM |
4090 FILE_ATTRIBUTE_HIDDEN |
4091 FILE_ATTRIBUTE_READONLY);
4092 if (correct == false) {
4096 /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
4097 status = cli_setpathinfo_basic(cli,
4103 FILE_ATTRIBUTE_NORMAL);
4104 if (!NT_STATUS_IS_OK(status)) {
4105 printf("cli_setpathinfo_basic failed with %s\n",
4110 /* Check attributes are correct. */
4111 correct = check_attributes(cli,
4113 FILE_ATTRIBUTE_SYSTEM |
4114 FILE_ATTRIBUTE_HIDDEN |
4115 FILE_ATTRIBUTE_READONLY);
4116 if (correct == false) {
4120 /* Setting to (uint16_t)-1 should also be ignored. */
4121 status = cli_setpathinfo_basic(cli,
4128 if (!NT_STATUS_IS_OK(status)) {
4129 printf("cli_setpathinfo_basic failed with %s\n",
4134 /* Check attributes are correct. */
4135 correct = check_attributes(cli,
4137 FILE_ATTRIBUTE_SYSTEM |
4138 FILE_ATTRIBUTE_HIDDEN |
4139 FILE_ATTRIBUTE_READONLY);
4140 if (correct == false) {
4144 /* Setting to 0 should clear them all. */
4145 status = cli_setpathinfo_basic(cli,
4152 if (!NT_STATUS_IS_OK(status)) {
4153 printf("cli_setpathinfo_basic failed with %s\n",
4158 /* Check attributes are correct. */
4159 correct = check_attributes(cli,
4161 FILE_ATTRIBUTE_NORMAL);
4162 if (correct == false) {
4170 FILE_ATTRIBUTE_SYSTEM |
4171 FILE_ATTRIBUTE_HIDDEN|
4172 FILE_ATTRIBUTE_READONLY);
4174 if (!torture_close_connection(cli)) {
4178 printf("attrib test finished\n");
4185 This checks a couple of trans2 calls
4187 static bool run_trans2test(int dummy)
4189 struct cli_state *cli;
4192 time_t c_time, a_time, m_time;
4193 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
4194 const char *fname = "\\trans2.tst";
4195 const char *dname = "\\trans2";
4196 const char *fname2 = "\\trans2\\trans2.tst";
4198 bool correct = True;
4202 printf("starting trans2 test\n");
4204 if (!torture_open_connection(&cli, 0)) {
4208 status = cli_get_fs_attr_info(cli, &fs_attr);
4209 if (!NT_STATUS_IS_OK(status)) {
4210 printf("ERROR: cli_get_fs_attr_info returned %s\n",
4215 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4216 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
4217 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
4218 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
4219 if (!NT_STATUS_IS_OK(status)) {
4220 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
4224 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
4225 if (!NT_STATUS_IS_OK(status)) {
4226 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
4229 else if (strcmp(pname, fname)) {
4230 printf("qfilename gave different name? [%s] [%s]\n",
4235 cli_close(cli, fnum);
4239 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4240 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
4242 if (!NT_STATUS_IS_OK(status)) {
4243 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4246 cli_close(cli, fnum);
4248 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
4250 if (!NT_STATUS_IS_OK(status)) {
4251 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
4254 time_t t = time(NULL);
4256 if (c_time != m_time) {
4257 printf("create time=%s", ctime(&c_time));
4258 printf("modify time=%s", ctime(&m_time));
4259 printf("This system appears to have sticky create times\n");
4261 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
4262 printf("access time=%s", ctime(&a_time));
4263 printf("This system appears to set a midnight access time\n");
4267 if (labs(m_time - t) > 60*60*24*7) {
4268 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
4274 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4275 cli_openx(cli, fname,
4276 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
4277 cli_close(cli, fnum);
4278 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
4279 &m_time_ts, &size, NULL, NULL);
4280 if (!NT_STATUS_IS_OK(status)) {
4281 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
4284 if (w_time_ts.tv_sec < 60*60*24*2) {
4285 printf("write time=%s", ctime(&w_time_ts.tv_sec));
4286 printf("This system appears to set a initial 0 write time\n");
4291 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4294 /* check if the server updates the directory modification time
4295 when creating a new file */
4296 status = cli_mkdir(cli, dname);
4297 if (!NT_STATUS_IS_OK(status)) {
4298 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
4302 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
4303 &w_time_ts, &m_time_ts, &size, NULL, NULL);
4304 if (!NT_STATUS_IS_OK(status)) {
4305 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
4309 cli_openx(cli, fname2,
4310 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
4311 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
4312 cli_close(cli, fnum);
4313 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
4314 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
4315 if (!NT_STATUS_IS_OK(status)) {
4316 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
4319 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
4321 printf("This system does not update directory modification times\n");
4325 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4326 cli_rmdir(cli, dname);
4328 if (!torture_close_connection(cli)) {
4332 printf("trans2 test finished\n");
4338 This checks new W2K calls.
4341 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
4343 uint8_t *buf = NULL;
4347 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
4348 CLI_BUFFER_SIZE, NULL, &buf, &len);
4349 if (!NT_STATUS_IS_OK(status)) {
4350 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
4353 printf("qfileinfo: level %d, len = %u\n", level, len);
4354 dump_data(0, (uint8_t *)buf, len);
4361 static bool run_w2ktest(int dummy)
4363 struct cli_state *cli;
4365 const char *fname = "\\w2ktest\\w2k.tst";
4367 bool correct = True;
4369 printf("starting w2k test\n");
4371 if (!torture_open_connection(&cli, 0)) {
4375 cli_openx(cli, fname,
4376 O_RDWR | O_CREAT , DENY_NONE, &fnum);
4378 for (level = 1004; level < 1040; level++) {
4379 new_trans(cli, fnum, level);
4382 cli_close(cli, fnum);
4384 if (!torture_close_connection(cli)) {
4388 printf("w2k test finished\n");
4395 this is a harness for some oplock tests
4397 static bool run_oplock1(int dummy)
4399 struct cli_state *cli1;
4400 const char *fname = "\\lockt1.lck";
4402 bool correct = True;
4405 printf("starting oplock test 1\n");
4407 if (!torture_open_connection(&cli1, 0)) {
4411 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4413 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4415 cli1->use_oplocks = True;
4417 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
4419 if (!NT_STATUS_IS_OK(status)) {
4420 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4424 cli1->use_oplocks = False;
4426 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4427 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4429 status = cli_close(cli1, fnum1);
4430 if (!NT_STATUS_IS_OK(status)) {
4431 printf("close2 failed (%s)\n", nt_errstr(status));
4435 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4436 if (!NT_STATUS_IS_OK(status)) {
4437 printf("unlink failed (%s)\n", nt_errstr(status));
4441 if (!torture_close_connection(cli1)) {
4445 printf("finished oplock test 1\n");
4450 static bool run_oplock2(int dummy)
4452 struct cli_state *cli1, *cli2;
4453 const char *fname = "\\lockt2.lck";
4454 uint16_t fnum1, fnum2;
4455 int saved_use_oplocks = use_oplocks;
4457 bool correct = True;
4458 volatile bool *shared_correct;
4462 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
4463 *shared_correct = True;
4465 use_level_II_oplocks = True;
4468 printf("starting oplock test 2\n");
4470 if (!torture_open_connection(&cli1, 0)) {
4471 use_level_II_oplocks = False;
4472 use_oplocks = saved_use_oplocks;
4476 if (!torture_open_connection(&cli2, 1)) {
4477 use_level_II_oplocks = False;
4478 use_oplocks = saved_use_oplocks;
4482 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4484 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4485 smbXcli_conn_set_sockopt(cli2->conn, sockops);
4487 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
4489 if (!NT_STATUS_IS_OK(status)) {
4490 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4494 /* Don't need the globals any more. */
4495 use_level_II_oplocks = False;
4496 use_oplocks = saved_use_oplocks;
4500 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
4501 if (!NT_STATUS_IS_OK(status)) {
4502 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
4503 *shared_correct = False;
4509 status = cli_close(cli2, fnum2);
4510 if (!NT_STATUS_IS_OK(status)) {
4511 printf("close2 failed (%s)\n", nt_errstr(status));
4512 *shared_correct = False;
4520 /* Ensure cli1 processes the break. Empty file should always return 0
4522 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
4523 if (!NT_STATUS_IS_OK(status)) {
4524 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
4526 } else if (nread != 0) {
4527 printf("read on empty fnum1 failed. recv %ld expected %d\n",
4528 (unsigned long)nread, 0);
4532 /* Should now be at level II. */
4533 /* Test if sending a write locks causes a break to none. */
4534 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
4535 if (!NT_STATUS_IS_OK(status)) {
4536 printf("lock failed (%s)\n", nt_errstr(status));
4540 cli_unlock(cli1, fnum1, 0, 4);
4544 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
4545 if (!NT_STATUS_IS_OK(status)) {
4546 printf("lock failed (%s)\n", nt_errstr(status));
4550 cli_unlock(cli1, fnum1, 0, 4);
4554 cli_read(cli1, fnum1, buf, 0, 4, NULL);
4556 status = cli_close(cli1, fnum1);
4557 if (!NT_STATUS_IS_OK(status)) {
4558 printf("close1 failed (%s)\n", nt_errstr(status));
4564 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4565 if (!NT_STATUS_IS_OK(status)) {
4566 printf("unlink failed (%s)\n", nt_errstr(status));
4570 if (!torture_close_connection(cli1)) {
4574 if (!*shared_correct) {
4578 printf("finished oplock test 2\n");
4583 struct oplock4_state {
4584 struct tevent_context *ev;
4585 struct cli_state *cli;
4590 static void oplock4_got_break(struct tevent_req *req);
4591 static void oplock4_got_open(struct tevent_req *req);
4593 static bool run_oplock4(int dummy)
4595 struct tevent_context *ev;
4596 struct cli_state *cli1, *cli2;
4597 struct tevent_req *oplock_req, *open_req;
4598 const char *fname = "\\lockt4.lck";
4599 const char *fname_ln = "\\lockt4_ln.lck";
4600 uint16_t fnum1, fnum2;
4601 int saved_use_oplocks = use_oplocks;
4603 bool correct = true;
4607 struct oplock4_state *state;
4609 printf("starting oplock test 4\n");
4611 if (!torture_open_connection(&cli1, 0)) {
4612 use_level_II_oplocks = false;
4613 use_oplocks = saved_use_oplocks;
4617 if (!torture_open_connection(&cli2, 1)) {
4618 use_level_II_oplocks = false;
4619 use_oplocks = saved_use_oplocks;
4623 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4624 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4626 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4627 smbXcli_conn_set_sockopt(cli2->conn, sockops);
4629 /* Create the file. */
4630 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
4632 if (!NT_STATUS_IS_OK(status)) {
4633 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4637 status = cli_close(cli1, fnum1);
4638 if (!NT_STATUS_IS_OK(status)) {
4639 printf("close1 failed (%s)\n", nt_errstr(status));
4643 /* Now create a hardlink. */
4644 status = cli_hardlink(cli1, fname, fname_ln);
4645 if (!NT_STATUS_IS_OK(status)) {
4646 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4650 /* Prove that opening hardlinks cause deny modes to conflict. */
4651 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
4652 if (!NT_STATUS_IS_OK(status)) {
4653 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4657 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
4658 if (NT_STATUS_IS_OK(status)) {
4659 printf("open of %s succeeded - should fail with sharing violation.\n",
4664 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
4665 printf("open of %s should fail with sharing violation. Got %s\n",
4666 fname_ln, nt_errstr(status));
4670 status = cli_close(cli1, fnum1);
4671 if (!NT_STATUS_IS_OK(status)) {
4672 printf("close1 failed (%s)\n", nt_errstr(status));
4676 cli1->use_oplocks = true;
4677 cli2->use_oplocks = true;
4679 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
4680 if (!NT_STATUS_IS_OK(status)) {
4681 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4685 ev = samba_tevent_context_init(talloc_tos());
4687 printf("tevent_context_init failed\n");
4691 state = talloc(ev, struct oplock4_state);
4692 if (state == NULL) {
4693 printf("talloc failed\n");
4698 state->got_break = &got_break;
4699 state->fnum2 = &fnum2;
4701 oplock_req = cli_smb_oplock_break_waiter_send(
4702 talloc_tos(), ev, cli1);
4703 if (oplock_req == NULL) {
4704 printf("cli_smb_oplock_break_waiter_send failed\n");
4707 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
4709 open_req = cli_openx_send(
4710 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
4711 if (open_req == NULL) {
4712 printf("cli_openx_send failed\n");
4715 tevent_req_set_callback(open_req, oplock4_got_open, state);
4720 while (!got_break || fnum2 == 0xffff) {
4722 ret = tevent_loop_once(ev);
4724 printf("tevent_loop_once failed: %s\n",
4730 status = cli_close(cli2, fnum2);
4731 if (!NT_STATUS_IS_OK(status)) {
4732 printf("close2 failed (%s)\n", nt_errstr(status));
4736 status = cli_close(cli1, fnum1);
4737 if (!NT_STATUS_IS_OK(status)) {
4738 printf("close1 failed (%s)\n", nt_errstr(status));
4742 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4743 if (!NT_STATUS_IS_OK(status)) {
4744 printf("unlink failed (%s)\n", nt_errstr(status));
4748 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4749 if (!NT_STATUS_IS_OK(status)) {
4750 printf("unlink failed (%s)\n", nt_errstr(status));
4754 if (!torture_close_connection(cli1)) {
4762 printf("finished oplock test 4\n");
4767 static void oplock4_got_break(struct tevent_req *req)
4769 struct oplock4_state *state = tevent_req_callback_data(
4770 req, struct oplock4_state);
4775 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
4777 if (!NT_STATUS_IS_OK(status)) {
4778 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
4782 *state->got_break = true;
4784 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
4787 printf("cli_oplock_ack_send failed\n");
4792 static void oplock4_got_open(struct tevent_req *req)
4794 struct oplock4_state *state = tevent_req_callback_data(
4795 req, struct oplock4_state);
4798 status = cli_openx_recv(req, state->fnum2);
4799 if (!NT_STATUS_IS_OK(status)) {
4800 printf("cli_openx_recv returned %s\n", nt_errstr(status));
4801 *state->fnum2 = 0xffff;
4805 #ifdef HAVE_KERNEL_OPLOCKS_LINUX
4807 struct oplock5_state {
4812 * Async open the file that has a kernel oplock, do an echo to get
4813 * that 100% across, close the file to signal to the child fd that the
4814 * oplock can be dropped, wait for the open reply.
4817 static void oplock5_opened(struct tevent_req *subreq);
4818 static void oplock5_pong(struct tevent_req *subreq);
4819 static void oplock5_timedout(struct tevent_req *subreq);
4821 static struct tevent_req *oplock5_send(
4822 TALLOC_CTX *mem_ctx,
4823 struct tevent_context *ev,
4824 struct cli_state *cli,
4828 struct tevent_req *req = NULL, *subreq = NULL;
4829 struct oplock5_state *state = NULL;
4830 static uint8_t data = 0;
4832 req = tevent_req_create(mem_ctx, &state, struct oplock5_state);
4836 state->pipe_down_fd = pipe_down_fd;
4838 subreq = cli_ntcreate_send(
4844 SEC_FILE_READ_DATA, /* DesiredAccess */
4845 FILE_ATTRIBUTE_NORMAL, /* FileAttributes */
4846 FILE_SHARE_WRITE|FILE_SHARE_READ, /* ShareAccess */
4847 FILE_OPEN, /* CreateDisposition */
4848 FILE_NON_DIRECTORY_FILE, /* CreateOptions */
4849 0, /* Impersonation */
4850 0); /* SecurityFlags */
4851 if (tevent_req_nomem(subreq, req)) {
4852 return tevent_req_post(req, ev);
4854 tevent_req_set_callback(subreq, oplock5_opened, req);
4856 subreq = cli_echo_send(
4861 (DATA_BLOB) { .data = &data, .length = sizeof(data) });
4862 if (tevent_req_nomem(subreq, req)) {
4863 return tevent_req_post(req, ev);
4865 tevent_req_set_callback(subreq, oplock5_pong, req);
4867 subreq = tevent_wakeup_send(state, ev, timeval_current_ofs(20, 0));
4868 if (tevent_req_nomem(subreq, req)) {
4869 return tevent_req_post(req, ev);
4871 tevent_req_set_callback(subreq, oplock5_timedout, req);
4876 static void oplock5_opened(struct tevent_req *subreq)
4878 struct tevent_req *req = tevent_req_callback_data(
4879 subreq, struct tevent_req);
4883 status = cli_ntcreate_recv(subreq, &fnum, NULL);
4884 TALLOC_FREE(subreq);
4885 if (tevent_req_nterror(req, status)) {
4888 tevent_req_done(req);
4891 static void oplock5_pong(struct tevent_req *subreq)
4893 struct tevent_req *req = tevent_req_callback_data(
4894 subreq, struct tevent_req);
4895 struct oplock5_state *state = tevent_req_data(
4896 req, struct oplock5_state);
4899 status = cli_echo_recv(subreq);
4900 TALLOC_FREE(subreq);
4901 if (tevent_req_nterror(req, status)) {
4905 close(state->pipe_down_fd);
4908 static void oplock5_timedout(struct tevent_req *subreq)
4910 struct tevent_req *req = tevent_req_callback_data(
4911 subreq, struct tevent_req);
4914 ok = tevent_wakeup_recv(subreq);
4915 TALLOC_FREE(subreq);
4917 tevent_req_oom(req);
4920 tevent_req_nterror(req, NT_STATUS_TIMEOUT);
4923 static NTSTATUS oplock5_recv(struct tevent_req *req)
4925 return tevent_req_simple_recv_ntstatus(req);
4928 static bool run_oplock5(int dummy)
4930 struct tevent_context *ev = NULL;
4931 struct tevent_req *req = NULL;
4932 struct cli_state *cli = NULL;
4933 const char *fname = "oplock5.txt";
4934 int pipe_down[2], pipe_up[2];
4941 printf("starting oplock5\n");
4943 if (local_path == NULL) {
4944 d_fprintf(stderr, "oplock5 must be given a local path via "
4945 "-l <localpath>\n");
4949 ret = pipe(pipe_down);
4951 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
4954 ret = pipe(pipe_up);
4956 d_fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
4961 if (child_pid == -1) {
4962 d_fprintf(stderr, "fork() failed: %s\n", strerror(errno));
4966 if (child_pid == 0) {
4967 char *local_file = NULL;
4970 close(pipe_down[1]);
4973 local_file = talloc_asprintf(
4974 talloc_tos(), "%s/%s", local_path, fname);
4975 if (local_file == 0) {
4979 fd = open(local_file, O_RDWR|O_CREAT, 0644);
4982 "open(%s) in child failed: %s\n",
4989 signal(SIGIO, SIG_IGN);
4991 ret = fcntl(fd, F_SETLEASE, F_WRLCK);
4994 "SETLEASE in child failed: %s\n",
5001 ret = sys_write(pipe_up[1], &c, sizeof(c));
5004 "sys_write failed: %s\n",
5008 ret = sys_read(pipe_down[0], &c, sizeof(c));
5011 "sys_read failed: %s\n",
5019 close(pipe_down[0]);
5021 ret = sys_read(pipe_up[0], &c, sizeof(c));
5024 "sys_read failed: %s\n",
5029 d_fprintf(stderr, "got error code %"PRIu8"\n", c);
5033 ok = torture_open_connection(&cli, 0);
5035 d_fprintf(stderr, "torture_open_connection failed\n");
5039 ev = samba_tevent_context_init(talloc_tos());
5041 d_fprintf(stderr, "samba_tevent_context_init failed\n");
5045 req = oplock5_send(ev, ev, cli, fname, pipe_down[1]);
5047 d_fprintf(stderr, "oplock5_send failed\n");
5051 ok = tevent_req_poll_ntstatus(req, ev, &status);
5054 "tevent_req_poll_ntstatus failed: %s\n",
5059 status = oplock5_recv(req);
5061 if (!NT_STATUS_IS_OK(status)) {
5063 "oplock5 failed: %s\n",
5071 #endif /* HAVE_KERNEL_OPLOCKS_LINUX */
5074 Test delete on close semantics.
5076 static bool run_deletetest(int dummy)
5078 struct cli_state *cli1 = NULL;
5079 struct cli_state *cli2 = NULL;
5080 const char *fname = "\\delete.file";
5081 uint16_t fnum1 = (uint16_t)-1;
5082 uint16_t fnum2 = (uint16_t)-1;
5083 bool correct = false;
5086 printf("starting delete test\n");
5088 if (!torture_open_connection(&cli1, 0)) {
5092 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5094 /* Test 1 - this should delete the file on close. */
5096 cli_setatr(cli1, fname, 0, 0);
5097 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5099 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5100 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5101 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
5102 if (!NT_STATUS_IS_OK(status)) {
5103 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
5107 status = cli_close(cli1, fnum1);
5108 if (!NT_STATUS_IS_OK(status)) {
5109 printf("[1] close failed (%s)\n", nt_errstr(status));
5113 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
5114 if (NT_STATUS_IS_OK(status)) {
5115 printf("[1] open of %s succeeded (should fail)\n", fname);
5119 printf("first delete on close test succeeded.\n");
5121 /* Test 2 - this should delete the file on close. */
5123 cli_setatr(cli1, fname, 0, 0);
5124 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5126 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
5127 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5128 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5129 if (!NT_STATUS_IS_OK(status)) {
5130 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
5134 status = cli_nt_delete_on_close(cli1, fnum1, true);
5135 if (!NT_STATUS_IS_OK(status)) {
5136 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
5140 status = cli_close(cli1, fnum1);
5141 if (!NT_STATUS_IS_OK(status)) {
5142 printf("[2] close failed (%s)\n", nt_errstr(status));
5146 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
5147 if (NT_STATUS_IS_OK(status)) {
5148 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
5149 status = cli_close(cli1, fnum1);
5150 if (!NT_STATUS_IS_OK(status)) {
5151 printf("[2] close failed (%s)\n", nt_errstr(status));
5153 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5157 printf("second delete on close test succeeded.\n");
5160 cli_setatr(cli1, fname, 0, 0);
5161 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5163 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
5164 FILE_ATTRIBUTE_NORMAL,
5165 FILE_SHARE_READ|FILE_SHARE_WRITE,
5166 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5167 if (!NT_STATUS_IS_OK(status)) {
5168 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
5172 /* This should fail with a sharing violation - open for delete is only compatible
5173 with SHARE_DELETE. */
5175 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5176 FILE_ATTRIBUTE_NORMAL,
5177 FILE_SHARE_READ|FILE_SHARE_WRITE,
5178 FILE_OPEN, 0, 0, &fnum2, NULL);
5179 if (NT_STATUS_IS_OK(status)) {
5180 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
5184 /* This should succeed. */
5185 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5186 FILE_ATTRIBUTE_NORMAL,
5187 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5188 FILE_OPEN, 0, 0, &fnum2, NULL);
5189 if (!NT_STATUS_IS_OK(status)) {
5190 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
5194 status = cli_nt_delete_on_close(cli1, fnum1, true);
5195 if (!NT_STATUS_IS_OK(status)) {
5196 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
5200 status = cli_close(cli1, fnum1);
5201 if (!NT_STATUS_IS_OK(status)) {
5202 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
5206 status = cli_close(cli1, fnum2);
5207 if (!NT_STATUS_IS_OK(status)) {
5208 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
5212 /* This should fail - file should no longer be there. */
5214 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
5215 if (NT_STATUS_IS_OK(status)) {
5216 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
5217 status = cli_close(cli1, fnum1);
5218 if (!NT_STATUS_IS_OK(status)) {
5219 printf("[3] close failed (%s)\n", nt_errstr(status));
5221 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5225 printf("third delete on close test succeeded.\n");
5228 cli_setatr(cli1, fname, 0, 0);
5229 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5231 status = cli_ntcreate(cli1, fname, 0,
5232 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5233 FILE_ATTRIBUTE_NORMAL,
5234 FILE_SHARE_READ|FILE_SHARE_WRITE,
5235 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5236 if (!NT_STATUS_IS_OK(status)) {
5237 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
5241 /* This should succeed. */
5242 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5243 FILE_ATTRIBUTE_NORMAL,
5244 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5245 FILE_OPEN, 0, 0, &fnum2, NULL);
5246 if (!NT_STATUS_IS_OK(status)) {
5247 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
5251 status = cli_close(cli1, fnum2);
5252 if (!NT_STATUS_IS_OK(status)) {
5253 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
5257 status = cli_nt_delete_on_close(cli1, fnum1, true);
5258 if (!NT_STATUS_IS_OK(status)) {
5259 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
5263 /* This should fail - no more opens once delete on close set. */
5264 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5265 FILE_ATTRIBUTE_NORMAL,
5266 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5267 FILE_OPEN, 0, 0, &fnum2, NULL);
5268 if (NT_STATUS_IS_OK(status)) {
5269 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
5273 status = cli_close(cli1, fnum1);
5274 if (!NT_STATUS_IS_OK(status)) {
5275 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
5279 printf("fourth delete on close test succeeded.\n");
5282 cli_setatr(cli1, fname, 0, 0);
5283 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5285 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
5286 if (!NT_STATUS_IS_OK(status)) {
5287 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
5291 /* This should fail - only allowed on NT opens with DELETE access. */
5293 status = cli_nt_delete_on_close(cli1, fnum1, true);
5294 if (NT_STATUS_IS_OK(status)) {
5295 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
5299 status = cli_close(cli1, fnum1);
5300 if (!NT_STATUS_IS_OK(status)) {
5301 printf("[5] close failed (%s)\n", nt_errstr(status));
5305 printf("fifth delete on close test succeeded.\n");
5308 cli_setatr(cli1, fname, 0, 0);
5309 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5311 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
5312 FILE_ATTRIBUTE_NORMAL,
5313 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5314 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5315 if (!NT_STATUS_IS_OK(status)) {
5316 printf("[6] open of %s failed (%s)\n", fname,
5321 /* This should fail - only allowed on NT opens with DELETE access. */
5323 status = cli_nt_delete_on_close(cli1, fnum1, true);
5324 if (NT_STATUS_IS_OK(status)) {
5325 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
5329 status = cli_close(cli1, fnum1);
5330 if (!NT_STATUS_IS_OK(status)) {
5331 printf("[6] close failed (%s)\n", nt_errstr(status));
5335 printf("sixth delete on close test succeeded.\n");
5338 cli_setatr(cli1, fname, 0, 0);
5339 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5341 status = cli_ntcreate(cli1, fname, 0,
5342 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5343 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5344 0, 0, &fnum1, NULL);
5345 if (!NT_STATUS_IS_OK(status)) {
5346 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
5350 status = cli_nt_delete_on_close(cli1, fnum1, true);
5351 if (!NT_STATUS_IS_OK(status)) {
5352 printf("[7] setting delete_on_close on file failed !\n");
5356 status = cli_nt_delete_on_close(cli1, fnum1, false);
5357 if (!NT_STATUS_IS_OK(status)) {
5358 printf("[7] unsetting delete_on_close on file failed !\n");
5362 status = cli_close(cli1, fnum1);
5363 if (!NT_STATUS_IS_OK(status)) {
5364 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
5368 /* This next open should succeed - we reset the flag. */
5369 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
5370 if (!NT_STATUS_IS_OK(status)) {
5371 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
5375 status = cli_close(cli1, fnum1);
5376 if (!NT_STATUS_IS_OK(status)) {
5377 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
5381 printf("seventh delete on close test succeeded.\n");
5384 cli_setatr(cli1, fname, 0, 0);
5385 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5387 if (!torture_open_connection(&cli2, 1)) {
5388 printf("[8] failed to open second connection.\n");
5392 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5394 status = cli_ntcreate(cli1, fname, 0,
5395 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5396 FILE_ATTRIBUTE_NORMAL,
5397 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5398 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5399 if (!NT_STATUS_IS_OK(status)) {
5400 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5404 status = cli_ntcreate(cli2, fname, 0,
5405 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5406 FILE_ATTRIBUTE_NORMAL,
5407 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5408 FILE_OPEN, 0, 0, &fnum2, NULL);
5409 if (!NT_STATUS_IS_OK(status)) {
5410 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5414 status = cli_nt_delete_on_close(cli1, fnum1, true);
5415 if (!NT_STATUS_IS_OK(status)) {
5416 printf("[8] setting delete_on_close on file failed !\n");
5420 status = cli_close(cli1, fnum1);
5421 if (!NT_STATUS_IS_OK(status)) {
5422 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
5426 status = cli_close(cli2, fnum2);
5427 if (!NT_STATUS_IS_OK(status)) {
5428 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
5432 /* This should fail.. */
5433 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
5434 if (NT_STATUS_IS_OK(status)) {
5435 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
5439 printf("eighth delete on close test succeeded.\n");
5443 /* This should fail - we need to set DELETE_ACCESS. */
5444 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
5445 FILE_ATTRIBUTE_NORMAL,
5448 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
5449 if (NT_STATUS_IS_OK(status)) {
5450 printf("[9] open of %s succeeded should have failed!\n", fname);
5454 printf("ninth delete on close test succeeded.\n");
5458 status = cli_ntcreate(cli1, fname, 0,
5459 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5460 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5461 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
5463 if (!NT_STATUS_IS_OK(status)) {
5464 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
5468 /* This should delete the file. */
5469 status = cli_close(cli1, fnum1);
5470 if (!NT_STATUS_IS_OK(status)) {
5471 printf("[10] close failed (%s)\n", nt_errstr(status));
5475 /* This should fail.. */
5476 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
5477 if (NT_STATUS_IS_OK(status)) {
5478 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
5482 printf("tenth delete on close test succeeded.\n");
5486 cli_setatr(cli1, fname, 0, 0);
5487 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5489 /* Can we open a read-only file with delete access? */
5491 /* Create a readonly file. */
5492 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
5493 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
5494 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5495 if (!NT_STATUS_IS_OK(status)) {
5496 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
5500 status = cli_close(cli1, fnum1);
5501 if (!NT_STATUS_IS_OK(status)) {
5502 printf("[11] close failed (%s)\n", nt_errstr(status));
5506 /* Now try open for delete access. */
5507 status = cli_ntcreate(cli1, fname, 0,
5508 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
5510 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5511 FILE_OPEN, 0, 0, &fnum1, NULL);
5512 if (!NT_STATUS_IS_OK(status)) {
5513 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
5517 cli_close(cli1, fnum1);
5519 printf("eleventh delete on close test succeeded.\n");
5523 * like test 4 but with initial delete on close
5526 cli_setatr(cli1, fname, 0, 0);
5527 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5529 status = cli_ntcreate(cli1, fname, 0,
5530 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5531 FILE_ATTRIBUTE_NORMAL,
5532 FILE_SHARE_READ|FILE_SHARE_WRITE,
5534 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
5535 if (!NT_STATUS_IS_OK(status)) {
5536 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5540 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5541 FILE_ATTRIBUTE_NORMAL,
5542 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5543 FILE_OPEN, 0, 0, &fnum2, NULL);
5544 if (!NT_STATUS_IS_OK(status)) {
5545 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
5549 status = cli_close(cli1, fnum2);
5550 if (!NT_STATUS_IS_OK(status)) {
5551 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
5555 status = cli_nt_delete_on_close(cli1, fnum1, true);
5556 if (!NT_STATUS_IS_OK(status)) {
5557 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
5561 /* This should fail - no more opens once delete on close set. */
5562 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5563 FILE_ATTRIBUTE_NORMAL,
5564 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5565 FILE_OPEN, 0, 0, &fnum2, NULL);
5566 if (NT_STATUS_IS_OK(status)) {
5567 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
5571 status = cli_nt_delete_on_close(cli1, fnum1, false);
5572 if (!NT_STATUS_IS_OK(status)) {
5573 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
5577 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5578 FILE_ATTRIBUTE_NORMAL,
5579 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5580 FILE_OPEN, 0, 0, &fnum2, NULL);
5581 if (!NT_STATUS_IS_OK(status)) {
5582 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
5586 status = cli_close(cli1, fnum2);
5587 if (!NT_STATUS_IS_OK(status)) {
5588 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
5592 status = cli_close(cli1, fnum1);
5593 if (!NT_STATUS_IS_OK(status)) {
5594 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
5599 * setting delete on close on the handle does
5600 * not unset the initial delete on close...
5602 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5603 FILE_ATTRIBUTE_NORMAL,
5604 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5605 FILE_OPEN, 0, 0, &fnum2, NULL);
5606 if (NT_STATUS_IS_OK(status)) {
5607 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
5609 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5610 printf("ntcreate returned %s, expected "
5611 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
5616 printf("twelfth delete on close test succeeded.\n");
5619 printf("finished delete test\n");
5624 /* FIXME: This will crash if we aborted before cli2 got
5625 * intialized, because these functions don't handle
5626 * uninitialized connections. */
5628 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
5629 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
5630 cli_setatr(cli1, fname, 0, 0);
5631 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5633 if (cli1 && !torture_close_connection(cli1)) {
5636 if (cli2 && !torture_close_connection(cli2)) {
5643 Exercise delete on close semantics - use on the PRINT1 share in torture
5646 static bool run_delete_print_test(int dummy)
5648 struct cli_state *cli1 = NULL;
5649 const char *fname = "print_delete.file";
5650 uint16_t fnum1 = (uint16_t)-1;
5651 bool correct = false;
5652 const char *buf = "print file data\n";
5655 printf("starting print delete test\n");
5657 if (!torture_open_connection(&cli1, 0)) {
5661 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5663 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5664 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5665 0, 0, &fnum1, NULL);
5666 if (!NT_STATUS_IS_OK(status)) {
5667 printf("open of %s failed (%s)\n",
5673 status = cli_writeall(cli1,
5676 (const uint8_t *)buf,
5678 strlen(buf), /* size */
5680 if (!NT_STATUS_IS_OK(status)) {
5681 printf("writing print file data failed (%s)\n",
5686 status = cli_nt_delete_on_close(cli1, fnum1, true);
5687 if (!NT_STATUS_IS_OK(status)) {
5688 printf("setting delete_on_close failed (%s)\n",
5693 status = cli_close(cli1, fnum1);
5694 if (!NT_STATUS_IS_OK(status)) {
5695 printf("close failed (%s)\n", nt_errstr(status));
5699 printf("finished print delete test\n");
5705 if (fnum1 != (uint16_t)-1) {
5706 cli_close(cli1, fnum1);
5709 if (cli1 && !torture_close_connection(cli1)) {
5716 Test wildcard delete.
5718 static bool run_wild_deletetest(int dummy)
5720 struct cli_state *cli = NULL;
5721 const char *dname = "\\WTEST";
5722 const char *fname = "\\WTEST\\A";
5723 const char *wunlink_name = "\\WTEST\\*";
5724 uint16_t fnum1 = (uint16_t)-1;
5725 bool correct = false;
5728 printf("starting wildcard delete test\n");
5730 if (!torture_open_connection(&cli, 0)) {
5734 smbXcli_conn_set_sockopt(cli->conn, sockops);
5736 cli_unlink(cli, fname, 0);
5737 cli_rmdir(cli, dname);
5738 status = cli_mkdir(cli, dname);
5739 if (!NT_STATUS_IS_OK(status)) {
5740 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
5743 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
5744 if (!NT_STATUS_IS_OK(status)) {
5745 printf("open of %s failed %s!\n", fname, nt_errstr(status));
5748 status = cli_close(cli, fnum1);
5752 * Note the unlink attribute-type of zero. This should
5753 * map into FILE_ATTRIBUTE_NORMAL at the server even
5754 * on a wildcard delete.
5757 status = cli_unlink(cli, wunlink_name, 0);
5758 if (!NT_STATUS_IS_OK(status)) {
5759 printf("unlink of %s failed %s!\n",
5760 wunlink_name, nt_errstr(status));
5764 printf("finished wildcard delete test\n");
5770 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
5771 cli_unlink(cli, fname, 0);
5772 cli_rmdir(cli, dname);
5774 if (cli && !torture_close_connection(cli)) {
5780 static bool run_deletetest_ln(int dummy)
5782 struct cli_state *cli;
5783 const char *fname = "\\delete1";
5784 const char *fname_ln = "\\delete1_ln";
5788 bool correct = true;
5791 printf("starting deletetest-ln\n");
5793 if (!torture_open_connection(&cli, 0)) {
5797 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5798 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5800 smbXcli_conn_set_sockopt(cli->conn, sockops);
5802 /* Create the file. */
5803 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5804 if (!NT_STATUS_IS_OK(status)) {
5805 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5809 status = cli_close(cli, fnum);
5810 if (!NT_STATUS_IS_OK(status)) {
5811 printf("close1 failed (%s)\n", nt_errstr(status));
5815 /* Now create a hardlink. */
5816 status = cli_hardlink(cli, fname, fname_ln);
5817 if (!NT_STATUS_IS_OK(status)) {
5818 printf("nt hardlink failed (%s)\n", nt_errstr(status));
5822 /* Open the original file. */
5823 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
5824 FILE_ATTRIBUTE_NORMAL,
5825 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5826 FILE_OPEN_IF, 0, 0, &fnum, NULL);
5827 if (!NT_STATUS_IS_OK(status)) {
5828 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
5832 /* Unlink the hard link path. */
5833 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
5834 FILE_ATTRIBUTE_NORMAL,
5835 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5836 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
5837 if (!NT_STATUS_IS_OK(status)) {
5838 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
5841 status = cli_nt_delete_on_close(cli, fnum1, true);
5842 if (!NT_STATUS_IS_OK(status)) {
5843 d_printf("(%s) failed to set delete_on_close %s: %s\n",
5844 __location__, fname_ln, nt_errstr(status));
5848 status = cli_close(cli, fnum1);
5849 if (!NT_STATUS_IS_OK(status)) {
5850 printf("close %s failed (%s)\n",
5851 fname_ln, nt_errstr(status));
5855 status = cli_close(cli, fnum);
5856 if (!NT_STATUS_IS_OK(status)) {
5857 printf("close %s failed (%s)\n",
5858 fname, nt_errstr(status));
5862 /* Ensure the original file is still there. */
5863 status = cli_getatr(cli, fname, NULL, NULL, &t);
5864 if (!NT_STATUS_IS_OK(status)) {
5865 printf("%s getatr on file %s failed (%s)\n",
5872 /* Ensure the link path is gone. */
5873 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
5874 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5875 printf("%s, getatr for file %s returned wrong error code %s "
5876 "- should have been deleted\n",
5878 fname_ln, nt_errstr(status));
5882 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5883 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5885 if (!torture_close_connection(cli)) {
5889 printf("finished deletetest-ln\n");
5895 print out server properties
5897 static bool run_properties(int dummy)
5899 struct cli_state *cli;
5900 bool correct = True;
5902 printf("starting properties test\n");
5906 if (!torture_open_connection(&cli, 0)) {
5910 smbXcli_conn_set_sockopt(cli->conn, sockops);
5912 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
5914 if (!torture_close_connection(cli)) {
5923 /* FIRST_DESIRED_ACCESS 0xf019f */
5924 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
5925 FILE_READ_EA| /* 0xf */ \
5926 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
5927 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
5928 DELETE_ACCESS|READ_CONTROL_ACCESS|\
5929 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
5930 /* SECOND_DESIRED_ACCESS 0xe0080 */
5931 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
5932 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
5933 WRITE_OWNER_ACCESS /* 0xe0000 */
5936 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
5937 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
5939 WRITE_OWNER_ACCESS /* */
5943 Test ntcreate calls made by xcopy
5945 static bool run_xcopy(int dummy)
5947 static struct cli_state *cli1;
5948 const char *fname = "\\test.txt";
5949 bool correct = True;
5950 uint16_t fnum1, fnum2;
5953 printf("starting xcopy test\n");
5955 if (!torture_open_connection(&cli1, 0)) {
5959 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
5960 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
5961 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
5962 if (!NT_STATUS_IS_OK(status)) {
5963 printf("First open failed - %s\n", nt_errstr(status));
5967 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
5968 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5969 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
5970 if (!NT_STATUS_IS_OK(status)) {
5971 printf("second open failed - %s\n", nt_errstr(status));
5975 if (!torture_close_connection(cli1)) {
5983 Test rename on files open with share delete and no share delete.
5985 static bool run_rename(int dummy)
5987 static struct cli_state *cli1;
5988 const char *fname = "\\test.txt";
5989 const char *fname1 = "\\test1.txt";
5990 bool correct = True;
5995 printf("starting rename test\n");
5997 if (!torture_open_connection(&cli1, 0)) {
6001 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6002 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6004 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
6005 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6006 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6007 if (!NT_STATUS_IS_OK(status)) {
6008 printf("First open failed - %s\n", nt_errstr(status));
6012 status = cli_rename(cli1, fname, fname1, false);
6013 if (!NT_STATUS_IS_OK(status)) {
6014 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
6016 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
6020 status = cli_close(cli1, fnum1);
6021 if (!NT_STATUS_IS_OK(status)) {
6022 printf("close - 1 failed (%s)\n", nt_errstr(status));
6026 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6027 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6028 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
6030 FILE_SHARE_DELETE|FILE_SHARE_NONE,
6032 FILE_SHARE_DELETE|FILE_SHARE_READ,
6034 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6035 if (!NT_STATUS_IS_OK(status)) {
6036 printf("Second open failed - %s\n", nt_errstr(status));
6040 status = cli_rename(cli1, fname, fname1, false);
6041 if (!NT_STATUS_IS_OK(status)) {
6042 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
6045 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
6048 status = cli_close(cli1, fnum1);
6049 if (!NT_STATUS_IS_OK(status)) {
6050 printf("close - 2 failed (%s)\n", nt_errstr(status));
6054 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6055 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6057 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
6058 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6059 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6060 if (!NT_STATUS_IS_OK(status)) {
6061 printf("Third open failed - %s\n", nt_errstr(status));
6070 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
6071 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
6072 printf("Fourth open failed - %s\n", cli_errstr(cli1));
6075 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
6076 printf("[8] setting delete_on_close on file failed !\n");
6080 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
6081 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
6087 status = cli_rename(cli1, fname, fname1, false);
6088 if (!NT_STATUS_IS_OK(status)) {
6089 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
6092 printf("Third rename succeeded (SHARE_NONE)\n");
6095 status = cli_close(cli1, fnum1);
6096 if (!NT_STATUS_IS_OK(status)) {
6097 printf("close - 3 failed (%s)\n", nt_errstr(status));
6101 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6102 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6106 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
6107 FILE_ATTRIBUTE_NORMAL,
6108 FILE_SHARE_READ | FILE_SHARE_WRITE,
6109 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6110 if (!NT_STATUS_IS_OK(status)) {
6111 printf("Fourth open failed - %s\n", nt_errstr(status));
6115 status = cli_rename(cli1, fname, fname1, false);
6116 if (!NT_STATUS_IS_OK(status)) {
6117 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
6119 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
6123 status = cli_close(cli1, fnum1);
6124 if (!NT_STATUS_IS_OK(status)) {
6125 printf("close - 4 failed (%s)\n", nt_errstr(status));
6129 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6130 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6134 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
6135 FILE_ATTRIBUTE_NORMAL,
6136 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
6137 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6138 if (!NT_STATUS_IS_OK(status)) {
6139 printf("Fifth open failed - %s\n", nt_errstr(status));
6143 status = cli_rename(cli1, fname, fname1, false);
6144 if (!NT_STATUS_IS_OK(status)) {
6145 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
6148 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
6152 * Now check if the first name still exists ...
6155 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
6156 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
6157 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
6158 printf("Opening original file after rename of open file fails: %s\n",
6162 printf("Opening original file after rename of open file works ...\n");
6163 (void)cli_close(cli1, fnum2);
6167 status = cli_close(cli1, fnum1);
6168 if (!NT_STATUS_IS_OK(status)) {
6169 printf("close - 5 failed (%s)\n", nt_errstr(status));
6173 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
6174 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
6175 if (!NT_STATUS_IS_OK(status)) {
6176 printf("getatr on file %s failed - %s ! \n",
6177 fname1, nt_errstr(status));
6180 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
6181 printf("Renamed file %s has wrong attr 0x%x "
6182 "(should be 0x%x)\n",
6185 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
6188 printf("Renamed file %s has archive bit set\n", fname1);
6192 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6193 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6195 if (!torture_close_connection(cli1)) {
6203 Test rename into a directory with an ACL denying it.
6205 static bool run_rename_access(int dummy)
6207 static struct cli_state *cli = NULL;
6208 static struct cli_state *posix_cli = NULL;
6209 const char *src = "test.txt";
6210 const char *dname = "dir";
6211 const char *dst = "dir\\test.txt";
6212 const char *dsrc = "test.dir";
6213 const char *ddst = "dir\\test.dir";
6214 uint16_t fnum = (uint16_t)-1;
6215 struct security_descriptor *sd = NULL;
6216 struct security_descriptor *newsd = NULL;
6218 TALLOC_CTX *frame = NULL;
6220 frame = talloc_stackframe();
6221 printf("starting rename access test\n");
6223 /* Windows connection. */
6224 if (!torture_open_connection(&cli, 0)) {
6228 smbXcli_conn_set_sockopt(cli->conn, sockops);
6230 /* Posix connection. */
6231 if (!torture_open_connection(&posix_cli, 0)) {
6235 smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
6237 status = torture_setup_unix_extensions(posix_cli);
6238 if (!NT_STATUS_IS_OK(status)) {
6242 /* Start with a clean slate. */
6243 cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6244 cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6245 cli_rmdir(cli, dsrc);
6246 cli_rmdir(cli, ddst);
6247 cli_rmdir(cli, dname);
6250 * Setup the destination directory with a DENY ACE to
6251 * prevent new files within it.
6253 status = cli_ntcreate(cli,
6256 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
6257 WRITE_DAC_ACCESS|FILE_READ_DATA|
6259 FILE_ATTRIBUTE_DIRECTORY,
6260 FILE_SHARE_READ|FILE_SHARE_WRITE,
6262 FILE_DIRECTORY_FILE,
6266 if (!NT_STATUS_IS_OK(status)) {
6267 printf("Create of %s - %s\n", dname, nt_errstr(status));
6271 status = cli_query_secdesc(cli,
6275 if (!NT_STATUS_IS_OK(status)) {
6276 printf("cli_query_secdesc failed for %s (%s)\n",
6277 dname, nt_errstr(status));
6281 newsd = security_descriptor_dacl_create(frame,
6286 SEC_ACE_TYPE_ACCESS_DENIED,
6287 SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
6290 if (newsd == NULL) {
6293 sd->dacl = security_acl_concatenate(frame,
6296 if (sd->dacl == NULL) {
6299 status = cli_set_secdesc(cli, fnum, sd);
6300 if (!NT_STATUS_IS_OK(status)) {
6301 printf("cli_set_secdesc failed for %s (%s)\n",
6302 dname, nt_errstr(status));
6305 status = cli_close(cli, fnum);
6306 if (!NT_STATUS_IS_OK(status)) {
6307 printf("close failed for %s (%s)\n",
6308 dname, nt_errstr(status));
6311 /* Now go around the back and chmod to 777 via POSIX. */
6312 status = cli_posix_chmod(posix_cli, dname, 0777);
6313 if (!NT_STATUS_IS_OK(status)) {
6314 printf("cli_posix_chmod failed for %s (%s)\n",
6315 dname, nt_errstr(status));
6319 /* Check we can't create a file within dname via Windows. */
6320 status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6321 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6322 cli_close(posix_cli, fnum);
6323 printf("Create of %s should be ACCESS denied, was %s\n",
6324 dst, nt_errstr(status));
6328 /* Make the sample file/directory. */
6329 status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6330 if (!NT_STATUS_IS_OK(status)) {
6331 printf("open of %s failed (%s)\n", src, nt_errstr(status));
6334 status = cli_close(cli, fnum);
6335 if (!NT_STATUS_IS_OK(status)) {
6336 printf("cli_close failed (%s)\n", nt_errstr(status));
6340 status = cli_mkdir(cli, dsrc);
6341 if (!NT_STATUS_IS_OK(status)) {
6342 printf("cli_mkdir of %s failed (%s)\n",
6343 dsrc, nt_errstr(status));
6348 * OK - renames of the new file and directory into the
6349 * dst directory should fail.
6352 status = cli_rename(cli, src, dst, false);
6353 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6354 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
6355 src, dst, nt_errstr(status));
6358 status = cli_rename(cli, dsrc, ddst, false);
6359 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6360 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
6361 src, dst, nt_errstr(status));
6371 torture_close_connection(posix_cli);
6375 if (fnum != (uint16_t)-1) {
6376 cli_close(cli, fnum);
6378 cli_unlink(cli, src,
6379 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6380 cli_unlink(cli, dst,
6381 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6382 cli_rmdir(cli, dsrc);
6383 cli_rmdir(cli, ddst);
6384 cli_rmdir(cli, dname);
6386 torture_close_connection(cli);
6394 Test owner rights ACE.
6396 static bool run_owner_rights(int dummy)
6398 static struct cli_state *cli = NULL;
6399 const char *fname = "owner_rights.txt";
6400 uint16_t fnum = (uint16_t)-1;
6401 struct security_descriptor *sd = NULL;
6402 struct security_descriptor *newsd = NULL;
6404 TALLOC_CTX *frame = NULL;
6406 frame = talloc_stackframe();
6407 printf("starting owner rights test\n");
6409 /* Windows connection. */
6410 if (!torture_open_connection(&cli, 0)) {
6414 smbXcli_conn_set_sockopt(cli->conn, sockops);
6416 /* Start with a clean slate. */
6417 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6419 /* Create the test file. */
6420 /* Now try and open for read and write-dac. */
6421 status = cli_ntcreate(cli,
6425 FILE_ATTRIBUTE_NORMAL,
6426 FILE_SHARE_READ|FILE_SHARE_WRITE|
6433 if (!NT_STATUS_IS_OK(status)) {
6434 printf("Create of %s - %s\n", fname, nt_errstr(status));
6438 /* Get the original SD. */
6439 status = cli_query_secdesc(cli,
6443 if (!NT_STATUS_IS_OK(status)) {
6444 printf("cli_query_secdesc failed for %s (%s)\n",
6445 fname, nt_errstr(status));
6450 * Add an "owner-rights" ACE denying WRITE_DATA,
6451 * and an "owner-rights" ACE allowing READ_DATA.
6454 newsd = security_descriptor_dacl_create(frame,
6459 SEC_ACE_TYPE_ACCESS_DENIED,
6463 SEC_ACE_TYPE_ACCESS_ALLOWED,
6467 if (newsd == NULL) {
6470 sd->dacl = security_acl_concatenate(frame,
6473 if (sd->dacl == NULL) {
6476 status = cli_set_secdesc(cli, fnum, sd);
6477 if (!NT_STATUS_IS_OK(status)) {
6478 printf("cli_set_secdesc failed for %s (%s)\n",
6479 fname, nt_errstr(status));
6482 status = cli_close(cli, fnum);
6483 if (!NT_STATUS_IS_OK(status)) {
6484 printf("close failed for %s (%s)\n",
6485 fname, nt_errstr(status));
6488 fnum = (uint16_t)-1;
6490 /* Try and open for FILE_WRITE_DATA */
6491 status = cli_ntcreate(cli,
6495 FILE_ATTRIBUTE_NORMAL,
6496 FILE_SHARE_READ|FILE_SHARE_WRITE|
6503 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6504 printf("Open of %s - %s\n", fname, nt_errstr(status));
6508 /* Now try and open for FILE_READ_DATA */
6509 status = cli_ntcreate(cli,
6513 FILE_ATTRIBUTE_NORMAL,
6514 FILE_SHARE_READ|FILE_SHARE_WRITE|
6521 if (!NT_STATUS_IS_OK(status)) {
6522 printf("Open of %s - %s\n", fname, nt_errstr(status));
6526 status = cli_close(cli, fnum);
6527 if (!NT_STATUS_IS_OK(status)) {
6528 printf("close failed for %s (%s)\n",
6529 fname, nt_errstr(status));
6533 /* Restore clean slate. */
6535 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6537 /* Create the test file. */
6538 status = cli_ntcreate(cli,
6542 FILE_ATTRIBUTE_NORMAL,
6543 FILE_SHARE_READ|FILE_SHARE_WRITE|
6550 if (!NT_STATUS_IS_OK(status)) {
6551 printf("Create of %s - %s\n", fname, nt_errstr(status));
6555 /* Get the original SD. */
6556 status = cli_query_secdesc(cli,
6560 if (!NT_STATUS_IS_OK(status)) {
6561 printf("cli_query_secdesc failed for %s (%s)\n",
6562 fname, nt_errstr(status));
6567 * Add an "owner-rights ACE denying WRITE_DATA,
6568 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
6571 newsd = security_descriptor_dacl_create(frame,
6576 SEC_ACE_TYPE_ACCESS_DENIED,
6580 SEC_ACE_TYPE_ACCESS_ALLOWED,
6581 FILE_READ_DATA|FILE_WRITE_DATA,
6584 if (newsd == NULL) {
6587 sd->dacl = security_acl_concatenate(frame,
6590 if (sd->dacl == NULL) {
6593 status = cli_set_secdesc(cli, fnum, sd);
6594 if (!NT_STATUS_IS_OK(status)) {
6595 printf("cli_set_secdesc failed for %s (%s)\n",
6596 fname, nt_errstr(status));
6599 status = cli_close(cli, fnum);
6600 if (!NT_STATUS_IS_OK(status)) {
6601 printf("close failed for %s (%s)\n",
6602 fname, nt_errstr(status));
6605 fnum = (uint16_t)-1;
6607 /* Try and open for FILE_WRITE_DATA */
6608 status = cli_ntcreate(cli,
6612 FILE_ATTRIBUTE_NORMAL,
6613 FILE_SHARE_READ|FILE_SHARE_WRITE|
6620 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6621 printf("Open of %s - %s\n", fname, nt_errstr(status));
6625 /* Now try and open for FILE_READ_DATA */
6626 status = cli_ntcreate(cli,
6630 FILE_ATTRIBUTE_NORMAL,
6631 FILE_SHARE_READ|FILE_SHARE_WRITE|
6638 if (!NT_STATUS_IS_OK(status)) {
6639 printf("Open of %s - %s\n", fname, nt_errstr(status));
6643 status = cli_close(cli, fnum);
6644 if (!NT_STATUS_IS_OK(status)) {
6645 printf("close failed for %s (%s)\n",
6646 fname, nt_errstr(status));
6650 /* Restore clean slate. */
6652 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6655 /* Create the test file. */
6656 status = cli_ntcreate(cli,
6660 FILE_ATTRIBUTE_NORMAL,
6661 FILE_SHARE_READ|FILE_SHARE_WRITE|
6668 if (!NT_STATUS_IS_OK(status)) {
6669 printf("Create of %s - %s\n", fname, nt_errstr(status));
6673 /* Get the original SD. */
6674 status = cli_query_secdesc(cli,
6678 if (!NT_STATUS_IS_OK(status)) {
6679 printf("cli_query_secdesc failed for %s (%s)\n",
6680 fname, nt_errstr(status));
6685 * Add an "authenticated users" ACE allowing READ_DATA,
6686 * add an "owner-rights" denying READ_DATA,
6687 * and an "authenticated users" ACE allowing WRITE_DATA.
6690 newsd = security_descriptor_dacl_create(frame,
6694 SID_NT_AUTHENTICATED_USERS,
6695 SEC_ACE_TYPE_ACCESS_ALLOWED,
6699 SEC_ACE_TYPE_ACCESS_DENIED,
6702 SID_NT_AUTHENTICATED_USERS,
6703 SEC_ACE_TYPE_ACCESS_ALLOWED,
6707 if (newsd == NULL) {
6708 printf("newsd == NULL\n");
6711 sd->dacl = security_acl_concatenate(frame,
6714 if (sd->dacl == NULL) {
6715 printf("sd->dacl == NULL\n");
6718 status = cli_set_secdesc(cli, fnum, sd);
6719 if (!NT_STATUS_IS_OK(status)) {
6720 printf("cli_set_secdesc failed for %s (%s)\n",
6721 fname, nt_errstr(status));
6724 status = cli_close(cli, fnum);
6725 if (!NT_STATUS_IS_OK(status)) {
6726 printf("close failed for %s (%s)\n",
6727 fname, nt_errstr(status));
6730 fnum = (uint16_t)-1;
6732 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
6733 status = cli_ntcreate(cli,
6736 FILE_READ_DATA|FILE_WRITE_DATA,
6737 FILE_ATTRIBUTE_NORMAL,
6738 FILE_SHARE_READ|FILE_SHARE_WRITE|
6745 if (!NT_STATUS_IS_OK(status)) {
6746 printf("Open of %s - %s\n", fname, nt_errstr(status));
6750 status = cli_close(cli, fnum);
6751 if (!NT_STATUS_IS_OK(status)) {
6752 printf("close failed for %s (%s)\n",
6753 fname, nt_errstr(status));
6757 cli_unlink(cli, fname,
6758 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6766 if (fnum != (uint16_t)-1) {
6767 cli_close(cli, fnum);
6769 cli_unlink(cli, fname,
6770 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6771 torture_close_connection(cli);
6778 static bool run_pipe_number(int dummy)
6780 struct cli_state *cli1;
6781 const char *pipe_name = "\\SPOOLSS";
6786 printf("starting pipenumber test\n");
6787 if (!torture_open_connection(&cli1, 0)) {
6791 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6793 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
6794 FILE_ATTRIBUTE_NORMAL,
6795 FILE_SHARE_READ|FILE_SHARE_WRITE,
6796 FILE_OPEN_IF, 0, 0, &fnum, NULL);
6797 if (!NT_STATUS_IS_OK(status)) {
6798 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
6802 printf("\r%6d", num_pipes);
6805 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
6806 torture_close_connection(cli1);
6811 Test open mode returns on read-only files.
6813 static bool run_opentest(int dummy)
6815 static struct cli_state *cli1;
6816 static struct cli_state *cli2;
6817 const char *fname = "\\readonly.file";
6818 uint16_t fnum1, fnum2;
6821 bool correct = True;
6825 printf("starting open test\n");
6827 if (!torture_open_connection(&cli1, 0)) {
6831 cli_setatr(cli1, fname, 0, 0);
6832 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6834 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6836 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
6837 if (!NT_STATUS_IS_OK(status)) {
6838 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
6842 status = cli_close(cli1, fnum1);
6843 if (!NT_STATUS_IS_OK(status)) {
6844 printf("close2 failed (%s)\n", nt_errstr(status));
6848 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
6849 if (!NT_STATUS_IS_OK(status)) {
6850 printf("cli_setatr failed (%s)\n", nt_errstr(status));
6854 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
6855 if (!NT_STATUS_IS_OK(status)) {
6856 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
6860 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
6861 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
6863 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
6864 NT_STATUS_ACCESS_DENIED)) {
6865 printf("correct error code ERRDOS/ERRnoaccess returned\n");
6868 printf("finished open test 1\n");
6870 cli_close(cli1, fnum1);
6872 /* Now try not readonly and ensure ERRbadshare is returned. */
6874 cli_setatr(cli1, fname, 0, 0);
6876 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
6877 if (!NT_STATUS_IS_OK(status)) {
6878 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
6882 /* This will fail - but the error should be ERRshare. */
6883 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
6885 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
6886 NT_STATUS_SHARING_VIOLATION)) {
6887 printf("correct error code ERRDOS/ERRbadshare returned\n");
6890 status = cli_close(cli1, fnum1);
6891 if (!NT_STATUS_IS_OK(status)) {
6892 printf("close2 failed (%s)\n", nt_errstr(status));
6896 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6898 printf("finished open test 2\n");
6900 /* Test truncate open disposition on file opened for read. */
6901 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
6902 if (!NT_STATUS_IS_OK(status)) {
6903 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
6907 /* write 20 bytes. */
6909 memset(buf, '\0', 20);
6911 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
6912 if (!NT_STATUS_IS_OK(status)) {
6913 printf("write failed (%s)\n", nt_errstr(status));
6917 status = cli_close(cli1, fnum1);
6918 if (!NT_STATUS_IS_OK(status)) {
6919 printf("(3) close1 failed (%s)\n", nt_errstr(status));
6923 /* Ensure size == 20. */
6924 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
6925 if (!NT_STATUS_IS_OK(status)) {
6926 printf("(3) getatr failed (%s)\n", nt_errstr(status));
6931 printf("(3) file size != 20\n");
6935 /* Now test if we can truncate a file opened for readonly. */
6936 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
6937 if (!NT_STATUS_IS_OK(status)) {
6938 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
6942 status = cli_close(cli1, fnum1);
6943 if (!NT_STATUS_IS_OK(status)) {
6944 printf("close2 failed (%s)\n", nt_errstr(status));
6948 /* Ensure size == 0. */
6949 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
6950 if (!NT_STATUS_IS_OK(status)) {
6951 printf("(3) getatr failed (%s)\n", nt_errstr(status));
6956 printf("(3) file size != 0\n");
6959 printf("finished open test 3\n");
6961 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6963 printf("Do ctemp tests\n");
6964 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
6965 if (!NT_STATUS_IS_OK(status)) {
6966 printf("ctemp failed (%s)\n", nt_errstr(status));
6970 printf("ctemp gave path %s\n", tmp_path);
6971 status = cli_close(cli1, fnum1);
6972 if (!NT_STATUS_IS_OK(status)) {
6973 printf("close of temp failed (%s)\n", nt_errstr(status));
6976 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6977 if (!NT_STATUS_IS_OK(status)) {
6978 printf("unlink of temp failed (%s)\n", nt_errstr(status));
6981 /* Test the non-io opens... */
6983 if (!torture_open_connection(&cli2, 1)) {
6987 cli_setatr(cli2, fname, 0, 0);
6988 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6990 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6992 printf("TEST #1 testing 2 non-io opens (no delete)\n");
6993 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
6994 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6995 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6996 if (!NT_STATUS_IS_OK(status)) {
6997 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
7001 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
7002 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7003 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
7004 if (!NT_STATUS_IS_OK(status)) {
7005 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
7009 status = cli_close(cli1, fnum1);
7010 if (!NT_STATUS_IS_OK(status)) {
7011 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
7015 status = cli_close(cli2, fnum2);
7016 if (!NT_STATUS_IS_OK(status)) {
7017 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
7021 printf("non-io open test #1 passed.\n");
7023 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7025 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
7027 status = cli_ntcreate(cli1, fname, 0,
7028 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
7029 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7030 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7031 if (!NT_STATUS_IS_OK(status)) {
7032 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
7036 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
7037 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7038 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
7039 if (!NT_STATUS_IS_OK(status)) {
7040 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
7044 status = cli_close(cli1, fnum1);
7045 if (!NT_STATUS_IS_OK(status)) {
7046 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
7050 status = cli_close(cli2, fnum2);
7051 if (!NT_STATUS_IS_OK(status)) {
7052 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
7056 printf("non-io open test #2 passed.\n");
7058 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7060 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
7062 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
7063 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7064 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7065 if (!NT_STATUS_IS_OK(status)) {
7066 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
7070 status = cli_ntcreate(cli2, fname, 0,
7071 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
7072 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7073 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
7074 if (!NT_STATUS_IS_OK(status)) {
7075 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
7079 status = cli_close(cli1, fnum1);
7080 if (!NT_STATUS_IS_OK(status)) {
7081 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
7085 status = cli_close(cli2, fnum2);
7086 if (!NT_STATUS_IS_OK(status)) {
7087 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
7091 printf("non-io open test #3 passed.\n");
7093 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7095 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
7097 status = cli_ntcreate(cli1, fname, 0,
7098 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
7099 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7100 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7101 if (!NT_STATUS_IS_OK(status)) {
7102 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
7106 status = cli_ntcreate(cli2, fname, 0,
7107 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
7108 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7109 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
7110 if (NT_STATUS_IS_OK(status)) {
7111 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
7115 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
7117 status = cli_close(cli1, fnum1);
7118 if (!NT_STATUS_IS_OK(status)) {
7119 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
7123 printf("non-io open test #4 passed.\n");
7125 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7127 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
7129 status = cli_ntcreate(cli1, fname, 0,
7130 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
7131 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
7132 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7133 if (!NT_STATUS_IS_OK(status)) {
7134 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
7138 status = cli_ntcreate(cli2, fname, 0,
7139 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
7140 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
7141 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
7142 if (!NT_STATUS_IS_OK(status)) {
7143 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
7147 status = cli_close(cli1, fnum1);
7148 if (!NT_STATUS_IS_OK(status)) {
7149 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
7153 status = cli_close(cli2, fnum2);
7154 if (!NT_STATUS_IS_OK(status)) {
7155 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
7159 printf("non-io open test #5 passed.\n");
7161 printf("TEST #6 testing 1 non-io open, one io open\n");
7163 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7165 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
7166 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7167 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7168 if (!NT_STATUS_IS_OK(status)) {
7169 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
7173 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
7174 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7175 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
7176 if (!NT_STATUS_IS_OK(status)) {
7177 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
7181 status = cli_close(cli1, fnum1);
7182 if (!NT_STATUS_IS_OK(status)) {
7183 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
7187 status = cli_close(cli2, fnum2);
7188 if (!NT_STATUS_IS_OK(status)) {
7189 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
7193 printf("non-io open test #6 passed.\n");
7195 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
7197 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7199 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
7200 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
7201 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7202 if (!NT_STATUS_IS_OK(status)) {
7203 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
7207 status = cli_ntcreate(cli2, fname, 0,
7208 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
7209 FILE_ATTRIBUTE_NORMAL,
7210 FILE_SHARE_READ|FILE_SHARE_DELETE,
7211 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
7212 if (NT_STATUS_IS_OK(status)) {
7213 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
7217 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
7219 status = cli_close(cli1, fnum1);
7220 if (!NT_STATUS_IS_OK(status)) {
7221 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
7225 printf("non-io open test #7 passed.\n");
7227 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7229 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
7230 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
7231 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7232 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7233 if (!NT_STATUS_IS_OK(status)) {
7234 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
7239 /* Write to ensure we have to update the file time. */
7240 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
7242 if (!NT_STATUS_IS_OK(status)) {
7243 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
7248 status = cli_close(cli1, fnum1);
7249 if (!NT_STATUS_IS_OK(status)) {
7250 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
7256 if (!torture_close_connection(cli1)) {
7259 if (!torture_close_connection(cli2)) {
7266 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
7268 uint16_t major, minor;
7269 uint32_t caplow, caphigh;
7272 if (!SERVER_HAS_UNIX_CIFS(cli)) {
7273 printf("Server doesn't support UNIX CIFS extensions.\n");
7274 return NT_STATUS_NOT_SUPPORTED;
7277 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
7279 if (!NT_STATUS_IS_OK(status)) {
7280 printf("Server didn't return UNIX CIFS extensions: %s\n",
7285 status = cli_set_unix_extensions_capabilities(cli, major, minor,
7287 if (!NT_STATUS_IS_OK(status)) {
7288 printf("Server doesn't support setting UNIX CIFS extensions: "
7289 "%s.\n", nt_errstr(status));
7293 return NT_STATUS_OK;
7297 Test POSIX open /mkdir calls.
7299 static bool run_simple_posix_open_test(int dummy)
7301 static struct cli_state *cli1;
7302 const char *fname = "posix:file";
7303 const char *hname = "posix:hlink";
7304 const char *sname = "posix:symlink";
7305 const char *dname = "posix:dir";
7307 char *target = NULL;
7308 uint16_t fnum1 = (uint16_t)-1;
7309 SMB_STRUCT_STAT sbuf;
7310 bool correct = false;
7313 const char *fname_windows = "windows_file";
7314 uint16_t fnum2 = (uint16_t)-1;
7316 printf("Starting simple POSIX open test\n");
7318 if (!torture_open_connection(&cli1, 0)) {
7322 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7324 status = torture_setup_unix_extensions(cli1);
7325 if (!NT_STATUS_IS_OK(status)) {
7329 cli_setatr(cli1, fname, 0, 0);
7330 cli_posix_unlink(cli1, fname);
7331 cli_setatr(cli1, dname, 0, 0);
7332 cli_posix_rmdir(cli1, dname);
7333 cli_setatr(cli1, hname, 0, 0);
7334 cli_posix_unlink(cli1, hname);
7335 cli_setatr(cli1, sname, 0, 0);
7336 cli_posix_unlink(cli1, sname);
7337 cli_setatr(cli1, fname_windows, 0, 0);
7338 cli_posix_unlink(cli1, fname_windows);
7340 /* Create a directory. */
7341 status = cli_posix_mkdir(cli1, dname, 0777);
7342 if (!NT_STATUS_IS_OK(status)) {
7343 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
7347 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
7349 if (!NT_STATUS_IS_OK(status)) {
7350 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
7354 /* Test ftruncate - set file size. */
7355 status = cli_ftruncate(cli1, fnum1, 1000);
7356 if (!NT_STATUS_IS_OK(status)) {
7357 printf("ftruncate failed (%s)\n", nt_errstr(status));
7361 /* Ensure st_size == 1000 */
7362 status = cli_posix_stat(cli1, fname, &sbuf);
7363 if (!NT_STATUS_IS_OK(status)) {
7364 printf("stat failed (%s)\n", nt_errstr(status));
7368 if (sbuf.st_ex_size != 1000) {
7369 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
7373 /* Ensure st_mode == 0600 */
7374 if ((sbuf.st_ex_mode & 07777) != 0600) {
7375 printf("posix_open - bad permissions 0%o != 0600\n",
7376 (unsigned int)(sbuf.st_ex_mode & 07777));
7380 /* Test ftruncate - set file size back to zero. */
7381 status = cli_ftruncate(cli1, fnum1, 0);
7382 if (!NT_STATUS_IS_OK(status)) {
7383 printf("ftruncate failed (%s)\n", nt_errstr(status));
7387 status = cli_close(cli1, fnum1);
7388 if (!NT_STATUS_IS_OK(status)) {
7389 printf("close failed (%s)\n", nt_errstr(status));
7393 /* Now open the file again for read only. */
7394 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
7395 if (!NT_STATUS_IS_OK(status)) {
7396 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
7400 /* Now unlink while open. */
7401 status = cli_posix_unlink(cli1, fname);
7402 if (!NT_STATUS_IS_OK(status)) {
7403 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
7407 status = cli_close(cli1, fnum1);
7408 if (!NT_STATUS_IS_OK(status)) {
7409 printf("close(2) failed (%s)\n", nt_errstr(status));
7413 /* Ensure the file has gone. */
7414 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
7415 if (NT_STATUS_IS_OK(status)) {
7416 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
7420 /* Create again to test open with O_TRUNC. */
7421 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
7422 if (!NT_STATUS_IS_OK(status)) {
7423 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
7427 /* Test ftruncate - set file size. */
7428 status = cli_ftruncate(cli1, fnum1, 1000);
7429 if (!NT_STATUS_IS_OK(status)) {
7430 printf("ftruncate failed (%s)\n", nt_errstr(status));
7434 /* Ensure st_size == 1000 */
7435 status = cli_posix_stat(cli1, fname, &sbuf);
7436 if (!NT_STATUS_IS_OK(status)) {
7437 printf("stat failed (%s)\n", nt_errstr(status));
7441 if (sbuf.st_ex_size != 1000) {
7442 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
7446 status = cli_close(cli1, fnum1);
7447 if (!NT_STATUS_IS_OK(status)) {
7448 printf("close(2) failed (%s)\n", nt_errstr(status));
7452 /* Re-open with O_TRUNC. */
7453 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
7454 if (!NT_STATUS_IS_OK(status)) {
7455 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
7459 /* Ensure st_size == 0 */
7460 status = cli_posix_stat(cli1, fname, &sbuf);
7461 if (!NT_STATUS_IS_OK(status)) {
7462 printf("stat failed (%s)\n", nt_errstr(status));
7466 if (sbuf.st_ex_size != 0) {
7467 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
7471 status = cli_close(cli1, fnum1);
7472 if (!NT_STATUS_IS_OK(status)) {
7473 printf("close failed (%s)\n", nt_errstr(status));
7477 status = cli_posix_unlink(cli1, fname);
7478 if (!NT_STATUS_IS_OK(status)) {
7479 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
7483 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
7484 if (!NT_STATUS_IS_OK(status)) {
7485 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
7486 dname, nt_errstr(status));
7490 cli_close(cli1, fnum1);
7492 /* What happens when we try and POSIX open a directory for write ? */
7493 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
7494 if (NT_STATUS_IS_OK(status)) {
7495 printf("POSIX open of directory %s succeeded, "
7496 "should have failed.\n",
7500 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
7501 NT_STATUS_FILE_IS_A_DIRECTORY)) {
7506 /* Create the file. */
7507 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
7509 if (!NT_STATUS_IS_OK(status)) {
7510 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
7514 /* Write some data into it. */
7515 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
7517 if (!NT_STATUS_IS_OK(status)) {
7518 printf("cli_write failed: %s\n", nt_errstr(status));
7522 cli_close(cli1, fnum1);
7524 /* Now create a hardlink. */
7525 status = cli_posix_hardlink(cli1, fname, hname);
7526 if (!NT_STATUS_IS_OK(status)) {
7527 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
7531 /* Now create a symlink. */
7532 status = cli_posix_symlink(cli1, fname, sname);
7533 if (!NT_STATUS_IS_OK(status)) {
7534 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
7538 /* Open the hardlink for read. */
7539 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
7540 if (!NT_STATUS_IS_OK(status)) {
7541 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
7545 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
7546 if (!NT_STATUS_IS_OK(status)) {
7547 printf("POSIX read of %s failed (%s)\n", hname,
7550 } else if (nread != 10) {
7551 printf("POSIX read of %s failed. Received %ld, expected %d\n",
7552 hname, (unsigned long)nread, 10);
7556 if (memcmp(buf, "TEST DATA\n", 10)) {
7557 printf("invalid data read from hardlink\n");
7561 /* Do a POSIX lock/unlock. */
7562 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
7563 if (!NT_STATUS_IS_OK(status)) {
7564 printf("POSIX lock failed %s\n", nt_errstr(status));
7568 /* Punch a hole in the locked area. */
7569 status = cli_posix_unlock(cli1, fnum1, 10, 80);
7570 if (!NT_STATUS_IS_OK(status)) {
7571 printf("POSIX unlock failed %s\n", nt_errstr(status));
7575 cli_close(cli1, fnum1);
7577 /* Open the symlink for read - this should fail. A POSIX
7578 client should not be doing opens on a symlink. */
7579 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
7580 if (NT_STATUS_IS_OK(status)) {
7581 printf("POSIX open of %s succeeded (should have failed)\n", sname);
7584 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
7585 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
7586 printf("POSIX open of %s should have failed "
7587 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
7588 "failed with %s instead.\n",
7589 sname, nt_errstr(status));
7594 status = cli_posix_readlink(cli1, sname, talloc_tos(), &target);
7595 if (!NT_STATUS_IS_OK(status)) {
7596 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
7600 if (strcmp(target, fname) != 0) {
7601 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
7602 sname, fname, target);
7606 status = cli_posix_rmdir(cli1, dname);
7607 if (!NT_STATUS_IS_OK(status)) {
7608 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
7612 /* Check directory opens with a specific permission. */
7613 status = cli_posix_mkdir(cli1, dname, 0700);
7614 if (!NT_STATUS_IS_OK(status)) {
7615 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
7619 /* Ensure st_mode == 0700 */
7620 status = cli_posix_stat(cli1, dname, &sbuf);
7621 if (!NT_STATUS_IS_OK(status)) {
7622 printf("stat failed (%s)\n", nt_errstr(status));
7626 if ((sbuf.st_ex_mode & 07777) != 0700) {
7627 printf("posix_mkdir - bad permissions 0%o != 0700\n",
7628 (unsigned int)(sbuf.st_ex_mode & 07777));
7633 * Now create a Windows file, and attempt a POSIX unlink.
7634 * This should fail with a sharing violation but due to:
7636 * [Bug 9571] Unlink after open causes smbd to panic
7638 * ensure we've fixed the lock ordering violation.
7641 status = cli_ntcreate(cli1, fname_windows, 0,
7642 FILE_READ_DATA|FILE_WRITE_DATA, 0,
7643 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7645 0x0, 0x0, &fnum2, NULL);
7646 if (!NT_STATUS_IS_OK(status)) {
7647 printf("Windows create of %s failed (%s)\n", fname_windows,
7652 /* Now try posix_unlink. */
7653 status = cli_posix_unlink(cli1, fname_windows);
7654 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
7655 printf("POSIX unlink of %s should fail "
7656 "with NT_STATUS_SHARING_VIOLATION "
7657 "got %s instead !\n",
7663 cli_close(cli1, fnum2);
7665 printf("Simple POSIX open test passed\n");
7670 if (fnum1 != (uint16_t)-1) {
7671 cli_close(cli1, fnum1);
7672 fnum1 = (uint16_t)-1;
7675 if (fnum2 != (uint16_t)-1) {
7676 cli_close(cli1, fnum2);
7677 fnum2 = (uint16_t)-1;
7680 cli_setatr(cli1, sname, 0, 0);
7681 cli_posix_unlink(cli1, sname);
7682 cli_setatr(cli1, hname, 0, 0);
7683 cli_posix_unlink(cli1, hname);
7684 cli_setatr(cli1, fname, 0, 0);
7685 cli_posix_unlink(cli1, fname);
7686 cli_setatr(cli1, dname, 0, 0);
7687 cli_posix_rmdir(cli1, dname);
7688 cli_setatr(cli1, fname_windows, 0, 0);
7689 cli_posix_unlink(cli1, fname_windows);
7691 if (!torture_close_connection(cli1)) {
7699 Test POSIX and Windows ACLs are rejected on symlinks.
7701 static bool run_acl_symlink_test(int dummy)
7703 static struct cli_state *cli;
7704 const char *fname = "posix_file";
7705 const char *sname = "posix_symlink";
7706 uint16_t fnum = (uint16_t)-1;
7707 bool correct = false;
7709 char *posix_acl = NULL;
7710 size_t posix_acl_len = 0;
7711 char *posix_acl_sym = NULL;
7712 size_t posix_acl_len_sym = 0;
7713 struct security_descriptor *sd = NULL;
7714 struct security_descriptor *sd_sym = NULL;
7715 TALLOC_CTX *frame = NULL;
7717 frame = talloc_stackframe();
7719 printf("Starting acl symlink test\n");
7721 if (!torture_open_connection(&cli, 0)) {
7726 smbXcli_conn_set_sockopt(cli->conn, sockops);
7728 status = torture_setup_unix_extensions(cli);
7729 if (!NT_STATUS_IS_OK(status)) {
7734 cli_setatr(cli, fname, 0, 0);
7735 cli_posix_unlink(cli, fname);
7736 cli_setatr(cli, sname, 0, 0);
7737 cli_posix_unlink(cli, sname);
7739 status = cli_ntcreate(cli,
7742 READ_CONTROL_ACCESS,
7744 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7751 if (!NT_STATUS_IS_OK(status)) {
7752 printf("cli_ntcreate of %s failed (%s)\n",
7758 /* Get the Windows ACL on the file. */
7759 status = cli_query_secdesc(cli,
7763 if (!NT_STATUS_IS_OK(status)) {
7764 printf("cli_query_secdesc failed (%s)\n",
7769 /* Get the POSIX ACL on the file. */
7770 status = cli_posix_getacl(cli,
7776 if (!NT_STATUS_IS_OK(status)) {
7777 printf("cli_posix_getacl failed (%s)\n",
7782 status = cli_close(cli, fnum);
7783 if (!NT_STATUS_IS_OK(status)) {
7784 printf("close failed (%s)\n", nt_errstr(status));
7787 fnum = (uint16_t)-1;
7789 /* Now create a symlink. */
7790 status = cli_posix_symlink(cli, fname, sname);
7791 if (!NT_STATUS_IS_OK(status)) {
7792 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
7799 /* Open a handle on the symlink for SD set/get should fail. */
7800 status = cli_ntcreate(cli,
7803 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
7805 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7812 if (NT_STATUS_IS_OK(status)) {
7813 printf("Symlink open for getsd/setsd of %s "
7814 "succeeded (should fail)\n",
7819 /* Open a handle on the symlink. */
7820 status = cli_ntcreate(cli,
7823 FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES,
7825 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7832 if (!NT_STATUS_IS_OK(status)) {
7833 printf("cli_posix_open of %s failed (%s)\n",
7839 /* Get the Windows ACL on the symlink handle. Should fail */
7840 status = cli_query_secdesc(cli,
7845 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7846 printf("cli_query_secdesc on a symlink gave %s. "
7847 "Should be NT_STATUS_ACCESS_DENIED.\n",
7852 /* Get the POSIX ACL on the symlink pathname. Should fail. */
7853 status = cli_posix_getacl(cli,
7859 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7860 printf("cli_posix_getacl on a symlink gave %s. "
7861 "Should be NT_STATUS_ACCESS_DENIED.\n",
7866 /* Set the Windows ACL on the symlink handle. Should fail */
7867 status = cli_set_security_descriptor(cli,
7872 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7873 printf("cli_query_secdesc on a symlink gave %s. "
7874 "Should be NT_STATUS_ACCESS_DENIED.\n",
7879 /* Set the POSIX ACL on the symlink pathname. Should fail. */
7880 status = cli_posix_setacl(cli,
7885 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7886 printf("cli_posix_setacl on a symlink gave %s. "
7887 "Should be NT_STATUS_ACCESS_DENIED.\n",
7892 printf("ACL symlink test passed\n");
7897 if (fnum != (uint16_t)-1) {
7898 cli_close(cli, fnum);
7899 fnum = (uint16_t)-1;
7902 cli_setatr(cli, sname, 0, 0);
7903 cli_posix_unlink(cli, sname);
7904 cli_setatr(cli, fname, 0, 0);
7905 cli_posix_unlink(cli, fname);
7907 if (!torture_close_connection(cli)) {
7916 Test POSIX can delete a file containing streams.
7918 static bool run_posix_stream_delete(int dummy)
7920 struct cli_state *cli1 = NULL;
7921 struct cli_state *cli2 = NULL;
7922 const char *fname = "streamfile";
7923 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
7924 uint16_t fnum1 = (uint16_t)-1;
7925 bool correct = false;
7927 TALLOC_CTX *frame = NULL;
7929 frame = talloc_stackframe();
7931 printf("Starting POSIX stream delete test\n");
7933 if (!torture_open_connection(&cli1, 0) ||
7934 !torture_open_connection(&cli2, 1)) {
7939 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7940 smbXcli_conn_set_sockopt(cli2->conn, sockops);
7942 status = torture_setup_unix_extensions(cli2);
7943 if (!NT_STATUS_IS_OK(status)) {
7947 cli_setatr(cli1, fname, 0, 0);
7948 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7950 /* Create the file. */
7951 status = cli_ntcreate(cli1,
7954 READ_CONTROL_ACCESS,
7956 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7963 if (!NT_STATUS_IS_OK(status)) {
7964 printf("cli_ntcreate of %s failed (%s)\n",
7970 status = cli_close(cli1, fnum1);
7971 if (!NT_STATUS_IS_OK(status)) {
7972 printf("cli_close of %s failed (%s)\n",
7977 fnum1 = (uint16_t)-1;
7979 /* Now create the stream. */
7980 status = cli_ntcreate(cli1,
7985 FILE_SHARE_READ|FILE_SHARE_WRITE,
7992 if (!NT_STATUS_IS_OK(status)) {
7993 printf("cli_ntcreate of %s failed (%s)\n",
7999 /* Leave the stream handle open... */
8001 /* POSIX unlink should fail. */
8002 status = cli_posix_unlink(cli2, fname);
8003 if (NT_STATUS_IS_OK(status)) {
8004 printf("cli_posix_unlink of %s succeeded, should have failed\n",
8009 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
8010 printf("cli_posix_unlink of %s failed with (%s) "
8011 "should have been NT_STATUS_SHARING_VIOLATION\n",
8017 /* Close the stream handle. */
8018 status = cli_close(cli1, fnum1);
8019 if (!NT_STATUS_IS_OK(status)) {
8020 printf("cli_close of %s failed (%s)\n",
8025 fnum1 = (uint16_t)-1;
8027 /* POSIX unlink after stream handle closed should succeed. */
8028 status = cli_posix_unlink(cli2, fname);
8029 if (!NT_STATUS_IS_OK(status)) {
8030 printf("cli_posix_unlink of %s failed (%s)\n",
8036 printf("POSIX stream delete test passed\n");
8041 if (fnum1 != (uint16_t)-1) {
8042 cli_close(cli1, fnum1);
8043 fnum1 = (uint16_t)-1;
8046 cli_setatr(cli1, fname, 0, 0);
8047 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8049 if (!torture_close_connection(cli1)) {
8052 if (!torture_close_connection(cli2)) {
8061 Test setting EA's are rejected on symlinks.
8063 static bool run_ea_symlink_test(int dummy)
8065 static struct cli_state *cli;
8066 const char *fname = "posix_file_ea";
8067 const char *sname = "posix_symlink_ea";
8068 const char *ea_name = "testea_name";
8069 const char *ea_value = "testea_value";
8070 uint16_t fnum = (uint16_t)-1;
8071 bool correct = false;
8074 struct ea_struct *eas = NULL;
8075 TALLOC_CTX *frame = NULL;
8077 frame = talloc_stackframe();
8079 printf("Starting EA symlink test\n");
8081 if (!torture_open_connection(&cli, 0)) {
8086 smbXcli_conn_set_sockopt(cli->conn, sockops);
8088 status = torture_setup_unix_extensions(cli);
8089 if (!NT_STATUS_IS_OK(status)) {
8094 cli_setatr(cli, fname, 0, 0);
8095 cli_posix_unlink(cli, fname);
8096 cli_setatr(cli, sname, 0, 0);
8097 cli_posix_unlink(cli, sname);
8099 status = cli_ntcreate(cli,
8102 READ_CONTROL_ACCESS,
8104 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8111 if (!NT_STATUS_IS_OK(status)) {
8112 printf("cli_ntcreate of %s failed (%s)\n",
8118 status = cli_close(cli, fnum);
8119 if (!NT_STATUS_IS_OK(status)) {
8120 printf("close failed (%s)\n",
8124 fnum = (uint16_t)-1;
8126 /* Set an EA on the path. */
8127 status = cli_set_ea_path(cli,
8131 strlen(ea_value)+1);
8133 if (!NT_STATUS_IS_OK(status)) {
8134 printf("cli_set_ea_path failed (%s)\n",
8139 /* Now create a symlink. */
8140 status = cli_posix_symlink(cli, fname, sname);
8141 if (!NT_STATUS_IS_OK(status)) {
8142 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
8149 /* Get the EA list on the path. Should return value set. */
8150 status = cli_get_ea_list_path(cli,
8156 if (!NT_STATUS_IS_OK(status)) {
8157 printf("cli_get_ea_list_path failed (%s)\n",
8162 /* Ensure the EA we set is there. */
8163 for (i=0; i<num_eas; i++) {
8164 if (strcmp(eas[i].name, ea_name) == 0 &&
8165 eas[i].value.length == strlen(ea_value)+1 &&
8166 memcmp(eas[i].value.data,
8168 eas[i].value.length) == 0) {
8174 printf("Didn't find EA on pathname %s\n",
8182 /* Get the EA list on the symlink. Should return empty list. */
8183 status = cli_get_ea_list_path(cli,
8189 if (!NT_STATUS_IS_OK(status)) {
8190 printf("cli_get_ea_list_path failed (%s)\n",
8196 printf("cli_get_ea_list_path failed (%s)\n",
8201 /* Set an EA on the symlink. Should fail. */
8202 status = cli_set_ea_path(cli,
8206 strlen(ea_value)+1);
8208 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
8209 printf("cli_set_ea_path on a symlink gave %s. "
8210 "Should be NT_STATUS_ACCESS_DENIED.\n",
8215 printf("EA symlink test passed\n");
8220 if (fnum != (uint16_t)-1) {
8221 cli_close(cli, fnum);
8222 fnum = (uint16_t)-1;
8225 cli_setatr(cli, sname, 0, 0);
8226 cli_posix_unlink(cli, sname);
8227 cli_setatr(cli, fname, 0, 0);
8228 cli_posix_unlink(cli, fname);
8230 if (!torture_close_connection(cli)) {
8239 Test POSIX locks are OFD-locks.
8241 static bool run_posix_ofd_lock_test(int dummy)
8243 static struct cli_state *cli;
8244 const char *fname = "posix_file";
8245 uint16_t fnum1 = (uint16_t)-1;
8246 uint16_t fnum2 = (uint16_t)-1;
8247 bool correct = false;
8249 TALLOC_CTX *frame = NULL;
8251 frame = talloc_stackframe();
8253 printf("Starting POSIX ofd-lock test\n");
8255 if (!torture_open_connection(&cli, 0)) {
8260 smbXcli_conn_set_sockopt(cli->conn, sockops);
8262 status = torture_setup_unix_extensions(cli);
8263 if (!NT_STATUS_IS_OK(status)) {
8268 cli_setatr(cli, fname, 0, 0);
8269 cli_posix_unlink(cli, fname);
8271 /* Open the file twice. */
8272 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
8274 if (!NT_STATUS_IS_OK(status)) {
8275 printf("First POSIX open of %s failed\n", fname);
8279 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
8280 if (!NT_STATUS_IS_OK(status)) {
8281 printf("First POSIX open of %s failed\n", fname);
8285 /* Set a 0-50 lock on fnum1. */
8286 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
8287 if (!NT_STATUS_IS_OK(status)) {
8288 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
8292 /* Set a 60-100 lock on fnum2. */
8293 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
8294 if (!NT_STATUS_IS_OK(status)) {
8295 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
8299 /* close fnum1 - 0-50 lock should go away. */
8300 status = cli_close(cli, fnum1);
8301 if (!NT_STATUS_IS_OK(status)) {
8302 printf("close failed (%s)\n",
8306 fnum1 = (uint16_t)-1;
8308 /* Change the lock context. */
8309 cli_setpid(cli, cli_getpid(cli) + 1);
8311 /* Re-open fnum1. */
8312 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
8313 if (!NT_STATUS_IS_OK(status)) {
8314 printf("Third POSIX open of %s failed\n", fname);
8318 /* 60-100 lock should still be there. */
8319 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
8320 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
8321 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
8325 /* 0-50 lock should be gone. */
8326 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
8327 if (!NT_STATUS_IS_OK(status)) {
8328 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
8332 printf("POSIX OFD lock test passed\n");
8337 if (fnum1 != (uint16_t)-1) {
8338 cli_close(cli, fnum1);
8339 fnum1 = (uint16_t)-1;
8341 if (fnum2 != (uint16_t)-1) {
8342 cli_close(cli, fnum2);
8343 fnum2 = (uint16_t)-1;
8346 cli_setatr(cli, fname, 0, 0);
8347 cli_posix_unlink(cli, fname);
8349 if (!torture_close_connection(cli)) {
8357 struct posix_blocking_state {
8358 struct tevent_context *ev;
8359 struct cli_state *cli1;
8361 struct cli_state *cli2;
8367 static void posix_blocking_locked(struct tevent_req *subreq);
8368 static void posix_blocking_gotblocked(struct tevent_req *subreq);
8369 static void posix_blocking_gotecho(struct tevent_req *subreq);
8370 static void posix_blocking_unlocked(struct tevent_req *subreq);
8372 static struct tevent_req *posix_blocking_send(
8373 TALLOC_CTX *mem_ctx,
8374 struct tevent_context *ev,
8375 struct cli_state *cli1,
8377 struct cli_state *cli2,
8380 struct tevent_req *req = NULL, *subreq = NULL;
8381 struct posix_blocking_state *state = NULL;
8383 req = tevent_req_create(mem_ctx, &state, struct posix_blocking_state);
8389 state->fnum1 = fnum1;
8391 state->fnum2 = fnum2;
8393 subreq = cli_posix_lock_send(
8402 if (tevent_req_nomem(subreq, req)) {
8403 return tevent_req_post(req, ev);
8405 tevent_req_set_callback(subreq, posix_blocking_locked, req);
8409 static void posix_blocking_locked(struct tevent_req *subreq)
8411 struct tevent_req *req = tevent_req_callback_data(
8412 subreq, struct tevent_req);
8413 struct posix_blocking_state *state = tevent_req_data(
8414 req, struct posix_blocking_state);
8417 status = cli_posix_lock_recv(subreq);
8418 TALLOC_FREE(subreq);
8419 if (tevent_req_nterror(req, status)) {
8423 subreq = cli_posix_lock_send(
8432 if (tevent_req_nomem(subreq, req)) {
8435 tevent_req_set_callback(subreq, posix_blocking_gotblocked, req);
8437 /* Make sure the blocking request is delivered */
8438 subreq = cli_echo_send(
8443 (DATA_BLOB) { .data = (uint8_t *)state, .length = 1 });
8444 if (tevent_req_nomem(subreq, req)) {
8447 tevent_req_set_callback(subreq, posix_blocking_gotecho, req);
8450 static void posix_blocking_gotblocked(struct tevent_req *subreq)
8452 struct tevent_req *req = tevent_req_callback_data(
8453 subreq, struct tevent_req);
8454 struct posix_blocking_state *state = tevent_req_data(
8455 req, struct posix_blocking_state);
8458 status = cli_posix_lock_recv(subreq);
8459 TALLOC_FREE(subreq);
8460 if (tevent_req_nterror(req, status)) {
8463 if (!state->gotecho) {
8464 printf("blocked req got through before echo\n");
8465 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
8468 tevent_req_done(req);
8471 static void posix_blocking_gotecho(struct tevent_req *subreq)
8473 struct tevent_req *req = tevent_req_callback_data(
8474 subreq, struct tevent_req);
8475 struct posix_blocking_state *state = tevent_req_data(
8476 req, struct posix_blocking_state);
8479 status = cli_echo_recv(subreq);
8480 TALLOC_FREE(subreq);
8481 if (tevent_req_nterror(req, status)) {
8484 if (state->gotblocked) {
8485 printf("blocked req got through before echo\n");
8486 tevent_req_nterror(req, NT_STATUS_INVALID_LOCK_SEQUENCE);
8489 state->gotecho = true;
8491 subreq = cli_posix_lock_send(
8500 if (tevent_req_nomem(subreq, req)) {
8503 tevent_req_set_callback(subreq, posix_blocking_unlocked, req);
8506 static void posix_blocking_unlocked(struct tevent_req *subreq)
8508 struct tevent_req *req = tevent_req_callback_data(
8509 subreq, struct tevent_req);
8512 status = cli_posix_lock_recv(subreq);
8513 TALLOC_FREE(subreq);
8514 if (tevent_req_nterror(req, status)) {
8517 /* tevent_req_done in posix_blocking_gotlocked */
8520 static NTSTATUS posix_blocking_recv(struct tevent_req *req)
8522 return tevent_req_simple_recv_ntstatus(req);
8525 static bool run_posix_blocking_lock(int dummy)
8527 struct tevent_context *ev = NULL;
8528 struct cli_state *cli1 = NULL, *cli2 = NULL;
8529 const char *fname = "posix_blocking";
8530 uint16_t fnum1 = UINT16_MAX, fnum2 = UINT16_MAX;
8531 struct tevent_req *req = NULL;
8536 printf("Starting posix blocking lock test\n");
8538 ev = samba_tevent_context_init(NULL);
8543 ok = torture_open_connection(&cli1, 0);
8547 ok = torture_open_connection(&cli2, 0);
8552 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8554 status = torture_setup_unix_extensions(cli1);
8555 if (!NT_STATUS_IS_OK(status)) {
8559 cli_setatr(cli1, fname, 0, 0);
8560 cli_posix_unlink(cli1, fname);
8562 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
8564 if (!NT_STATUS_IS_OK(status)) {
8565 printf("First POSIX open of %s failed: %s\n",
8571 status = cli_posix_open(cli2, fname, O_RDWR, 0600, &fnum2);
8572 if (!NT_STATUS_IS_OK(status)) {
8573 printf("Second POSIX open of %s failed: %s\n",
8579 req = posix_blocking_send(ev, ev, cli1, fnum1, cli2, fnum2);
8581 printf("cli_posix_blocking failed\n");
8585 ok = tevent_req_poll_ntstatus(req, ev, &status);
8587 printf("tevent_req_poll_ntstatus failed: %s\n",
8591 status = posix_blocking_recv(req);
8593 if (!NT_STATUS_IS_OK(status)) {
8594 printf("posix_blocking_recv returned %s\n",
8602 if (fnum1 != UINT16_MAX) {
8603 cli_close(cli1, fnum1);
8606 if (fnum2 != UINT16_MAX) {
8607 cli_close(cli2, fnum2);
8612 cli_setatr(cli1, fname, 0, 0);
8613 cli_posix_unlink(cli1, fname);
8619 ok &= torture_close_connection(cli1);
8623 ok &= torture_close_connection(cli2);
8635 Test POSIX mkdir is case-sensitive.
8637 static bool run_posix_mkdir_test(int dummy)
8639 static struct cli_state *cli;
8640 const char *fname_foo = "POSIX_foo";
8641 const char *fname_foo_Foo = "POSIX_foo/Foo";
8642 const char *fname_foo_foo = "POSIX_foo/foo";
8643 const char *fname_Foo = "POSIX_Foo";
8644 const char *fname_Foo_Foo = "POSIX_Foo/Foo";
8645 const char *fname_Foo_foo = "POSIX_Foo/foo";
8646 bool correct = false;
8648 TALLOC_CTX *frame = NULL;
8649 uint16_t fnum = (uint16_t)-1;
8651 frame = talloc_stackframe();
8653 printf("Starting POSIX mkdir test\n");
8655 if (!torture_open_connection(&cli, 0)) {
8660 smbXcli_conn_set_sockopt(cli->conn, sockops);
8662 status = torture_setup_unix_extensions(cli);
8663 if (!NT_STATUS_IS_OK(status)) {
8668 cli_posix_rmdir(cli, fname_foo_foo);
8669 cli_posix_rmdir(cli, fname_foo_Foo);
8670 cli_posix_rmdir(cli, fname_foo);
8672 cli_posix_rmdir(cli, fname_Foo_foo);
8673 cli_posix_rmdir(cli, fname_Foo_Foo);
8674 cli_posix_rmdir(cli, fname_Foo);
8677 * Create a file POSIX_foo then try
8678 * and use it in a directory path by
8679 * doing mkdir POSIX_foo/bar.
8680 * The mkdir should fail with
8681 * NT_STATUS_OBJECT_PATH_NOT_FOUND
8684 status = cli_posix_open(cli,
8689 if (!NT_STATUS_IS_OK(status)) {
8690 printf("cli_posix_open of %s failed error %s\n",
8696 status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
8697 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
8698 printf("cli_posix_mkdir of %s should fail with "
8699 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
8706 status = cli_close(cli, fnum);
8707 if (!NT_STATUS_IS_OK(status)) {
8708 printf("cli_close failed %s\n", nt_errstr(status));
8711 fnum = (uint16_t)-1;
8713 status = cli_posix_unlink(cli, fname_foo);
8714 if (!NT_STATUS_IS_OK(status)) {
8715 printf("cli_posix_unlink of %s failed error %s\n",
8722 * Now we've deleted everything, posix_mkdir, posix_rmdir,
8723 * posix_open, posix_unlink, on
8724 * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND
8725 * not silently create POSIX_foo/foo.
8728 status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
8729 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
8730 printf("cli_posix_mkdir of %s should fail with "
8731 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
8738 status = cli_posix_rmdir(cli, fname_foo_foo);
8739 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
8740 printf("cli_posix_rmdir of %s should fail with "
8741 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
8748 status = cli_posix_open(cli,
8753 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
8754 printf("cli_posix_open of %s should fail with "
8755 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
8762 status = cli_posix_unlink(cli, fname_foo_foo);
8763 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
8764 printf("cli_posix_unlink of %s should fail with "
8765 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
8772 status = cli_posix_mkdir(cli, fname_foo, 0777);
8773 if (!NT_STATUS_IS_OK(status)) {
8774 printf("cli_posix_mkdir of %s failed\n", fname_foo);
8778 status = cli_posix_mkdir(cli, fname_Foo, 0777);
8779 if (!NT_STATUS_IS_OK(status)) {
8780 printf("cli_posix_mkdir of %s failed\n", fname_Foo);
8784 status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
8785 if (!NT_STATUS_IS_OK(status)) {
8786 printf("cli_posix_mkdir of %s failed\n", fname_foo_foo);
8790 status = cli_posix_mkdir(cli, fname_foo_Foo, 0777);
8791 if (!NT_STATUS_IS_OK(status)) {
8792 printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo);
8796 status = cli_posix_mkdir(cli, fname_Foo_foo, 0777);
8797 if (!NT_STATUS_IS_OK(status)) {
8798 printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo);
8802 status = cli_posix_mkdir(cli, fname_Foo_Foo, 0777);
8803 if (!NT_STATUS_IS_OK(status)) {
8804 printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo);
8808 printf("POSIX mkdir test passed\n");
8813 if (fnum != (uint16_t)-1) {
8814 cli_close(cli, fnum);
8815 fnum = (uint16_t)-1;
8818 cli_posix_rmdir(cli, fname_foo_foo);
8819 cli_posix_rmdir(cli, fname_foo_Foo);
8820 cli_posix_rmdir(cli, fname_foo);
8822 cli_posix_rmdir(cli, fname_Foo_foo);
8823 cli_posix_rmdir(cli, fname_Foo_Foo);
8824 cli_posix_rmdir(cli, fname_Foo);
8826 if (!torture_close_connection(cli)) {
8834 struct posix_acl_oplock_state {
8835 struct tevent_context *ev;
8836 struct cli_state *cli;
8842 static void posix_acl_oplock_got_break(struct tevent_req *req)
8844 struct posix_acl_oplock_state *state = tevent_req_callback_data(
8845 req, struct posix_acl_oplock_state);
8850 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
8852 if (!NT_STATUS_IS_OK(status)) {
8853 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
8857 *state->got_break = true;
8859 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
8862 printf("cli_oplock_ack_send failed\n");
8867 static void posix_acl_oplock_got_acl(struct tevent_req *req)
8869 struct posix_acl_oplock_state *state = tevent_req_callback_data(
8870 req, struct posix_acl_oplock_state);
8871 size_t ret_size = 0;
8872 char *ret_data = NULL;
8874 state->status = cli_posix_getacl_recv(req,
8879 if (!NT_STATUS_IS_OK(state->status)) {
8880 printf("cli_posix_getacl_recv returned %s\n",
8881 nt_errstr(state->status));
8883 *state->acl_ret = true;
8886 static bool run_posix_acl_oplock_test(int dummy)
8888 struct tevent_context *ev;
8889 struct cli_state *cli1, *cli2;
8890 struct tevent_req *oplock_req, *getacl_req;
8891 const char *fname = "posix_acl_oplock";
8893 int saved_use_oplocks = use_oplocks;
8895 bool correct = true;
8896 bool got_break = false;
8897 bool acl_ret = false;
8899 struct posix_acl_oplock_state *state;
8901 printf("starting posix_acl_oplock test\n");
8903 if (!torture_open_connection(&cli1, 0)) {
8904 use_level_II_oplocks = false;
8905 use_oplocks = saved_use_oplocks;
8909 if (!torture_open_connection(&cli2, 1)) {
8910 use_level_II_oplocks = false;
8911 use_oplocks = saved_use_oplocks;
8915 /* Setup posix on cli2 only. */
8916 status = torture_setup_unix_extensions(cli2);
8917 if (!NT_STATUS_IS_OK(status)) {
8921 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8922 smbXcli_conn_set_sockopt(cli2->conn, sockops);
8924 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8926 /* Create the file on the Windows connection. */
8927 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
8929 if (!NT_STATUS_IS_OK(status)) {
8930 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
8934 status = cli_close(cli1, fnum);
8935 if (!NT_STATUS_IS_OK(status)) {
8936 printf("close1 failed (%s)\n", nt_errstr(status));
8940 cli1->use_oplocks = true;
8942 /* Open with oplock. */
8943 status = cli_ntcreate(cli1,
8947 FILE_ATTRIBUTE_NORMAL,
8948 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8955 if (!NT_STATUS_IS_OK(status)) {
8956 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
8960 ev = samba_tevent_context_init(talloc_tos());
8962 printf("tevent_context_init failed\n");
8966 state = talloc_zero(ev, struct posix_acl_oplock_state);
8967 if (state == NULL) {
8968 printf("talloc failed\n");
8973 state->got_break = &got_break;
8974 state->acl_ret = &acl_ret;
8976 oplock_req = cli_smb_oplock_break_waiter_send(
8977 talloc_tos(), ev, cli1);
8978 if (oplock_req == NULL) {
8979 printf("cli_smb_oplock_break_waiter_send failed\n");
8982 tevent_req_set_callback(oplock_req, posix_acl_oplock_got_break, state);
8984 /* Get ACL on POSIX connection - should break oplock. */
8985 getacl_req = cli_posix_getacl_send(talloc_tos(),
8989 if (getacl_req == NULL) {
8990 printf("cli_posix_getacl_send failed\n");
8993 tevent_req_set_callback(getacl_req, posix_acl_oplock_got_acl, state);
8995 while (!got_break || !acl_ret) {
8997 ret = tevent_loop_once(ev);
8999 printf("tevent_loop_once failed: %s\n",
9005 if (!NT_STATUS_IS_OK(state->status)) {
9006 printf("getacl failed (%s)\n", nt_errstr(state->status));
9010 status = cli_close(cli1, fnum);
9011 if (!NT_STATUS_IS_OK(status)) {
9012 printf("close2 failed (%s)\n", nt_errstr(status));
9016 status = cli_unlink(cli1,
9018 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9019 if (!NT_STATUS_IS_OK(status)) {
9020 printf("unlink failed (%s)\n", nt_errstr(status));
9024 if (!torture_close_connection(cli1)) {
9027 if (!torture_close_connection(cli2)) {
9035 printf("finished posix acl oplock test\n");
9040 static bool run_posix_acl_shareroot_test(int dummy)
9042 struct cli_state *cli;
9044 bool correct = false;
9045 char *posix_acl = NULL;
9046 size_t posix_acl_len = 0;
9047 uint16_t num_file_acls = 0;
9048 uint16_t num_dir_acls = 0;
9050 uint32_t expected_size = 0;
9051 bool got_user = false;
9052 bool got_group = false;
9053 bool got_other = false;
9054 TALLOC_CTX *frame = NULL;
9056 frame = talloc_stackframe();
9058 printf("starting posix_acl_shareroot test\n");
9060 if (!torture_open_connection(&cli, 0)) {
9065 smbXcli_conn_set_sockopt(cli->conn, sockops);
9067 status = torture_setup_unix_extensions(cli);
9068 if (!NT_STATUS_IS_OK(status)) {
9069 printf("Failed to setup unix extensions\n");
9073 /* Get the POSIX ACL on the root of the share. */
9074 status = cli_posix_getacl(cli,
9080 if (!NT_STATUS_IS_OK(status)) {
9081 printf("cli_posix_getacl of '.' failed (%s)\n",
9086 if (posix_acl_len < 6 ||
9087 SVAL(posix_acl,0) != SMB_POSIX_ACL_VERSION) {
9088 printf("getfacl ., unknown POSIX acl version %u.\n",
9089 (unsigned int)CVAL(posix_acl,0) );
9093 num_file_acls = SVAL(posix_acl,2);
9094 num_dir_acls = SVAL(posix_acl,4);
9095 expected_size = SMB_POSIX_ACL_HEADER_SIZE +
9096 SMB_POSIX_ACL_ENTRY_SIZE*
9097 (num_file_acls+num_dir_acls);
9099 if (posix_acl_len != expected_size) {
9100 printf("incorrect POSIX acl buffer size "
9101 "(should be %u, was %u).\n",
9102 (unsigned int)expected_size,
9103 (unsigned int)posix_acl_len);
9108 * We don't need to know what the ACL's are
9109 * we just need to know we have at least 3
9110 * file entries (u,g,o).
9113 for (i = 0; i < num_file_acls; i++) {
9114 unsigned char tagtype =
9116 SMB_POSIX_ACL_HEADER_SIZE+
9117 (i*SMB_POSIX_ACL_ENTRY_SIZE));
9120 case SMB_POSIX_ACL_USER_OBJ:
9123 case SMB_POSIX_ACL_GROUP_OBJ:
9126 case SMB_POSIX_ACL_OTHER:
9135 printf("Missing user entry\n");
9140 printf("Missing group entry\n");
9145 printf("Missing other entry\n");
9153 if (!torture_close_connection(cli)) {
9157 printf("finished posix acl shareroot test\n");
9163 static uint32_t open_attrs_table[] = {
9164 FILE_ATTRIBUTE_NORMAL,
9165 FILE_ATTRIBUTE_ARCHIVE,
9166 FILE_ATTRIBUTE_READONLY,
9167 FILE_ATTRIBUTE_HIDDEN,
9168 FILE_ATTRIBUTE_SYSTEM,
9170 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
9171 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
9172 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
9173 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
9174 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
9175 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
9177 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
9178 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
9179 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
9180 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
9183 struct trunc_open_results {
9186 uint32_t trunc_attr;
9187 uint32_t result_attr;
9190 static struct trunc_open_results attr_results[] = {
9191 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
9192 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
9193 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
9194 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
9195 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
9196 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
9197 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
9198 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
9199 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
9200 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
9201 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
9202 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
9203 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
9204 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
9205 { 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 },
9206 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
9207 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
9208 { 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 },
9209 { 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 },
9210 { 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 },
9211 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
9212 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
9213 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
9214 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
9215 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
9216 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
9219 static bool run_openattrtest(int dummy)
9221 static struct cli_state *cli1;
9222 const char *fname = "\\openattr.file";
9224 bool correct = True;
9226 unsigned int i, j, k, l;
9229 printf("starting open attr test\n");
9231 if (!torture_open_connection(&cli1, 0)) {
9235 smbXcli_conn_set_sockopt(cli1->conn, sockops);
9237 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
9238 cli_setatr(cli1, fname, 0, 0);
9239 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9241 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
9242 open_attrs_table[i], FILE_SHARE_NONE,
9243 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
9244 if (!NT_STATUS_IS_OK(status)) {
9245 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
9249 status = cli_close(cli1, fnum1);
9250 if (!NT_STATUS_IS_OK(status)) {
9251 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
9255 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
9256 status = cli_ntcreate(cli1, fname, 0,
9257 FILE_READ_DATA|FILE_WRITE_DATA,
9258 open_attrs_table[j],
9259 FILE_SHARE_NONE, FILE_OVERWRITE,
9260 0, 0, &fnum1, NULL);
9261 if (!NT_STATUS_IS_OK(status)) {
9262 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
9263 if (attr_results[l].num == k) {
9264 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
9265 k, open_attrs_table[i],
9266 open_attrs_table[j],
9267 fname, NT_STATUS_V(status), nt_errstr(status));
9272 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
9273 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
9274 k, open_attrs_table[i], open_attrs_table[j],
9279 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
9285 status = cli_close(cli1, fnum1);
9286 if (!NT_STATUS_IS_OK(status)) {
9287 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
9291 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
9292 if (!NT_STATUS_IS_OK(status)) {
9293 printf("getatr(2) failed (%s)\n", nt_errstr(status));
9298 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
9299 k, open_attrs_table[i], open_attrs_table[j], attr );
9302 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
9303 if (attr_results[l].num == k) {
9304 if (attr != attr_results[l].result_attr ||
9305 open_attrs_table[i] != attr_results[l].init_attr ||
9306 open_attrs_table[j] != attr_results[l].trunc_attr) {
9307 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
9308 open_attrs_table[i],
9309 open_attrs_table[j],
9311 attr_results[l].result_attr);
9321 cli_setatr(cli1, fname, 0, 0);
9322 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9324 printf("open attr test %s.\n", correct ? "passed" : "failed");
9326 if (!torture_close_connection(cli1)) {
9332 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
9333 const char *name, void *state)
9335 int *matched = (int *)state;
9336 if (matched != NULL) {
9339 return NT_STATUS_OK;
9343 test directory listing speed
9345 static bool run_dirtest(int dummy)
9348 static struct cli_state *cli;
9350 struct timeval core_start;
9351 bool correct = True;
9354 printf("starting directory test\n");
9356 if (!torture_open_connection(&cli, 0)) {
9360 smbXcli_conn_set_sockopt(cli->conn, sockops);
9363 for (i=0;i<torture_numops;i++) {
9365 slprintf(fname, sizeof(fname), "\\%x", (int)random());
9366 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
9367 fprintf(stderr,"Failed to open %s\n", fname);
9370 cli_close(cli, fnum);
9373 core_start = timeval_current();
9376 cli_list(cli, "a*.*", 0, list_fn, &matched);
9377 printf("Matched %d\n", matched);
9380 cli_list(cli, "b*.*", 0, list_fn, &matched);
9381 printf("Matched %d\n", matched);
9384 cli_list(cli, "xyzabc", 0, list_fn, &matched);
9385 printf("Matched %d\n", matched);
9387 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
9390 for (i=0;i<torture_numops;i++) {
9392 slprintf(fname, sizeof(fname), "\\%x", (int)random());
9393 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9396 if (!torture_close_connection(cli)) {
9400 printf("finished dirtest\n");
9405 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
9408 struct cli_state *pcli = (struct cli_state *)state;
9410 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
9412 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9413 return NT_STATUS_OK;
9415 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9416 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
9417 printf("del_fn: failed to rmdir %s\n,", fname );
9419 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
9420 printf("del_fn: failed to unlink %s\n,", fname );
9422 return NT_STATUS_OK;
9427 sees what IOCTLs are supported
9429 bool torture_ioctl_test(int dummy)
9431 static struct cli_state *cli;
9432 uint16_t device, function;
9434 const char *fname = "\\ioctl.dat";
9438 if (!torture_open_connection(&cli, 0)) {
9442 printf("starting ioctl test\n");
9444 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9446 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
9447 if (!NT_STATUS_IS_OK(status)) {
9448 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
9452 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
9453 printf("ioctl device info: %s\n", nt_errstr(status));
9455 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
9456 printf("ioctl job info: %s\n", nt_errstr(status));
9458 for (device=0;device<0x100;device++) {
9459 printf("ioctl test with device = 0x%x\n", device);
9460 for (function=0;function<0x100;function++) {
9461 uint32_t code = (device<<16) | function;
9463 status = cli_raw_ioctl(cli, fnum, code, &blob);
9465 if (NT_STATUS_IS_OK(status)) {
9466 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
9468 data_blob_free(&blob);
9473 if (!torture_close_connection(cli)) {
9482 tries varients of chkpath
9484 bool torture_chkpath_test(int dummy)
9486 static struct cli_state *cli;
9491 if (!torture_open_connection(&cli, 0)) {
9495 printf("starting chkpath test\n");
9497 /* cleanup from an old run */
9498 cli_rmdir(cli, "\\chkpath.dir\\dir2");
9499 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9500 cli_rmdir(cli, "\\chkpath.dir");
9502 status = cli_mkdir(cli, "\\chkpath.dir");
9503 if (!NT_STATUS_IS_OK(status)) {
9504 printf("mkdir1 failed : %s\n", nt_errstr(status));
9508 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
9509 if (!NT_STATUS_IS_OK(status)) {
9510 printf("mkdir2 failed : %s\n", nt_errstr(status));
9514 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
9516 if (!NT_STATUS_IS_OK(status)) {
9517 printf("open1 failed (%s)\n", nt_errstr(status));
9520 cli_close(cli, fnum);
9522 status = cli_chkpath(cli, "\\chkpath.dir");
9523 if (!NT_STATUS_IS_OK(status)) {
9524 printf("chkpath1 failed: %s\n", nt_errstr(status));
9528 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
9529 if (!NT_STATUS_IS_OK(status)) {
9530 printf("chkpath2 failed: %s\n", nt_errstr(status));
9534 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
9535 if (!NT_STATUS_IS_OK(status)) {
9536 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
9537 NT_STATUS_NOT_A_DIRECTORY);
9539 printf("* chkpath on a file should fail\n");
9543 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
9544 if (!NT_STATUS_IS_OK(status)) {
9545 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
9546 NT_STATUS_OBJECT_NAME_NOT_FOUND);
9548 printf("* chkpath on a non existent file should fail\n");
9552 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
9553 if (!NT_STATUS_IS_OK(status)) {
9554 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
9555 NT_STATUS_OBJECT_PATH_NOT_FOUND);
9557 printf("* chkpath on a non existent component should fail\n");
9561 cli_rmdir(cli, "\\chkpath.dir\\dir2");
9562 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9563 cli_rmdir(cli, "\\chkpath.dir");
9565 if (!torture_close_connection(cli)) {
9572 static bool run_eatest(int dummy)
9574 static struct cli_state *cli;
9575 const char *fname = "\\eatest.txt";
9576 bool correct = True;
9580 struct ea_struct *ea_list = NULL;
9581 TALLOC_CTX *mem_ctx = talloc_init("eatest");
9584 printf("starting eatest\n");
9586 if (!torture_open_connection(&cli, 0)) {
9587 talloc_destroy(mem_ctx);
9591 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9593 status = cli_ntcreate(cli, fname, 0,
9594 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
9595 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
9596 0x4044, 0, &fnum, NULL);
9597 if (!NT_STATUS_IS_OK(status)) {
9598 printf("open failed - %s\n", nt_errstr(status));
9599 talloc_destroy(mem_ctx);
9603 for (i = 0; i < 10; i++) {
9604 fstring ea_name, ea_val;
9606 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
9607 memset(ea_val, (char)i+1, i+1);
9608 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
9609 if (!NT_STATUS_IS_OK(status)) {
9610 printf("ea_set of name %s failed - %s\n", ea_name,
9612 talloc_destroy(mem_ctx);
9617 cli_close(cli, fnum);
9618 for (i = 0; i < 10; i++) {
9619 fstring ea_name, ea_val;
9621 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
9622 memset(ea_val, (char)i+1, i+1);
9623 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
9624 if (!NT_STATUS_IS_OK(status)) {
9625 printf("ea_set of name %s failed - %s\n", ea_name,
9627 talloc_destroy(mem_ctx);
9632 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
9633 if (!NT_STATUS_IS_OK(status)) {
9634 printf("ea_get list failed - %s\n", nt_errstr(status));
9638 printf("num_eas = %d\n", (int)num_eas);
9640 if (num_eas != 20) {
9641 printf("Should be 20 EA's stored... failing.\n");
9645 for (i = 0; i < num_eas; i++) {
9646 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
9647 dump_data(0, ea_list[i].value.data,
9648 ea_list[i].value.length);
9651 /* Setting EA's to zero length deletes them. Test this */
9652 printf("Now deleting all EA's - case indepenent....\n");
9655 cli_set_ea_path(cli, fname, "", "", 0);
9657 for (i = 0; i < 20; i++) {
9659 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
9660 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
9661 if (!NT_STATUS_IS_OK(status)) {
9662 printf("ea_set of name %s failed - %s\n", ea_name,
9664 talloc_destroy(mem_ctx);
9670 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
9671 if (!NT_STATUS_IS_OK(status)) {
9672 printf("ea_get list failed - %s\n", nt_errstr(status));
9676 printf("num_eas = %d\n", (int)num_eas);
9677 for (i = 0; i < num_eas; i++) {
9678 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
9679 dump_data(0, ea_list[i].value.data,
9680 ea_list[i].value.length);
9684 printf("deleting EA's failed.\n");
9688 /* Try and delete a non existent EA. */
9689 status = cli_set_ea_path(cli, fname, "foo", "", 0);
9690 if (!NT_STATUS_IS_OK(status)) {
9691 printf("deleting non-existent EA 'foo' should succeed. %s\n",
9696 talloc_destroy(mem_ctx);
9697 if (!torture_close_connection(cli)) {
9704 static bool run_dirtest1(int dummy)
9707 static struct cli_state *cli;
9710 bool correct = True;
9712 printf("starting directory test\n");
9714 if (!torture_open_connection(&cli, 0)) {
9718 smbXcli_conn_set_sockopt(cli->conn, sockops);
9720 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
9721 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
9722 cli_rmdir(cli, "\\LISTDIR");
9723 cli_mkdir(cli, "\\LISTDIR");
9725 /* Create 1000 files and 1000 directories. */
9726 for (i=0;i<1000;i++) {
9728 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
9729 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
9730 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
9731 0, 0, &fnum, NULL))) {
9732 fprintf(stderr,"Failed to open %s\n", fname);
9735 cli_close(cli, fnum);
9737 for (i=0;i<1000;i++) {
9739 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
9740 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
9741 fprintf(stderr,"Failed to open %s\n", fname);
9746 /* Now ensure that doing an old list sees both files and directories. */
9748 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
9749 printf("num_seen = %d\n", num_seen );
9750 /* We should see 100 files + 1000 directories + . and .. */
9751 if (num_seen != 2002)
9754 /* Ensure if we have the "must have" bits we only see the
9758 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
9759 printf("num_seen = %d\n", num_seen );
9760 if (num_seen != 1002)
9764 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
9765 printf("num_seen = %d\n", num_seen );
9766 if (num_seen != 1000)
9769 /* Delete everything. */
9770 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
9771 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
9772 cli_rmdir(cli, "\\LISTDIR");
9775 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
9776 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
9777 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
9780 if (!torture_close_connection(cli)) {
9784 printf("finished dirtest1\n");
9789 static bool run_error_map_extract(int dummy) {
9791 static struct cli_state *c_dos;
9792 static struct cli_state *c_nt;
9804 /* NT-Error connection */
9806 disable_spnego = true;
9807 if (!(c_nt = open_nbt_connection())) {
9808 disable_spnego = false;
9811 disable_spnego = false;
9813 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
9816 if (!NT_STATUS_IS_OK(status)) {
9817 printf("%s rejected the NT-error negprot (%s)\n", host,
9823 status = cli_session_setup_anon(c_nt);
9824 if (!NT_STATUS_IS_OK(status)) {
9825 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
9829 /* DOS-Error connection */
9831 disable_spnego = true;
9832 force_dos_errors = true;
9833 if (!(c_dos = open_nbt_connection())) {
9834 disable_spnego = false;
9835 force_dos_errors = false;
9838 disable_spnego = false;
9839 force_dos_errors = false;
9841 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
9843 if (!NT_STATUS_IS_OK(status)) {
9844 printf("%s rejected the DOS-error negprot (%s)\n", host,
9846 cli_shutdown(c_dos);
9850 status = cli_session_setup_anon(c_dos);
9851 if (!NT_STATUS_IS_OK(status)) {
9852 printf("%s rejected the DOS-error initial session setup (%s)\n",
9853 host, nt_errstr(status));
9857 c_nt->map_dos_errors = false;
9858 c_dos->map_dos_errors = false;
9860 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
9861 struct cli_credentials *user_creds = NULL;
9863 fstr_sprintf(user, "%X", error);
9865 user_creds = cli_session_creds_init(talloc_tos(),
9870 false, /* use_kerberos */
9871 false, /* fallback_after_kerberos */
9872 false, /* use_ccache */
9873 false); /* password_is_nt_hash */
9874 if (user_creds == NULL) {
9875 printf("cli_session_creds_init(%s) failed\n", user);
9879 status = cli_session_setup_creds(c_nt, user_creds);
9880 if (NT_STATUS_IS_OK(status)) {
9881 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
9884 /* Case #1: 32-bit NT errors */
9885 if (!NT_STATUS_IS_DOS(status)) {
9888 printf("/** Dos error on NT connection! (%s) */\n",
9890 nt_status = NT_STATUS(0xc0000000);
9893 status = cli_session_setup_creds(c_dos, user_creds);
9894 if (NT_STATUS_IS_OK(status)) {
9895 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
9898 /* Case #1: 32-bit NT errors */
9899 if (NT_STATUS_IS_DOS(status)) {
9900 printf("/** NT error on DOS connection! (%s) */\n",
9902 errnum = errclass = 0;
9904 errclass = NT_STATUS_DOS_CLASS(status);
9905 errnum = NT_STATUS_DOS_CODE(status);
9908 if (NT_STATUS_V(nt_status) != error) {
9909 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
9910 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
9911 get_nt_error_c_code(talloc_tos(), nt_status));
9914 printf("\t{%s,\t%s,\t%s},\n",
9915 smb_dos_err_class(errclass),
9916 smb_dos_err_name(errclass, errnum),
9917 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
9919 TALLOC_FREE(user_creds);
9924 static bool run_sesssetup_bench(int dummy)
9926 static struct cli_state *c;
9927 const char *fname = "\\file.dat";
9932 if (!torture_open_connection(&c, 0)) {
9936 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
9937 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9938 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
9939 if (!NT_STATUS_IS_OK(status)) {
9940 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
9944 for (i=0; i<torture_numops; i++) {
9945 status = cli_session_setup_creds(c, torture_creds);
9946 if (!NT_STATUS_IS_OK(status)) {
9947 d_printf("(%s) cli_session_setup_creds failed: %s\n",
9948 __location__, nt_errstr(status));
9952 d_printf("\r%d ", (int)cli_state_get_uid(c));
9954 status = cli_ulogoff(c);
9955 if (!NT_STATUS_IS_OK(status)) {
9956 d_printf("(%s) cli_ulogoff failed: %s\n",
9957 __location__, nt_errstr(status));
9965 static bool subst_test(const char *str, const char *user, const char *domain,
9966 uid_t uid, gid_t gid, const char *expected)
9971 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
9973 if (strcmp(subst, expected) != 0) {
9974 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
9975 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
9984 static void chain1_open_completion(struct tevent_req *req)
9988 status = cli_openx_recv(req, &fnum);
9991 d_printf("cli_openx_recv returned %s: %d\n",
9993 NT_STATUS_IS_OK(status) ? fnum : -1);
9996 static void chain1_write_completion(struct tevent_req *req)
10000 status = cli_write_andx_recv(req, &written);
10003 d_printf("cli_write_andx_recv returned %s: %d\n",
10005 NT_STATUS_IS_OK(status) ? (int)written : -1);
10008 static void chain1_close_completion(struct tevent_req *req)
10011 bool *done = (bool *)tevent_req_callback_data_void(req);
10013 status = cli_close_recv(req);
10018 d_printf("cli_close returned %s\n", nt_errstr(status));
10021 static bool run_chain1(int dummy)
10023 struct cli_state *cli1;
10024 struct tevent_context *evt = samba_tevent_context_init(NULL);
10025 struct tevent_req *reqs[3], *smbreqs[3];
10027 const char *str = "foobar";
10028 const char *fname = "\\test_chain";
10031 printf("starting chain1 test\n");
10032 if (!torture_open_connection(&cli1, 0)) {
10036 smbXcli_conn_set_sockopt(cli1->conn, sockops);
10038 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
10040 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname,
10041 O_CREAT|O_RDWR, 0, &smbreqs[0]);
10042 if (reqs[0] == NULL) return false;
10043 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
10046 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
10047 (const uint8_t *)str, 0, strlen(str)+1,
10048 smbreqs, 1, &smbreqs[1]);
10049 if (reqs[1] == NULL) return false;
10050 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
10052 reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
10053 if (reqs[2] == NULL) return false;
10054 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
10056 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
10057 if (!NT_STATUS_IS_OK(status)) {
10062 tevent_loop_once(evt);
10065 torture_close_connection(cli1);
10069 static void chain2_sesssetup_completion(struct tevent_req *req)
10072 status = cli_session_setup_guest_recv(req);
10073 d_printf("sesssetup returned %s\n", nt_errstr(status));
10076 static void chain2_tcon_completion(struct tevent_req *req)
10078 bool *done = (bool *)tevent_req_callback_data_void(req);
10080 status = cli_tcon_andx_recv(req);
10081 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
10085 static bool run_chain2(int dummy)
10087 struct cli_state *cli1;
10088 struct tevent_context *evt = samba_tevent_context_init(NULL);
10089 struct tevent_req *reqs[2], *smbreqs[2];
10092 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
10094 printf("starting chain2 test\n");
10095 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
10096 port_to_use, SMB_SIGNING_DEFAULT, flags);
10097 if (!NT_STATUS_IS_OK(status)) {
10101 smbXcli_conn_set_sockopt(cli1->conn, sockops);
10103 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
10105 if (reqs[0] == NULL) return false;
10106 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
10108 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
10109 "?????", NULL, 0, &smbreqs[1]);
10110 if (reqs[1] == NULL) return false;
10111 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
10113 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
10114 if (!NT_STATUS_IS_OK(status)) {
10119 tevent_loop_once(evt);
10122 torture_close_connection(cli1);
10127 struct torture_createdel_state {
10128 struct tevent_context *ev;
10129 struct cli_state *cli;
10132 static void torture_createdel_created(struct tevent_req *subreq);
10133 static void torture_createdel_closed(struct tevent_req *subreq);
10135 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
10136 struct tevent_context *ev,
10137 struct cli_state *cli,
10140 struct tevent_req *req, *subreq;
10141 struct torture_createdel_state *state;
10143 req = tevent_req_create(mem_ctx, &state,
10144 struct torture_createdel_state);
10151 subreq = cli_ntcreate_send(
10152 state, ev, cli, name, 0,
10153 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
10154 FILE_ATTRIBUTE_NORMAL,
10155 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
10156 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE,
10157 SMB2_IMPERSONATION_IMPERSONATION, 0);
10159 if (tevent_req_nomem(subreq, req)) {
10160 return tevent_req_post(req, ev);
10162 tevent_req_set_callback(subreq, torture_createdel_created, req);
10166 static void torture_createdel_created(struct tevent_req *subreq)
10168 struct tevent_req *req = tevent_req_callback_data(
10169 subreq, struct tevent_req);
10170 struct torture_createdel_state *state = tevent_req_data(
10171 req, struct torture_createdel_state);
10175 status = cli_ntcreate_recv(subreq, &fnum, NULL);
10176 TALLOC_FREE(subreq);
10177 if (tevent_req_nterror(req, status)) {
10178 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
10179 nt_errstr(status)));
10183 subreq = cli_close_send(state, state->ev, state->cli, fnum);
10184 if (tevent_req_nomem(subreq, req)) {
10187 tevent_req_set_callback(subreq, torture_createdel_closed, req);
10190 static void torture_createdel_closed(struct tevent_req *subreq)
10192 struct tevent_req *req = tevent_req_callback_data(
10193 subreq, struct tevent_req);
10196 status = cli_close_recv(subreq);
10197 if (tevent_req_nterror(req, status)) {
10198 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
10201 tevent_req_done(req);
10204 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
10206 return tevent_req_simple_recv_ntstatus(req);
10209 struct torture_createdels_state {
10210 struct tevent_context *ev;
10211 struct cli_state *cli;
10212 const char *base_name;
10216 struct tevent_req **reqs;
10219 static void torture_createdels_done(struct tevent_req *subreq);
10221 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
10222 struct tevent_context *ev,
10223 struct cli_state *cli,
10224 const char *base_name,
10228 struct tevent_req *req;
10229 struct torture_createdels_state *state;
10232 req = tevent_req_create(mem_ctx, &state,
10233 struct torture_createdels_state);
10239 state->base_name = talloc_strdup(state, base_name);
10240 if (tevent_req_nomem(state->base_name, req)) {
10241 return tevent_req_post(req, ev);
10243 state->num_files = MAX(num_parallel, num_files);
10245 state->received = 0;
10247 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
10248 if (tevent_req_nomem(state->reqs, req)) {
10249 return tevent_req_post(req, ev);
10252 for (i=0; i<num_parallel; i++) {
10255 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
10257 if (tevent_req_nomem(name, req)) {
10258 return tevent_req_post(req, ev);
10260 state->reqs[i] = torture_createdel_send(
10261 state->reqs, state->ev, state->cli, name);
10262 if (tevent_req_nomem(state->reqs[i], req)) {
10263 return tevent_req_post(req, ev);
10265 name = talloc_move(state->reqs[i], &name);
10266 tevent_req_set_callback(state->reqs[i],
10267 torture_createdels_done, req);
10273 static void torture_createdels_done(struct tevent_req *subreq)
10275 struct tevent_req *req = tevent_req_callback_data(
10276 subreq, struct tevent_req);
10277 struct torture_createdels_state *state = tevent_req_data(
10278 req, struct torture_createdels_state);
10279 size_t num_parallel = talloc_array_length(state->reqs);
10284 status = torture_createdel_recv(subreq);
10285 if (!NT_STATUS_IS_OK(status)){
10286 DEBUG(10, ("torture_createdel_recv returned %s\n",
10287 nt_errstr(status)));
10288 TALLOC_FREE(subreq);
10289 tevent_req_nterror(req, status);
10293 for (i=0; i<num_parallel; i++) {
10294 if (subreq == state->reqs[i]) {
10298 if (i == num_parallel) {
10299 DEBUG(10, ("received something we did not send\n"));
10300 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
10303 TALLOC_FREE(state->reqs[i]);
10305 if (state->sent >= state->num_files) {
10306 tevent_req_done(req);
10310 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
10312 if (tevent_req_nomem(name, req)) {
10315 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
10317 if (tevent_req_nomem(state->reqs[i], req)) {
10320 name = talloc_move(state->reqs[i], &name);
10321 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
10325 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
10327 return tevent_req_simple_recv_ntstatus(req);
10330 struct swallow_notify_state {
10331 struct tevent_context *ev;
10332 struct cli_state *cli;
10334 uint32_t completion_filter;
10336 bool (*fn)(uint32_t action, const char *name, void *priv);
10340 static void swallow_notify_done(struct tevent_req *subreq);
10342 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
10343 struct tevent_context *ev,
10344 struct cli_state *cli,
10346 uint32_t completion_filter,
10348 bool (*fn)(uint32_t action,
10353 struct tevent_req *req, *subreq;
10354 struct swallow_notify_state *state;
10356 req = tevent_req_create(mem_ctx, &state,
10357 struct swallow_notify_state);
10363 state->fnum = fnum;
10364 state->completion_filter = completion_filter;
10365 state->recursive = recursive;
10367 state->priv = priv;
10369 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
10370 0xffff, state->completion_filter,
10372 if (tevent_req_nomem(subreq, req)) {
10373 return tevent_req_post(req, ev);
10375 tevent_req_set_callback(subreq, swallow_notify_done, req);
10379 static void swallow_notify_done(struct tevent_req *subreq)
10381 struct tevent_req *req = tevent_req_callback_data(
10382 subreq, struct tevent_req);
10383 struct swallow_notify_state *state = tevent_req_data(
10384 req, struct swallow_notify_state);
10386 uint32_t i, num_changes;
10387 struct notify_change *changes;
10389 status = cli_notify_recv(subreq, state, &num_changes, &changes);
10390 TALLOC_FREE(subreq);
10391 if (!NT_STATUS_IS_OK(status)) {
10392 DEBUG(10, ("cli_notify_recv returned %s\n",
10393 nt_errstr(status)));
10394 tevent_req_nterror(req, status);
10398 for (i=0; i<num_changes; i++) {
10399 state->fn(changes[i].action, changes[i].name, state->priv);
10401 TALLOC_FREE(changes);
10403 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
10404 0xffff, state->completion_filter,
10406 if (tevent_req_nomem(subreq, req)) {
10409 tevent_req_set_callback(subreq, swallow_notify_done, req);
10412 static bool print_notifies(uint32_t action, const char *name, void *priv)
10414 if (DEBUGLEVEL > 5) {
10415 d_printf("%d %s\n", (int)action, name);
10420 static void notify_bench_done(struct tevent_req *req)
10422 int *num_finished = (int *)tevent_req_callback_data_void(req);
10423 *num_finished += 1;
10426 static bool run_notify_bench(int dummy)
10428 const char *dname = "\\notify-bench";
10429 struct tevent_context *ev;
10432 struct tevent_req *req1;
10433 struct tevent_req *req2 = NULL;
10434 int i, num_unc_names;
10435 int num_finished = 0;
10437 printf("starting notify-bench test\n");
10439 if (use_multishare_conn) {
10441 unc_list = file_lines_load(multishare_conn_fname,
10442 &num_unc_names, 0, NULL);
10443 if (!unc_list || num_unc_names <= 0) {
10444 d_printf("Failed to load unc names list from '%s'\n",
10445 multishare_conn_fname);
10448 TALLOC_FREE(unc_list);
10453 ev = samba_tevent_context_init(talloc_tos());
10455 d_printf("tevent_context_init failed\n");
10459 for (i=0; i<num_unc_names; i++) {
10460 struct cli_state *cli;
10463 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
10465 if (base_fname == NULL) {
10469 if (!torture_open_connection(&cli, i)) {
10473 status = cli_ntcreate(cli, dname, 0,
10474 MAXIMUM_ALLOWED_ACCESS,
10475 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
10477 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
10480 if (!NT_STATUS_IS_OK(status)) {
10481 d_printf("Could not create %s: %s\n", dname,
10482 nt_errstr(status));
10486 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
10487 FILE_NOTIFY_CHANGE_FILE_NAME |
10488 FILE_NOTIFY_CHANGE_DIR_NAME |
10489 FILE_NOTIFY_CHANGE_ATTRIBUTES |
10490 FILE_NOTIFY_CHANGE_LAST_WRITE,
10491 false, print_notifies, NULL);
10492 if (req1 == NULL) {
10493 d_printf("Could not create notify request\n");
10497 req2 = torture_createdels_send(talloc_tos(), ev, cli,
10498 base_fname, 10, torture_numops);
10499 if (req2 == NULL) {
10500 d_printf("Could not create createdels request\n");
10503 TALLOC_FREE(base_fname);
10505 tevent_req_set_callback(req2, notify_bench_done,
10509 while (num_finished < num_unc_names) {
10511 ret = tevent_loop_once(ev);
10513 d_printf("tevent_loop_once failed\n");
10518 if (!tevent_req_poll(req2, ev)) {
10519 d_printf("tevent_req_poll failed\n");
10522 status = torture_createdels_recv(req2);
10523 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
10528 static bool run_mangle1(int dummy)
10530 struct cli_state *cli;
10531 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
10535 time_t change_time, access_time, write_time;
10539 printf("starting mangle1 test\n");
10540 if (!torture_open_connection(&cli, 0)) {
10544 smbXcli_conn_set_sockopt(cli->conn, sockops);
10546 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
10547 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
10548 0, 0, &fnum, NULL);
10549 if (!NT_STATUS_IS_OK(status)) {
10550 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
10553 cli_close(cli, fnum);
10555 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
10556 if (!NT_STATUS_IS_OK(status)) {
10557 d_printf("cli_qpathinfo_alt_name failed: %s\n",
10558 nt_errstr(status));
10561 d_printf("alt_name: %s\n", alt_name);
10563 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
10564 if (!NT_STATUS_IS_OK(status)) {
10565 d_printf("cli_openx(%s) failed: %s\n", alt_name,
10566 nt_errstr(status));
10569 cli_close(cli, fnum);
10571 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
10572 &write_time, &size, &mode);
10573 if (!NT_STATUS_IS_OK(status)) {
10574 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
10575 nt_errstr(status));
10582 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
10583 struct file_info *f,
10587 if (f->short_name == NULL) {
10588 return NT_STATUS_OK;
10591 if (strlen(f->short_name) == 0) {
10592 return NT_STATUS_OK;
10595 printf("unexpected shortname: %s\n", f->short_name);
10597 return NT_STATUS_OBJECT_NAME_INVALID;
10600 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
10601 struct file_info *f,
10605 char *name = state;
10607 printf("name: %s\n", f->name);
10608 fstrcpy(name, f->name);
10609 return NT_STATUS_OK;
10612 static bool run_mangle_illegal(int dummy)
10614 struct cli_state *cli = NULL;
10615 struct cli_state *cli_posix = NULL;
10616 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
10617 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
10618 char *mangled_path = NULL;
10624 printf("starting mangle-illegal test\n");
10626 if (!torture_open_connection(&cli, 0)) {
10630 smbXcli_conn_set_sockopt(cli->conn, sockops);
10632 if (!torture_open_connection(&cli_posix, 0)) {
10636 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
10638 status = torture_setup_unix_extensions(cli_posix);
10639 if (!NT_STATUS_IS_OK(status)) {
10643 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
10644 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
10645 if (!NT_STATUS_IS_OK(status)) {
10646 printf("mkdir1 failed : %s\n", nt_errstr(status));
10651 * Create a file with illegal NTFS characters and test that we
10652 * get a usable mangled name
10655 cli_setatr(cli_posix, illegal_fname, 0, 0);
10656 cli_posix_unlink(cli_posix, illegal_fname);
10658 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
10660 if (!NT_STATUS_IS_OK(status)) {
10661 printf("POSIX create of %s failed (%s)\n",
10662 illegal_fname, nt_errstr(status));
10666 status = cli_close(cli_posix, fnum);
10667 if (!NT_STATUS_IS_OK(status)) {
10668 printf("close failed (%s)\n", nt_errstr(status));
10672 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
10673 if (!NT_STATUS_IS_OK(status)) {
10674 d_printf("cli_list failed: %s\n", nt_errstr(status));
10678 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
10679 if (mangled_path == NULL) {
10683 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
10684 if (!NT_STATUS_IS_OK(status)) {
10685 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
10686 TALLOC_FREE(mangled_path);
10689 TALLOC_FREE(mangled_path);
10690 cli_close(cli, fnum);
10692 cli_setatr(cli_posix, illegal_fname, 0, 0);
10693 cli_posix_unlink(cli_posix, illegal_fname);
10696 * Create a file with a long name and check that we got *no* short name.
10699 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
10700 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
10701 0, 0, &fnum, NULL);
10702 if (!NT_STATUS_IS_OK(status)) {
10703 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
10706 cli_close(cli, fnum);
10708 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
10709 if (!NT_STATUS_IS_OK(status)) {
10710 d_printf("cli_list failed\n");
10714 cli_unlink(cli, fname, 0);
10715 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
10717 if (!torture_close_connection(cli_posix)) {
10721 if (!torture_close_connection(cli)) {
10728 static size_t null_source(uint8_t *buf, size_t n, void *priv)
10730 size_t *to_pull = (size_t *)priv;
10731 size_t thistime = *to_pull;
10733 thistime = MIN(thistime, n);
10734 if (thistime == 0) {
10738 memset(buf, 0, thistime);
10739 *to_pull -= thistime;
10743 static bool run_windows_write(int dummy)
10745 struct cli_state *cli1;
10749 const char *fname = "\\writetest.txt";
10750 struct timeval start_time;
10755 printf("starting windows_write test\n");
10756 if (!torture_open_connection(&cli1, 0)) {
10760 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
10761 if (!NT_STATUS_IS_OK(status)) {
10762 printf("open failed (%s)\n", nt_errstr(status));
10766 smbXcli_conn_set_sockopt(cli1->conn, sockops);
10768 start_time = timeval_current();
10770 for (i=0; i<torture_numops; i++) {
10772 off_t start = i * torture_blocksize;
10773 size_t to_pull = torture_blocksize - 1;
10775 status = cli_writeall(cli1, fnum, 0, &c,
10776 start + torture_blocksize - 1, 1, NULL);
10777 if (!NT_STATUS_IS_OK(status)) {
10778 printf("cli_write failed: %s\n", nt_errstr(status));
10782 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
10783 null_source, &to_pull);
10784 if (!NT_STATUS_IS_OK(status)) {
10785 printf("cli_push returned: %s\n", nt_errstr(status));
10790 seconds = timeval_elapsed(&start_time);
10791 kbytes = (double)torture_blocksize * torture_numops;
10794 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
10795 (double)seconds, (int)(kbytes/seconds));
10799 cli_close(cli1, fnum);
10800 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
10801 torture_close_connection(cli1);
10805 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
10807 size_t max_pdu = 0x1FFFF;
10809 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
10810 max_pdu = 0xFFFFFF;
10813 if (smb1cli_conn_signing_is_active(cli->conn)) {
10817 if (smb1cli_conn_encryption_on(cli->conn)) {
10818 max_pdu = CLI_BUFFER_SIZE;
10821 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
10822 len_requested &= 0xFFFF;
10825 return MIN(len_requested,
10826 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
10829 static bool check_read_call(struct cli_state *cli,
10832 size_t len_requested)
10835 struct tevent_req *subreq = NULL;
10836 ssize_t len_read = 0;
10837 size_t len_expected = 0;
10838 struct tevent_context *ev = NULL;
10840 ev = samba_tevent_context_init(talloc_tos());
10845 subreq = cli_read_andx_send(talloc_tos(),
10852 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
10856 status = cli_read_andx_recv(subreq, &len_read, &buf);
10857 if (!NT_STATUS_IS_OK(status)) {
10858 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
10862 TALLOC_FREE(subreq);
10865 len_expected = calc_expected_return(cli, len_requested);
10867 if (len_expected > 0x10000 && len_read == 0x10000) {
10868 /* Windows servers only return a max of 0x10000,
10869 doesn't matter if you set CAP_LARGE_READX in
10870 the client sessionsetupX call or not. */
10871 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
10872 (unsigned int)len_requested);
10873 } else if (len_read != len_expected) {
10874 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
10875 (unsigned int)len_requested,
10876 (unsigned int)len_read,
10877 (unsigned int)len_expected);
10880 d_printf("Correct read reply.\n");
10886 /* Test large readX variants. */
10887 static bool large_readx_tests(struct cli_state *cli,
10891 /* A read of 0xFFFF0001 should *always* return 1 byte. */
10892 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
10895 /* A read of 0x10000 should return 0x10000 bytes. */
10896 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
10899 /* A read of 0x10000 should return 0x10001 bytes. */
10900 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
10903 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
10904 the requested number of bytes. */
10905 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
10908 /* A read of 1MB should return 1MB bytes (on Samba). */
10909 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
10913 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
10916 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
10919 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
10925 static bool run_large_readx(int dummy)
10927 uint8_t *buf = NULL;
10928 struct cli_state *cli1 = NULL;
10929 struct cli_state *cli2 = NULL;
10930 bool correct = false;
10931 const char *fname = "\\large_readx.dat";
10933 uint16_t fnum1 = UINT16_MAX;
10934 uint32_t normal_caps = 0;
10935 size_t file_size = 20*1024*1024;
10936 TALLOC_CTX *frame = talloc_stackframe();
10940 enum smb_signing_setting signing_setting;
10941 enum protocol_types protocol;
10945 .signing_setting = SMB_SIGNING_IF_REQUIRED,
10946 .protocol = PROTOCOL_NT1,
10948 .name = "NT1 - SIGNING_REQUIRED",
10949 .signing_setting = SMB_SIGNING_REQUIRED,
10950 .protocol = PROTOCOL_NT1,
10954 printf("starting large_readx test\n");
10956 if (!torture_open_connection(&cli1, 0)) {
10960 normal_caps = smb1cli_conn_capabilities(cli1->conn);
10962 if (!(normal_caps & CAP_LARGE_READX)) {
10963 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
10964 (unsigned int)normal_caps);
10968 /* Create a file of size 4MB. */
10969 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
10970 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
10971 0, 0, &fnum1, NULL);
10973 if (!NT_STATUS_IS_OK(status)) {
10974 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
10978 /* Write file_size bytes. */
10979 buf = talloc_zero_array(frame, uint8_t, file_size);
10984 status = cli_writeall(cli1,
10991 if (!NT_STATUS_IS_OK(status)) {
10992 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
10996 status = cli_close(cli1, fnum1);
10997 if (!NT_STATUS_IS_OK(status)) {
10998 d_printf("cli_close failed: %s\n", nt_errstr(status));
11002 fnum1 = UINT16_MAX;
11004 for (i=0; i < ARRAY_SIZE(runs); i++) {
11005 enum smb_signing_setting saved_signing_setting = signing_state;
11006 uint16_t fnum2 = -1;
11009 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
11011 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
11015 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
11017 signing_state = runs[i].signing_setting;
11018 cli2 = open_nbt_connection();
11019 signing_state = saved_signing_setting;
11020 if (cli2 == NULL) {
11024 status = smbXcli_negprot(cli2->conn,
11028 if (!NT_STATUS_IS_OK(status)) {
11032 status = cli_session_setup_creds(cli2, torture_creds);
11033 if (!NT_STATUS_IS_OK(status)) {
11037 status = cli_tree_connect(cli2,
11041 if (!NT_STATUS_IS_OK(status)) {
11045 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
11047 normal_caps = smb1cli_conn_capabilities(cli2->conn);
11049 if (!(normal_caps & CAP_LARGE_READX)) {
11050 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
11051 (unsigned int)normal_caps);
11056 if (force_cli_encryption(cli2, share) == false) {
11059 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
11060 uint16_t major, minor;
11061 uint32_t caplow, caphigh;
11063 status = cli_unix_extensions_version(cli2,
11065 &caplow, &caphigh);
11066 if (!NT_STATUS_IS_OK(status)) {
11071 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
11072 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
11073 0, 0, &fnum2, NULL);
11074 if (!NT_STATUS_IS_OK(status)) {
11075 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
11079 /* All reads must return less than file_size bytes. */
11080 if (!large_readx_tests(cli2, fnum2, buf)) {
11084 status = cli_close(cli2, fnum2);
11085 if (!NT_STATUS_IS_OK(status)) {
11086 d_printf("cli_close failed: %s\n", nt_errstr(status));
11091 if (!torture_close_connection(cli2)) {
11098 printf("Success on large_readx test\n");
11103 if (!torture_close_connection(cli2)) {
11109 if (fnum1 != UINT16_MAX) {
11110 status = cli_close(cli1, fnum1);
11111 if (!NT_STATUS_IS_OK(status)) {
11112 d_printf("cli_close failed: %s\n", nt_errstr(status));
11114 fnum1 = UINT16_MAX;
11117 status = cli_unlink(cli1, fname,
11118 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11119 if (!NT_STATUS_IS_OK(status)) {
11120 printf("unlink failed (%s)\n", nt_errstr(status));
11123 if (!torture_close_connection(cli1)) {
11128 TALLOC_FREE(frame);
11130 printf("finished large_readx test\n");
11134 static bool run_cli_echo(int dummy)
11136 struct cli_state *cli;
11139 printf("starting cli_echo test\n");
11140 if (!torture_open_connection(&cli, 0)) {
11143 smbXcli_conn_set_sockopt(cli->conn, sockops);
11145 status = cli_echo(cli, 5, data_blob_const("hello", 5));
11147 d_printf("cli_echo returned %s\n", nt_errstr(status));
11149 torture_close_connection(cli);
11150 return NT_STATUS_IS_OK(status);
11153 static int splice_status(off_t written, void *priv)
11158 static bool run_cli_splice(int dummy)
11160 uint8_t *buf = NULL;
11161 struct cli_state *cli1 = NULL;
11162 bool correct = false;
11163 const char *fname_src = "\\splice_src.dat";
11164 const char *fname_dst = "\\splice_dst.dat";
11166 uint16_t fnum1 = UINT16_MAX;
11167 uint16_t fnum2 = UINT16_MAX;
11168 size_t file_size = 2*1024*1024;
11169 size_t splice_size = 1*1024*1024 + 713;
11170 uint8_t digest1[16], digest2[16];
11173 TALLOC_CTX *frame = talloc_stackframe();
11175 printf("starting cli_splice test\n");
11177 if (!torture_open_connection(&cli1, 0)) {
11181 cli_unlink(cli1, fname_src,
11182 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11183 cli_unlink(cli1, fname_dst,
11184 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11186 /* Create a file */
11187 status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
11188 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
11189 0, 0, &fnum1, NULL);
11191 if (!NT_STATUS_IS_OK(status)) {
11192 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
11196 /* Write file_size bytes - must be bigger than splice_size. */
11197 buf = talloc_zero_array(frame, uint8_t, file_size);
11199 d_printf("talloc_fail\n");
11203 /* Fill it with random numbers. */
11204 generate_random_buffer(buf, file_size);
11206 /* MD5 the first 1MB + 713 bytes. */
11207 gnutls_hash_fast(GNUTLS_DIG_MD5,
11212 status = cli_writeall(cli1,
11219 if (!NT_STATUS_IS_OK(status)) {
11220 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
11224 status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
11225 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
11226 0, 0, &fnum2, NULL);
11228 if (!NT_STATUS_IS_OK(status)) {
11229 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
11233 /* Now splice 1MB + 713 bytes. */
11234 status = cli_splice(cli1,
11245 if (!NT_STATUS_IS_OK(status)) {
11246 d_printf("cli_splice failed: %s\n", nt_errstr(status));
11250 /* Clear the old buffer. */
11251 memset(buf, '\0', file_size);
11253 /* Read the new file. */
11254 status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
11255 if (!NT_STATUS_IS_OK(status)) {
11256 d_printf("cli_read failed: %s\n", nt_errstr(status));
11259 if (nread != splice_size) {
11260 d_printf("bad read of 0x%x, should be 0x%x\n",
11261 (unsigned int)nread,
11262 (unsigned int)splice_size);
11266 /* MD5 the first 1MB + 713 bytes. */
11267 gnutls_hash_fast(GNUTLS_DIG_MD5,
11272 /* Must be the same. */
11273 if (memcmp(digest1, digest2, 16) != 0) {
11274 d_printf("bad MD5 compare\n");
11279 printf("Success on cli_splice test\n");
11284 if (fnum1 != UINT16_MAX) {
11285 cli_close(cli1, fnum1);
11287 if (fnum2 != UINT16_MAX) {
11288 cli_close(cli1, fnum2);
11291 cli_unlink(cli1, fname_src,
11292 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11293 cli_unlink(cli1, fname_dst,
11294 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11296 if (!torture_close_connection(cli1)) {
11301 TALLOC_FREE(frame);
11305 static bool run_uid_regression_test(int dummy)
11307 static struct cli_state *cli;
11310 bool correct = True;
11311 struct smbXcli_tcon *orig_tcon = NULL;
11314 printf("starting uid regression test\n");
11316 if (!torture_open_connection(&cli, 0)) {
11320 smbXcli_conn_set_sockopt(cli->conn, sockops);
11322 /* Ok - now save then logoff our current user. */
11323 old_vuid = cli_state_get_uid(cli);
11325 status = cli_ulogoff(cli);
11326 if (!NT_STATUS_IS_OK(status)) {
11327 d_printf("(%s) cli_ulogoff failed: %s\n",
11328 __location__, nt_errstr(status));
11333 cli_state_set_uid(cli, old_vuid);
11335 /* Try an operation. */
11336 status = cli_mkdir(cli, "\\uid_reg_test");
11337 if (NT_STATUS_IS_OK(status)) {
11338 d_printf("(%s) cli_mkdir succeeded\n",
11343 /* Should be bad uid. */
11344 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
11345 NT_STATUS_USER_SESSION_DELETED)) {
11351 old_cnum = cli_state_get_tid(cli);
11352 orig_tcon = cli_state_save_tcon(cli);
11353 if (orig_tcon == NULL) {
11358 /* Now try a SMBtdis with the invalid vuid set to zero. */
11359 cli_state_set_uid(cli, 0);
11361 /* This should succeed. */
11362 status = cli_tdis(cli);
11364 if (NT_STATUS_IS_OK(status)) {
11365 d_printf("First tdis with invalid vuid should succeed.\n");
11367 d_printf("First tdis failed (%s)\n", nt_errstr(status));
11369 cli_state_restore_tcon(cli, orig_tcon);
11373 cli_state_restore_tcon(cli, orig_tcon);
11374 cli_state_set_uid(cli, old_vuid);
11375 cli_state_set_tid(cli, old_cnum);
11377 /* This should fail. */
11378 status = cli_tdis(cli);
11379 if (NT_STATUS_IS_OK(status)) {
11380 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
11384 /* Should be bad tid. */
11385 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
11386 NT_STATUS_NETWORK_NAME_DELETED)) {
11392 cli_rmdir(cli, "\\uid_reg_test");
11401 static const char *illegal_chars = "*\\/?<>|\":";
11402 static char force_shortname_chars[] = " +,.[];=\177";
11404 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
11405 const char *mask, void *state)
11407 struct cli_state *pcli = (struct cli_state *)state;
11409 NTSTATUS status = NT_STATUS_OK;
11411 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
11413 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
11414 return NT_STATUS_OK;
11416 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
11417 status = cli_rmdir(pcli, fname);
11418 if (!NT_STATUS_IS_OK(status)) {
11419 printf("del_fn: failed to rmdir %s\n,", fname );
11422 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11423 if (!NT_STATUS_IS_OK(status)) {
11424 printf("del_fn: failed to unlink %s\n,", fname );
11436 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
11437 const char *name, void *state)
11439 struct sn_state *s = (struct sn_state *)state;
11443 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
11444 i, finfo->name, finfo->short_name);
11447 if (strchr(force_shortname_chars, i)) {
11448 if (!finfo->short_name) {
11449 /* Shortname not created when it should be. */
11450 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
11451 __location__, finfo->name, i);
11454 } else if (finfo->short_name){
11455 /* Shortname created when it should not be. */
11456 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
11457 __location__, finfo->short_name, finfo->name);
11461 return NT_STATUS_OK;
11464 static bool run_shortname_test(int dummy)
11466 static struct cli_state *cli;
11467 bool correct = True;
11473 printf("starting shortname test\n");
11475 if (!torture_open_connection(&cli, 0)) {
11479 smbXcli_conn_set_sockopt(cli->conn, sockops);
11481 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
11482 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
11483 cli_rmdir(cli, "\\shortname");
11485 status = cli_mkdir(cli, "\\shortname");
11486 if (!NT_STATUS_IS_OK(status)) {
11487 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
11488 __location__, nt_errstr(status));
11493 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
11497 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
11504 for (i = 32; i < 128; i++) {
11505 uint16_t fnum = (uint16_t)-1;
11509 if (strchr(illegal_chars, i)) {
11514 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
11515 FILE_SHARE_READ|FILE_SHARE_WRITE,
11516 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
11517 if (!NT_STATUS_IS_OK(status)) {
11518 d_printf("(%s) cli_nt_create of %s failed: %s\n",
11519 __location__, fname, nt_errstr(status));
11523 cli_close(cli, fnum);
11526 status = cli_list(cli, "\\shortname\\test*.*", 0,
11527 shortname_list_fn, &s);
11528 if (s.matched != 1) {
11529 d_printf("(%s) failed to list %s: %s\n",
11530 __location__, fname, nt_errstr(status));
11535 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11536 if (!NT_STATUS_IS_OK(status)) {
11537 d_printf("(%s) failed to delete %s: %s\n",
11538 __location__, fname, nt_errstr(status));
11551 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
11552 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
11553 cli_rmdir(cli, "\\shortname");
11554 torture_close_connection(cli);
11558 static void pagedsearch_cb(struct tevent_req *req)
11561 struct tldap_message *msg;
11564 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
11565 if (!TLDAP_RC_IS_SUCCESS(rc)) {
11566 d_printf("tldap_search_paged_recv failed: %s\n",
11567 tldap_rc2string(rc));
11570 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
11574 if (!tldap_entry_dn(msg, &dn)) {
11575 d_printf("tldap_entry_dn failed\n");
11578 d_printf("%s\n", dn);
11582 static bool run_tldap(int dummy)
11584 struct tldap_context *ld;
11588 struct sockaddr_storage addr;
11589 struct tevent_context *ev;
11590 struct tevent_req *req;
11592 const char *filter;
11594 if (!resolve_name(host, &addr, 0, false)) {
11595 d_printf("could not find host %s\n", host);
11598 status = open_socket_out(&addr, 389, 9999, &fd);
11599 if (!NT_STATUS_IS_OK(status)) {
11600 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
11604 ld = tldap_context_create(talloc_tos(), fd);
11607 d_printf("tldap_context_create failed\n");
11611 rc = tldap_fetch_rootdse(ld);
11612 if (!TLDAP_RC_IS_SUCCESS(rc)) {
11613 d_printf("tldap_fetch_rootdse failed: %s\n",
11614 tldap_errstr(talloc_tos(), ld, rc));
11618 basedn = tldap_talloc_single_attribute(
11619 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
11620 if (basedn == NULL) {
11621 d_printf("no defaultNamingContext\n");
11624 d_printf("defaultNamingContext: %s\n", basedn);
11626 ev = samba_tevent_context_init(talloc_tos());
11628 d_printf("tevent_context_init failed\n");
11632 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
11633 TLDAP_SCOPE_SUB, "(objectclass=*)",
11635 NULL, 0, NULL, 0, 0, 0, 0, 5);
11637 d_printf("tldap_search_paged_send failed\n");
11640 tevent_req_set_callback(req, pagedsearch_cb, NULL);
11642 tevent_req_poll(req, ev);
11646 /* test search filters against rootDSE */
11647 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
11648 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
11650 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
11651 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
11652 talloc_tos(), NULL);
11653 if (!TLDAP_RC_IS_SUCCESS(rc)) {
11654 d_printf("tldap_search with complex filter failed: %s\n",
11655 tldap_errstr(talloc_tos(), ld, rc));
11663 /* Torture test to ensure no regression of :
11664 https://bugzilla.samba.org/show_bug.cgi?id=7084
11667 static bool run_dir_createtime(int dummy)
11669 struct cli_state *cli;
11670 const char *dname = "\\testdir_createtime";
11671 const char *fname = "\\testdir_createtime\\testfile";
11673 struct timespec create_time;
11674 struct timespec create_time1;
11678 if (!torture_open_connection(&cli, 0)) {
11682 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11683 cli_rmdir(cli, dname);
11685 status = cli_mkdir(cli, dname);
11686 if (!NT_STATUS_IS_OK(status)) {
11687 printf("mkdir failed: %s\n", nt_errstr(status));
11691 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
11693 if (!NT_STATUS_IS_OK(status)) {
11694 printf("cli_qpathinfo2 returned %s\n",
11695 nt_errstr(status));
11699 /* Sleep 3 seconds, then create a file. */
11702 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
11704 if (!NT_STATUS_IS_OK(status)) {
11705 printf("cli_openx failed: %s\n", nt_errstr(status));
11709 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
11711 if (!NT_STATUS_IS_OK(status)) {
11712 printf("cli_qpathinfo2 (2) returned %s\n",
11713 nt_errstr(status));
11717 if (timespec_compare(&create_time1, &create_time)) {
11718 printf("run_dir_createtime: create time was updated (error)\n");
11720 printf("run_dir_createtime: create time was not updated (correct)\n");
11726 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11727 cli_rmdir(cli, dname);
11728 if (!torture_close_connection(cli)) {
11735 static bool run_streamerror(int dummy)
11737 struct cli_state *cli;
11738 const char *dname = "\\testdir_streamerror";
11739 const char *streamname =
11740 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
11742 time_t change_time, access_time, write_time;
11744 uint16_t mode, fnum;
11747 if (!torture_open_connection(&cli, 0)) {
11751 cli_unlink(cli, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
11752 cli_rmdir(cli, dname);
11754 status = cli_mkdir(cli, dname);
11755 if (!NT_STATUS_IS_OK(status)) {
11756 printf("mkdir failed: %s\n", nt_errstr(status));
11760 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
11761 &write_time, &size, &mode);
11762 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
11763 printf("pathinfo returned %s, expected "
11764 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
11765 nt_errstr(status));
11769 status = cli_ntcreate(cli, streamname, 0x16,
11770 FILE_READ_DATA|FILE_READ_EA|
11771 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
11772 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
11773 FILE_OPEN, 0, 0, &fnum, NULL);
11775 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
11776 printf("ntcreate returned %s, expected "
11777 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
11778 nt_errstr(status));
11783 cli_rmdir(cli, dname);
11787 struct pidtest_state {
11793 static void pid_echo_done(struct tevent_req *subreq);
11795 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
11796 struct tevent_context *ev,
11797 struct cli_state *cli)
11799 struct tevent_req *req, *subreq;
11800 struct pidtest_state *state;
11802 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
11807 SSVAL(state->vwv, 0, 1);
11808 state->data = data_blob_const("hello", 5);
11810 subreq = smb1cli_req_send(state,
11814 0, 0, /* *_flags */
11815 0, 0, /* *_flags2 */
11817 0xDEADBEEF, /* pid */
11819 NULL, /* session */
11820 ARRAY_SIZE(state->vwv), state->vwv,
11821 state->data.length, state->data.data);
11823 if (tevent_req_nomem(subreq, req)) {
11824 return tevent_req_post(req, ev);
11826 tevent_req_set_callback(subreq, pid_echo_done, req);
11830 static void pid_echo_done(struct tevent_req *subreq)
11832 struct tevent_req *req = tevent_req_callback_data(
11833 subreq, struct tevent_req);
11834 struct pidtest_state *state = tevent_req_data(
11835 req, struct pidtest_state);
11837 uint32_t num_bytes;
11838 uint8_t *bytes = NULL;
11839 struct iovec *recv_iov = NULL;
11840 uint8_t *phdr = NULL;
11841 uint16_t pidlow = 0;
11842 uint16_t pidhigh = 0;
11843 struct smb1cli_req_expected_response expected[] = {
11845 .status = NT_STATUS_OK,
11850 status = smb1cli_req_recv(subreq, state,
11855 NULL, /* pvwv_offset */
11858 NULL, /* pbytes_offset */
11860 expected, ARRAY_SIZE(expected));
11862 TALLOC_FREE(subreq);
11864 if (!NT_STATUS_IS_OK(status)) {
11865 tevent_req_nterror(req, status);
11869 if (num_bytes != state->data.length) {
11870 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
11874 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
11875 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
11879 /* Check pid low/high == DEADBEEF */
11880 pidlow = SVAL(phdr, HDR_PID);
11881 if (pidlow != 0xBEEF){
11882 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
11883 (unsigned int)pidlow);
11884 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
11887 pidhigh = SVAL(phdr, HDR_PIDHIGH);
11888 if (pidhigh != 0xDEAD){
11889 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
11890 (unsigned int)pidhigh);
11891 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
11895 tevent_req_done(req);
11898 static NTSTATUS pid_echo_recv(struct tevent_req *req)
11900 return tevent_req_simple_recv_ntstatus(req);
11903 static bool run_pidhigh(int dummy)
11905 bool success = false;
11906 struct cli_state *cli = NULL;
11908 struct tevent_context *ev = NULL;
11909 struct tevent_req *req = NULL;
11910 TALLOC_CTX *frame = talloc_stackframe();
11912 printf("starting pid high test\n");
11913 if (!torture_open_connection(&cli, 0)) {
11916 smbXcli_conn_set_sockopt(cli->conn, sockops);
11918 ev = samba_tevent_context_init(frame);
11923 req = pid_echo_send(frame, ev, cli);
11928 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
11932 status = pid_echo_recv(req);
11933 if (NT_STATUS_IS_OK(status)) {
11934 printf("pid high test ok\n");
11940 TALLOC_FREE(frame);
11941 torture_close_connection(cli);
11946 Test Windows open on a bad POSIX symlink.
11948 static bool run_symlink_open_test(int dummy)
11950 static struct cli_state *cli;
11951 const char *fname = "non_existant_file";
11952 const char *sname = "dangling_symlink";
11953 uint16_t fnum = (uint16_t)-1;
11954 bool correct = false;
11956 TALLOC_CTX *frame = NULL;
11958 frame = talloc_stackframe();
11960 printf("Starting Windows bad symlink open test\n");
11962 if (!torture_open_connection(&cli, 0)) {
11963 TALLOC_FREE(frame);
11967 smbXcli_conn_set_sockopt(cli->conn, sockops);
11969 status = torture_setup_unix_extensions(cli);
11970 if (!NT_STATUS_IS_OK(status)) {
11971 TALLOC_FREE(frame);
11975 /* Ensure nothing exists. */
11976 cli_setatr(cli, fname, 0, 0);
11977 cli_posix_unlink(cli, fname);
11978 cli_setatr(cli, sname, 0, 0);
11979 cli_posix_unlink(cli, sname);
11981 /* Create a symlink pointing nowhere. */
11982 status = cli_posix_symlink(cli, fname, sname);
11983 if (!NT_STATUS_IS_OK(status)) {
11984 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
11987 nt_errstr(status));
11991 /* Now ensure that a Windows open doesn't hang. */
11992 status = cli_ntcreate(cli,
11995 FILE_READ_DATA|FILE_WRITE_DATA,
11997 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
12005 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
12006 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
12007 * we use O_NOFOLLOW on the server or not.
12009 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
12010 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
12014 printf("cli_ntcreate of %s returned %s - should return"
12015 " either (%s) or (%s)\n",
12018 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
12019 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
12027 if (fnum != (uint16_t)-1) {
12028 cli_close(cli, fnum);
12029 fnum = (uint16_t)-1;
12032 cli_setatr(cli, sname, 0, 0);
12033 cli_posix_unlink(cli, sname);
12034 cli_setatr(cli, fname, 0, 0);
12035 cli_posix_unlink(cli, fname);
12037 if (!torture_close_connection(cli)) {
12041 TALLOC_FREE(frame);
12046 * Only testing minimal time strings, as the others
12047 * need (locale-dependent) guessing at what strftime does and
12048 * even may differ in builds.
12050 static bool timesubst_test(void)
12052 TALLOC_CTX *ctx = NULL;
12053 /* Sa 23. Dez 04:33:20 CET 2017 */
12054 const struct timeval tv = { 1514000000, 123 };
12055 const char* expect_minimal = "20171223_033320";
12056 const char* expect_minus = "20171223_033320_000123";
12058 char *env_tz, *orig_tz = NULL;
12059 bool result = true;
12061 ctx = talloc_new(NULL);
12063 env_tz = getenv("TZ");
12065 orig_tz = talloc_strdup(ctx, env_tz);
12067 setenv("TZ", "UTC", 1);
12069 s = minimal_timeval_string(ctx, &tv, false);
12071 if(!s || strcmp(s, expect_minimal)) {
12072 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
12073 "[%s]\n", s ? s : "<nil>", expect_minimal);
12077 s = minimal_timeval_string(ctx, &tv, true);
12078 if(!s || strcmp(s, expect_minus)) {
12079 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
12080 "[%s]\n", s ? s : "<nil>", expect_minus);
12086 setenv("TZ", orig_tz, 1);
12093 static bool run_local_substitute(int dummy)
12097 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
12098 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
12099 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
12100 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
12101 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
12102 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
12103 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
12104 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
12105 ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
12106 /* Substitution depends on current time, so better test the underlying
12107 formatting function. At least covers %t. */
12108 ok &= timesubst_test();
12110 /* Different captialization rules in sub_basic... */
12112 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
12118 static bool run_local_base64(int dummy)
12123 for (i=1; i<2000; i++) {
12124 DATA_BLOB blob1, blob2;
12127 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
12129 generate_random_buffer(blob1.data, blob1.length);
12131 b64 = base64_encode_data_blob(talloc_tos(), blob1);
12133 d_fprintf(stderr, "base64_encode_data_blob failed "
12134 "for %d bytes\n", i);
12137 blob2 = base64_decode_data_blob(b64);
12140 if (data_blob_cmp(&blob1, &blob2)) {
12141 d_fprintf(stderr, "data_blob_cmp failed for %d "
12145 TALLOC_FREE(blob1.data);
12146 data_blob_free(&blob2);
12151 static void parse_fn(const struct gencache_timeout *t,
12153 void *private_data)
12158 static bool run_local_gencache(int dummy)
12164 struct memcache *mem;
12167 mem = memcache_init(NULL, 0);
12169 d_printf("%s: memcache_init failed\n", __location__);
12172 memcache_set_global(mem);
12174 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
12175 d_printf("%s: gencache_set() failed\n", __location__);
12179 if (!gencache_get("foo", NULL, NULL, NULL)) {
12180 d_printf("%s: gencache_get() failed\n", __location__);
12184 for (i=0; i<1000000; i++) {
12185 gencache_parse("foo", parse_fn, NULL);
12188 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
12189 d_printf("%s: gencache_get() failed\n", __location__);
12194 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
12195 d_printf("%s: gencache_get() failed\n", __location__);
12199 if (strcmp(val, "bar") != 0) {
12200 d_printf("%s: gencache_get() returned %s, expected %s\n",
12201 __location__, val, "bar");
12208 if (!gencache_del("foo")) {
12209 d_printf("%s: gencache_del() failed\n", __location__);
12212 if (gencache_del("foo")) {
12213 d_printf("%s: second gencache_del() succeeded\n",
12218 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
12219 d_printf("%s: gencache_get() on deleted entry "
12220 "succeeded\n", __location__);
12224 blob = data_blob_string_const_null("bar");
12225 tm = time(NULL) + 60;
12227 if (!gencache_set_data_blob("foo", blob, tm)) {
12228 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
12232 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
12233 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
12237 if (strcmp((const char *)blob.data, "bar") != 0) {
12238 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
12239 __location__, (const char *)blob.data, "bar");
12240 data_blob_free(&blob);
12244 data_blob_free(&blob);
12246 if (!gencache_del("foo")) {
12247 d_printf("%s: gencache_del() failed\n", __location__);
12250 if (gencache_del("foo")) {
12251 d_printf("%s: second gencache_del() succeeded\n",
12256 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
12257 d_printf("%s: gencache_get_data_blob() on deleted entry "
12258 "succeeded\n", __location__);
12263 blob.data = (uint8_t *)&v;
12264 blob.length = sizeof(v);
12266 if (!gencache_set_data_blob("blob", blob, tm)) {
12267 d_printf("%s: gencache_set_data_blob() failed\n",
12271 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
12272 d_printf("%s: gencache_get succeeded\n", __location__);
12279 static bool rbt_testval(struct db_context *db, const char *key,
12282 struct db_record *rec;
12283 TDB_DATA data = string_tdb_data(value);
12288 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
12290 d_fprintf(stderr, "fetch_locked failed\n");
12293 status = dbwrap_record_store(rec, data, 0);
12294 if (!NT_STATUS_IS_OK(status)) {
12295 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
12300 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
12302 d_fprintf(stderr, "second fetch_locked failed\n");
12306 dbvalue = dbwrap_record_get_value(rec);
12307 if ((dbvalue.dsize != data.dsize)
12308 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
12309 d_fprintf(stderr, "Got wrong data back\n");
12319 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
12321 int *count2 = (int *)private_data;
12326 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
12328 int *count2 = (int *)private_data;
12330 dbwrap_record_delete(rec);
12334 static bool run_local_rbtree(int dummy)
12336 struct db_context *db;
12343 db = db_open_rbt(NULL);
12346 d_fprintf(stderr, "db_open_rbt failed\n");
12350 for (i=0; i<1000; i++) {
12353 if (asprintf(&key, "key%ld", random()) == -1) {
12356 if (asprintf(&value, "value%ld", random()) == -1) {
12361 if (!rbt_testval(db, key, value)) {
12368 if (asprintf(&value, "value%ld", random()) == -1) {
12373 if (!rbt_testval(db, key, value)) {
12384 count = 0; count2 = 0;
12385 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
12387 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
12388 if ((count != count2) || (count != 1000)) {
12391 count = 0; count2 = 0;
12392 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
12394 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
12395 if ((count != count2) || (count != 1000)) {
12398 count = 0; count2 = 0;
12399 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
12401 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
12402 if ((count != count2) || (count != 0)) {
12413 local test for character set functions
12415 This is a very simple test for the functionality in convert_string_error()
12417 static bool run_local_convert_string(int dummy)
12419 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
12420 const char *test_strings[2] = { "March", "M\303\244rz" };
12424 for (i=0; i<2; i++) {
12425 const char *str = test_strings[i];
12426 int len = strlen(str);
12427 size_t converted_size;
12430 memset(dst, 'X', sizeof(dst));
12432 /* first try with real source length */
12433 ret = convert_string_error(CH_UNIX, CH_UTF8,
12438 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
12442 if (converted_size != len) {
12443 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
12444 str, len, (int)converted_size);
12448 if (strncmp(str, dst, converted_size) != 0) {
12449 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
12453 if (strlen(str) != converted_size) {
12454 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
12455 (int)strlen(str), (int)converted_size);
12459 if (dst[converted_size] != 'X') {
12460 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
12464 /* now with srclen==-1, this causes the nul to be
12466 ret = convert_string_error(CH_UNIX, CH_UTF8,
12471 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
12475 if (converted_size != len+1) {
12476 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
12477 str, len, (int)converted_size);
12481 if (strncmp(str, dst, converted_size) != 0) {
12482 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
12486 if (len+1 != converted_size) {
12487 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
12488 len+1, (int)converted_size);
12492 if (dst[converted_size] != 'X') {
12493 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
12500 TALLOC_FREE(tmp_ctx);
12503 TALLOC_FREE(tmp_ctx);
12507 static bool run_local_string_to_sid(int dummy) {
12508 struct dom_sid sid;
12510 if (string_to_sid(&sid, "S--1-5-32-545")) {
12511 printf("allowing S--1-5-32-545\n");
12514 if (string_to_sid(&sid, "S-1-5-32-+545")) {
12515 printf("allowing S-1-5-32-+545\n");
12518 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")) {
12519 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
12522 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
12523 printf("allowing S-1-5-32-545-abc\n");
12526 if (string_to_sid(&sid, "S-300-5-32-545")) {
12527 printf("allowing S-300-5-32-545\n");
12530 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
12531 printf("allowing S-1-0xfffffffffffffe-32-545\n");
12534 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
12535 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
12538 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
12539 printf("could not parse S-1-0xfffffffffffe-32-545\n");
12542 if (!string_to_sid(&sid, "S-1-5-32-545")) {
12543 printf("could not parse S-1-5-32-545\n");
12546 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
12547 struct dom_sid_buf buf;
12548 printf("mis-parsed S-1-5-32-545 as %s\n",
12549 dom_sid_str_buf(&sid, &buf));
12555 static bool sid_to_string_test(const char *expected) {
12558 struct dom_sid sid;
12560 if (!string_to_sid(&sid, expected)) {
12561 printf("could not parse %s\n", expected);
12565 str = dom_sid_string(NULL, &sid);
12566 if (strcmp(str, expected)) {
12567 printf("Comparison failed (%s != %s)\n", str, expected);
12574 static bool run_local_sid_to_string(int dummy) {
12575 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
12577 if (!sid_to_string_test("S-1-545"))
12579 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
12584 static bool run_local_binary_to_sid(int dummy) {
12586 struct dom_sid *sid = talloc(NULL, struct dom_sid);
12587 static const uint8_t good_binary_sid[] = {
12588 0x1, /* revision number */
12589 15, /* num auths */
12590 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
12591 0x1, 0x1, 0x1, 0x1, /* auth[0] */
12592 0x1, 0x1, 0x1, 0x1, /* auth[1] */
12593 0x1, 0x1, 0x1, 0x1, /* auth[2] */
12594 0x1, 0x1, 0x1, 0x1, /* auth[3] */
12595 0x1, 0x1, 0x1, 0x1, /* auth[4] */
12596 0x1, 0x1, 0x1, 0x1, /* auth[5] */
12597 0x1, 0x1, 0x1, 0x1, /* auth[6] */
12598 0x1, 0x1, 0x1, 0x1, /* auth[7] */
12599 0x1, 0x1, 0x1, 0x1, /* auth[8] */
12600 0x1, 0x1, 0x1, 0x1, /* auth[9] */
12601 0x1, 0x1, 0x1, 0x1, /* auth[10] */
12602 0x1, 0x1, 0x1, 0x1, /* auth[11] */
12603 0x1, 0x1, 0x1, 0x1, /* auth[12] */
12604 0x1, 0x1, 0x1, 0x1, /* auth[13] */
12605 0x1, 0x1, 0x1, 0x1, /* auth[14] */
12608 static const uint8_t long_binary_sid[] = {
12609 0x1, /* revision number */
12610 15, /* num auths */
12611 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
12612 0x1, 0x1, 0x1, 0x1, /* auth[0] */
12613 0x1, 0x1, 0x1, 0x1, /* auth[1] */
12614 0x1, 0x1, 0x1, 0x1, /* auth[2] */
12615 0x1, 0x1, 0x1, 0x1, /* auth[3] */
12616 0x1, 0x1, 0x1, 0x1, /* auth[4] */
12617 0x1, 0x1, 0x1, 0x1, /* auth[5] */
12618 0x1, 0x1, 0x1, 0x1, /* auth[6] */
12619 0x1, 0x1, 0x1, 0x1, /* auth[7] */
12620 0x1, 0x1, 0x1, 0x1, /* auth[8] */
12621 0x1, 0x1, 0x1, 0x1, /* auth[9] */
12622 0x1, 0x1, 0x1, 0x1, /* auth[10] */
12623 0x1, 0x1, 0x1, 0x1, /* auth[11] */
12624 0x1, 0x1, 0x1, 0x1, /* auth[12] */
12625 0x1, 0x1, 0x1, 0x1, /* auth[13] */
12626 0x1, 0x1, 0x1, 0x1, /* auth[14] */
12627 0x1, 0x1, 0x1, 0x1, /* auth[15] */
12628 0x1, 0x1, 0x1, 0x1, /* auth[16] */
12629 0x1, 0x1, 0x1, 0x1, /* auth[17] */
12632 static const uint8_t long_binary_sid2[] = {
12633 0x1, /* revision number */
12634 32, /* num auths */
12635 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
12636 0x1, 0x1, 0x1, 0x1, /* auth[0] */
12637 0x1, 0x1, 0x1, 0x1, /* auth[1] */
12638 0x1, 0x1, 0x1, 0x1, /* auth[2] */
12639 0x1, 0x1, 0x1, 0x1, /* auth[3] */
12640 0x1, 0x1, 0x1, 0x1, /* auth[4] */
12641 0x1, 0x1, 0x1, 0x1, /* auth[5] */
12642 0x1, 0x1, 0x1, 0x1, /* auth[6] */
12643 0x1, 0x1, 0x1, 0x1, /* auth[7] */
12644 0x1, 0x1, 0x1, 0x1, /* auth[8] */
12645 0x1, 0x1, 0x1, 0x1, /* auth[9] */
12646 0x1, 0x1, 0x1, 0x1, /* auth[10] */
12647 0x1, 0x1, 0x1, 0x1, /* auth[11] */
12648 0x1, 0x1, 0x1, 0x1, /* auth[12] */
12649 0x1, 0x1, 0x1, 0x1, /* auth[13] */
12650 0x1, 0x1, 0x1, 0x1, /* auth[14] */
12651 0x1, 0x1, 0x1, 0x1, /* auth[15] */
12652 0x1, 0x1, 0x1, 0x1, /* auth[16] */
12653 0x1, 0x1, 0x1, 0x1, /* auth[17] */
12654 0x1, 0x1, 0x1, 0x1, /* auth[18] */
12655 0x1, 0x1, 0x1, 0x1, /* auth[19] */
12656 0x1, 0x1, 0x1, 0x1, /* auth[20] */
12657 0x1, 0x1, 0x1, 0x1, /* auth[21] */
12658 0x1, 0x1, 0x1, 0x1, /* auth[22] */
12659 0x1, 0x1, 0x1, 0x1, /* auth[23] */
12660 0x1, 0x1, 0x1, 0x1, /* auth[24] */
12661 0x1, 0x1, 0x1, 0x1, /* auth[25] */
12662 0x1, 0x1, 0x1, 0x1, /* auth[26] */
12663 0x1, 0x1, 0x1, 0x1, /* auth[27] */
12664 0x1, 0x1, 0x1, 0x1, /* auth[28] */
12665 0x1, 0x1, 0x1, 0x1, /* auth[29] */
12666 0x1, 0x1, 0x1, 0x1, /* auth[30] */
12667 0x1, 0x1, 0x1, 0x1, /* auth[31] */
12670 ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
12674 ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
12678 ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
12685 /* Split a path name into filename and stream name components. Canonicalise
12686 * such that an implicit $DATA token is always explicit.
12688 * The "specification" of this function can be found in the
12689 * run_local_stream_name() function in torture.c, I've tried those
12690 * combinations against a W2k3 server.
12693 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
12694 char **pbase, char **pstream)
12697 char *stream = NULL;
12698 char *sname; /* stream name */
12699 const char *stype; /* stream type */
12701 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
12703 sname = strchr_m(fname, ':');
12705 if (sname == NULL) {
12706 if (pbase != NULL) {
12707 base = talloc_strdup(mem_ctx, fname);
12708 NT_STATUS_HAVE_NO_MEMORY(base);
12713 if (pbase != NULL) {
12714 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
12715 NT_STATUS_HAVE_NO_MEMORY(base);
12720 stype = strchr_m(sname, ':');
12722 if (stype == NULL) {
12723 sname = talloc_strdup(mem_ctx, sname);
12727 if (strcasecmp_m(stype, ":$DATA") != 0) {
12729 * If there is an explicit stream type, so far we only
12730 * allow $DATA. Is there anything else allowed? -- vl
12732 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
12734 return NT_STATUS_OBJECT_NAME_INVALID;
12736 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
12740 if (sname == NULL) {
12742 return NT_STATUS_NO_MEMORY;
12745 if (sname[0] == '\0') {
12747 * no stream name, so no stream
12752 if (pstream != NULL) {
12753 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
12754 if (stream == NULL) {
12755 TALLOC_FREE(sname);
12757 return NT_STATUS_NO_MEMORY;
12760 * upper-case the type field
12762 (void)strupper_m(strchr_m(stream, ':')+1);
12766 if (pbase != NULL) {
12769 if (pstream != NULL) {
12772 return NT_STATUS_OK;
12775 static bool test_stream_name(const char *fname, const char *expected_base,
12776 const char *expected_stream,
12777 NTSTATUS expected_status)
12781 char *stream = NULL;
12783 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
12784 if (!NT_STATUS_EQUAL(status, expected_status)) {
12788 if (!NT_STATUS_IS_OK(status)) {
12792 if (base == NULL) goto error;
12794 if (strcmp(expected_base, base) != 0) goto error;
12796 if ((expected_stream != NULL) && (stream == NULL)) goto error;
12797 if ((expected_stream == NULL) && (stream != NULL)) goto error;
12799 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
12803 TALLOC_FREE(stream);
12807 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
12808 fname, expected_base ? expected_base : "<NULL>",
12809 expected_stream ? expected_stream : "<NULL>",
12810 nt_errstr(expected_status));
12811 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
12812 base ? base : "<NULL>", stream ? stream : "<NULL>",
12813 nt_errstr(status));
12815 TALLOC_FREE(stream);
12819 static bool run_local_stream_name(int dummy)
12823 ret &= test_stream_name(
12824 "bla", "bla", NULL, NT_STATUS_OK);
12825 ret &= test_stream_name(
12826 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
12827 ret &= test_stream_name(
12828 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
12829 ret &= test_stream_name(
12830 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
12831 ret &= test_stream_name(
12832 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
12833 ret &= test_stream_name(
12834 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
12835 ret &= test_stream_name(
12836 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
12837 ret &= test_stream_name(
12838 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
12843 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
12845 if (a.length != b.length) {
12846 printf("a.length=%d != b.length=%d\n",
12847 (int)a.length, (int)b.length);
12850 if (memcmp(a.data, b.data, a.length) != 0) {
12851 printf("a.data and b.data differ\n");
12857 static bool run_local_memcache(int dummy)
12859 struct memcache *cache;
12860 DATA_BLOB k1, k2, k3, k4, k5;
12864 TALLOC_CTX *mem_ctx;
12870 size_t size1, size2;
12873 mem_ctx = talloc_init("foo");
12874 if (mem_ctx == NULL) {
12878 /* STAT_CACHE TESTS */
12880 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
12882 if (cache == NULL) {
12883 printf("memcache_init failed\n");
12887 d1 = data_blob_const("d1", 2);
12888 d3 = data_blob_const("d3", 2);
12890 k1 = data_blob_const("d1", 2);
12891 k2 = data_blob_const("d2", 2);
12892 k3 = data_blob_const("d3", 2);
12893 k4 = data_blob_const("d4", 2);
12894 k5 = data_blob_const("d5", 2);
12896 memcache_add(cache, STAT_CACHE, k1, d1);
12898 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
12899 printf("could not find k1\n");
12902 if (!data_blob_equal(d1, v1)) {
12906 memcache_add(cache, STAT_CACHE, k1, d3);
12908 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
12909 printf("could not find replaced k1\n");
12912 if (!data_blob_equal(d3, v3)) {
12916 TALLOC_FREE(cache);
12918 /* GETWD_CACHE TESTS */
12919 str1 = talloc_strdup(mem_ctx, "string1");
12920 if (str1 == NULL) {
12923 ptr2 = str1; /* Keep an alias for comparison. */
12925 str2 = talloc_strdup(mem_ctx, "string2");
12926 if (str2 == NULL) {
12930 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
12931 if (cache == NULL) {
12932 printf("memcache_init failed\n");
12936 memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
12937 /* str1 == NULL now. */
12938 ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
12939 if (ptr1 == NULL) {
12940 printf("could not find k2\n");
12943 if (ptr1 != ptr2) {
12944 printf("fetch of k2 got wrong string\n");
12948 /* Add a blob to ensure k2 gets purged. */
12949 d3 = data_blob_talloc_zero(mem_ctx, 180);
12950 memcache_add(cache, STAT_CACHE, k3, d3);
12952 ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
12953 if (ptr2 != NULL) {
12954 printf("Did find k2, should have been purged\n");
12959 * Test that talloc size also is accounted in memcache and
12960 * causes purge of other object.
12963 str1 = talloc_zero_size(mem_ctx, 100);
12964 str2 = talloc_zero_size(mem_ctx, 100);
12966 memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
12967 memcache_add_talloc(cache, GETWD_CACHE, k5, &str1);
12969 ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
12970 if (ptr3 != NULL) {
12971 printf("Did find k4, should have been purged\n");
12976 * Test that adding a duplicate non-talloced
12977 * key/value on top of a talloced key/value takes account
12978 * of the talloc_freed value size.
12980 TALLOC_FREE(cache);
12981 TALLOC_FREE(mem_ctx);
12983 mem_ctx = talloc_init("key_replace");
12984 if (mem_ctx == NULL) {
12988 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
12989 if (cache == NULL) {
12994 * Add a 100 byte talloced string. This will
12995 * store a (4 or 8 byte) pointer and record the
12996 * total talloced size.
12998 str1 = talloc_zero_size(mem_ctx, 100);
12999 memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
13001 * Now overwrite with a small talloced
13002 * value. This should fit in the existing size
13003 * and the total talloced size should be removed
13004 * from the cache size.
13006 str1 = talloc_zero_size(mem_ctx, 2);
13007 memcache_add_talloc(cache, GETWD_CACHE, k4, &str1);
13009 * Now store a 20 byte string. If the
13010 * total talloced size wasn't accounted for
13011 * and removed in the overwrite, then this
13014 str2 = talloc_zero_size(mem_ctx, 20);
13015 memcache_add_talloc(cache, GETWD_CACHE, k5, &str2);
13017 ptr3 = memcache_lookup_talloc(cache, GETWD_CACHE, k4);
13018 if (ptr3 == NULL) {
13019 printf("Did not find k4, should not have been purged\n");
13023 TALLOC_FREE(cache);
13024 TALLOC_FREE(mem_ctx);
13026 mem_ctx = talloc_init("foo");
13027 if (mem_ctx == NULL) {
13031 cache = memcache_init(NULL, 0);
13032 if (cache == NULL) {
13036 str1 = talloc_strdup(mem_ctx, "string1");
13037 if (str1 == NULL) {
13040 str2 = talloc_strdup(mem_ctx, "string2");
13041 if (str2 == NULL) {
13044 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
13045 data_blob_string_const("torture"), &str1);
13046 size1 = talloc_total_size(cache);
13048 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
13049 data_blob_string_const("torture"), &str2);
13050 size2 = talloc_total_size(cache);
13052 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
13054 if (size2 > size1) {
13055 printf("memcache leaks memory!\n");
13061 TALLOC_FREE(cache);
13065 static void wbclient_done(struct tevent_req *req)
13068 struct winbindd_response *wb_resp;
13069 int *i = (int *)tevent_req_callback_data_void(req);
13071 wbc_err = wb_trans_recv(req, req, &wb_resp);
13074 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
13077 static bool run_wbclient_multi_ping(int dummy)
13079 struct tevent_context *ev;
13080 struct wb_context **wb_ctx;
13081 struct winbindd_request wb_req;
13082 bool result = false;
13085 BlockSignals(True, SIGPIPE);
13087 ev = tevent_context_init(talloc_tos());
13092 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
13093 if (wb_ctx == NULL) {
13097 ZERO_STRUCT(wb_req);
13098 wb_req.cmd = WINBINDD_PING;
13100 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
13102 for (i=0; i<torture_nprocs; i++) {
13103 wb_ctx[i] = wb_context_init(ev, NULL);
13104 if (wb_ctx[i] == NULL) {
13107 for (j=0; j<torture_numops; j++) {
13108 struct tevent_req *req;
13109 req = wb_trans_send(ev, ev, wb_ctx[i],
13110 (j % 2) == 0, &wb_req);
13114 tevent_req_set_callback(req, wbclient_done, &i);
13120 while (i < torture_nprocs * torture_numops) {
13121 tevent_loop_once(ev);
13130 static bool dbtrans_inc(struct db_context *db)
13132 struct db_record *rec;
13138 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
13140 printf(__location__ "fetch_lock failed\n");
13144 value = dbwrap_record_get_value(rec);
13146 if (value.dsize != sizeof(uint32_t)) {
13147 printf(__location__ "value.dsize = %d\n",
13152 memcpy(&val, value.dptr, sizeof(val));
13155 status = dbwrap_record_store(
13156 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
13157 if (!NT_STATUS_IS_OK(status)) {
13158 printf(__location__ "store failed: %s\n",
13159 nt_errstr(status));
13169 static bool run_local_dbtrans(int dummy)
13171 struct db_context *db;
13172 struct db_record *rec;
13178 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
13179 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
13182 printf("Could not open transtest.db\n");
13186 res = dbwrap_transaction_start(db);
13188 printf(__location__ "transaction_start failed\n");
13192 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
13194 printf(__location__ "fetch_lock failed\n");
13198 value = dbwrap_record_get_value(rec);
13200 if (value.dptr == NULL) {
13202 status = dbwrap_record_store(
13203 rec, make_tdb_data((uint8_t *)&initial,
13206 if (!NT_STATUS_IS_OK(status)) {
13207 printf(__location__ "store returned %s\n",
13208 nt_errstr(status));
13215 res = dbwrap_transaction_commit(db);
13217 printf(__location__ "transaction_commit failed\n");
13222 uint32_t val, val2;
13225 res = dbwrap_transaction_start(db);
13227 printf(__location__ "transaction_start failed\n");
13231 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
13232 if (!NT_STATUS_IS_OK(status)) {
13233 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
13234 nt_errstr(status));
13238 for (i=0; i<10; i++) {
13239 if (!dbtrans_inc(db)) {
13244 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
13245 if (!NT_STATUS_IS_OK(status)) {
13246 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
13247 nt_errstr(status));
13251 if (val2 != val + 10) {
13252 printf(__location__ "val=%d, val2=%d\n",
13253 (int)val, (int)val2);
13257 printf("val2=%d\r", val2);
13259 res = dbwrap_transaction_commit(db);
13261 printf(__location__ "transaction_commit failed\n");
13271 * Just a dummy test to be run under a debugger. There's no real way
13272 * to inspect the tevent_poll specific function from outside of
13276 static bool run_local_tevent_poll(int dummy)
13278 struct tevent_context *ev;
13279 struct tevent_fd *fd1, *fd2;
13280 bool result = false;
13282 ev = tevent_context_init_byname(NULL, "poll");
13284 d_fprintf(stderr, "tevent_context_init_byname failed\n");
13288 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
13290 d_fprintf(stderr, "tevent_add_fd failed\n");
13293 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
13295 d_fprintf(stderr, "tevent_add_fd failed\n");
13300 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
13302 d_fprintf(stderr, "tevent_add_fd failed\n");
13312 static bool run_local_hex_encode_buf(int dummy)
13318 for (i=0; i<sizeof(src); i++) {
13321 hex_encode_buf(buf, src, sizeof(src));
13322 if (strcmp(buf, "0001020304050607") != 0) {
13325 hex_encode_buf(buf, NULL, 0);
13326 if (buf[0] != '\0') {
13332 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
13354 "1001:1111:1111:1000:0:1111:1111:1111",
13363 static const char *remove_duplicate_addrs2_test_strings_result[] = {
13377 "1001:1111:1111:1000:0:1111:1111:1111"
13380 static bool run_local_remove_duplicate_addrs2(int dummy)
13382 struct ip_service test_vector[28];
13385 /* Construct the sockaddr_storage test vector. */
13386 for (i = 0; i < 28; i++) {
13387 struct addrinfo hints;
13388 struct addrinfo *res = NULL;
13391 memset(&hints, '\0', sizeof(hints));
13392 hints.ai_flags = AI_NUMERICHOST;
13393 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
13398 fprintf(stderr, "getaddrinfo failed on [%s]\n",
13399 remove_duplicate_addrs2_test_strings_vector[i]);
13402 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
13403 memcpy(&test_vector[i].ss,
13409 count = remove_duplicate_addrs2(test_vector, i);
13412 fprintf(stderr, "count wrong (%d) should be 14\n",
13417 for (i = 0; i < count; i++) {
13418 char addr[INET6_ADDRSTRLEN];
13420 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
13422 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
13423 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
13426 remove_duplicate_addrs2_test_strings_result[i]);
13431 printf("run_local_remove_duplicate_addrs2: success\n");
13435 static bool run_local_tdb_opener(int dummy)
13441 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
13442 O_RDWR|O_CREAT, 0755);
13444 perror("tdb_open failed");
13455 static bool run_local_tdb_writer(int dummy)
13461 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
13463 perror("tdb_open failed");
13467 val.dptr = (uint8_t *)&v;
13468 val.dsize = sizeof(v);
13474 ret = tdb_store(t, val, val, 0);
13476 printf("%s\n", tdb_errorstr(t));
13481 data = tdb_fetch(t, val);
13482 if (data.dptr != NULL) {
13483 SAFE_FREE(data.dptr);
13489 static bool run_local_canonicalize_path(int dummy)
13491 const char *src[] = {
13498 ".././././../../../boo",
13502 const char *dst[] = {
13515 for (i = 0; src[i] != NULL; i++) {
13516 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
13518 perror("talloc fail\n");
13521 if (strcmp(d, dst[i]) != 0) {
13523 "canonicalize mismatch %s -> %s != %s",
13524 src[i], d, dst[i]);
13532 static bool run_ign_bad_negprot(int dummy)
13534 struct tevent_context *ev;
13535 struct tevent_req *req;
13536 struct smbXcli_conn *conn;
13537 struct sockaddr_storage ss;
13542 printf("starting ignore bad negprot\n");
13544 ok = resolve_name(host, &ss, 0x20, true);
13546 d_fprintf(stderr, "Could not resolve name %s\n", host);
13550 status = open_socket_out(&ss, 445, 10000, &fd);
13551 if (!NT_STATUS_IS_OK(status)) {
13552 d_fprintf(stderr, "open_socket_out failed: %s\n",
13553 nt_errstr(status));
13557 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
13559 if (conn == NULL) {
13560 d_fprintf(stderr, "smbXcli_conn_create failed\n");
13564 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
13565 if (NT_STATUS_IS_OK(status)) {
13566 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
13570 ev = samba_tevent_context_init(talloc_tos());
13572 d_fprintf(stderr, "samba_tevent_context_init failed\n");
13576 req = smb1cli_session_setup_nt1_send(
13577 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
13578 data_blob_null, data_blob_null, 0x40,
13579 "Windows 2000 2195", "Windows 2000 5.0");
13581 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
13585 ok = tevent_req_poll_ntstatus(req, ev, &status);
13587 d_fprintf(stderr, "tevent_req_poll failed\n");
13591 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
13593 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
13594 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
13595 "%s, expected NT_STATUS_CONNECTION_RESET\n",
13596 nt_errstr(status));
13602 printf("starting ignore bad negprot\n");
13607 static double create_procs(bool (*fn)(int), bool *result)
13610 volatile pid_t *child_status;
13611 volatile bool *child_status_out;
13614 struct timeval start;
13618 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
13619 if (!child_status) {
13620 printf("Failed to setup shared memory\n");
13624 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
13625 if (!child_status_out) {
13626 printf("Failed to setup result status shared memory\n");
13630 for (i = 0; i < torture_nprocs; i++) {
13631 child_status[i] = 0;
13632 child_status_out[i] = True;
13635 start = timeval_current();
13637 for (i=0;i<torture_nprocs;i++) {
13640 pid_t mypid = getpid();
13641 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
13643 slprintf(myname,sizeof(myname),"CLIENT%d", i);
13646 if (torture_open_connection(¤t_cli, i)) break;
13647 if (tries-- == 0) {
13648 printf("pid %d failed to start\n", (int)getpid());
13654 child_status[i] = getpid();
13656 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
13658 child_status_out[i] = fn(i);
13665 for (i=0;i<torture_nprocs;i++) {
13666 if (child_status[i]) synccount++;
13668 if (synccount == torture_nprocs) break;
13670 } while (timeval_elapsed(&start) < 30);
13672 if (synccount != torture_nprocs) {
13673 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
13675 return timeval_elapsed(&start);
13678 /* start the client load */
13679 start = timeval_current();
13681 for (i=0;i<torture_nprocs;i++) {
13682 child_status[i] = 0;
13685 printf("%d clients started\n", torture_nprocs);
13687 for (i=0;i<torture_nprocs;i++) {
13688 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
13693 for (i=0;i<torture_nprocs;i++) {
13694 if (!child_status_out[i]) {
13698 return timeval_elapsed(&start);
13701 #define FLAG_MULTIPROC 1
13707 } torture_ops[] = {
13710 .fn = run_fdpasstest,
13714 .fn = run_locktest1,
13718 .fn = run_locktest2,
13722 .fn = run_locktest3,
13726 .fn = run_locktest4,
13730 .fn = run_locktest5,
13734 .fn = run_locktest6,
13738 .fn = run_locktest7,
13742 .fn = run_locktest8,
13746 .fn = run_locktest9,
13750 .fn = run_locktest10,
13754 .fn = run_locktest11,
13758 .fn = run_locktest12,
13762 .fn = run_locktest13,
13766 .fn = run_unlinktest,
13770 .fn = run_browsetest,
13774 .fn = run_attrtest,
13778 .fn = run_trans2test,
13782 .fn = run_maxfidtest,
13783 .flags = FLAG_MULTIPROC,
13788 .flags = FLAG_MULTIPROC,
13791 .name = "RANDOMIPC",
13792 .fn = run_randomipc,
13795 .name = "NEGNOWAIT",
13796 .fn = run_negprot_nowait,
13828 .fn = run_dirtest1,
13831 .name = "DIR-CREATETIME",
13832 .fn = run_dir_createtime,
13836 .fn = torture_denytest1,
13840 .fn = torture_denytest2,
13844 .fn = run_tcon_test,
13848 .fn = run_tcon_devtype_test,
13852 .fn = run_readwritetest,
13856 .fn = run_readwritemulti,
13857 .flags = FLAG_MULTIPROC
13861 .fn = run_readwritelarge,
13864 .name = "RW-SIGNING",
13865 .fn = run_readwritelarge_signtest,
13869 .fn = run_opentest,
13873 .fn = run_simple_posix_open_test,
13876 .name = "POSIX-APPEND",
13877 .fn = run_posix_append,
13880 .name = "POSIX-SYMLINK-ACL",
13881 .fn = run_acl_symlink_test,
13884 .name = "POSIX-SYMLINK-EA",
13885 .fn = run_ea_symlink_test,
13888 .name = "POSIX-STREAM-DELETE",
13889 .fn = run_posix_stream_delete,
13892 .name = "POSIX-OFD-LOCK",
13893 .fn = run_posix_ofd_lock_test,
13896 .name = "POSIX-BLOCKING-LOCK",
13897 .fn = run_posix_blocking_lock,
13900 .name = "POSIX-MKDIR",
13901 .fn = run_posix_mkdir_test,
13904 .name = "POSIX-ACL-OPLOCK",
13905 .fn = run_posix_acl_oplock_test,
13908 .name = "POSIX-ACL-SHAREROOT",
13909 .fn = run_posix_acl_shareroot_test,
13912 .name = "WINDOWS-BAD-SYMLINK",
13913 .fn = run_symlink_open_test,
13916 .name = "CASE-INSENSITIVE-CREATE",
13917 .fn = run_case_insensitive_create,
13920 .name = "ASYNC-ECHO",
13921 .fn = run_async_echo,
13924 .name = "UID-REGRESSION-TEST",
13925 .fn = run_uid_regression_test,
13928 .name = "SHORTNAME-TEST",
13929 .fn = run_shortname_test,
13932 .name = "ADDRCHANGE",
13933 .fn = run_addrchange,
13937 .name = "OPENATTR",
13938 .fn = run_openattrtest,
13950 .name = "RENAME-ACCESS",
13951 .fn = run_rename_access,
13954 .name = "OWNER-RIGHTS",
13955 .fn = run_owner_rights,
13959 .fn = run_deletetest,
13962 .name = "DELETE-PRINT",
13963 .fn = run_delete_print_test,
13966 .name = "WILDDELETE",
13967 .fn = run_wild_deletetest,
13970 .name = "DELETE-LN",
13971 .fn = run_deletetest_ln,
13974 .name = "PROPERTIES",
13975 .fn = run_properties,
13979 .fn = torture_mangle,
13986 .name = "MANGLE-ILLEGAL",
13987 .fn = run_mangle_illegal,
13994 .name = "TRANS2SCAN",
13995 .fn = torture_trans2_scan,
13998 .name = "NTTRANSSCAN",
13999 .fn = torture_nttrans_scan,
14003 .fn = torture_utable,
14006 .name = "CASETABLE",
14007 .fn = torture_casetable,
14010 .name = "ERRMAPEXTRACT",
14011 .fn = run_error_map_extract,
14014 .name = "PIPE_NUMBER",
14015 .fn = run_pipe_number,
14019 .fn = run_tcon2_test,
14023 .fn = torture_ioctl_test,
14027 .fn = torture_chkpath_test,
14031 .fn = run_fdsesstest,
14038 .name = "SESSSETUP_BENCH",
14039 .fn = run_sesssetup_bench,
14054 .name = "WINDOWS-WRITE",
14055 .fn = run_windows_write,
14058 .name = "LARGE_READX",
14059 .fn = run_large_readx,
14062 .name = "NTTRANS-CREATE",
14063 .fn = run_nttrans_create,
14066 .name = "NTTRANS-FSCTL",
14067 .fn = run_nttrans_fsctl,
14070 .name = "CLI_ECHO",
14071 .fn = run_cli_echo,
14074 .name = "CLI_SPLICE",
14075 .fn = run_cli_splice,
14082 .name = "STREAMERROR",
14083 .fn = run_streamerror,
14086 .name = "NOTIFY-BENCH",
14087 .fn = run_notify_bench,
14090 .name = "NOTIFY-BENCH2",
14091 .fn = run_notify_bench2,
14094 .name = "NOTIFY-BENCH3",
14095 .fn = run_notify_bench3,
14098 .name = "BAD-NBT-SESSION",
14099 .fn = run_bad_nbt_session,
14102 .name = "IGN-BAD-NEGPROT",
14103 .fn = run_ign_bad_negprot,
14106 .name = "SMB-ANY-CONNECT",
14107 .fn = run_smb_any_connect,
14110 .name = "NOTIFY-ONLINE",
14111 .fn = run_notify_online,
14114 .name = "SMB2-BASIC",
14115 .fn = run_smb2_basic,
14118 .name = "SMB2-NEGPROT",
14119 .fn = run_smb2_negprot,
14122 .name = "SMB2-ANONYMOUS",
14123 .fn = run_smb2_anonymous,
14126 .name = "SMB2-SESSION-RECONNECT",
14127 .fn = run_smb2_session_reconnect,
14130 .name = "SMB2-TCON-DEPENDENCE",
14131 .fn = run_smb2_tcon_dependence,
14134 .name = "SMB2-MULTI-CHANNEL",
14135 .fn = run_smb2_multi_channel,
14138 .name = "SMB2-SESSION-REAUTH",
14139 .fn = run_smb2_session_reauth,
14142 .name = "SMB2-FTRUNCATE",
14143 .fn = run_smb2_ftruncate,
14146 .name = "SMB2-DIR-FSYNC",
14147 .fn = run_smb2_dir_fsync,
14150 .name = "CLEANUP1",
14151 .fn = run_cleanup1,
14154 .name = "CLEANUP2",
14155 .fn = run_cleanup2,
14158 .name = "CLEANUP3",
14159 .fn = run_cleanup3,
14162 .name = "CLEANUP4",
14163 .fn = run_cleanup4,
14166 .name = "OPLOCK-CANCEL",
14167 .fn = run_oplock_cancel,
14174 .name = "LOCAL-SUBSTITUTE",
14175 .fn = run_local_substitute,
14178 .name = "LOCAL-GENCACHE",
14179 .fn = run_local_gencache,
14182 .name = "LOCAL-DBWRAP-WATCH1",
14183 .fn = run_dbwrap_watch1,
14186 .name = "LOCAL-DBWRAP-WATCH2",
14187 .fn = run_dbwrap_watch2,
14190 .name = "LOCAL-DBWRAP-DO-LOCKED1",
14191 .fn = run_dbwrap_do_locked1,
14194 .name = "LOCAL-MESSAGING-READ1",
14195 .fn = run_messaging_read1,
14198 .name = "LOCAL-MESSAGING-READ2",
14199 .fn = run_messaging_read2,
14202 .name = "LOCAL-MESSAGING-READ3",
14203 .fn = run_messaging_read3,
14206 .name = "LOCAL-MESSAGING-READ4",
14207 .fn = run_messaging_read4,
14210 .name = "LOCAL-MESSAGING-FDPASS1",
14211 .fn = run_messaging_fdpass1,
14214 .name = "LOCAL-MESSAGING-FDPASS2",
14215 .fn = run_messaging_fdpass2,
14218 .name = "LOCAL-MESSAGING-FDPASS2a",
14219 .fn = run_messaging_fdpass2a,
14222 .name = "LOCAL-MESSAGING-FDPASS2b",
14223 .fn = run_messaging_fdpass2b,
14226 .name = "LOCAL-MESSAGING-SEND-ALL",
14227 .fn = run_messaging_send_all,
14230 .name = "LOCAL-BASE64",
14231 .fn = run_local_base64,
14234 .name = "LOCAL-RBTREE",
14235 .fn = run_local_rbtree,
14238 .name = "LOCAL-MEMCACHE",
14239 .fn = run_local_memcache,
14242 .name = "LOCAL-STREAM-NAME",
14243 .fn = run_local_stream_name,
14246 .name = "WBCLIENT-MULTI-PING",
14247 .fn = run_wbclient_multi_ping,
14250 .name = "LOCAL-string_to_sid",
14251 .fn = run_local_string_to_sid,
14254 .name = "LOCAL-sid_to_string",
14255 .fn = run_local_sid_to_string,
14258 .name = "LOCAL-binary_to_sid",
14259 .fn = run_local_binary_to_sid,
14262 .name = "LOCAL-DBTRANS",
14263 .fn = run_local_dbtrans,
14266 .name = "LOCAL-TEVENT-POLL",
14267 .fn = run_local_tevent_poll,
14270 .name = "LOCAL-CONVERT-STRING",
14271 .fn = run_local_convert_string,
14274 .name = "LOCAL-CONV-AUTH-INFO",
14275 .fn = run_local_conv_auth_info,
14278 .name = "LOCAL-hex_encode_buf",
14279 .fn = run_local_hex_encode_buf,
14282 .name = "LOCAL-IDMAP-TDB-COMMON",
14283 .fn = run_idmap_tdb_common_test,
14286 .name = "LOCAL-remove_duplicate_addrs2",
14287 .fn = run_local_remove_duplicate_addrs2,
14290 .name = "local-tdb-opener",
14291 .fn = run_local_tdb_opener,
14294 .name = "local-tdb-writer",
14295 .fn = run_local_tdb_writer,
14298 .name = "LOCAL-DBWRAP-CTDB",
14299 .fn = run_local_dbwrap_ctdb,
14302 .name = "LOCAL-BENCH-PTHREADPOOL",
14303 .fn = run_bench_pthreadpool,
14306 .name = "LOCAL-PTHREADPOOL-TEVENT",
14307 .fn = run_pthreadpool_tevent,
14310 .name = "LOCAL-G-LOCK1",
14314 .name = "LOCAL-G-LOCK2",
14318 .name = "LOCAL-G-LOCK3",
14322 .name = "LOCAL-G-LOCK4",
14326 .name = "LOCAL-G-LOCK5",
14330 .name = "LOCAL-G-LOCK6",
14334 .name = "LOCAL-G-LOCK-PING-PONG",
14335 .fn = run_g_lock_ping_pong,
14338 .name = "LOCAL-CANONICALIZE-PATH",
14339 .fn = run_local_canonicalize_path,
14342 .name = "LOCAL-NAMEMAP-CACHE1",
14343 .fn = run_local_namemap_cache1,
14346 .name = "LOCAL-IDMAP-CACHE1",
14347 .fn = run_local_idmap_cache1,
14350 .name = "qpathinfo-bufsize",
14351 .fn = run_qpathinfo_bufsize,
14354 .name = "hide-new-files-timeout",
14355 .fn = run_hidenewfiles,
14362 /****************************************************************************
14363 run a specified test or "ALL"
14364 ****************************************************************************/
14365 static bool run_test(const char *name)
14368 bool result = True;
14369 bool found = False;
14372 if (strequal(name,"ALL")) {
14373 for (i=0;torture_ops[i].name;i++) {
14374 run_test(torture_ops[i].name);
14379 for (i=0;torture_ops[i].name;i++) {
14380 fstr_sprintf(randomfname, "\\XX%x",
14381 (unsigned)random());
14383 if (strequal(name, torture_ops[i].name)) {
14385 printf("Running %s\n", name);
14386 if (torture_ops[i].flags & FLAG_MULTIPROC) {
14387 t = create_procs(torture_ops[i].fn, &result);
14390 printf("TEST %s FAILED!\n", name);
14393 struct timeval start;
14394 start = timeval_current();
14395 if (!torture_ops[i].fn(0)) {
14397 printf("TEST %s FAILED!\n", name);
14399 t = timeval_elapsed(&start);
14401 printf("%s took %g secs\n\n", name, t);
14406 printf("Did not find a test named %s\n", name);
14414 static void usage(void)
14418 printf("WARNING samba4 test suite is much more complete nowadays.\n");
14419 printf("Please use samba4 torture.\n\n");
14421 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
14423 printf("\t-d debuglevel\n");
14424 printf("\t-U user%%pass\n");
14425 printf("\t-k use kerberos\n");
14426 printf("\t-N numprocs\n");
14427 printf("\t-n my_netbios_name\n");
14428 printf("\t-W workgroup\n");
14429 printf("\t-o num_operations\n");
14430 printf("\t-O socket_options\n");
14431 printf("\t-m maximum protocol\n");
14432 printf("\t-L use oplocks\n");
14433 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
14434 printf("\t-A showall\n");
14435 printf("\t-p port\n");
14436 printf("\t-s seed\n");
14437 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
14438 printf("\t-f filename filename to test\n");
14439 printf("\t-e encrypt\n");
14442 printf("tests are:");
14443 for (i=0;torture_ops[i].name;i++) {
14444 printf(" %s", torture_ops[i].name);
14448 printf("default test is ALL\n");
14453 /****************************************************************************
14455 ****************************************************************************/
14456 int main(int argc,char *argv[])
14462 bool correct = True;
14463 TALLOC_CTX *frame = talloc_stackframe();
14464 int seed = time(NULL);
14466 #ifdef HAVE_SETBUFFER
14467 setbuffer(stdout, NULL, 0);
14470 setup_logging("smbtorture", DEBUG_STDOUT);
14475 if (is_default_dyn_CONFIGFILE()) {
14476 if(getenv("SMB_CONF_PATH")) {
14477 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
14480 lp_load_global(get_dyn_CONFIGFILE());
14487 for(p = argv[1]; *p; p++)
14491 if (strncmp(argv[1], "//", 2)) {
14495 fstrcpy(host, &argv[1][2]);
14496 p = strchr_m(&host[2],'/');
14501 fstrcpy(share, p+1);
14503 fstrcpy(myname, get_myname(talloc_tos()));
14505 fprintf(stderr, "Failed to get my hostname.\n");
14509 if (*username == 0 && getenv("LOGNAME")) {
14510 fstrcpy(username,getenv("LOGNAME"));
14516 fstrcpy(workgroup, lp_workgroup());
14518 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
14522 port_to_use = atoi(optarg);
14525 seed = atoi(optarg);
14528 fstrcpy(workgroup,optarg);
14531 lp_set_cmdline("client max protocol", optarg);
14534 torture_nprocs = atoi(optarg);
14537 torture_numops = atoi(optarg);
14540 lp_set_cmdline("log level", optarg);
14546 use_oplocks = True;
14549 local_path = optarg;
14552 torture_showall = True;
14555 fstrcpy(myname, optarg);
14558 client_txt = optarg;
14565 use_kerberos = True;
14567 d_printf("No kerberos support compiled in\n");
14573 fstrcpy(username,optarg);
14574 p = strchr_m(username,'%');
14577 fstrcpy(password, p+1);
14582 fstrcpy(multishare_conn_fname, optarg);
14583 use_multishare_conn = True;
14586 torture_blocksize = atoi(optarg);
14589 test_filename = SMB_STRDUP(optarg);
14592 printf("Unknown option %c (%d)\n", (char)opt, opt);
14597 d_printf("using seed %d\n", seed);
14601 if(use_kerberos && !gotuser) gotpass = True;
14604 char pwd[256] = {0};
14607 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
14609 fstrcpy(password, pwd);
14614 printf("host=%s share=%s user=%s myname=%s\n",
14615 host, share, username, myname);
14617 torture_creds = cli_session_creds_init(frame,
14623 false, /* fallback_after_kerberos */
14624 false, /* use_ccache */
14625 false); /* password_is_nt_hash */
14626 if (torture_creds == NULL) {
14627 d_printf("cli_session_creds_init() failed.\n");
14631 if (argc == optind) {
14632 correct = run_test("ALL");
14634 for (i=optind;i<argc;i++) {
14635 if (!run_test(argv[i])) {
14641 TALLOC_FREE(frame);