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"
51 fstring host, workgroup, share, password, username, myname;
52 struct cli_credentials *torture_creds;
53 static const char *sockops="TCP_NODELAY";
55 static int port_to_use=0;
56 int torture_numops=100;
57 int torture_blocksize=1024*1024;
58 static int procnum; /* records process count number when forking */
59 static struct cli_state *current_cli;
60 static fstring randomfname;
61 static bool use_oplocks;
62 static bool use_level_II_oplocks;
63 static const char *client_txt = "client_oplocks.txt";
64 static bool disable_spnego;
65 static bool use_kerberos;
66 static bool force_dos_errors;
67 static fstring multishare_conn_fname;
68 static bool use_multishare_conn = False;
69 static bool do_encrypt;
70 static const char *local_path = NULL;
71 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
74 bool torture_showall = False;
76 static double create_procs(bool (*fn)(int), bool *result);
78 /********************************************************************
79 Ensure a connection is encrypted.
80 ********************************************************************/
82 static bool force_cli_encryption(struct cli_state *c,
83 const char *sharename)
85 uint16_t major, minor;
86 uint32_t caplow, caphigh;
89 if (!SERVER_HAS_UNIX_CIFS(c)) {
90 d_printf("Encryption required and "
91 "server that doesn't support "
92 "UNIX extensions - failing connect\n");
96 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
98 if (!NT_STATUS_IS_OK(status)) {
99 d_printf("Encryption required and "
100 "can't get UNIX CIFS extensions "
101 "version from server: %s\n", nt_errstr(status));
105 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
106 d_printf("Encryption required and "
107 "share %s doesn't support "
108 "encryption.\n", sharename);
112 status = cli_smb1_setup_encryption(c, torture_creds);
113 if (!NT_STATUS_IS_OK(status)) {
114 d_printf("Encryption required and "
115 "setup failed with error %s.\n",
124 static struct cli_state *open_nbt_connection(void)
130 if (disable_spnego) {
131 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
135 flags |= CLI_FULL_CONNECTION_OPLOCKS;
138 if (use_level_II_oplocks) {
139 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
143 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
146 if (force_dos_errors) {
147 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
150 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
151 signing_state, flags, &c);
152 if (!NT_STATUS_IS_OK(status)) {
153 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
157 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
162 /****************************************************************************
163 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
164 ****************************************************************************/
166 static bool cli_bad_session_request(int fd,
167 struct nmb_name *calling, struct nmb_name *called)
176 uint8_t message_type;
178 struct tevent_context *ev;
179 struct tevent_req *req;
181 frame = talloc_stackframe();
183 iov[0].iov_base = len_buf;
184 iov[0].iov_len = sizeof(len_buf);
186 /* put in the destination name */
188 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
190 if (iov[1].iov_base == NULL) {
193 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
194 talloc_get_size(iov[1].iov_base));
198 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
200 if (iov[2].iov_base == NULL) {
203 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
204 talloc_get_size(iov[2].iov_base));
206 /* Deliberately corrupt the name len (first byte) */
207 *((uint8_t *)iov[2].iov_base) = 100;
209 /* send a session request (RFC 1002) */
210 /* setup the packet length
211 * Remove four bytes from the length count, since the length
212 * field in the NBT Session Service header counts the number
213 * of bytes which follow. The cli_send_smb() function knows
214 * about this and accounts for those four bytes.
218 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
219 SCVAL(len_buf,0,0x81);
221 len = write_data_iov(fd, iov, 3);
226 ev = samba_tevent_context_init(frame);
230 req = read_smb_send(frame, ev, fd);
234 if (!tevent_req_poll(req, ev)) {
237 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
244 message_type = CVAL(inbuf, 0);
245 if (message_type != 0x83) {
246 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
251 if (smb_len(inbuf) != 1) {
252 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
253 (int)smb_len(inbuf));
257 error = CVAL(inbuf, 4);
259 d_fprintf(stderr, "Expected error 0x82, got %d\n",
270 /* Insert a NULL at the first separator of the given path and return a pointer
271 * to the remainder of the string.
274 terminate_path_at_separator(char * path)
282 if ((p = strchr_m(path, '/'))) {
287 if ((p = strchr_m(path, '\\'))) {
297 parse a //server/share type UNC name
299 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
300 char **hostname, char **sharename)
304 *hostname = *sharename = NULL;
306 if (strncmp(unc_name, "\\\\", 2) &&
307 strncmp(unc_name, "//", 2)) {
311 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
312 p = terminate_path_at_separator(*hostname);
315 *sharename = talloc_strdup(mem_ctx, p);
316 terminate_path_at_separator(*sharename);
319 if (*hostname && *sharename) {
323 TALLOC_FREE(*hostname);
324 TALLOC_FREE(*sharename);
328 static bool torture_open_connection_share(struct cli_state **c,
329 const char *hostname,
330 const char *sharename,
335 status = cli_full_connection_creds(c,
345 if (!NT_STATUS_IS_OK(status)) {
346 printf("failed to open share connection: //%s/%s port:%d - %s\n",
347 hostname, sharename, port_to_use, nt_errstr(status));
351 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
354 return force_cli_encryption(*c,
360 bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
362 char **unc_list = NULL;
363 int num_unc_names = 0;
366 if (use_multishare_conn==True) {
368 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
369 if (!unc_list || num_unc_names <= 0) {
370 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
374 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
376 printf("Failed to parse UNC name %s\n",
377 unc_list[conn_index % num_unc_names]);
378 TALLOC_FREE(unc_list);
382 result = torture_open_connection_share(c, h, s, flags);
384 /* h, s were copied earlier */
385 TALLOC_FREE(unc_list);
389 return torture_open_connection_share(c, host, share, flags);
392 bool torture_open_connection(struct cli_state **c, int conn_index)
394 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
397 flags |= CLI_FULL_CONNECTION_OPLOCKS;
399 if (use_level_II_oplocks) {
400 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
403 return torture_open_connection_flags(c, conn_index, flags);
406 bool torture_init_connection(struct cli_state **pcli)
408 struct cli_state *cli;
410 cli = open_nbt_connection();
419 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
421 uint16_t old_vuid = cli_state_get_uid(cli);
425 cli_state_set_uid(cli, 0);
426 status = cli_session_setup_creds(cli, torture_creds);
427 ret = NT_STATUS_IS_OK(status);
428 *new_vuid = cli_state_get_uid(cli);
429 cli_state_set_uid(cli, old_vuid);
434 bool torture_close_connection(struct cli_state *c)
439 status = cli_tdis(c);
440 if (!NT_STATUS_IS_OK(status)) {
441 printf("tdis failed (%s)\n", nt_errstr(status));
451 /* check if the server produced the expected dos or nt error code */
452 static bool check_both_error(int line, NTSTATUS status,
453 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
455 if (NT_STATUS_IS_DOS(status)) {
459 /* Check DOS error */
460 cclass = NT_STATUS_DOS_CLASS(status);
461 num = NT_STATUS_DOS_CODE(status);
463 if (eclass != cclass || ecode != num) {
464 printf("unexpected error code class=%d code=%d\n",
465 (int)cclass, (int)num);
466 printf(" expected %d/%d %s (line=%d)\n",
467 (int)eclass, (int)ecode, nt_errstr(nterr), line);
472 if (!NT_STATUS_EQUAL(nterr, status)) {
473 printf("unexpected error code %s\n",
475 printf(" expected %s (line=%d)\n",
476 nt_errstr(nterr), line);
485 /* check if the server produced the expected error code */
486 static bool check_error(int line, NTSTATUS status,
487 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
489 if (NT_STATUS_IS_DOS(status)) {
493 /* Check DOS error */
495 cclass = NT_STATUS_DOS_CLASS(status);
496 num = NT_STATUS_DOS_CODE(status);
498 if (eclass != cclass || ecode != num) {
499 printf("unexpected error code class=%d code=%d\n",
500 (int)cclass, (int)num);
501 printf(" expected %d/%d %s (line=%d)\n",
502 (int)eclass, (int)ecode, nt_errstr(nterr),
510 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
511 printf("unexpected error code %s\n",
513 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
523 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
527 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
529 while (!NT_STATUS_IS_OK(status)) {
530 if (!check_both_error(__LINE__, status, ERRDOS,
531 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
535 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
542 static bool rw_torture(struct cli_state *c)
544 const char *lockfname = "\\torture.lck";
548 pid_t pid2, pid = getpid();
555 memset(buf, '\0', sizeof(buf));
557 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
559 if (!NT_STATUS_IS_OK(status)) {
560 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
562 if (!NT_STATUS_IS_OK(status)) {
563 printf("open of %s failed (%s)\n",
564 lockfname, nt_errstr(status));
568 for (i=0;i<torture_numops;i++) {
569 unsigned n = (unsigned)sys_random()%10;
572 printf("%d\r", i); fflush(stdout);
574 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
576 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
580 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
582 if (!NT_STATUS_IS_OK(status)) {
583 printf("open failed (%s)\n", nt_errstr(status));
588 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
590 if (!NT_STATUS_IS_OK(status)) {
591 printf("write failed (%s)\n", nt_errstr(status));
596 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
597 sizeof(pid)+(j*sizeof(buf)),
599 if (!NT_STATUS_IS_OK(status)) {
600 printf("write failed (%s)\n",
608 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
610 if (!NT_STATUS_IS_OK(status)) {
611 printf("read failed (%s)\n", nt_errstr(status));
613 } else if (nread != sizeof(pid)) {
614 printf("read/write compare failed: "
615 "recv %ld req %ld\n", (unsigned long)nread,
616 (unsigned long)sizeof(pid));
621 printf("data corruption!\n");
625 status = cli_close(c, fnum);
626 if (!NT_STATUS_IS_OK(status)) {
627 printf("close failed (%s)\n", nt_errstr(status));
631 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
632 if (!NT_STATUS_IS_OK(status)) {
633 printf("unlink failed (%s)\n", nt_errstr(status));
637 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
638 if (!NT_STATUS_IS_OK(status)) {
639 printf("unlock failed (%s)\n", nt_errstr(status));
645 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
652 static bool run_torture(int dummy)
654 struct cli_state *cli;
659 smbXcli_conn_set_sockopt(cli->conn, sockops);
661 ret = rw_torture(cli);
663 if (!torture_close_connection(cli)) {
670 static bool rw_torture3(struct cli_state *c, char *lockfname)
672 uint16_t fnum = (uint16_t)-1;
677 unsigned countprev = 0;
680 NTSTATUS status = NT_STATUS_OK;
683 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
685 SIVAL(buf, i, sys_random());
692 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
693 if (!NT_STATUS_IS_OK(status)) {
694 printf("unlink failed (%s) (normal, this file should "
695 "not exist)\n", nt_errstr(status));
698 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
700 if (!NT_STATUS_IS_OK(status)) {
701 printf("first open read/write of %s failed (%s)\n",
702 lockfname, nt_errstr(status));
708 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
710 status = cli_openx(c, lockfname, O_RDONLY,
712 if (NT_STATUS_IS_OK(status)) {
717 if (!NT_STATUS_IS_OK(status)) {
718 printf("second open read-only of %s failed (%s)\n",
719 lockfname, nt_errstr(status));
725 for (count = 0; count < sizeof(buf); count += sent)
727 if (count >= countprev) {
728 printf("%d %8d\r", i, count);
731 countprev += (sizeof(buf) / 20);
736 sent = ((unsigned)sys_random()%(20))+ 1;
737 if (sent > sizeof(buf) - count)
739 sent = sizeof(buf) - count;
742 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
744 if (!NT_STATUS_IS_OK(status)) {
745 printf("write failed (%s)\n",
752 status = cli_read(c, fnum, buf_rd+count, count,
753 sizeof(buf)-count, &sent);
754 if(!NT_STATUS_IS_OK(status)) {
755 printf("read failed offset:%d size:%ld (%s)\n",
756 count, (unsigned long)sizeof(buf)-count,
760 } else if (sent > 0) {
761 if (memcmp(buf_rd+count, buf+count, sent) != 0)
763 printf("read/write compare failed\n");
764 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
773 status = cli_close(c, fnum);
774 if (!NT_STATUS_IS_OK(status)) {
775 printf("close failed (%s)\n", nt_errstr(status));
782 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
784 const char *lockfname = "\\torture2.lck";
794 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
795 if (!NT_STATUS_IS_OK(status)) {
796 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
799 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
801 if (!NT_STATUS_IS_OK(status)) {
802 printf("first open read/write of %s failed (%s)\n",
803 lockfname, nt_errstr(status));
807 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
808 if (!NT_STATUS_IS_OK(status)) {
809 printf("second open read-only of %s failed (%s)\n",
810 lockfname, nt_errstr(status));
811 cli_close(c1, fnum1);
815 for (i = 0; i < torture_numops; i++)
817 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
819 printf("%d\r", i); fflush(stdout);
822 generate_random_buffer((unsigned char *)buf, buf_size);
824 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
826 if (!NT_STATUS_IS_OK(status)) {
827 printf("write failed (%s)\n", nt_errstr(status));
832 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
833 if(!NT_STATUS_IS_OK(status)) {
834 printf("read failed (%s)\n", nt_errstr(status));
837 } else if (bytes_read != buf_size) {
838 printf("read failed\n");
839 printf("read %ld, expected %ld\n",
840 (unsigned long)bytes_read,
841 (unsigned long)buf_size);
846 if (memcmp(buf_rd, buf, buf_size) != 0)
848 printf("read/write compare failed\n");
854 status = cli_close(c2, fnum2);
855 if (!NT_STATUS_IS_OK(status)) {
856 printf("close failed (%s)\n", nt_errstr(status));
860 status = cli_close(c1, fnum1);
861 if (!NT_STATUS_IS_OK(status)) {
862 printf("close failed (%s)\n", nt_errstr(status));
866 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
867 if (!NT_STATUS_IS_OK(status)) {
868 printf("unlink failed (%s)\n", nt_errstr(status));
875 static bool run_readwritetest(int dummy)
877 struct cli_state *cli1, *cli2;
878 bool test1, test2 = False;
880 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
883 smbXcli_conn_set_sockopt(cli1->conn, sockops);
884 smbXcli_conn_set_sockopt(cli2->conn, sockops);
886 printf("starting readwritetest\n");
888 test1 = rw_torture2(cli1, cli2);
889 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
892 test2 = rw_torture2(cli1, cli1);
893 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
896 if (!torture_close_connection(cli1)) {
900 if (!torture_close_connection(cli2)) {
904 return (test1 && test2);
907 static bool run_readwritemulti(int dummy)
909 struct cli_state *cli;
914 smbXcli_conn_set_sockopt(cli->conn, sockops);
916 printf("run_readwritemulti: fname %s\n", randomfname);
917 test = rw_torture3(cli, randomfname);
919 if (!torture_close_connection(cli)) {
926 static bool run_readwritelarge_internal(void)
928 static struct cli_state *cli1;
930 const char *lockfname = "\\large.dat";
936 if (!torture_open_connection(&cli1, 0)) {
939 smbXcli_conn_set_sockopt(cli1->conn, sockops);
940 memset(buf,'\0',sizeof(buf));
942 printf("starting readwritelarge_internal\n");
944 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
946 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
948 if (!NT_STATUS_IS_OK(status)) {
949 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
953 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
955 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
957 if (!NT_STATUS_IS_OK(status)) {
958 printf("qfileinfo failed (%s)\n", nt_errstr(status));
962 if (fsize == sizeof(buf))
963 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
964 (unsigned long)fsize);
966 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
967 (unsigned long)fsize);
971 status = cli_close(cli1, fnum1);
972 if (!NT_STATUS_IS_OK(status)) {
973 printf("close failed (%s)\n", nt_errstr(status));
977 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
978 if (!NT_STATUS_IS_OK(status)) {
979 printf("unlink failed (%s)\n", nt_errstr(status));
983 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
985 if (!NT_STATUS_IS_OK(status)) {
986 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
990 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
992 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
994 if (!NT_STATUS_IS_OK(status)) {
995 printf("qfileinfo failed (%s)\n", nt_errstr(status));
999 if (fsize == sizeof(buf))
1000 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1001 (unsigned long)fsize);
1003 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1004 (unsigned long)fsize);
1009 /* ToDo - set allocation. JRA */
1010 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1011 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1014 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1016 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1020 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1023 status = cli_close(cli1, fnum1);
1024 if (!NT_STATUS_IS_OK(status)) {
1025 printf("close failed (%s)\n", nt_errstr(status));
1029 if (!torture_close_connection(cli1)) {
1035 static bool run_readwritelarge(int dummy)
1037 return run_readwritelarge_internal();
1040 static bool run_readwritelarge_signtest(int dummy)
1043 signing_state = SMB_SIGNING_REQUIRED;
1044 ret = run_readwritelarge_internal();
1045 signing_state = SMB_SIGNING_DEFAULT;
1052 #define ival(s) strtol(s, NULL, 0)
1054 /* run a test that simulates an approximate netbench client load */
1055 static bool run_netbench(int client)
1057 struct cli_state *cli;
1062 const char *params[20];
1063 bool correct = True;
1069 smbXcli_conn_set_sockopt(cli->conn, sockops);
1073 slprintf(cname,sizeof(cname)-1, "client%d", client);
1075 f = fopen(client_txt, "r");
1082 while (fgets(line, sizeof(line)-1, f)) {
1086 line[strlen(line)-1] = 0;
1088 /* printf("[%d] %s\n", line_count, line); */
1090 all_string_sub(line,"client1", cname, sizeof(line));
1092 /* parse the command parameters */
1093 params[0] = strtok_r(line, " ", &saveptr);
1095 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1099 if (i < 2) continue;
1101 if (!strncmp(params[0],"SMB", 3)) {
1102 printf("ERROR: You are using a dbench 1 load file\n");
1106 if (!strcmp(params[0],"NTCreateX")) {
1107 nb_createx(params[1], ival(params[2]), ival(params[3]),
1109 } else if (!strcmp(params[0],"Close")) {
1110 nb_close(ival(params[1]));
1111 } else if (!strcmp(params[0],"Rename")) {
1112 nb_rename(params[1], params[2]);
1113 } else if (!strcmp(params[0],"Unlink")) {
1114 nb_unlink(params[1]);
1115 } else if (!strcmp(params[0],"Deltree")) {
1116 nb_deltree(params[1]);
1117 } else if (!strcmp(params[0],"Rmdir")) {
1118 nb_rmdir(params[1]);
1119 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1120 nb_qpathinfo(params[1]);
1121 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1122 nb_qfileinfo(ival(params[1]));
1123 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1124 nb_qfsinfo(ival(params[1]));
1125 } else if (!strcmp(params[0],"FIND_FIRST")) {
1126 nb_findfirst(params[1]);
1127 } else if (!strcmp(params[0],"WriteX")) {
1128 nb_writex(ival(params[1]),
1129 ival(params[2]), ival(params[3]), ival(params[4]));
1130 } else if (!strcmp(params[0],"ReadX")) {
1131 nb_readx(ival(params[1]),
1132 ival(params[2]), ival(params[3]), ival(params[4]));
1133 } else if (!strcmp(params[0],"Flush")) {
1134 nb_flush(ival(params[1]));
1136 printf("Unknown operation %s\n", params[0]);
1144 if (!torture_close_connection(cli)) {
1152 /* run a test that simulates an approximate netbench client load */
1153 static bool run_nbench(int dummy)
1156 bool correct = True;
1158 nbio_shmem(torture_nprocs);
1162 signal(SIGALRM, nb_alarm);
1164 t = create_procs(run_netbench, &correct);
1167 printf("\nThroughput %g MB/sec\n",
1168 1.0e-6 * nbio_total() / t);
1174 This test checks for two things:
1176 1) correct support for retaining locks over a close (ie. the server
1177 must not use posix semantics)
1178 2) support for lock timeouts
1180 static bool run_locktest1(int dummy)
1182 struct cli_state *cli1, *cli2;
1183 const char *fname = "\\lockt1.lck";
1184 uint16_t fnum1, fnum2, fnum3;
1186 unsigned lock_timeout;
1189 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1192 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1193 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1195 printf("starting locktest1\n");
1197 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1199 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1201 if (!NT_STATUS_IS_OK(status)) {
1202 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1206 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1207 if (!NT_STATUS_IS_OK(status)) {
1208 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1212 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1213 if (!NT_STATUS_IS_OK(status)) {
1214 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1218 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1219 if (!NT_STATUS_IS_OK(status)) {
1220 printf("lock1 failed (%s)\n", nt_errstr(status));
1224 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1225 if (NT_STATUS_IS_OK(status)) {
1226 printf("lock2 succeeded! This is a locking bug\n");
1229 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1230 NT_STATUS_LOCK_NOT_GRANTED)) {
1235 lock_timeout = (1 + (random() % 20));
1236 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1238 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1239 if (NT_STATUS_IS_OK(status)) {
1240 printf("lock3 succeeded! This is a locking bug\n");
1243 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1244 NT_STATUS_FILE_LOCK_CONFLICT)) {
1250 if (ABS(t2 - t1) < lock_timeout-1) {
1251 printf("error: This server appears not to support timed lock requests\n");
1254 printf("server slept for %u seconds for a %u second timeout\n",
1255 (unsigned int)(t2-t1), lock_timeout);
1257 status = cli_close(cli1, fnum2);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 printf("close1 failed (%s)\n", nt_errstr(status));
1263 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1264 if (NT_STATUS_IS_OK(status)) {
1265 printf("lock4 succeeded! This is a locking bug\n");
1268 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1269 NT_STATUS_FILE_LOCK_CONFLICT)) {
1274 status = cli_close(cli1, fnum1);
1275 if (!NT_STATUS_IS_OK(status)) {
1276 printf("close2 failed (%s)\n", nt_errstr(status));
1280 status = cli_close(cli2, fnum3);
1281 if (!NT_STATUS_IS_OK(status)) {
1282 printf("close3 failed (%s)\n", nt_errstr(status));
1286 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1287 if (!NT_STATUS_IS_OK(status)) {
1288 printf("unlink failed (%s)\n", nt_errstr(status));
1293 if (!torture_close_connection(cli1)) {
1297 if (!torture_close_connection(cli2)) {
1301 printf("Passed locktest1\n");
1306 this checks to see if a secondary tconx can use open files from an
1309 static bool run_tcon_test(int dummy)
1311 static struct cli_state *cli;
1312 const char *fname = "\\tcontest.tmp";
1314 uint32_t cnum1, cnum2, cnum3;
1315 struct smbXcli_tcon *orig_tcon = NULL;
1316 uint16_t vuid1, vuid2;
1321 memset(buf, '\0', sizeof(buf));
1323 if (!torture_open_connection(&cli, 0)) {
1326 smbXcli_conn_set_sockopt(cli->conn, sockops);
1328 printf("starting tcontest\n");
1330 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1332 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1333 if (!NT_STATUS_IS_OK(status)) {
1334 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1338 cnum1 = cli_state_get_tid(cli);
1339 vuid1 = cli_state_get_uid(cli);
1341 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1342 if (!NT_STATUS_IS_OK(status)) {
1343 printf("initial write failed (%s)", nt_errstr(status));
1347 orig_tcon = cli_state_save_tcon(cli);
1348 if (orig_tcon == NULL) {
1352 status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1353 if (!NT_STATUS_IS_OK(status)) {
1354 printf("%s refused 2nd tree connect (%s)\n", host,
1360 cnum2 = cli_state_get_tid(cli);
1361 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1362 vuid2 = cli_state_get_uid(cli) + 1;
1364 /* try a write with the wrong tid */
1365 cli_state_set_tid(cli, cnum2);
1367 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1368 if (NT_STATUS_IS_OK(status)) {
1369 printf("* server allows write with wrong TID\n");
1372 printf("server fails write with wrong TID : %s\n",
1377 /* try a write with an invalid tid */
1378 cli_state_set_tid(cli, cnum3);
1380 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1381 if (NT_STATUS_IS_OK(status)) {
1382 printf("* server allows write with invalid TID\n");
1385 printf("server fails write with invalid TID : %s\n",
1389 /* try a write with an invalid vuid */
1390 cli_state_set_uid(cli, vuid2);
1391 cli_state_set_tid(cli, cnum1);
1393 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1394 if (NT_STATUS_IS_OK(status)) {
1395 printf("* server allows write with invalid VUID\n");
1398 printf("server fails write with invalid VUID : %s\n",
1402 cli_state_set_tid(cli, cnum1);
1403 cli_state_set_uid(cli, vuid1);
1405 status = cli_close(cli, fnum1);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 printf("close failed (%s)\n", nt_errstr(status));
1411 cli_state_set_tid(cli, cnum2);
1413 status = cli_tdis(cli);
1414 if (!NT_STATUS_IS_OK(status)) {
1415 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1419 cli_state_restore_tcon(cli, orig_tcon);
1421 cli_state_set_tid(cli, cnum1);
1423 if (!torture_close_connection(cli)) {
1432 checks for old style tcon support
1434 static bool run_tcon2_test(int dummy)
1436 static struct cli_state *cli;
1437 uint16_t cnum, max_xmit;
1441 if (!torture_open_connection(&cli, 0)) {
1444 smbXcli_conn_set_sockopt(cli->conn, sockops);
1446 printf("starting tcon2 test\n");
1448 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1452 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1456 if (!NT_STATUS_IS_OK(status)) {
1457 printf("tcon2 failed : %s\n", nt_errstr(status));
1459 printf("tcon OK : max_xmit=%d cnum=%d\n",
1460 (int)max_xmit, (int)cnum);
1463 if (!torture_close_connection(cli)) {
1467 printf("Passed tcon2 test\n");
1471 static bool tcon_devtest(struct cli_state *cli,
1472 const char *myshare, const char *devtype,
1473 const char *return_devtype,
1474 NTSTATUS expected_error)
1479 status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
1481 if (NT_STATUS_IS_OK(expected_error)) {
1482 if (NT_STATUS_IS_OK(status)) {
1483 if (return_devtype != NULL &&
1484 strequal(cli->dev, return_devtype)) {
1487 printf("tconX to share %s with type %s "
1488 "succeeded but returned the wrong "
1489 "device type (got [%s] but should have got [%s])\n",
1490 myshare, devtype, cli->dev, return_devtype);
1494 printf("tconX to share %s with type %s "
1495 "should have succeeded but failed\n",
1501 if (NT_STATUS_IS_OK(status)) {
1502 printf("tconx to share %s with type %s "
1503 "should have failed but succeeded\n",
1507 if (NT_STATUS_EQUAL(status, expected_error)) {
1510 printf("Returned unexpected error\n");
1519 checks for correct tconX support
1521 static bool run_tcon_devtype_test(int dummy)
1523 static struct cli_state *cli1 = NULL;
1524 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
1528 status = cli_full_connection_creds(&cli1,
1534 NULL, /* service_type */
1539 if (!NT_STATUS_IS_OK(status)) {
1540 printf("could not open connection\n");
1544 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1547 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1550 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1553 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1556 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1559 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1562 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1565 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1568 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1571 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1577 printf("Passed tcondevtest\n");
1584 This test checks that
1586 1) the server supports multiple locking contexts on the one SMB
1587 connection, distinguished by PID.
1589 2) the server correctly fails overlapping locks made by the same PID (this
1590 goes against POSIX behaviour, which is why it is tricky to implement)
1592 3) the server denies unlock requests by an incorrect client PID
1594 static bool run_locktest2(int dummy)
1596 static struct cli_state *cli;
1597 const char *fname = "\\lockt2.lck";
1598 uint16_t fnum1, fnum2, fnum3;
1599 bool correct = True;
1602 if (!torture_open_connection(&cli, 0)) {
1606 smbXcli_conn_set_sockopt(cli->conn, sockops);
1608 printf("starting locktest2\n");
1610 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1614 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1615 if (!NT_STATUS_IS_OK(status)) {
1616 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1620 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1621 if (!NT_STATUS_IS_OK(status)) {
1622 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1628 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1629 if (!NT_STATUS_IS_OK(status)) {
1630 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1636 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1637 if (!NT_STATUS_IS_OK(status)) {
1638 printf("lock1 failed (%s)\n", nt_errstr(status));
1642 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1643 if (NT_STATUS_IS_OK(status)) {
1644 printf("WRITE lock1 succeeded! This is a locking bug\n");
1647 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1648 NT_STATUS_LOCK_NOT_GRANTED)) {
1653 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1654 if (NT_STATUS_IS_OK(status)) {
1655 printf("WRITE lock2 succeeded! This is a locking bug\n");
1658 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1659 NT_STATUS_LOCK_NOT_GRANTED)) {
1664 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1665 if (NT_STATUS_IS_OK(status)) {
1666 printf("READ lock2 succeeded! This is a locking bug\n");
1669 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1670 NT_STATUS_FILE_LOCK_CONFLICT)) {
1675 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1676 if (!NT_STATUS_IS_OK(status)) {
1677 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1680 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1681 printf("unlock at 100 succeeded! This is a locking bug\n");
1685 status = cli_unlock(cli, fnum1, 0, 4);
1686 if (NT_STATUS_IS_OK(status)) {
1687 printf("unlock1 succeeded! This is a locking bug\n");
1690 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1691 NT_STATUS_RANGE_NOT_LOCKED)) {
1696 status = cli_unlock(cli, fnum1, 0, 8);
1697 if (NT_STATUS_IS_OK(status)) {
1698 printf("unlock2 succeeded! This is a locking bug\n");
1701 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1702 NT_STATUS_RANGE_NOT_LOCKED)) {
1707 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1708 if (NT_STATUS_IS_OK(status)) {
1709 printf("lock3 succeeded! This is a locking bug\n");
1712 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1713 NT_STATUS_LOCK_NOT_GRANTED)) {
1720 status = cli_close(cli, fnum1);
1721 if (!NT_STATUS_IS_OK(status)) {
1722 printf("close1 failed (%s)\n", nt_errstr(status));
1726 status = cli_close(cli, fnum2);
1727 if (!NT_STATUS_IS_OK(status)) {
1728 printf("close2 failed (%s)\n", nt_errstr(status));
1732 status = cli_close(cli, fnum3);
1733 if (!NT_STATUS_IS_OK(status)) {
1734 printf("close3 failed (%s)\n", nt_errstr(status));
1738 if (!torture_close_connection(cli)) {
1742 printf("locktest2 finished\n");
1749 This test checks that
1751 1) the server supports the full offset range in lock requests
1753 static bool run_locktest3(int dummy)
1755 static struct cli_state *cli1, *cli2;
1756 const char *fname = "\\lockt3.lck";
1757 uint16_t fnum1, fnum2;
1760 bool correct = True;
1763 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1765 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1768 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1769 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1771 printf("starting locktest3\n");
1773 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1775 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1777 if (!NT_STATUS_IS_OK(status)) {
1778 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1782 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1783 if (!NT_STATUS_IS_OK(status)) {
1784 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1788 for (offset=i=0;i<torture_numops;i++) {
1791 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1792 if (!NT_STATUS_IS_OK(status)) {
1793 printf("lock1 %d failed (%s)\n",
1799 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1800 if (!NT_STATUS_IS_OK(status)) {
1801 printf("lock2 %d failed (%s)\n",
1808 for (offset=i=0;i<torture_numops;i++) {
1811 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1812 if (NT_STATUS_IS_OK(status)) {
1813 printf("error: lock1 %d succeeded!\n", i);
1817 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1818 if (NT_STATUS_IS_OK(status)) {
1819 printf("error: lock2 %d succeeded!\n", i);
1823 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1824 if (NT_STATUS_IS_OK(status)) {
1825 printf("error: lock3 %d succeeded!\n", i);
1829 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1830 if (NT_STATUS_IS_OK(status)) {
1831 printf("error: lock4 %d succeeded!\n", i);
1836 for (offset=i=0;i<torture_numops;i++) {
1839 status = cli_unlock(cli1, fnum1, offset-1, 1);
1840 if (!NT_STATUS_IS_OK(status)) {
1841 printf("unlock1 %d failed (%s)\n",
1847 status = cli_unlock(cli2, fnum2, offset-2, 1);
1848 if (!NT_STATUS_IS_OK(status)) {
1849 printf("unlock2 %d failed (%s)\n",
1856 status = cli_close(cli1, fnum1);
1857 if (!NT_STATUS_IS_OK(status)) {
1858 printf("close1 failed (%s)\n", nt_errstr(status));
1862 status = cli_close(cli2, fnum2);
1863 if (!NT_STATUS_IS_OK(status)) {
1864 printf("close2 failed (%s)\n", nt_errstr(status));
1868 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1869 if (!NT_STATUS_IS_OK(status)) {
1870 printf("unlink failed (%s)\n", nt_errstr(status));
1874 if (!torture_close_connection(cli1)) {
1878 if (!torture_close_connection(cli2)) {
1882 printf("finished locktest3\n");
1887 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1888 char *buf, off_t offset, size_t size,
1889 size_t *nread, size_t expect)
1894 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1896 if(!NT_STATUS_IS_OK(status)) {
1898 } else if (l_nread != expect) {
1909 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1910 printf("** "); correct = False; \
1914 looks at overlapping locks
1916 static bool run_locktest4(int dummy)
1918 static struct cli_state *cli1, *cli2;
1919 const char *fname = "\\lockt4.lck";
1920 uint16_t fnum1, fnum2, f;
1923 bool correct = True;
1926 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1930 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1931 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1933 printf("starting locktest4\n");
1935 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1937 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1938 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1940 memset(buf, 0, sizeof(buf));
1942 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1944 if (!NT_STATUS_IS_OK(status)) {
1945 printf("Failed to create file: %s\n", nt_errstr(status));
1950 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1951 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1952 EXPECTED(ret, False);
1953 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1955 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1956 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1957 EXPECTED(ret, True);
1958 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1960 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1961 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1962 EXPECTED(ret, False);
1963 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1965 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1966 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1967 EXPECTED(ret, True);
1968 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1970 ret = (cli_setpid(cli1, 1),
1971 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1972 (cli_setpid(cli1, 2),
1973 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1974 EXPECTED(ret, False);
1975 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1977 ret = (cli_setpid(cli1, 1),
1978 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1979 (cli_setpid(cli1, 2),
1980 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1981 EXPECTED(ret, True);
1982 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1984 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1985 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1986 EXPECTED(ret, True);
1987 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1989 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1990 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1991 EXPECTED(ret, False);
1992 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1994 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1995 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1996 EXPECTED(ret, False);
1997 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1999 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
2000 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2001 EXPECTED(ret, True);
2002 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2004 ret = (cli_setpid(cli1, 1),
2005 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2006 (cli_setpid(cli1, 2),
2007 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2008 EXPECTED(ret, False);
2009 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2011 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2012 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2013 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2014 EXPECTED(ret, False);
2015 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2018 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2019 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2020 EXPECTED(ret, False);
2021 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2023 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2024 ret = NT_STATUS_IS_OK(status);
2026 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2028 ret = NT_STATUS_IS_OK(status);
2030 EXPECTED(ret, False);
2031 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2034 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2035 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2036 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2037 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2038 EXPECTED(ret, True);
2039 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2042 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2043 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2044 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2045 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2046 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2048 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2049 EXPECTED(ret, True);
2050 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2052 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2053 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2054 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2056 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2057 EXPECTED(ret, True);
2058 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2060 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2061 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2062 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2064 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2065 EXPECTED(ret, True);
2066 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2068 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2069 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2070 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2071 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2073 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2074 EXPECTED(ret, True);
2075 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2077 cli_close(cli1, fnum1);
2078 cli_close(cli2, fnum2);
2079 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2080 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2081 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2082 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2083 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2084 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2085 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2087 cli_close(cli1, fnum1);
2088 EXPECTED(ret, True);
2089 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2092 cli_close(cli1, fnum1);
2093 cli_close(cli2, fnum2);
2094 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2095 torture_close_connection(cli1);
2096 torture_close_connection(cli2);
2098 printf("finished locktest4\n");
2103 looks at lock upgrade/downgrade.
2105 static bool run_locktest5(int dummy)
2107 static struct cli_state *cli1, *cli2;
2108 const char *fname = "\\lockt5.lck";
2109 uint16_t fnum1, fnum2, fnum3;
2112 bool correct = True;
2115 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2119 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2120 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2122 printf("starting locktest5\n");
2124 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2126 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2127 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2128 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2130 memset(buf, 0, sizeof(buf));
2132 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2134 if (!NT_STATUS_IS_OK(status)) {
2135 printf("Failed to create file: %s\n", nt_errstr(status));
2140 /* Check for NT bug... */
2141 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2142 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2143 cli_close(cli1, fnum1);
2144 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2145 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2146 ret = NT_STATUS_IS_OK(status);
2147 EXPECTED(ret, True);
2148 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2149 cli_close(cli1, fnum1);
2150 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2151 cli_unlock(cli1, fnum3, 0, 1);
2153 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2154 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2155 EXPECTED(ret, True);
2156 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2158 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2159 ret = NT_STATUS_IS_OK(status);
2160 EXPECTED(ret, False);
2162 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2164 /* Unlock the process 2 lock. */
2165 cli_unlock(cli2, fnum2, 0, 4);
2167 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2168 ret = NT_STATUS_IS_OK(status);
2169 EXPECTED(ret, False);
2171 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2173 /* Unlock the process 1 fnum3 lock. */
2174 cli_unlock(cli1, fnum3, 0, 4);
2176 /* Stack 2 more locks here. */
2177 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2178 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2180 EXPECTED(ret, True);
2181 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2183 /* Unlock the first process lock, then check this was the WRITE lock that was
2186 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2187 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2189 EXPECTED(ret, True);
2190 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2192 /* Unlock the process 2 lock. */
2193 cli_unlock(cli2, fnum2, 0, 4);
2195 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2197 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2198 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2199 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2201 EXPECTED(ret, True);
2202 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2204 /* Ensure the next unlock fails. */
2205 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2206 EXPECTED(ret, False);
2207 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2209 /* Ensure connection 2 can get a write lock. */
2210 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2211 ret = NT_STATUS_IS_OK(status);
2212 EXPECTED(ret, True);
2214 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2218 cli_close(cli1, fnum1);
2219 cli_close(cli2, fnum2);
2220 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2221 if (!torture_close_connection(cli1)) {
2224 if (!torture_close_connection(cli2)) {
2228 printf("finished locktest5\n");
2234 tries the unusual lockingX locktype bits
2236 static bool run_locktest6(int dummy)
2238 static struct cli_state *cli;
2239 const char *fname[1] = { "\\lock6.txt" };
2244 if (!torture_open_connection(&cli, 0)) {
2248 smbXcli_conn_set_sockopt(cli->conn, sockops);
2250 printf("starting locktest6\n");
2253 printf("Testing %s\n", fname[i]);
2255 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2257 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2258 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2259 cli_close(cli, fnum);
2260 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2262 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2263 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2264 cli_close(cli, fnum);
2265 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2267 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2270 torture_close_connection(cli);
2272 printf("finished locktest6\n");
2276 static bool run_locktest7(int dummy)
2278 struct cli_state *cli1;
2279 const char *fname = "\\lockt7.lck";
2282 bool correct = False;
2286 if (!torture_open_connection(&cli1, 0)) {
2290 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2292 printf("starting locktest7\n");
2294 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2296 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2298 memset(buf, 0, sizeof(buf));
2300 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2302 if (!NT_STATUS_IS_OK(status)) {
2303 printf("Failed to create file: %s\n", nt_errstr(status));
2307 cli_setpid(cli1, 1);
2309 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2310 if (!NT_STATUS_IS_OK(status)) {
2311 printf("Unable to apply read lock on range 130:4, "
2312 "error was %s\n", nt_errstr(status));
2315 printf("pid1 successfully locked range 130:4 for READ\n");
2318 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2319 if (!NT_STATUS_IS_OK(status)) {
2320 printf("pid1 unable to read the range 130:4, error was %s\n",
2323 } else if (nread != 4) {
2324 printf("pid1 unable to read the range 130:4, "
2325 "recv %ld req %d\n", (unsigned long)nread, 4);
2328 printf("pid1 successfully read the range 130:4\n");
2331 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2332 if (!NT_STATUS_IS_OK(status)) {
2333 printf("pid1 unable to write to the range 130:4, error was "
2334 "%s\n", nt_errstr(status));
2335 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2336 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2340 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2344 cli_setpid(cli1, 2);
2346 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2347 if (!NT_STATUS_IS_OK(status)) {
2348 printf("pid2 unable to read the range 130:4, error was %s\n",
2351 } else if (nread != 4) {
2352 printf("pid2 unable to read the range 130:4, "
2353 "recv %ld req %d\n", (unsigned long)nread, 4);
2356 printf("pid2 successfully read the range 130:4\n");
2359 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2360 if (!NT_STATUS_IS_OK(status)) {
2361 printf("pid2 unable to write to the range 130:4, error was "
2362 "%s\n", nt_errstr(status));
2363 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2364 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2368 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2372 cli_setpid(cli1, 1);
2373 cli_unlock(cli1, fnum1, 130, 4);
2375 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2376 if (!NT_STATUS_IS_OK(status)) {
2377 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2380 printf("pid1 successfully locked range 130:4 for WRITE\n");
2383 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2384 if (!NT_STATUS_IS_OK(status)) {
2385 printf("pid1 unable to read the range 130:4, error was %s\n",
2388 } else if (nread != 4) {
2389 printf("pid1 unable to read the range 130:4, "
2390 "recv %ld req %d\n", (unsigned long)nread, 4);
2393 printf("pid1 successfully read the range 130:4\n");
2396 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2397 if (!NT_STATUS_IS_OK(status)) {
2398 printf("pid1 unable to write to the range 130:4, error was "
2399 "%s\n", nt_errstr(status));
2402 printf("pid1 successfully wrote to the range 130:4\n");
2405 cli_setpid(cli1, 2);
2407 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2408 if (!NT_STATUS_IS_OK(status)) {
2409 printf("pid2 unable to read the range 130:4, error was "
2410 "%s\n", nt_errstr(status));
2411 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2412 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2416 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2417 (unsigned long)nread);
2421 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2422 if (!NT_STATUS_IS_OK(status)) {
2423 printf("pid2 unable to write to the range 130:4, error was "
2424 "%s\n", nt_errstr(status));
2425 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2426 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2430 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2434 cli_unlock(cli1, fnum1, 130, 0);
2438 cli_close(cli1, fnum1);
2439 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2440 torture_close_connection(cli1);
2442 printf("finished locktest7\n");
2447 * This demonstrates a problem with our use of GPFS share modes: A file
2448 * descriptor sitting in the pending close queue holding a GPFS share mode
2449 * blocks opening a file another time. Happens with Word 2007 temp files.
2450 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2451 * open is denied with NT_STATUS_SHARING_VIOLATION.
2454 static bool run_locktest8(int dummy)
2456 struct cli_state *cli1;
2457 const char *fname = "\\lockt8.lck";
2458 uint16_t fnum1, fnum2;
2460 bool correct = False;
2463 if (!torture_open_connection(&cli1, 0)) {
2467 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2469 printf("starting locktest8\n");
2471 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2473 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2475 if (!NT_STATUS_IS_OK(status)) {
2476 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2480 memset(buf, 0, sizeof(buf));
2482 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2483 if (!NT_STATUS_IS_OK(status)) {
2484 d_fprintf(stderr, "cli_openx second time returned %s\n",
2489 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2490 if (!NT_STATUS_IS_OK(status)) {
2491 printf("Unable to apply read lock on range 1:1, error was "
2492 "%s\n", nt_errstr(status));
2496 status = cli_close(cli1, fnum1);
2497 if (!NT_STATUS_IS_OK(status)) {
2498 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2502 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2503 if (!NT_STATUS_IS_OK(status)) {
2504 d_fprintf(stderr, "cli_openx third time returned %s\n",
2512 cli_close(cli1, fnum1);
2513 cli_close(cli1, fnum2);
2514 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2515 torture_close_connection(cli1);
2517 printf("finished locktest8\n");
2522 * This test is designed to be run in conjunction with
2523 * external NFS or POSIX locks taken in the filesystem.
2524 * It checks that the smbd server will block until the
2525 * lock is released and then acquire it. JRA.
2528 static bool got_alarm;
2529 static struct cli_state *alarm_cli;
2531 static void alarm_handler(int dummy)
2536 static void alarm_handler_parent(int dummy)
2538 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2541 static void do_local_lock(int read_fd, int write_fd)
2546 const char *local_pathname = NULL;
2549 local_pathname = talloc_asprintf(talloc_tos(),
2550 "%s/lockt9.lck", local_path);
2551 if (!local_pathname) {
2552 printf("child: alloc fail\n");
2556 unlink(local_pathname);
2557 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2559 printf("child: open of %s failed %s.\n",
2560 local_pathname, strerror(errno));
2564 /* Now take a fcntl lock. */
2565 lock.l_type = F_WRLCK;
2566 lock.l_whence = SEEK_SET;
2569 lock.l_pid = getpid();
2571 ret = fcntl(fd,F_SETLK,&lock);
2573 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2574 local_pathname, strerror(errno));
2577 printf("child: got lock 0:4 on file %s.\n",
2582 CatchSignal(SIGALRM, alarm_handler);
2584 /* Signal the parent. */
2585 if (write(write_fd, &c, 1) != 1) {
2586 printf("child: start signal fail %s.\n",
2593 /* Wait for the parent to be ready. */
2594 if (read(read_fd, &c, 1) != 1) {
2595 printf("child: reply signal fail %s.\n",
2603 printf("child: released lock 0:4 on file %s.\n",
2609 static bool run_locktest9(int dummy)
2611 struct cli_state *cli1;
2612 const char *fname = "\\lockt9.lck";
2614 bool correct = False;
2615 int pipe_in[2], pipe_out[2];
2619 struct timeval start;
2623 printf("starting locktest9\n");
2625 if (local_path == NULL) {
2626 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2630 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2635 if (child_pid == -1) {
2639 if (child_pid == 0) {
2641 do_local_lock(pipe_out[0], pipe_in[1]);
2651 ret = read(pipe_in[0], &c, 1);
2653 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2658 if (!torture_open_connection(&cli1, 0)) {
2662 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2664 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2666 if (!NT_STATUS_IS_OK(status)) {
2667 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2671 /* Ensure the child has the lock. */
2672 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2673 if (NT_STATUS_IS_OK(status)) {
2674 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2677 d_printf("Child has the lock.\n");
2680 /* Tell the child to wait 5 seconds then exit. */
2681 ret = write(pipe_out[1], &c, 1);
2683 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2688 /* Wait 20 seconds for the lock. */
2690 CatchSignal(SIGALRM, alarm_handler_parent);
2693 start = timeval_current();
2695 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2696 if (!NT_STATUS_IS_OK(status)) {
2697 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2698 "%s\n", nt_errstr(status));
2703 seconds = timeval_elapsed(&start);
2705 printf("Parent got the lock after %.2f seconds.\n",
2708 status = cli_close(cli1, fnum);
2709 if (!NT_STATUS_IS_OK(status)) {
2710 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2717 cli_close(cli1, fnum);
2718 torture_close_connection(cli1);
2722 printf("finished locktest9\n");
2727 test whether fnums and tids open on one VC are available on another (a major
2730 static bool run_fdpasstest(int dummy)
2732 struct cli_state *cli1, *cli2;
2733 const char *fname = "\\fdpass.tst";
2738 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2741 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2742 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2744 printf("starting fdpasstest\n");
2746 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2748 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2750 if (!NT_STATUS_IS_OK(status)) {
2751 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2755 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2757 if (!NT_STATUS_IS_OK(status)) {
2758 printf("write failed (%s)\n", nt_errstr(status));
2762 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2763 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2764 cli_setpid(cli2, cli_getpid(cli1));
2766 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2767 printf("read succeeded! nasty security hole [%s]\n", buf);
2771 cli_close(cli1, fnum1);
2772 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2774 torture_close_connection(cli1);
2775 torture_close_connection(cli2);
2777 printf("finished fdpasstest\n");
2781 static bool run_fdsesstest(int dummy)
2783 struct cli_state *cli;
2785 uint16_t saved_vuid;
2787 uint32_t saved_cnum;
2788 const char *fname = "\\fdsess.tst";
2789 const char *fname1 = "\\fdsess1.tst";
2796 if (!torture_open_connection(&cli, 0))
2798 smbXcli_conn_set_sockopt(cli->conn, sockops);
2800 if (!torture_cli_session_setup2(cli, &new_vuid))
2803 saved_cnum = cli_state_get_tid(cli);
2804 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
2806 new_cnum = cli_state_get_tid(cli);
2807 cli_state_set_tid(cli, saved_cnum);
2809 printf("starting fdsesstest\n");
2811 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2812 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2814 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2815 if (!NT_STATUS_IS_OK(status)) {
2816 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2820 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2822 if (!NT_STATUS_IS_OK(status)) {
2823 printf("write failed (%s)\n", nt_errstr(status));
2827 saved_vuid = cli_state_get_uid(cli);
2828 cli_state_set_uid(cli, new_vuid);
2830 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2831 printf("read succeeded with different vuid! "
2832 "nasty security hole [%s]\n", buf);
2835 /* Try to open a file with different vuid, samba cnum. */
2836 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2837 printf("create with different vuid, same cnum succeeded.\n");
2838 cli_close(cli, fnum2);
2839 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2841 printf("create with different vuid, same cnum failed.\n");
2842 printf("This will cause problems with service clients.\n");
2846 cli_state_set_uid(cli, saved_vuid);
2848 /* Try with same vuid, different cnum. */
2849 cli_state_set_tid(cli, new_cnum);
2851 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2852 printf("read succeeded with different cnum![%s]\n", buf);
2856 cli_state_set_tid(cli, saved_cnum);
2857 cli_close(cli, fnum1);
2858 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2860 torture_close_connection(cli);
2862 printf("finished fdsesstest\n");
2867 This test checks that
2869 1) the server does not allow an unlink on a file that is open
2871 static bool run_unlinktest(int dummy)
2873 struct cli_state *cli;
2874 const char *fname = "\\unlink.tst";
2876 bool correct = True;
2879 if (!torture_open_connection(&cli, 0)) {
2883 smbXcli_conn_set_sockopt(cli->conn, sockops);
2885 printf("starting unlink test\n");
2887 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2891 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2892 if (!NT_STATUS_IS_OK(status)) {
2893 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2897 status = cli_unlink(cli, fname,
2898 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2899 if (NT_STATUS_IS_OK(status)) {
2900 printf("error: server allowed unlink on an open file\n");
2903 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2904 NT_STATUS_SHARING_VIOLATION);
2907 cli_close(cli, fnum);
2908 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2910 if (!torture_close_connection(cli)) {
2914 printf("unlink test finished\n");
2921 test how many open files this server supports on the one socket
2923 static bool run_maxfidtest(int dummy)
2925 struct cli_state *cli;
2927 uint16_t fnums[0x11000];
2930 bool correct = True;
2936 printf("failed to connect\n");
2940 smbXcli_conn_set_sockopt(cli->conn, sockops);
2942 for (i=0; i<0x11000; i++) {
2943 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2944 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2946 if (!NT_STATUS_IS_OK(status)) {
2947 printf("open of %s failed (%s)\n",
2948 fname, nt_errstr(status));
2949 printf("maximum fnum is %d\n", i);
2957 printf("cleaning up\n");
2959 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2960 cli_close(cli, fnums[i]);
2962 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2963 if (!NT_STATUS_IS_OK(status)) {
2964 printf("unlink of %s failed (%s)\n",
2965 fname, nt_errstr(status));
2972 printf("maxfid test finished\n");
2973 if (!torture_close_connection(cli)) {
2979 /* generate a random buffer */
2980 static void rand_buf(char *buf, int len)
2983 *buf = (char)sys_random();
2988 /* send smb negprot commands, not reading the response */
2989 static bool run_negprot_nowait(int dummy)
2991 struct tevent_context *ev;
2993 struct cli_state *cli;
2994 bool correct = True;
2996 printf("starting negprot nowait test\n");
2998 ev = samba_tevent_context_init(talloc_tos());
3003 if (!(cli = open_nbt_connection())) {
3008 for (i=0;i<50000;i++) {
3009 struct tevent_req *req;
3011 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3012 PROTOCOL_CORE, PROTOCOL_NT1, 0);
3017 if (!tevent_req_poll(req, ev)) {
3018 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3026 if (torture_close_connection(cli)) {
3030 printf("finished negprot nowait test\n");
3035 /* send smb negprot commands, not reading the response */
3036 static bool run_bad_nbt_session(int dummy)
3038 struct nmb_name called, calling;
3039 struct sockaddr_storage ss;
3044 printf("starting bad nbt session test\n");
3046 make_nmb_name(&calling, myname, 0x0);
3047 make_nmb_name(&called , host, 0x20);
3049 if (!resolve_name(host, &ss, 0x20, true)) {
3050 d_fprintf(stderr, "Could not resolve name %s\n", host);
3054 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 d_fprintf(stderr, "open_socket_out failed: %s\n",
3061 ret = cli_bad_session_request(fd, &calling, &called);
3064 d_fprintf(stderr, "open_socket_out failed: %s\n",
3069 printf("finished bad nbt session test\n");
3073 /* send random IPC commands */
3074 static bool run_randomipc(int dummy)
3076 char *rparam = NULL;
3078 unsigned int rdrcnt,rprcnt;
3080 int api, param_len, i;
3081 struct cli_state *cli;
3082 bool correct = True;
3085 printf("starting random ipc test\n");
3087 if (!torture_open_connection(&cli, 0)) {
3091 for (i=0;i<count;i++) {
3092 api = sys_random() % 500;
3093 param_len = (sys_random() % 64);
3095 rand_buf(param, param_len);
3100 param, param_len, 8,
3101 NULL, 0, CLI_BUFFER_SIZE,
3105 printf("%d/%d\r", i,count);
3108 printf("%d/%d\n", i, count);
3110 if (!torture_close_connection(cli)) {
3117 printf("finished random ipc test\n");
3124 static void browse_callback(const char *sname, uint32_t stype,
3125 const char *comment, void *state)
3127 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3133 This test checks the browse list code
3136 static bool run_browsetest(int dummy)
3138 static struct cli_state *cli;
3139 bool correct = True;
3141 printf("starting browse test\n");
3143 if (!torture_open_connection(&cli, 0)) {
3147 printf("domain list:\n");
3148 cli_NetServerEnum(cli, cli->server_domain,
3149 SV_TYPE_DOMAIN_ENUM,
3150 browse_callback, NULL);
3152 printf("machine list:\n");
3153 cli_NetServerEnum(cli, cli->server_domain,
3155 browse_callback, NULL);
3157 if (!torture_close_connection(cli)) {
3161 printf("browse test finished\n");
3167 static bool check_attributes(struct cli_state *cli,
3169 uint16_t expected_attrs)
3172 NTSTATUS status = cli_getatr(cli,
3177 if (!NT_STATUS_IS_OK(status)) {
3178 printf("cli_getatr failed with %s\n",
3182 if (attrs != expected_attrs) {
3183 printf("Attributes incorrect 0x%x, should be 0x%x\n",
3184 (unsigned int)attrs,
3185 (unsigned int)expected_attrs);
3192 This checks how the getatr calls works
3194 static bool run_attrtest(int dummy)
3196 struct cli_state *cli;
3199 const char *fname = "\\attrib123456789.tst";
3200 bool correct = True;
3203 printf("starting attrib test\n");
3205 if (!torture_open_connection(&cli, 0)) {
3209 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3210 cli_openx(cli, fname,
3211 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3212 cli_close(cli, fnum);
3214 status = cli_getatr(cli, fname, NULL, NULL, &t);
3215 if (!NT_STATUS_IS_OK(status)) {
3216 printf("getatr failed (%s)\n", nt_errstr(status));
3220 if (labs(t - time(NULL)) > 60*60*24*10) {
3221 printf("ERROR: SMBgetatr bug. time is %s",
3227 t2 = t-60*60*24; /* 1 day ago */
3229 status = cli_setatr(cli, fname, 0, t2);
3230 if (!NT_STATUS_IS_OK(status)) {
3231 printf("setatr failed (%s)\n", nt_errstr(status));
3235 status = cli_getatr(cli, fname, NULL, NULL, &t);
3236 if (!NT_STATUS_IS_OK(status)) {
3237 printf("getatr failed (%s)\n", nt_errstr(status));
3242 printf("ERROR: getatr/setatr bug. times are\n%s",
3244 printf("%s", ctime(&t2));
3248 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3250 /* Check cli_setpathinfo_basic() */
3251 /* Re-create the file. */
3252 status = cli_openx(cli, fname,
3253 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 printf("Failed to recreate %s (%s)\n",
3256 fname, nt_errstr(status));
3259 cli_close(cli, fnum);
3261 status = cli_setpathinfo_basic(cli,
3267 FILE_ATTRIBUTE_SYSTEM |
3268 FILE_ATTRIBUTE_HIDDEN |
3269 FILE_ATTRIBUTE_READONLY);
3270 if (!NT_STATUS_IS_OK(status)) {
3271 printf("cli_setpathinfo_basic failed with %s\n",
3276 /* Check attributes are correct. */
3277 correct = check_attributes(cli,
3279 FILE_ATTRIBUTE_SYSTEM |
3280 FILE_ATTRIBUTE_HIDDEN |
3281 FILE_ATTRIBUTE_READONLY);
3282 if (correct == false) {
3286 /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
3287 status = cli_setpathinfo_basic(cli,
3293 FILE_ATTRIBUTE_NORMAL);
3294 if (!NT_STATUS_IS_OK(status)) {
3295 printf("cli_setpathinfo_basic failed with %s\n",
3300 /* Check attributes are correct. */
3301 correct = check_attributes(cli,
3303 FILE_ATTRIBUTE_SYSTEM |
3304 FILE_ATTRIBUTE_HIDDEN |
3305 FILE_ATTRIBUTE_READONLY);
3306 if (correct == false) {
3310 /* Setting to (uint16_t)-1 should also be ignored. */
3311 status = cli_setpathinfo_basic(cli,
3318 if (!NT_STATUS_IS_OK(status)) {
3319 printf("cli_setpathinfo_basic failed with %s\n",
3324 /* Check attributes are correct. */
3325 correct = check_attributes(cli,
3327 FILE_ATTRIBUTE_SYSTEM |
3328 FILE_ATTRIBUTE_HIDDEN |
3329 FILE_ATTRIBUTE_READONLY);
3330 if (correct == false) {
3334 /* Setting to 0 should clear them all. */
3335 status = cli_setpathinfo_basic(cli,
3342 if (!NT_STATUS_IS_OK(status)) {
3343 printf("cli_setpathinfo_basic failed with %s\n",
3348 /* Check attributes are correct. */
3349 correct = check_attributes(cli,
3351 FILE_ATTRIBUTE_NORMAL);
3352 if (correct == false) {
3360 FILE_ATTRIBUTE_SYSTEM |
3361 FILE_ATTRIBUTE_HIDDEN|
3362 FILE_ATTRIBUTE_READONLY);
3364 if (!torture_close_connection(cli)) {
3368 printf("attrib test finished\n");
3375 This checks a couple of trans2 calls
3377 static bool run_trans2test(int dummy)
3379 struct cli_state *cli;
3382 time_t c_time, a_time, m_time;
3383 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3384 const char *fname = "\\trans2.tst";
3385 const char *dname = "\\trans2";
3386 const char *fname2 = "\\trans2\\trans2.tst";
3388 bool correct = True;
3392 printf("starting trans2 test\n");
3394 if (!torture_open_connection(&cli, 0)) {
3398 status = cli_get_fs_attr_info(cli, &fs_attr);
3399 if (!NT_STATUS_IS_OK(status)) {
3400 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3405 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3406 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3407 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3408 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3409 if (!NT_STATUS_IS_OK(status)) {
3410 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3414 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3415 if (!NT_STATUS_IS_OK(status)) {
3416 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3419 else if (strcmp(pname, fname)) {
3420 printf("qfilename gave different name? [%s] [%s]\n",
3425 cli_close(cli, fnum);
3429 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3430 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3432 if (!NT_STATUS_IS_OK(status)) {
3433 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3436 cli_close(cli, fnum);
3438 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3440 if (!NT_STATUS_IS_OK(status)) {
3441 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3444 time_t t = time(NULL);
3446 if (c_time != m_time) {
3447 printf("create time=%s", ctime(&c_time));
3448 printf("modify time=%s", ctime(&m_time));
3449 printf("This system appears to have sticky create times\n");
3451 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3452 printf("access time=%s", ctime(&a_time));
3453 printf("This system appears to set a midnight access time\n");
3457 if (labs(m_time - t) > 60*60*24*7) {
3458 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3464 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3465 cli_openx(cli, fname,
3466 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3467 cli_close(cli, fnum);
3468 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3469 &m_time_ts, &size, NULL, NULL);
3470 if (!NT_STATUS_IS_OK(status)) {
3471 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3474 if (w_time_ts.tv_sec < 60*60*24*2) {
3475 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3476 printf("This system appears to set a initial 0 write time\n");
3481 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3484 /* check if the server updates the directory modification time
3485 when creating a new file */
3486 status = cli_mkdir(cli, dname);
3487 if (!NT_STATUS_IS_OK(status)) {
3488 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3492 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3493 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3494 if (!NT_STATUS_IS_OK(status)) {
3495 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3499 cli_openx(cli, fname2,
3500 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3501 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3502 cli_close(cli, fnum);
3503 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3504 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3505 if (!NT_STATUS_IS_OK(status)) {
3506 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3509 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3511 printf("This system does not update directory modification times\n");
3515 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3516 cli_rmdir(cli, dname);
3518 if (!torture_close_connection(cli)) {
3522 printf("trans2 test finished\n");
3528 This checks new W2K calls.
3531 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3533 uint8_t *buf = NULL;
3537 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3538 CLI_BUFFER_SIZE, NULL, &buf, &len);
3539 if (!NT_STATUS_IS_OK(status)) {
3540 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3543 printf("qfileinfo: level %d, len = %u\n", level, len);
3544 dump_data(0, (uint8_t *)buf, len);
3551 static bool run_w2ktest(int dummy)
3553 struct cli_state *cli;
3555 const char *fname = "\\w2ktest\\w2k.tst";
3557 bool correct = True;
3559 printf("starting w2k test\n");
3561 if (!torture_open_connection(&cli, 0)) {
3565 cli_openx(cli, fname,
3566 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3568 for (level = 1004; level < 1040; level++) {
3569 new_trans(cli, fnum, level);
3572 cli_close(cli, fnum);
3574 if (!torture_close_connection(cli)) {
3578 printf("w2k test finished\n");
3585 this is a harness for some oplock tests
3587 static bool run_oplock1(int dummy)
3589 struct cli_state *cli1;
3590 const char *fname = "\\lockt1.lck";
3592 bool correct = True;
3595 printf("starting oplock test 1\n");
3597 if (!torture_open_connection(&cli1, 0)) {
3601 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3603 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3605 cli1->use_oplocks = True;
3607 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3609 if (!NT_STATUS_IS_OK(status)) {
3610 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3614 cli1->use_oplocks = False;
3616 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3617 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3619 status = cli_close(cli1, fnum1);
3620 if (!NT_STATUS_IS_OK(status)) {
3621 printf("close2 failed (%s)\n", nt_errstr(status));
3625 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3626 if (!NT_STATUS_IS_OK(status)) {
3627 printf("unlink failed (%s)\n", nt_errstr(status));
3631 if (!torture_close_connection(cli1)) {
3635 printf("finished oplock test 1\n");
3640 static bool run_oplock2(int dummy)
3642 struct cli_state *cli1, *cli2;
3643 const char *fname = "\\lockt2.lck";
3644 uint16_t fnum1, fnum2;
3645 int saved_use_oplocks = use_oplocks;
3647 bool correct = True;
3648 volatile bool *shared_correct;
3652 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3653 *shared_correct = True;
3655 use_level_II_oplocks = True;
3658 printf("starting oplock test 2\n");
3660 if (!torture_open_connection(&cli1, 0)) {
3661 use_level_II_oplocks = False;
3662 use_oplocks = saved_use_oplocks;
3666 if (!torture_open_connection(&cli2, 1)) {
3667 use_level_II_oplocks = False;
3668 use_oplocks = saved_use_oplocks;
3672 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3674 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3675 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3677 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3679 if (!NT_STATUS_IS_OK(status)) {
3680 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3684 /* Don't need the globals any more. */
3685 use_level_II_oplocks = False;
3686 use_oplocks = saved_use_oplocks;
3690 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3691 if (!NT_STATUS_IS_OK(status)) {
3692 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3693 *shared_correct = False;
3699 status = cli_close(cli2, fnum2);
3700 if (!NT_STATUS_IS_OK(status)) {
3701 printf("close2 failed (%s)\n", nt_errstr(status));
3702 *shared_correct = False;
3710 /* Ensure cli1 processes the break. Empty file should always return 0
3712 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3713 if (!NT_STATUS_IS_OK(status)) {
3714 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3716 } else if (nread != 0) {
3717 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3718 (unsigned long)nread, 0);
3722 /* Should now be at level II. */
3723 /* Test if sending a write locks causes a break to none. */
3724 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3725 if (!NT_STATUS_IS_OK(status)) {
3726 printf("lock failed (%s)\n", nt_errstr(status));
3730 cli_unlock(cli1, fnum1, 0, 4);
3734 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3735 if (!NT_STATUS_IS_OK(status)) {
3736 printf("lock failed (%s)\n", nt_errstr(status));
3740 cli_unlock(cli1, fnum1, 0, 4);
3744 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3746 status = cli_close(cli1, fnum1);
3747 if (!NT_STATUS_IS_OK(status)) {
3748 printf("close1 failed (%s)\n", nt_errstr(status));
3754 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3755 if (!NT_STATUS_IS_OK(status)) {
3756 printf("unlink failed (%s)\n", nt_errstr(status));
3760 if (!torture_close_connection(cli1)) {
3764 if (!*shared_correct) {
3768 printf("finished oplock test 2\n");
3773 struct oplock4_state {
3774 struct tevent_context *ev;
3775 struct cli_state *cli;
3780 static void oplock4_got_break(struct tevent_req *req);
3781 static void oplock4_got_open(struct tevent_req *req);
3783 static bool run_oplock4(int dummy)
3785 struct tevent_context *ev;
3786 struct cli_state *cli1, *cli2;
3787 struct tevent_req *oplock_req, *open_req;
3788 const char *fname = "\\lockt4.lck";
3789 const char *fname_ln = "\\lockt4_ln.lck";
3790 uint16_t fnum1, fnum2;
3791 int saved_use_oplocks = use_oplocks;
3793 bool correct = true;
3797 struct oplock4_state *state;
3799 printf("starting oplock test 4\n");
3801 if (!torture_open_connection(&cli1, 0)) {
3802 use_level_II_oplocks = false;
3803 use_oplocks = saved_use_oplocks;
3807 if (!torture_open_connection(&cli2, 1)) {
3808 use_level_II_oplocks = false;
3809 use_oplocks = saved_use_oplocks;
3813 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3814 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3816 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3817 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3819 /* Create the file. */
3820 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3822 if (!NT_STATUS_IS_OK(status)) {
3823 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3827 status = cli_close(cli1, fnum1);
3828 if (!NT_STATUS_IS_OK(status)) {
3829 printf("close1 failed (%s)\n", nt_errstr(status));
3833 /* Now create a hardlink. */
3834 status = cli_nt_hardlink(cli1, fname, fname_ln);
3835 if (!NT_STATUS_IS_OK(status)) {
3836 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3840 /* Prove that opening hardlinks cause deny modes to conflict. */
3841 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3847 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3848 if (NT_STATUS_IS_OK(status)) {
3849 printf("open of %s succeeded - should fail with sharing violation.\n",
3854 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3855 printf("open of %s should fail with sharing violation. Got %s\n",
3856 fname_ln, nt_errstr(status));
3860 status = cli_close(cli1, fnum1);
3861 if (!NT_STATUS_IS_OK(status)) {
3862 printf("close1 failed (%s)\n", nt_errstr(status));
3866 cli1->use_oplocks = true;
3867 cli2->use_oplocks = true;
3869 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3870 if (!NT_STATUS_IS_OK(status)) {
3871 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3875 ev = samba_tevent_context_init(talloc_tos());
3877 printf("tevent_context_init failed\n");
3881 state = talloc(ev, struct oplock4_state);
3882 if (state == NULL) {
3883 printf("talloc failed\n");
3888 state->got_break = &got_break;
3889 state->fnum2 = &fnum2;
3891 oplock_req = cli_smb_oplock_break_waiter_send(
3892 talloc_tos(), ev, cli1);
3893 if (oplock_req == NULL) {
3894 printf("cli_smb_oplock_break_waiter_send failed\n");
3897 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3899 open_req = cli_openx_send(
3900 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3901 if (open_req == NULL) {
3902 printf("cli_openx_send failed\n");
3905 tevent_req_set_callback(open_req, oplock4_got_open, state);
3910 while (!got_break || fnum2 == 0xffff) {
3912 ret = tevent_loop_once(ev);
3914 printf("tevent_loop_once failed: %s\n",
3920 status = cli_close(cli2, fnum2);
3921 if (!NT_STATUS_IS_OK(status)) {
3922 printf("close2 failed (%s)\n", nt_errstr(status));
3926 status = cli_close(cli1, fnum1);
3927 if (!NT_STATUS_IS_OK(status)) {
3928 printf("close1 failed (%s)\n", nt_errstr(status));
3932 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3933 if (!NT_STATUS_IS_OK(status)) {
3934 printf("unlink failed (%s)\n", nt_errstr(status));
3938 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3939 if (!NT_STATUS_IS_OK(status)) {
3940 printf("unlink failed (%s)\n", nt_errstr(status));
3944 if (!torture_close_connection(cli1)) {
3952 printf("finished oplock test 4\n");
3957 static void oplock4_got_break(struct tevent_req *req)
3959 struct oplock4_state *state = tevent_req_callback_data(
3960 req, struct oplock4_state);
3965 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3967 if (!NT_STATUS_IS_OK(status)) {
3968 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3972 *state->got_break = true;
3974 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3977 printf("cli_oplock_ack_send failed\n");
3982 static void oplock4_got_open(struct tevent_req *req)
3984 struct oplock4_state *state = tevent_req_callback_data(
3985 req, struct oplock4_state);
3988 status = cli_openx_recv(req, state->fnum2);
3989 if (!NT_STATUS_IS_OK(status)) {
3990 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3991 *state->fnum2 = 0xffff;
3996 Test delete on close semantics.
3998 static bool run_deletetest(int dummy)
4000 struct cli_state *cli1 = NULL;
4001 struct cli_state *cli2 = NULL;
4002 const char *fname = "\\delete.file";
4003 uint16_t fnum1 = (uint16_t)-1;
4004 uint16_t fnum2 = (uint16_t)-1;
4005 bool correct = false;
4008 printf("starting delete test\n");
4010 if (!torture_open_connection(&cli1, 0)) {
4014 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4016 /* Test 1 - this should delete the file on close. */
4018 cli_setatr(cli1, fname, 0, 0);
4019 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4021 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4022 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4023 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4024 if (!NT_STATUS_IS_OK(status)) {
4025 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
4029 status = cli_close(cli1, fnum1);
4030 if (!NT_STATUS_IS_OK(status)) {
4031 printf("[1] close failed (%s)\n", nt_errstr(status));
4035 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
4036 if (NT_STATUS_IS_OK(status)) {
4037 printf("[1] open of %s succeeded (should fail)\n", fname);
4041 printf("first delete on close test succeeded.\n");
4043 /* Test 2 - this should delete the file on close. */
4045 cli_setatr(cli1, fname, 0, 0);
4046 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4048 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4049 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4050 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4051 if (!NT_STATUS_IS_OK(status)) {
4052 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
4056 status = cli_nt_delete_on_close(cli1, fnum1, true);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
4062 status = cli_close(cli1, fnum1);
4063 if (!NT_STATUS_IS_OK(status)) {
4064 printf("[2] close failed (%s)\n", nt_errstr(status));
4068 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4069 if (NT_STATUS_IS_OK(status)) {
4070 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
4071 status = cli_close(cli1, fnum1);
4072 if (!NT_STATUS_IS_OK(status)) {
4073 printf("[2] close failed (%s)\n", nt_errstr(status));
4075 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4079 printf("second delete on close test succeeded.\n");
4082 cli_setatr(cli1, fname, 0, 0);
4083 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4085 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4086 FILE_ATTRIBUTE_NORMAL,
4087 FILE_SHARE_READ|FILE_SHARE_WRITE,
4088 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4089 if (!NT_STATUS_IS_OK(status)) {
4090 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
4094 /* This should fail with a sharing violation - open for delete is only compatible
4095 with SHARE_DELETE. */
4097 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4098 FILE_ATTRIBUTE_NORMAL,
4099 FILE_SHARE_READ|FILE_SHARE_WRITE,
4100 FILE_OPEN, 0, 0, &fnum2, NULL);
4101 if (NT_STATUS_IS_OK(status)) {
4102 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4106 /* This should succeed. */
4107 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4108 FILE_ATTRIBUTE_NORMAL,
4109 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4110 FILE_OPEN, 0, 0, &fnum2, NULL);
4111 if (!NT_STATUS_IS_OK(status)) {
4112 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
4116 status = cli_nt_delete_on_close(cli1, fnum1, true);
4117 if (!NT_STATUS_IS_OK(status)) {
4118 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4122 status = cli_close(cli1, fnum1);
4123 if (!NT_STATUS_IS_OK(status)) {
4124 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4128 status = cli_close(cli1, fnum2);
4129 if (!NT_STATUS_IS_OK(status)) {
4130 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4134 /* This should fail - file should no longer be there. */
4136 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4137 if (NT_STATUS_IS_OK(status)) {
4138 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4139 status = cli_close(cli1, fnum1);
4140 if (!NT_STATUS_IS_OK(status)) {
4141 printf("[3] close failed (%s)\n", nt_errstr(status));
4143 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4147 printf("third delete on close test succeeded.\n");
4150 cli_setatr(cli1, fname, 0, 0);
4151 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4153 status = cli_ntcreate(cli1, fname, 0,
4154 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4155 FILE_ATTRIBUTE_NORMAL,
4156 FILE_SHARE_READ|FILE_SHARE_WRITE,
4157 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4158 if (!NT_STATUS_IS_OK(status)) {
4159 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4163 /* This should succeed. */
4164 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4165 FILE_ATTRIBUTE_NORMAL,
4166 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4167 FILE_OPEN, 0, 0, &fnum2, NULL);
4168 if (!NT_STATUS_IS_OK(status)) {
4169 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4173 status = cli_close(cli1, fnum2);
4174 if (!NT_STATUS_IS_OK(status)) {
4175 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4179 status = cli_nt_delete_on_close(cli1, fnum1, true);
4180 if (!NT_STATUS_IS_OK(status)) {
4181 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4185 /* This should fail - no more opens once delete on close set. */
4186 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4187 FILE_ATTRIBUTE_NORMAL,
4188 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4189 FILE_OPEN, 0, 0, &fnum2, NULL);
4190 if (NT_STATUS_IS_OK(status)) {
4191 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4195 status = cli_close(cli1, fnum1);
4196 if (!NT_STATUS_IS_OK(status)) {
4197 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4201 printf("fourth delete on close test succeeded.\n");
4204 cli_setatr(cli1, fname, 0, 0);
4205 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4207 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4208 if (!NT_STATUS_IS_OK(status)) {
4209 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4213 /* This should fail - only allowed on NT opens with DELETE access. */
4215 status = cli_nt_delete_on_close(cli1, fnum1, true);
4216 if (NT_STATUS_IS_OK(status)) {
4217 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4221 status = cli_close(cli1, fnum1);
4222 if (!NT_STATUS_IS_OK(status)) {
4223 printf("[5] close failed (%s)\n", nt_errstr(status));
4227 printf("fifth delete on close test succeeded.\n");
4230 cli_setatr(cli1, fname, 0, 0);
4231 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4233 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4234 FILE_ATTRIBUTE_NORMAL,
4235 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4236 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4237 if (!NT_STATUS_IS_OK(status)) {
4238 printf("[6] open of %s failed (%s)\n", fname,
4243 /* This should fail - only allowed on NT opens with DELETE access. */
4245 status = cli_nt_delete_on_close(cli1, fnum1, true);
4246 if (NT_STATUS_IS_OK(status)) {
4247 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4251 status = cli_close(cli1, fnum1);
4252 if (!NT_STATUS_IS_OK(status)) {
4253 printf("[6] close failed (%s)\n", nt_errstr(status));
4257 printf("sixth delete on close test succeeded.\n");
4260 cli_setatr(cli1, fname, 0, 0);
4261 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4263 status = cli_ntcreate(cli1, fname, 0,
4264 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4265 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4266 0, 0, &fnum1, NULL);
4267 if (!NT_STATUS_IS_OK(status)) {
4268 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4272 status = cli_nt_delete_on_close(cli1, fnum1, true);
4273 if (!NT_STATUS_IS_OK(status)) {
4274 printf("[7] setting delete_on_close on file failed !\n");
4278 status = cli_nt_delete_on_close(cli1, fnum1, false);
4279 if (!NT_STATUS_IS_OK(status)) {
4280 printf("[7] unsetting delete_on_close on file failed !\n");
4284 status = cli_close(cli1, fnum1);
4285 if (!NT_STATUS_IS_OK(status)) {
4286 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4290 /* This next open should succeed - we reset the flag. */
4291 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4292 if (!NT_STATUS_IS_OK(status)) {
4293 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4297 status = cli_close(cli1, fnum1);
4298 if (!NT_STATUS_IS_OK(status)) {
4299 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4303 printf("seventh delete on close test succeeded.\n");
4306 cli_setatr(cli1, fname, 0, 0);
4307 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4309 if (!torture_open_connection(&cli2, 1)) {
4310 printf("[8] failed to open second connection.\n");
4314 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4316 status = cli_ntcreate(cli1, fname, 0,
4317 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4318 FILE_ATTRIBUTE_NORMAL,
4319 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4320 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4321 if (!NT_STATUS_IS_OK(status)) {
4322 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4326 status = cli_ntcreate(cli2, fname, 0,
4327 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4328 FILE_ATTRIBUTE_NORMAL,
4329 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4330 FILE_OPEN, 0, 0, &fnum2, NULL);
4331 if (!NT_STATUS_IS_OK(status)) {
4332 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4336 status = cli_nt_delete_on_close(cli1, fnum1, true);
4337 if (!NT_STATUS_IS_OK(status)) {
4338 printf("[8] setting delete_on_close on file failed !\n");
4342 status = cli_close(cli1, fnum1);
4343 if (!NT_STATUS_IS_OK(status)) {
4344 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4348 status = cli_close(cli2, fnum2);
4349 if (!NT_STATUS_IS_OK(status)) {
4350 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4354 /* This should fail.. */
4355 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4356 if (NT_STATUS_IS_OK(status)) {
4357 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4361 printf("eighth delete on close test succeeded.\n");
4365 /* This should fail - we need to set DELETE_ACCESS. */
4366 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4367 FILE_ATTRIBUTE_NORMAL,
4370 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4371 if (NT_STATUS_IS_OK(status)) {
4372 printf("[9] open of %s succeeded should have failed!\n", fname);
4376 printf("ninth delete on close test succeeded.\n");
4380 status = cli_ntcreate(cli1, fname, 0,
4381 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4382 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4383 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4385 if (!NT_STATUS_IS_OK(status)) {
4386 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4390 /* This should delete the file. */
4391 status = cli_close(cli1, fnum1);
4392 if (!NT_STATUS_IS_OK(status)) {
4393 printf("[10] close failed (%s)\n", nt_errstr(status));
4397 /* This should fail.. */
4398 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4399 if (NT_STATUS_IS_OK(status)) {
4400 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4404 printf("tenth delete on close test succeeded.\n");
4408 cli_setatr(cli1, fname, 0, 0);
4409 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4411 /* Can we open a read-only file with delete access? */
4413 /* Create a readonly file. */
4414 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4415 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4416 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4417 if (!NT_STATUS_IS_OK(status)) {
4418 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4422 status = cli_close(cli1, fnum1);
4423 if (!NT_STATUS_IS_OK(status)) {
4424 printf("[11] close failed (%s)\n", nt_errstr(status));
4428 /* Now try open for delete access. */
4429 status = cli_ntcreate(cli1, fname, 0,
4430 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4432 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4433 FILE_OPEN, 0, 0, &fnum1, NULL);
4434 if (!NT_STATUS_IS_OK(status)) {
4435 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4439 cli_close(cli1, fnum1);
4441 printf("eleventh delete on close test succeeded.\n");
4445 * like test 4 but with initial delete on close
4448 cli_setatr(cli1, fname, 0, 0);
4449 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4451 status = cli_ntcreate(cli1, fname, 0,
4452 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4453 FILE_ATTRIBUTE_NORMAL,
4454 FILE_SHARE_READ|FILE_SHARE_WRITE,
4456 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4457 if (!NT_STATUS_IS_OK(status)) {
4458 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4462 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4463 FILE_ATTRIBUTE_NORMAL,
4464 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4465 FILE_OPEN, 0, 0, &fnum2, NULL);
4466 if (!NT_STATUS_IS_OK(status)) {
4467 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4471 status = cli_close(cli1, fnum2);
4472 if (!NT_STATUS_IS_OK(status)) {
4473 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4477 status = cli_nt_delete_on_close(cli1, fnum1, true);
4478 if (!NT_STATUS_IS_OK(status)) {
4479 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4483 /* This should fail - no more opens once delete on close set. */
4484 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4485 FILE_ATTRIBUTE_NORMAL,
4486 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4487 FILE_OPEN, 0, 0, &fnum2, NULL);
4488 if (NT_STATUS_IS_OK(status)) {
4489 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4493 status = cli_nt_delete_on_close(cli1, fnum1, false);
4494 if (!NT_STATUS_IS_OK(status)) {
4495 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4499 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4500 FILE_ATTRIBUTE_NORMAL,
4501 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4502 FILE_OPEN, 0, 0, &fnum2, NULL);
4503 if (!NT_STATUS_IS_OK(status)) {
4504 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4508 status = cli_close(cli1, fnum2);
4509 if (!NT_STATUS_IS_OK(status)) {
4510 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4514 status = cli_close(cli1, fnum1);
4515 if (!NT_STATUS_IS_OK(status)) {
4516 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4521 * setting delete on close on the handle does
4522 * not unset the initial delete on close...
4524 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4525 FILE_ATTRIBUTE_NORMAL,
4526 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4527 FILE_OPEN, 0, 0, &fnum2, NULL);
4528 if (NT_STATUS_IS_OK(status)) {
4529 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4531 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4532 printf("ntcreate returned %s, expected "
4533 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4538 printf("twelfth delete on close test succeeded.\n");
4541 printf("finished delete test\n");
4546 /* FIXME: This will crash if we aborted before cli2 got
4547 * intialized, because these functions don't handle
4548 * uninitialized connections. */
4550 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4551 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4552 cli_setatr(cli1, fname, 0, 0);
4553 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4555 if (cli1 && !torture_close_connection(cli1)) {
4558 if (cli2 && !torture_close_connection(cli2)) {
4566 Test wildcard delete.
4568 static bool run_wild_deletetest(int dummy)
4570 struct cli_state *cli = NULL;
4571 const char *dname = "\\WTEST";
4572 const char *fname = "\\WTEST\\A";
4573 const char *wunlink_name = "\\WTEST\\*";
4574 uint16_t fnum1 = (uint16_t)-1;
4575 bool correct = false;
4578 printf("starting wildcard delete test\n");
4580 if (!torture_open_connection(&cli, 0)) {
4584 smbXcli_conn_set_sockopt(cli->conn, sockops);
4586 cli_unlink(cli, fname, 0);
4587 cli_rmdir(cli, dname);
4588 status = cli_mkdir(cli, dname);
4589 if (!NT_STATUS_IS_OK(status)) {
4590 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4593 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4594 if (!NT_STATUS_IS_OK(status)) {
4595 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4598 status = cli_close(cli, fnum1);
4602 * Note the unlink attribute-type of zero. This should
4603 * map into FILE_ATTRIBUTE_NORMAL at the server even
4604 * on a wildcard delete.
4607 status = cli_unlink(cli, wunlink_name, 0);
4608 if (!NT_STATUS_IS_OK(status)) {
4609 printf("unlink of %s failed %s!\n",
4610 wunlink_name, nt_errstr(status));
4614 printf("finished wildcard delete test\n");
4620 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4621 cli_unlink(cli, fname, 0);
4622 cli_rmdir(cli, dname);
4624 if (cli && !torture_close_connection(cli)) {
4630 static bool run_deletetest_ln(int dummy)
4632 struct cli_state *cli;
4633 const char *fname = "\\delete1";
4634 const char *fname_ln = "\\delete1_ln";
4638 bool correct = true;
4641 printf("starting deletetest-ln\n");
4643 if (!torture_open_connection(&cli, 0)) {
4647 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4648 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4650 smbXcli_conn_set_sockopt(cli->conn, sockops);
4652 /* Create the file. */
4653 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4654 if (!NT_STATUS_IS_OK(status)) {
4655 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4659 status = cli_close(cli, fnum);
4660 if (!NT_STATUS_IS_OK(status)) {
4661 printf("close1 failed (%s)\n", nt_errstr(status));
4665 /* Now create a hardlink. */
4666 status = cli_nt_hardlink(cli, fname, fname_ln);
4667 if (!NT_STATUS_IS_OK(status)) {
4668 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4672 /* Open the original file. */
4673 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4674 FILE_ATTRIBUTE_NORMAL,
4675 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4676 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4677 if (!NT_STATUS_IS_OK(status)) {
4678 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4682 /* Unlink the hard link path. */
4683 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4684 FILE_ATTRIBUTE_NORMAL,
4685 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4686 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4687 if (!NT_STATUS_IS_OK(status)) {
4688 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4691 status = cli_nt_delete_on_close(cli, fnum1, true);
4692 if (!NT_STATUS_IS_OK(status)) {
4693 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4694 __location__, fname_ln, nt_errstr(status));
4698 status = cli_close(cli, fnum1);
4699 if (!NT_STATUS_IS_OK(status)) {
4700 printf("close %s failed (%s)\n",
4701 fname_ln, nt_errstr(status));
4705 status = cli_close(cli, fnum);
4706 if (!NT_STATUS_IS_OK(status)) {
4707 printf("close %s failed (%s)\n",
4708 fname, nt_errstr(status));
4712 /* Ensure the original file is still there. */
4713 status = cli_getatr(cli, fname, NULL, NULL, &t);
4714 if (!NT_STATUS_IS_OK(status)) {
4715 printf("%s getatr on file %s failed (%s)\n",
4722 /* Ensure the link path is gone. */
4723 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4724 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4725 printf("%s, getatr for file %s returned wrong error code %s "
4726 "- should have been deleted\n",
4728 fname_ln, nt_errstr(status));
4732 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4733 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4735 if (!torture_close_connection(cli)) {
4739 printf("finished deletetest-ln\n");
4745 print out server properties
4747 static bool run_properties(int dummy)
4749 struct cli_state *cli;
4750 bool correct = True;
4752 printf("starting properties test\n");
4756 if (!torture_open_connection(&cli, 0)) {
4760 smbXcli_conn_set_sockopt(cli->conn, sockops);
4762 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4764 if (!torture_close_connection(cli)) {
4773 /* FIRST_DESIRED_ACCESS 0xf019f */
4774 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4775 FILE_READ_EA| /* 0xf */ \
4776 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4777 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4778 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4779 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4780 /* SECOND_DESIRED_ACCESS 0xe0080 */
4781 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4782 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4783 WRITE_OWNER_ACCESS /* 0xe0000 */
4786 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4787 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4789 WRITE_OWNER_ACCESS /* */
4793 Test ntcreate calls made by xcopy
4795 static bool run_xcopy(int dummy)
4797 static struct cli_state *cli1;
4798 const char *fname = "\\test.txt";
4799 bool correct = True;
4800 uint16_t fnum1, fnum2;
4803 printf("starting xcopy test\n");
4805 if (!torture_open_connection(&cli1, 0)) {
4809 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4810 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4811 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4812 if (!NT_STATUS_IS_OK(status)) {
4813 printf("First open failed - %s\n", nt_errstr(status));
4817 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4818 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4819 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4820 if (!NT_STATUS_IS_OK(status)) {
4821 printf("second open failed - %s\n", nt_errstr(status));
4825 if (!torture_close_connection(cli1)) {
4833 Test rename on files open with share delete and no share delete.
4835 static bool run_rename(int dummy)
4837 static struct cli_state *cli1;
4838 const char *fname = "\\test.txt";
4839 const char *fname1 = "\\test1.txt";
4840 bool correct = True;
4845 printf("starting rename test\n");
4847 if (!torture_open_connection(&cli1, 0)) {
4851 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4852 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4854 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4855 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4856 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4857 if (!NT_STATUS_IS_OK(status)) {
4858 printf("First open failed - %s\n", nt_errstr(status));
4862 status = cli_rename(cli1, fname, fname1, false);
4863 if (!NT_STATUS_IS_OK(status)) {
4864 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4866 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4870 status = cli_close(cli1, fnum1);
4871 if (!NT_STATUS_IS_OK(status)) {
4872 printf("close - 1 failed (%s)\n", nt_errstr(status));
4876 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4877 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4878 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4880 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4882 FILE_SHARE_DELETE|FILE_SHARE_READ,
4884 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4885 if (!NT_STATUS_IS_OK(status)) {
4886 printf("Second open failed - %s\n", nt_errstr(status));
4890 status = cli_rename(cli1, fname, fname1, false);
4891 if (!NT_STATUS_IS_OK(status)) {
4892 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4895 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4898 status = cli_close(cli1, fnum1);
4899 if (!NT_STATUS_IS_OK(status)) {
4900 printf("close - 2 failed (%s)\n", nt_errstr(status));
4904 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4905 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4907 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4908 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4909 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4910 if (!NT_STATUS_IS_OK(status)) {
4911 printf("Third open failed - %s\n", nt_errstr(status));
4920 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4921 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4922 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4925 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4926 printf("[8] setting delete_on_close on file failed !\n");
4930 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4931 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4937 status = cli_rename(cli1, fname, fname1, false);
4938 if (!NT_STATUS_IS_OK(status)) {
4939 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4942 printf("Third rename succeeded (SHARE_NONE)\n");
4945 status = cli_close(cli1, fnum1);
4946 if (!NT_STATUS_IS_OK(status)) {
4947 printf("close - 3 failed (%s)\n", nt_errstr(status));
4951 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4952 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4956 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4957 FILE_ATTRIBUTE_NORMAL,
4958 FILE_SHARE_READ | FILE_SHARE_WRITE,
4959 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4960 if (!NT_STATUS_IS_OK(status)) {
4961 printf("Fourth open failed - %s\n", nt_errstr(status));
4965 status = cli_rename(cli1, fname, fname1, false);
4966 if (!NT_STATUS_IS_OK(status)) {
4967 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4969 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4973 status = cli_close(cli1, fnum1);
4974 if (!NT_STATUS_IS_OK(status)) {
4975 printf("close - 4 failed (%s)\n", nt_errstr(status));
4979 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4980 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4984 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4985 FILE_ATTRIBUTE_NORMAL,
4986 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4987 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4988 if (!NT_STATUS_IS_OK(status)) {
4989 printf("Fifth open failed - %s\n", nt_errstr(status));
4993 status = cli_rename(cli1, fname, fname1, false);
4994 if (!NT_STATUS_IS_OK(status)) {
4995 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4998 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
5002 * Now check if the first name still exists ...
5005 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
5006 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5007 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
5008 printf("Opening original file after rename of open file fails: %s\n",
5012 printf("Opening original file after rename of open file works ...\n");
5013 (void)cli_close(cli1, fnum2);
5017 status = cli_close(cli1, fnum1);
5018 if (!NT_STATUS_IS_OK(status)) {
5019 printf("close - 5 failed (%s)\n", nt_errstr(status));
5023 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
5024 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
5025 if (!NT_STATUS_IS_OK(status)) {
5026 printf("getatr on file %s failed - %s ! \n",
5027 fname1, nt_errstr(status));
5030 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
5031 printf("Renamed file %s has wrong attr 0x%x "
5032 "(should be 0x%x)\n",
5035 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
5038 printf("Renamed file %s has archive bit set\n", fname1);
5042 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5043 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5045 if (!torture_close_connection(cli1)) {
5053 Test rename into a directory with an ACL denying it.
5055 static bool run_rename_access(int dummy)
5057 static struct cli_state *cli = NULL;
5058 static struct cli_state *posix_cli = NULL;
5059 const char *src = "test.txt";
5060 const char *dname = "dir";
5061 const char *dst = "dir\\test.txt";
5062 const char *dsrc = "test.dir";
5063 const char *ddst = "dir\\test.dir";
5064 uint16_t fnum = (uint16_t)-1;
5065 struct security_descriptor *sd = NULL;
5066 struct security_descriptor *newsd = NULL;
5068 TALLOC_CTX *frame = NULL;
5070 frame = talloc_stackframe();
5071 printf("starting rename access test\n");
5073 /* Windows connection. */
5074 if (!torture_open_connection(&cli, 0)) {
5078 smbXcli_conn_set_sockopt(cli->conn, sockops);
5080 /* Posix connection. */
5081 if (!torture_open_connection(&posix_cli, 0)) {
5085 smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
5087 status = torture_setup_unix_extensions(posix_cli);
5088 if (!NT_STATUS_IS_OK(status)) {
5092 /* Start with a clean slate. */
5093 cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5094 cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5095 cli_rmdir(cli, dsrc);
5096 cli_rmdir(cli, ddst);
5097 cli_rmdir(cli, dname);
5100 * Setup the destination directory with a DENY ACE to
5101 * prevent new files within it.
5103 status = cli_ntcreate(cli,
5106 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
5107 WRITE_DAC_ACCESS|FILE_READ_DATA|
5109 FILE_ATTRIBUTE_DIRECTORY,
5110 FILE_SHARE_READ|FILE_SHARE_WRITE,
5112 FILE_DIRECTORY_FILE,
5116 if (!NT_STATUS_IS_OK(status)) {
5117 printf("Create of %s - %s\n", dname, nt_errstr(status));
5121 status = cli_query_secdesc(cli,
5125 if (!NT_STATUS_IS_OK(status)) {
5126 printf("cli_query_secdesc failed for %s (%s)\n",
5127 dname, nt_errstr(status));
5131 newsd = security_descriptor_dacl_create(frame,
5136 SEC_ACE_TYPE_ACCESS_DENIED,
5137 SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
5140 if (newsd == NULL) {
5143 sd->dacl = security_acl_concatenate(frame,
5146 if (sd->dacl == NULL) {
5149 status = cli_set_secdesc(cli, fnum, sd);
5150 if (!NT_STATUS_IS_OK(status)) {
5151 printf("cli_set_secdesc failed for %s (%s)\n",
5152 dname, nt_errstr(status));
5155 status = cli_close(cli, fnum);
5156 if (!NT_STATUS_IS_OK(status)) {
5157 printf("close failed for %s (%s)\n",
5158 dname, nt_errstr(status));
5161 /* Now go around the back and chmod to 777 via POSIX. */
5162 status = cli_posix_chmod(posix_cli, dname, 0777);
5163 if (!NT_STATUS_IS_OK(status)) {
5164 printf("cli_posix_chmod failed for %s (%s)\n",
5165 dname, nt_errstr(status));
5169 /* Check we can't create a file within dname via Windows. */
5170 status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5171 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5172 cli_close(posix_cli, fnum);
5173 printf("Create of %s should be ACCESS denied, was %s\n",
5174 dst, nt_errstr(status));
5178 /* Make the sample file/directory. */
5179 status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5180 if (!NT_STATUS_IS_OK(status)) {
5181 printf("open of %s failed (%s)\n", src, nt_errstr(status));
5184 status = cli_close(cli, fnum);
5185 if (!NT_STATUS_IS_OK(status)) {
5186 printf("cli_close failed (%s)\n", nt_errstr(status));
5190 status = cli_mkdir(cli, dsrc);
5191 if (!NT_STATUS_IS_OK(status)) {
5192 printf("cli_mkdir of %s failed (%s)\n",
5193 dsrc, nt_errstr(status));
5198 * OK - renames of the new file and directory into the
5199 * dst directory should fail.
5202 status = cli_rename(cli, src, dst, false);
5203 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5204 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5205 src, dst, nt_errstr(status));
5208 status = cli_rename(cli, dsrc, ddst, false);
5209 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5210 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5211 src, dst, nt_errstr(status));
5221 torture_close_connection(posix_cli);
5225 if (fnum != (uint16_t)-1) {
5226 cli_close(cli, fnum);
5228 cli_unlink(cli, src,
5229 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5230 cli_unlink(cli, dst,
5231 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5232 cli_rmdir(cli, dsrc);
5233 cli_rmdir(cli, ddst);
5234 cli_rmdir(cli, dname);
5236 torture_close_connection(cli);
5244 Test owner rights ACE.
5246 static bool run_owner_rights(int dummy)
5248 static struct cli_state *cli = NULL;
5249 const char *fname = "owner_rights.txt";
5250 uint16_t fnum = (uint16_t)-1;
5251 struct security_descriptor *sd = NULL;
5252 struct security_descriptor *newsd = NULL;
5254 TALLOC_CTX *frame = NULL;
5256 frame = talloc_stackframe();
5257 printf("starting owner rights test\n");
5259 /* Windows connection. */
5260 if (!torture_open_connection(&cli, 0)) {
5264 smbXcli_conn_set_sockopt(cli->conn, sockops);
5266 /* Start with a clean slate. */
5267 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5269 /* Create the test file. */
5270 /* Now try and open for read and write-dac. */
5271 status = cli_ntcreate(cli,
5275 FILE_ATTRIBUTE_NORMAL,
5276 FILE_SHARE_READ|FILE_SHARE_WRITE|
5283 if (!NT_STATUS_IS_OK(status)) {
5284 printf("Create of %s - %s\n", fname, nt_errstr(status));
5288 /* Get the original SD. */
5289 status = cli_query_secdesc(cli,
5293 if (!NT_STATUS_IS_OK(status)) {
5294 printf("cli_query_secdesc failed for %s (%s)\n",
5295 fname, nt_errstr(status));
5300 * Add an "owner-rights" ACE denying WRITE_DATA,
5301 * and an "owner-rights" ACE allowing READ_DATA.
5304 newsd = security_descriptor_dacl_create(frame,
5309 SEC_ACE_TYPE_ACCESS_DENIED,
5313 SEC_ACE_TYPE_ACCESS_ALLOWED,
5317 if (newsd == NULL) {
5320 sd->dacl = security_acl_concatenate(frame,
5323 if (sd->dacl == NULL) {
5326 status = cli_set_secdesc(cli, fnum, sd);
5327 if (!NT_STATUS_IS_OK(status)) {
5328 printf("cli_set_secdesc failed for %s (%s)\n",
5329 fname, nt_errstr(status));
5332 status = cli_close(cli, fnum);
5333 if (!NT_STATUS_IS_OK(status)) {
5334 printf("close failed for %s (%s)\n",
5335 fname, nt_errstr(status));
5338 fnum = (uint16_t)-1;
5340 /* Try and open for FILE_WRITE_DATA */
5341 status = cli_ntcreate(cli,
5345 FILE_ATTRIBUTE_NORMAL,
5346 FILE_SHARE_READ|FILE_SHARE_WRITE|
5353 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5354 printf("Open of %s - %s\n", fname, nt_errstr(status));
5358 /* Now try and open for FILE_READ_DATA */
5359 status = cli_ntcreate(cli,
5363 FILE_ATTRIBUTE_NORMAL,
5364 FILE_SHARE_READ|FILE_SHARE_WRITE|
5371 if (!NT_STATUS_IS_OK(status)) {
5372 printf("Open of %s - %s\n", fname, nt_errstr(status));
5376 status = cli_close(cli, fnum);
5377 if (!NT_STATUS_IS_OK(status)) {
5378 printf("close failed for %s (%s)\n",
5379 fname, nt_errstr(status));
5383 /* Restore clean slate. */
5385 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5387 /* Create the test file. */
5388 status = cli_ntcreate(cli,
5392 FILE_ATTRIBUTE_NORMAL,
5393 FILE_SHARE_READ|FILE_SHARE_WRITE|
5400 if (!NT_STATUS_IS_OK(status)) {
5401 printf("Create of %s - %s\n", fname, nt_errstr(status));
5405 /* Get the original SD. */
5406 status = cli_query_secdesc(cli,
5410 if (!NT_STATUS_IS_OK(status)) {
5411 printf("cli_query_secdesc failed for %s (%s)\n",
5412 fname, nt_errstr(status));
5417 * Add an "owner-rights ACE denying WRITE_DATA,
5418 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5421 newsd = security_descriptor_dacl_create(frame,
5426 SEC_ACE_TYPE_ACCESS_DENIED,
5430 SEC_ACE_TYPE_ACCESS_ALLOWED,
5431 FILE_READ_DATA|FILE_WRITE_DATA,
5434 if (newsd == NULL) {
5437 sd->dacl = security_acl_concatenate(frame,
5440 if (sd->dacl == NULL) {
5443 status = cli_set_secdesc(cli, fnum, sd);
5444 if (!NT_STATUS_IS_OK(status)) {
5445 printf("cli_set_secdesc failed for %s (%s)\n",
5446 fname, nt_errstr(status));
5449 status = cli_close(cli, fnum);
5450 if (!NT_STATUS_IS_OK(status)) {
5451 printf("close failed for %s (%s)\n",
5452 fname, nt_errstr(status));
5455 fnum = (uint16_t)-1;
5457 /* Try and open for FILE_WRITE_DATA */
5458 status = cli_ntcreate(cli,
5462 FILE_ATTRIBUTE_NORMAL,
5463 FILE_SHARE_READ|FILE_SHARE_WRITE|
5470 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5471 printf("Open of %s - %s\n", fname, nt_errstr(status));
5475 /* Now try and open for FILE_READ_DATA */
5476 status = cli_ntcreate(cli,
5480 FILE_ATTRIBUTE_NORMAL,
5481 FILE_SHARE_READ|FILE_SHARE_WRITE|
5488 if (!NT_STATUS_IS_OK(status)) {
5489 printf("Open of %s - %s\n", fname, nt_errstr(status));
5493 status = cli_close(cli, fnum);
5494 if (!NT_STATUS_IS_OK(status)) {
5495 printf("close failed for %s (%s)\n",
5496 fname, nt_errstr(status));
5500 /* Restore clean slate. */
5502 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5505 /* Create the test file. */
5506 status = cli_ntcreate(cli,
5510 FILE_ATTRIBUTE_NORMAL,
5511 FILE_SHARE_READ|FILE_SHARE_WRITE|
5518 if (!NT_STATUS_IS_OK(status)) {
5519 printf("Create of %s - %s\n", fname, nt_errstr(status));
5523 /* Get the original SD. */
5524 status = cli_query_secdesc(cli,
5528 if (!NT_STATUS_IS_OK(status)) {
5529 printf("cli_query_secdesc failed for %s (%s)\n",
5530 fname, nt_errstr(status));
5535 * Add an "authenticated users" ACE allowing READ_DATA,
5536 * add an "owner-rights" denying READ_DATA,
5537 * and an "authenticated users" ACE allowing WRITE_DATA.
5540 newsd = security_descriptor_dacl_create(frame,
5544 SID_NT_AUTHENTICATED_USERS,
5545 SEC_ACE_TYPE_ACCESS_ALLOWED,
5549 SEC_ACE_TYPE_ACCESS_DENIED,
5552 SID_NT_AUTHENTICATED_USERS,
5553 SEC_ACE_TYPE_ACCESS_ALLOWED,
5557 if (newsd == NULL) {
5558 printf("newsd == NULL\n");
5561 sd->dacl = security_acl_concatenate(frame,
5564 if (sd->dacl == NULL) {
5565 printf("sd->dacl == NULL\n");
5568 status = cli_set_secdesc(cli, fnum, sd);
5569 if (!NT_STATUS_IS_OK(status)) {
5570 printf("cli_set_secdesc failed for %s (%s)\n",
5571 fname, nt_errstr(status));
5574 status = cli_close(cli, fnum);
5575 if (!NT_STATUS_IS_OK(status)) {
5576 printf("close failed for %s (%s)\n",
5577 fname, nt_errstr(status));
5580 fnum = (uint16_t)-1;
5582 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5583 status = cli_ntcreate(cli,
5586 FILE_READ_DATA|FILE_WRITE_DATA,
5587 FILE_ATTRIBUTE_NORMAL,
5588 FILE_SHARE_READ|FILE_SHARE_WRITE|
5595 if (!NT_STATUS_IS_OK(status)) {
5596 printf("Open of %s - %s\n", fname, nt_errstr(status));
5600 status = cli_close(cli, fnum);
5601 if (!NT_STATUS_IS_OK(status)) {
5602 printf("close failed for %s (%s)\n",
5603 fname, nt_errstr(status));
5607 cli_unlink(cli, fname,
5608 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5616 if (fnum != (uint16_t)-1) {
5617 cli_close(cli, fnum);
5619 cli_unlink(cli, fname,
5620 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5621 torture_close_connection(cli);
5628 static bool run_pipe_number(int dummy)
5630 struct cli_state *cli1;
5631 const char *pipe_name = "\\SPOOLSS";
5636 printf("starting pipenumber test\n");
5637 if (!torture_open_connection(&cli1, 0)) {
5641 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5643 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
5644 FILE_ATTRIBUTE_NORMAL,
5645 FILE_SHARE_READ|FILE_SHARE_WRITE,
5646 FILE_OPEN_IF, 0, 0, &fnum, NULL);
5647 if (!NT_STATUS_IS_OK(status)) {
5648 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
5652 printf("\r%6d", num_pipes);
5655 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
5656 torture_close_connection(cli1);
5661 Test open mode returns on read-only files.
5663 static bool run_opentest(int dummy)
5665 static struct cli_state *cli1;
5666 static struct cli_state *cli2;
5667 const char *fname = "\\readonly.file";
5668 uint16_t fnum1, fnum2;
5671 bool correct = True;
5675 printf("starting open test\n");
5677 if (!torture_open_connection(&cli1, 0)) {
5681 cli_setatr(cli1, fname, 0, 0);
5682 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5684 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5686 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5687 if (!NT_STATUS_IS_OK(status)) {
5688 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5692 status = cli_close(cli1, fnum1);
5693 if (!NT_STATUS_IS_OK(status)) {
5694 printf("close2 failed (%s)\n", nt_errstr(status));
5698 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
5699 if (!NT_STATUS_IS_OK(status)) {
5700 printf("cli_setatr failed (%s)\n", nt_errstr(status));
5704 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5705 if (!NT_STATUS_IS_OK(status)) {
5706 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5710 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5711 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5713 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
5714 NT_STATUS_ACCESS_DENIED)) {
5715 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5718 printf("finished open test 1\n");
5720 cli_close(cli1, fnum1);
5722 /* Now try not readonly and ensure ERRbadshare is returned. */
5724 cli_setatr(cli1, fname, 0, 0);
5726 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5727 if (!NT_STATUS_IS_OK(status)) {
5728 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5732 /* This will fail - but the error should be ERRshare. */
5733 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5735 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5736 NT_STATUS_SHARING_VIOLATION)) {
5737 printf("correct error code ERRDOS/ERRbadshare returned\n");
5740 status = cli_close(cli1, fnum1);
5741 if (!NT_STATUS_IS_OK(status)) {
5742 printf("close2 failed (%s)\n", nt_errstr(status));
5746 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5748 printf("finished open test 2\n");
5750 /* Test truncate open disposition on file opened for read. */
5751 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5752 if (!NT_STATUS_IS_OK(status)) {
5753 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5757 /* write 20 bytes. */
5759 memset(buf, '\0', 20);
5761 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5762 if (!NT_STATUS_IS_OK(status)) {
5763 printf("write failed (%s)\n", nt_errstr(status));
5767 status = cli_close(cli1, fnum1);
5768 if (!NT_STATUS_IS_OK(status)) {
5769 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5773 /* Ensure size == 20. */
5774 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5775 if (!NT_STATUS_IS_OK(status)) {
5776 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5781 printf("(3) file size != 20\n");
5785 /* Now test if we can truncate a file opened for readonly. */
5786 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5787 if (!NT_STATUS_IS_OK(status)) {
5788 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5792 status = cli_close(cli1, fnum1);
5793 if (!NT_STATUS_IS_OK(status)) {
5794 printf("close2 failed (%s)\n", nt_errstr(status));
5798 /* Ensure size == 0. */
5799 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5800 if (!NT_STATUS_IS_OK(status)) {
5801 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5806 printf("(3) file size != 0\n");
5809 printf("finished open test 3\n");
5811 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5813 printf("Do ctemp tests\n");
5814 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5815 if (!NT_STATUS_IS_OK(status)) {
5816 printf("ctemp failed (%s)\n", nt_errstr(status));
5820 printf("ctemp gave path %s\n", tmp_path);
5821 status = cli_close(cli1, fnum1);
5822 if (!NT_STATUS_IS_OK(status)) {
5823 printf("close of temp failed (%s)\n", nt_errstr(status));
5826 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5827 if (!NT_STATUS_IS_OK(status)) {
5828 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5831 /* Test the non-io opens... */
5833 if (!torture_open_connection(&cli2, 1)) {
5837 cli_setatr(cli2, fname, 0, 0);
5838 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5840 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5842 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5843 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5844 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5845 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5846 if (!NT_STATUS_IS_OK(status)) {
5847 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5851 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5852 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5853 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5854 if (!NT_STATUS_IS_OK(status)) {
5855 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5859 status = cli_close(cli1, fnum1);
5860 if (!NT_STATUS_IS_OK(status)) {
5861 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5865 status = cli_close(cli2, fnum2);
5866 if (!NT_STATUS_IS_OK(status)) {
5867 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5871 printf("non-io open test #1 passed.\n");
5873 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5875 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5877 status = cli_ntcreate(cli1, fname, 0,
5878 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5879 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5880 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5881 if (!NT_STATUS_IS_OK(status)) {
5882 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5886 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5887 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5888 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5889 if (!NT_STATUS_IS_OK(status)) {
5890 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5894 status = cli_close(cli1, fnum1);
5895 if (!NT_STATUS_IS_OK(status)) {
5896 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5900 status = cli_close(cli2, fnum2);
5901 if (!NT_STATUS_IS_OK(status)) {
5902 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5906 printf("non-io open test #2 passed.\n");
5908 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5910 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5912 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5913 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5914 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5915 if (!NT_STATUS_IS_OK(status)) {
5916 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5920 status = cli_ntcreate(cli2, fname, 0,
5921 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5922 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5923 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5924 if (!NT_STATUS_IS_OK(status)) {
5925 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5929 status = cli_close(cli1, fnum1);
5930 if (!NT_STATUS_IS_OK(status)) {
5931 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5935 status = cli_close(cli2, fnum2);
5936 if (!NT_STATUS_IS_OK(status)) {
5937 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5941 printf("non-io open test #3 passed.\n");
5943 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5945 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5947 status = cli_ntcreate(cli1, fname, 0,
5948 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5949 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5950 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5951 if (!NT_STATUS_IS_OK(status)) {
5952 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5956 status = cli_ntcreate(cli2, fname, 0,
5957 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5958 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5959 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5960 if (NT_STATUS_IS_OK(status)) {
5961 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5965 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5967 status = cli_close(cli1, fnum1);
5968 if (!NT_STATUS_IS_OK(status)) {
5969 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5973 printf("non-io open test #4 passed.\n");
5975 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5977 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5979 status = cli_ntcreate(cli1, fname, 0,
5980 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5981 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5982 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5983 if (!NT_STATUS_IS_OK(status)) {
5984 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5988 status = cli_ntcreate(cli2, fname, 0,
5989 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5990 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5991 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5992 if (!NT_STATUS_IS_OK(status)) {
5993 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5997 status = cli_close(cli1, fnum1);
5998 if (!NT_STATUS_IS_OK(status)) {
5999 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6003 status = cli_close(cli2, fnum2);
6004 if (!NT_STATUS_IS_OK(status)) {
6005 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6009 printf("non-io open test #5 passed.\n");
6011 printf("TEST #6 testing 1 non-io open, one io open\n");
6013 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6015 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6016 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6017 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6018 if (!NT_STATUS_IS_OK(status)) {
6019 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6023 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
6024 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6025 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6026 if (!NT_STATUS_IS_OK(status)) {
6027 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6031 status = cli_close(cli1, fnum1);
6032 if (!NT_STATUS_IS_OK(status)) {
6033 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6037 status = cli_close(cli2, fnum2);
6038 if (!NT_STATUS_IS_OK(status)) {
6039 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6043 printf("non-io open test #6 passed.\n");
6045 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
6047 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6049 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6050 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6051 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6052 if (!NT_STATUS_IS_OK(status)) {
6053 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6057 status = cli_ntcreate(cli2, fname, 0,
6058 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6059 FILE_ATTRIBUTE_NORMAL,
6060 FILE_SHARE_READ|FILE_SHARE_DELETE,
6061 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6062 if (NT_STATUS_IS_OK(status)) {
6063 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
6067 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
6069 status = cli_close(cli1, fnum1);
6070 if (!NT_STATUS_IS_OK(status)) {
6071 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6075 printf("non-io open test #7 passed.\n");
6077 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6079 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
6080 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
6081 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6082 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6083 if (!NT_STATUS_IS_OK(status)) {
6084 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
6089 /* Write to ensure we have to update the file time. */
6090 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6092 if (!NT_STATUS_IS_OK(status)) {
6093 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
6098 status = cli_close(cli1, fnum1);
6099 if (!NT_STATUS_IS_OK(status)) {
6100 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
6106 if (!torture_close_connection(cli1)) {
6109 if (!torture_close_connection(cli2)) {
6116 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
6118 uint16_t major, minor;
6119 uint32_t caplow, caphigh;
6122 if (!SERVER_HAS_UNIX_CIFS(cli)) {
6123 printf("Server doesn't support UNIX CIFS extensions.\n");
6124 return NT_STATUS_NOT_SUPPORTED;
6127 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
6129 if (!NT_STATUS_IS_OK(status)) {
6130 printf("Server didn't return UNIX CIFS extensions: %s\n",
6135 status = cli_set_unix_extensions_capabilities(cli, major, minor,
6137 if (!NT_STATUS_IS_OK(status)) {
6138 printf("Server doesn't support setting UNIX CIFS extensions: "
6139 "%s.\n", nt_errstr(status));
6143 return NT_STATUS_OK;
6147 Test POSIX open /mkdir calls.
6149 static bool run_simple_posix_open_test(int dummy)
6151 static struct cli_state *cli1;
6152 const char *fname = "posix:file";
6153 const char *hname = "posix:hlink";
6154 const char *sname = "posix:symlink";
6155 const char *dname = "posix:dir";
6158 uint16_t fnum1 = (uint16_t)-1;
6159 SMB_STRUCT_STAT sbuf;
6160 bool correct = false;
6163 const char *fname_windows = "windows_file";
6164 uint16_t fnum2 = (uint16_t)-1;
6166 printf("Starting simple POSIX open test\n");
6168 if (!torture_open_connection(&cli1, 0)) {
6172 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6174 status = torture_setup_unix_extensions(cli1);
6175 if (!NT_STATUS_IS_OK(status)) {
6179 cli_setatr(cli1, fname, 0, 0);
6180 cli_posix_unlink(cli1, fname);
6181 cli_setatr(cli1, dname, 0, 0);
6182 cli_posix_rmdir(cli1, dname);
6183 cli_setatr(cli1, hname, 0, 0);
6184 cli_posix_unlink(cli1, hname);
6185 cli_setatr(cli1, sname, 0, 0);
6186 cli_posix_unlink(cli1, sname);
6187 cli_setatr(cli1, fname_windows, 0, 0);
6188 cli_posix_unlink(cli1, fname_windows);
6190 /* Create a directory. */
6191 status = cli_posix_mkdir(cli1, dname, 0777);
6192 if (!NT_STATUS_IS_OK(status)) {
6193 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6197 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6199 if (!NT_STATUS_IS_OK(status)) {
6200 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6204 /* Test ftruncate - set file size. */
6205 status = cli_ftruncate(cli1, fnum1, 1000);
6206 if (!NT_STATUS_IS_OK(status)) {
6207 printf("ftruncate failed (%s)\n", nt_errstr(status));
6211 /* Ensure st_size == 1000 */
6212 status = cli_posix_stat(cli1, fname, &sbuf);
6213 if (!NT_STATUS_IS_OK(status)) {
6214 printf("stat failed (%s)\n", nt_errstr(status));
6218 if (sbuf.st_ex_size != 1000) {
6219 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6223 /* Ensure st_mode == 0600 */
6224 if ((sbuf.st_ex_mode & 07777) != 0600) {
6225 printf("posix_open - bad permissions 0%o != 0600\n",
6226 (unsigned int)(sbuf.st_ex_mode & 07777));
6230 /* Test ftruncate - set file size back to zero. */
6231 status = cli_ftruncate(cli1, fnum1, 0);
6232 if (!NT_STATUS_IS_OK(status)) {
6233 printf("ftruncate failed (%s)\n", nt_errstr(status));
6237 status = cli_close(cli1, fnum1);
6238 if (!NT_STATUS_IS_OK(status)) {
6239 printf("close failed (%s)\n", nt_errstr(status));
6243 /* Now open the file again for read only. */
6244 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6245 if (!NT_STATUS_IS_OK(status)) {
6246 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
6250 /* Now unlink while open. */
6251 status = cli_posix_unlink(cli1, fname);
6252 if (!NT_STATUS_IS_OK(status)) {
6253 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6257 status = cli_close(cli1, fnum1);
6258 if (!NT_STATUS_IS_OK(status)) {
6259 printf("close(2) failed (%s)\n", nt_errstr(status));
6263 /* Ensure the file has gone. */
6264 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6265 if (NT_STATUS_IS_OK(status)) {
6266 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
6270 /* Create again to test open with O_TRUNC. */
6271 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
6272 if (!NT_STATUS_IS_OK(status)) {
6273 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6277 /* Test ftruncate - set file size. */
6278 status = cli_ftruncate(cli1, fnum1, 1000);
6279 if (!NT_STATUS_IS_OK(status)) {
6280 printf("ftruncate failed (%s)\n", nt_errstr(status));
6284 /* Ensure st_size == 1000 */
6285 status = cli_posix_stat(cli1, fname, &sbuf);
6286 if (!NT_STATUS_IS_OK(status)) {
6287 printf("stat failed (%s)\n", nt_errstr(status));
6291 if (sbuf.st_ex_size != 1000) {
6292 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6296 status = cli_close(cli1, fnum1);
6297 if (!NT_STATUS_IS_OK(status)) {
6298 printf("close(2) failed (%s)\n", nt_errstr(status));
6302 /* Re-open with O_TRUNC. */
6303 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
6304 if (!NT_STATUS_IS_OK(status)) {
6305 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6309 /* Ensure st_size == 0 */
6310 status = cli_posix_stat(cli1, fname, &sbuf);
6311 if (!NT_STATUS_IS_OK(status)) {
6312 printf("stat failed (%s)\n", nt_errstr(status));
6316 if (sbuf.st_ex_size != 0) {
6317 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
6321 status = cli_close(cli1, fnum1);
6322 if (!NT_STATUS_IS_OK(status)) {
6323 printf("close failed (%s)\n", nt_errstr(status));
6327 status = cli_posix_unlink(cli1, fname);
6328 if (!NT_STATUS_IS_OK(status)) {
6329 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6333 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
6334 if (!NT_STATUS_IS_OK(status)) {
6335 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6336 dname, nt_errstr(status));
6340 cli_close(cli1, fnum1);
6342 /* What happens when we try and POSIX open a directory for write ? */
6343 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
6344 if (NT_STATUS_IS_OK(status)) {
6345 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
6348 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
6349 NT_STATUS_FILE_IS_A_DIRECTORY)) {
6354 /* Create the file. */
6355 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6357 if (!NT_STATUS_IS_OK(status)) {
6358 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6362 /* Write some data into it. */
6363 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6365 if (!NT_STATUS_IS_OK(status)) {
6366 printf("cli_write failed: %s\n", nt_errstr(status));
6370 cli_close(cli1, fnum1);
6372 /* Now create a hardlink. */
6373 status = cli_posix_hardlink(cli1, fname, hname);
6374 if (!NT_STATUS_IS_OK(status)) {
6375 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
6379 /* Now create a symlink. */
6380 status = cli_posix_symlink(cli1, fname, sname);
6381 if (!NT_STATUS_IS_OK(status)) {
6382 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
6386 /* Open the hardlink for read. */
6387 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
6388 if (!NT_STATUS_IS_OK(status)) {
6389 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
6393 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
6394 if (!NT_STATUS_IS_OK(status)) {
6395 printf("POSIX read of %s failed (%s)\n", hname,
6398 } else if (nread != 10) {
6399 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6400 hname, (unsigned long)nread, 10);
6404 if (memcmp(buf, "TEST DATA\n", 10)) {
6405 printf("invalid data read from hardlink\n");
6409 /* Do a POSIX lock/unlock. */
6410 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
6411 if (!NT_STATUS_IS_OK(status)) {
6412 printf("POSIX lock failed %s\n", nt_errstr(status));
6416 /* Punch a hole in the locked area. */
6417 status = cli_posix_unlock(cli1, fnum1, 10, 80);
6418 if (!NT_STATUS_IS_OK(status)) {
6419 printf("POSIX unlock failed %s\n", nt_errstr(status));
6423 cli_close(cli1, fnum1);
6425 /* Open the symlink for read - this should fail. A POSIX
6426 client should not be doing opens on a symlink. */
6427 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
6428 if (NT_STATUS_IS_OK(status)) {
6429 printf("POSIX open of %s succeeded (should have failed)\n", sname);
6432 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
6433 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
6434 printf("POSIX open of %s should have failed "
6435 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6436 "failed with %s instead.\n",
6437 sname, nt_errstr(status));
6442 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
6443 if (!NT_STATUS_IS_OK(status)) {
6444 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
6448 if (strcmp(namebuf, fname) != 0) {
6449 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6450 sname, fname, namebuf);
6454 status = cli_posix_rmdir(cli1, dname);
6455 if (!NT_STATUS_IS_OK(status)) {
6456 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
6460 /* Check directory opens with a specific permission. */
6461 status = cli_posix_mkdir(cli1, dname, 0700);
6462 if (!NT_STATUS_IS_OK(status)) {
6463 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6467 /* Ensure st_mode == 0700 */
6468 status = cli_posix_stat(cli1, dname, &sbuf);
6469 if (!NT_STATUS_IS_OK(status)) {
6470 printf("stat failed (%s)\n", nt_errstr(status));
6474 if ((sbuf.st_ex_mode & 07777) != 0700) {
6475 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6476 (unsigned int)(sbuf.st_ex_mode & 07777));
6481 * Now create a Windows file, and attempt a POSIX unlink.
6482 * This should fail with a sharing violation but due to:
6484 * [Bug 9571] Unlink after open causes smbd to panic
6486 * ensure we've fixed the lock ordering violation.
6489 status = cli_ntcreate(cli1, fname_windows, 0,
6490 FILE_READ_DATA|FILE_WRITE_DATA, 0,
6491 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6493 0x0, 0x0, &fnum2, NULL);
6494 if (!NT_STATUS_IS_OK(status)) {
6495 printf("Windows create of %s failed (%s)\n", fname_windows,
6500 /* Now try posix_unlink. */
6501 status = cli_posix_unlink(cli1, fname_windows);
6502 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6503 printf("POSIX unlink of %s should fail "
6504 "with NT_STATUS_SHARING_VIOLATION "
6505 "got %s instead !\n",
6511 cli_close(cli1, fnum2);
6513 printf("Simple POSIX open test passed\n");
6518 if (fnum1 != (uint16_t)-1) {
6519 cli_close(cli1, fnum1);
6520 fnum1 = (uint16_t)-1;
6523 if (fnum2 != (uint16_t)-1) {
6524 cli_close(cli1, fnum2);
6525 fnum2 = (uint16_t)-1;
6528 cli_setatr(cli1, sname, 0, 0);
6529 cli_posix_unlink(cli1, sname);
6530 cli_setatr(cli1, hname, 0, 0);
6531 cli_posix_unlink(cli1, hname);
6532 cli_setatr(cli1, fname, 0, 0);
6533 cli_posix_unlink(cli1, fname);
6534 cli_setatr(cli1, dname, 0, 0);
6535 cli_posix_rmdir(cli1, dname);
6536 cli_setatr(cli1, fname_windows, 0, 0);
6537 cli_posix_unlink(cli1, fname_windows);
6539 if (!torture_close_connection(cli1)) {
6547 Test POSIX and Windows ACLs are rejected on symlinks.
6549 static bool run_acl_symlink_test(int dummy)
6551 static struct cli_state *cli;
6552 const char *fname = "posix_file";
6553 const char *sname = "posix_symlink";
6554 uint16_t fnum = (uint16_t)-1;
6555 bool correct = false;
6557 char *posix_acl = NULL;
6558 size_t posix_acl_len = 0;
6559 char *posix_acl_sym = NULL;
6560 size_t posix_acl_len_sym = 0;
6561 struct security_descriptor *sd = NULL;
6562 struct security_descriptor *sd_sym = NULL;
6563 TALLOC_CTX *frame = NULL;
6565 frame = talloc_stackframe();
6567 printf("Starting acl symlink test\n");
6569 if (!torture_open_connection(&cli, 0)) {
6574 smbXcli_conn_set_sockopt(cli->conn, sockops);
6576 status = torture_setup_unix_extensions(cli);
6577 if (!NT_STATUS_IS_OK(status)) {
6582 cli_setatr(cli, fname, 0, 0);
6583 cli_posix_unlink(cli, fname);
6584 cli_setatr(cli, sname, 0, 0);
6585 cli_posix_unlink(cli, sname);
6587 status = cli_ntcreate(cli,
6590 READ_CONTROL_ACCESS,
6592 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6599 if (!NT_STATUS_IS_OK(status)) {
6600 printf("cli_ntcreate of %s failed (%s)\n",
6606 /* Get the Windows ACL on the file. */
6607 status = cli_query_secdesc(cli,
6611 if (!NT_STATUS_IS_OK(status)) {
6612 printf("cli_query_secdesc failed (%s)\n",
6617 /* Get the POSIX ACL on the file. */
6618 status = cli_posix_getacl(cli,
6624 if (!NT_STATUS_IS_OK(status)) {
6625 printf("cli_posix_getacl failed (%s)\n",
6630 status = cli_close(cli, fnum);
6631 if (!NT_STATUS_IS_OK(status)) {
6632 printf("close failed (%s)\n", nt_errstr(status));
6635 fnum = (uint16_t)-1;
6637 /* Now create a symlink. */
6638 status = cli_posix_symlink(cli, fname, sname);
6639 if (!NT_STATUS_IS_OK(status)) {
6640 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6647 /* Open a handle on the symlink. */
6648 status = cli_ntcreate(cli,
6651 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
6653 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6660 if (!NT_STATUS_IS_OK(status)) {
6661 printf("cli_posix_open of %s failed (%s)\n",
6667 /* Get the Windows ACL on the symlink handle. Should fail */
6668 status = cli_query_secdesc(cli,
6673 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6674 printf("cli_query_secdesc on a symlink gave %s. "
6675 "Should be NT_STATUS_ACCESS_DENIED.\n",
6680 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6681 status = cli_posix_getacl(cli,
6687 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6688 printf("cli_posix_getacl on a symlink gave %s. "
6689 "Should be NT_STATUS_ACCESS_DENIED.\n",
6694 /* Set the Windows ACL on the symlink handle. Should fail */
6695 status = cli_set_security_descriptor(cli,
6700 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6701 printf("cli_query_secdesc on a symlink gave %s. "
6702 "Should be NT_STATUS_ACCESS_DENIED.\n",
6707 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6708 status = cli_posix_setacl(cli,
6713 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6714 printf("cli_posix_getacl on a symlink gave %s. "
6715 "Should be NT_STATUS_ACCESS_DENIED.\n",
6720 printf("ACL symlink test passed\n");
6725 if (fnum != (uint16_t)-1) {
6726 cli_close(cli, fnum);
6727 fnum = (uint16_t)-1;
6730 cli_setatr(cli, sname, 0, 0);
6731 cli_posix_unlink(cli, sname);
6732 cli_setatr(cli, fname, 0, 0);
6733 cli_posix_unlink(cli, fname);
6735 if (!torture_close_connection(cli)) {
6744 Test POSIX can delete a file containing streams.
6746 static bool run_posix_stream_delete(int dummy)
6748 struct cli_state *cli1 = NULL;
6749 struct cli_state *cli2 = NULL;
6750 const char *fname = "streamfile";
6751 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6752 uint16_t fnum1 = (uint16_t)-1;
6753 bool correct = false;
6755 TALLOC_CTX *frame = NULL;
6757 frame = talloc_stackframe();
6759 printf("Starting POSIX stream delete test\n");
6761 if (!torture_open_connection(&cli1, 0) ||
6762 !torture_open_connection(&cli2, 1)) {
6767 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6768 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6770 status = torture_setup_unix_extensions(cli2);
6771 if (!NT_STATUS_IS_OK(status)) {
6775 cli_setatr(cli1, fname, 0, 0);
6776 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6778 /* Create the file. */
6779 status = cli_ntcreate(cli1,
6782 READ_CONTROL_ACCESS,
6784 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6791 if (!NT_STATUS_IS_OK(status)) {
6792 printf("cli_ntcreate of %s failed (%s)\n",
6798 status = cli_close(cli1, fnum1);
6799 if (!NT_STATUS_IS_OK(status)) {
6800 printf("cli_close of %s failed (%s)\n",
6805 fnum1 = (uint16_t)-1;
6807 /* Now create the stream. */
6808 status = cli_ntcreate(cli1,
6813 FILE_SHARE_READ|FILE_SHARE_WRITE,
6820 if (!NT_STATUS_IS_OK(status)) {
6821 printf("cli_ntcreate of %s failed (%s)\n",
6827 /* Leave the stream handle open... */
6829 /* POSIX unlink should fail. */
6830 status = cli_posix_unlink(cli2, fname);
6831 if (NT_STATUS_IS_OK(status)) {
6832 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6837 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6838 printf("cli_posix_unlink of %s failed with (%s) "
6839 "should have been NT_STATUS_SHARING_VIOLATION\n",
6845 /* Close the stream handle. */
6846 status = cli_close(cli1, fnum1);
6847 if (!NT_STATUS_IS_OK(status)) {
6848 printf("cli_close of %s failed (%s)\n",
6853 fnum1 = (uint16_t)-1;
6855 /* POSIX unlink after stream handle closed should succeed. */
6856 status = cli_posix_unlink(cli2, fname);
6857 if (!NT_STATUS_IS_OK(status)) {
6858 printf("cli_posix_unlink of %s failed (%s)\n",
6864 printf("POSIX stream delete test passed\n");
6869 if (fnum1 != (uint16_t)-1) {
6870 cli_close(cli1, fnum1);
6871 fnum1 = (uint16_t)-1;
6874 cli_setatr(cli1, fname, 0, 0);
6875 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6877 if (!torture_close_connection(cli1)) {
6880 if (!torture_close_connection(cli2)) {
6889 Test setting EA's are rejected on symlinks.
6891 static bool run_ea_symlink_test(int dummy)
6893 static struct cli_state *cli;
6894 const char *fname = "posix_file_ea";
6895 const char *sname = "posix_symlink_ea";
6896 const char *ea_name = "testea_name";
6897 const char *ea_value = "testea_value";
6898 uint16_t fnum = (uint16_t)-1;
6899 bool correct = false;
6902 struct ea_struct *eas = NULL;
6903 TALLOC_CTX *frame = NULL;
6905 frame = talloc_stackframe();
6907 printf("Starting EA symlink test\n");
6909 if (!torture_open_connection(&cli, 0)) {
6914 smbXcli_conn_set_sockopt(cli->conn, sockops);
6916 status = torture_setup_unix_extensions(cli);
6917 if (!NT_STATUS_IS_OK(status)) {
6922 cli_setatr(cli, fname, 0, 0);
6923 cli_posix_unlink(cli, fname);
6924 cli_setatr(cli, sname, 0, 0);
6925 cli_posix_unlink(cli, sname);
6927 status = cli_ntcreate(cli,
6930 READ_CONTROL_ACCESS,
6932 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6939 if (!NT_STATUS_IS_OK(status)) {
6940 printf("cli_ntcreate of %s failed (%s)\n",
6946 status = cli_close(cli, fnum);
6947 if (!NT_STATUS_IS_OK(status)) {
6948 printf("close failed (%s)\n",
6952 fnum = (uint16_t)-1;
6954 /* Set an EA on the path. */
6955 status = cli_set_ea_path(cli,
6959 strlen(ea_value)+1);
6961 if (!NT_STATUS_IS_OK(status)) {
6962 printf("cli_set_ea_path failed (%s)\n",
6967 /* Now create a symlink. */
6968 status = cli_posix_symlink(cli, fname, sname);
6969 if (!NT_STATUS_IS_OK(status)) {
6970 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6977 /* Get the EA list on the path. Should return value set. */
6978 status = cli_get_ea_list_path(cli,
6984 if (!NT_STATUS_IS_OK(status)) {
6985 printf("cli_get_ea_list_path failed (%s)\n",
6990 /* Ensure the EA we set is there. */
6991 for (i=0; i<num_eas; i++) {
6992 if (strcmp(eas[i].name, ea_name) == 0 &&
6993 eas[i].value.length == strlen(ea_value)+1 &&
6994 memcmp(eas[i].value.data,
6996 eas[i].value.length) == 0) {
7002 printf("Didn't find EA on pathname %s\n",
7010 /* Get the EA list on the symlink. Should return empty list. */
7011 status = cli_get_ea_list_path(cli,
7017 if (!NT_STATUS_IS_OK(status)) {
7018 printf("cli_get_ea_list_path failed (%s)\n",
7024 printf("cli_get_ea_list_path failed (%s)\n",
7029 /* Set an EA on the symlink. Should fail. */
7030 status = cli_set_ea_path(cli,
7034 strlen(ea_value)+1);
7036 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7037 printf("cli_set_ea_path on a symlink gave %s. "
7038 "Should be NT_STATUS_ACCESS_DENIED.\n",
7043 printf("EA symlink test passed\n");
7048 if (fnum != (uint16_t)-1) {
7049 cli_close(cli, fnum);
7050 fnum = (uint16_t)-1;
7053 cli_setatr(cli, sname, 0, 0);
7054 cli_posix_unlink(cli, sname);
7055 cli_setatr(cli, fname, 0, 0);
7056 cli_posix_unlink(cli, fname);
7058 if (!torture_close_connection(cli)) {
7067 Test POSIX locks are OFD-locks.
7069 static bool run_posix_ofd_lock_test(int dummy)
7071 static struct cli_state *cli;
7072 const char *fname = "posix_file";
7073 uint16_t fnum1 = (uint16_t)-1;
7074 uint16_t fnum2 = (uint16_t)-1;
7075 bool correct = false;
7077 TALLOC_CTX *frame = NULL;
7079 frame = talloc_stackframe();
7081 printf("Starting POSIX ofd-lock test\n");
7083 if (!torture_open_connection(&cli, 0)) {
7088 smbXcli_conn_set_sockopt(cli->conn, sockops);
7090 status = torture_setup_unix_extensions(cli);
7091 if (!NT_STATUS_IS_OK(status)) {
7096 cli_setatr(cli, fname, 0, 0);
7097 cli_posix_unlink(cli, fname);
7099 /* Open the file twice. */
7100 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
7102 if (!NT_STATUS_IS_OK(status)) {
7103 printf("First POSIX open of %s failed\n", fname);
7107 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
7108 if (!NT_STATUS_IS_OK(status)) {
7109 printf("First POSIX open of %s failed\n", fname);
7113 /* Set a 0-50 lock on fnum1. */
7114 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7115 if (!NT_STATUS_IS_OK(status)) {
7116 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
7120 /* Set a 60-100 lock on fnum2. */
7121 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
7122 if (!NT_STATUS_IS_OK(status)) {
7123 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
7127 /* close fnum1 - 0-50 lock should go away. */
7128 status = cli_close(cli, fnum1);
7129 if (!NT_STATUS_IS_OK(status)) {
7130 printf("close failed (%s)\n",
7134 fnum1 = (uint16_t)-1;
7136 /* Change the lock context. */
7137 cli_setpid(cli, cli_getpid(cli) + 1);
7139 /* Re-open fnum1. */
7140 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
7141 if (!NT_STATUS_IS_OK(status)) {
7142 printf("Third POSIX open of %s failed\n", fname);
7146 /* 60-100 lock should still be there. */
7147 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
7148 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
7149 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
7153 /* 0-50 lock should be gone. */
7154 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7155 if (!NT_STATUS_IS_OK(status)) {
7156 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
7160 printf("POSIX OFD lock test passed\n");
7165 if (fnum1 != (uint16_t)-1) {
7166 cli_close(cli, fnum1);
7167 fnum1 = (uint16_t)-1;
7169 if (fnum2 != (uint16_t)-1) {
7170 cli_close(cli, fnum2);
7171 fnum2 = (uint16_t)-1;
7174 cli_setatr(cli, fname, 0, 0);
7175 cli_posix_unlink(cli, fname);
7177 if (!torture_close_connection(cli)) {
7185 static uint32_t open_attrs_table[] = {
7186 FILE_ATTRIBUTE_NORMAL,
7187 FILE_ATTRIBUTE_ARCHIVE,
7188 FILE_ATTRIBUTE_READONLY,
7189 FILE_ATTRIBUTE_HIDDEN,
7190 FILE_ATTRIBUTE_SYSTEM,
7192 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7193 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7194 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7195 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7196 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7197 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7199 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7200 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7201 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7202 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7205 struct trunc_open_results {
7208 uint32_t trunc_attr;
7209 uint32_t result_attr;
7212 static struct trunc_open_results attr_results[] = {
7213 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7214 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7215 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7216 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7217 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7218 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7219 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7220 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7221 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7222 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7223 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7224 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7225 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7226 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7227 { 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 },
7228 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7229 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7230 { 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 },
7231 { 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 },
7232 { 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 },
7233 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7234 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7235 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7236 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7237 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7238 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7241 static bool run_openattrtest(int dummy)
7243 static struct cli_state *cli1;
7244 const char *fname = "\\openattr.file";
7246 bool correct = True;
7248 unsigned int i, j, k, l;
7251 printf("starting open attr test\n");
7253 if (!torture_open_connection(&cli1, 0)) {
7257 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7259 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7260 cli_setatr(cli1, fname, 0, 0);
7261 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7263 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7264 open_attrs_table[i], FILE_SHARE_NONE,
7265 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7266 if (!NT_STATUS_IS_OK(status)) {
7267 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7271 status = cli_close(cli1, fnum1);
7272 if (!NT_STATUS_IS_OK(status)) {
7273 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7277 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7278 status = cli_ntcreate(cli1, fname, 0,
7279 FILE_READ_DATA|FILE_WRITE_DATA,
7280 open_attrs_table[j],
7281 FILE_SHARE_NONE, FILE_OVERWRITE,
7282 0, 0, &fnum1, NULL);
7283 if (!NT_STATUS_IS_OK(status)) {
7284 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7285 if (attr_results[l].num == k) {
7286 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7287 k, open_attrs_table[i],
7288 open_attrs_table[j],
7289 fname, NT_STATUS_V(status), nt_errstr(status));
7294 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7295 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7296 k, open_attrs_table[i], open_attrs_table[j],
7301 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7307 status = cli_close(cli1, fnum1);
7308 if (!NT_STATUS_IS_OK(status)) {
7309 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7313 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7314 if (!NT_STATUS_IS_OK(status)) {
7315 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7320 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7321 k, open_attrs_table[i], open_attrs_table[j], attr );
7324 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7325 if (attr_results[l].num == k) {
7326 if (attr != attr_results[l].result_attr ||
7327 open_attrs_table[i] != attr_results[l].init_attr ||
7328 open_attrs_table[j] != attr_results[l].trunc_attr) {
7329 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7330 open_attrs_table[i],
7331 open_attrs_table[j],
7333 attr_results[l].result_attr);
7343 cli_setatr(cli1, fname, 0, 0);
7344 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7346 printf("open attr test %s.\n", correct ? "passed" : "failed");
7348 if (!torture_close_connection(cli1)) {
7354 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7355 const char *name, void *state)
7357 int *matched = (int *)state;
7358 if (matched != NULL) {
7361 return NT_STATUS_OK;
7365 test directory listing speed
7367 static bool run_dirtest(int dummy)
7370 static struct cli_state *cli;
7372 struct timeval core_start;
7373 bool correct = True;
7376 printf("starting directory test\n");
7378 if (!torture_open_connection(&cli, 0)) {
7382 smbXcli_conn_set_sockopt(cli->conn, sockops);
7385 for (i=0;i<torture_numops;i++) {
7387 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7388 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7389 fprintf(stderr,"Failed to open %s\n", fname);
7392 cli_close(cli, fnum);
7395 core_start = timeval_current();
7398 cli_list(cli, "a*.*", 0, list_fn, &matched);
7399 printf("Matched %d\n", matched);
7402 cli_list(cli, "b*.*", 0, list_fn, &matched);
7403 printf("Matched %d\n", matched);
7406 cli_list(cli, "xyzabc", 0, list_fn, &matched);
7407 printf("Matched %d\n", matched);
7409 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7412 for (i=0;i<torture_numops;i++) {
7414 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7415 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7418 if (!torture_close_connection(cli)) {
7422 printf("finished dirtest\n");
7427 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7430 struct cli_state *pcli = (struct cli_state *)state;
7432 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7434 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7435 return NT_STATUS_OK;
7437 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7438 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7439 printf("del_fn: failed to rmdir %s\n,", fname );
7441 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7442 printf("del_fn: failed to unlink %s\n,", fname );
7444 return NT_STATUS_OK;
7449 sees what IOCTLs are supported
7451 bool torture_ioctl_test(int dummy)
7453 static struct cli_state *cli;
7454 uint16_t device, function;
7456 const char *fname = "\\ioctl.dat";
7460 if (!torture_open_connection(&cli, 0)) {
7464 printf("starting ioctl test\n");
7466 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7468 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7469 if (!NT_STATUS_IS_OK(status)) {
7470 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7474 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7475 printf("ioctl device info: %s\n", nt_errstr(status));
7477 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7478 printf("ioctl job info: %s\n", nt_errstr(status));
7480 for (device=0;device<0x100;device++) {
7481 printf("ioctl test with device = 0x%x\n", device);
7482 for (function=0;function<0x100;function++) {
7483 uint32_t code = (device<<16) | function;
7485 status = cli_raw_ioctl(cli, fnum, code, &blob);
7487 if (NT_STATUS_IS_OK(status)) {
7488 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7490 data_blob_free(&blob);
7495 if (!torture_close_connection(cli)) {
7504 tries varients of chkpath
7506 bool torture_chkpath_test(int dummy)
7508 static struct cli_state *cli;
7513 if (!torture_open_connection(&cli, 0)) {
7517 printf("starting chkpath test\n");
7519 /* cleanup from an old run */
7520 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7521 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7522 cli_rmdir(cli, "\\chkpath.dir");
7524 status = cli_mkdir(cli, "\\chkpath.dir");
7525 if (!NT_STATUS_IS_OK(status)) {
7526 printf("mkdir1 failed : %s\n", nt_errstr(status));
7530 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7531 if (!NT_STATUS_IS_OK(status)) {
7532 printf("mkdir2 failed : %s\n", nt_errstr(status));
7536 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7538 if (!NT_STATUS_IS_OK(status)) {
7539 printf("open1 failed (%s)\n", nt_errstr(status));
7542 cli_close(cli, fnum);
7544 status = cli_chkpath(cli, "\\chkpath.dir");
7545 if (!NT_STATUS_IS_OK(status)) {
7546 printf("chkpath1 failed: %s\n", nt_errstr(status));
7550 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7551 if (!NT_STATUS_IS_OK(status)) {
7552 printf("chkpath2 failed: %s\n", nt_errstr(status));
7556 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7557 if (!NT_STATUS_IS_OK(status)) {
7558 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7559 NT_STATUS_NOT_A_DIRECTORY);
7561 printf("* chkpath on a file should fail\n");
7565 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7566 if (!NT_STATUS_IS_OK(status)) {
7567 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7568 NT_STATUS_OBJECT_NAME_NOT_FOUND);
7570 printf("* chkpath on a non existent file should fail\n");
7574 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7575 if (!NT_STATUS_IS_OK(status)) {
7576 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7577 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7579 printf("* chkpath on a non existent component should fail\n");
7583 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7584 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7585 cli_rmdir(cli, "\\chkpath.dir");
7587 if (!torture_close_connection(cli)) {
7594 static bool run_eatest(int dummy)
7596 static struct cli_state *cli;
7597 const char *fname = "\\eatest.txt";
7598 bool correct = True;
7602 struct ea_struct *ea_list = NULL;
7603 TALLOC_CTX *mem_ctx = talloc_init("eatest");
7606 printf("starting eatest\n");
7608 if (!torture_open_connection(&cli, 0)) {
7609 talloc_destroy(mem_ctx);
7613 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7615 status = cli_ntcreate(cli, fname, 0,
7616 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7617 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7618 0x4044, 0, &fnum, NULL);
7619 if (!NT_STATUS_IS_OK(status)) {
7620 printf("open failed - %s\n", nt_errstr(status));
7621 talloc_destroy(mem_ctx);
7625 for (i = 0; i < 10; i++) {
7626 fstring ea_name, ea_val;
7628 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7629 memset(ea_val, (char)i+1, i+1);
7630 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7631 if (!NT_STATUS_IS_OK(status)) {
7632 printf("ea_set of name %s failed - %s\n", ea_name,
7634 talloc_destroy(mem_ctx);
7639 cli_close(cli, fnum);
7640 for (i = 0; i < 10; i++) {
7641 fstring ea_name, ea_val;
7643 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7644 memset(ea_val, (char)i+1, i+1);
7645 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7646 if (!NT_STATUS_IS_OK(status)) {
7647 printf("ea_set of name %s failed - %s\n", ea_name,
7649 talloc_destroy(mem_ctx);
7654 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7655 if (!NT_STATUS_IS_OK(status)) {
7656 printf("ea_get list failed - %s\n", nt_errstr(status));
7660 printf("num_eas = %d\n", (int)num_eas);
7662 if (num_eas != 20) {
7663 printf("Should be 20 EA's stored... failing.\n");
7667 for (i = 0; i < num_eas; i++) {
7668 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7669 dump_data(0, ea_list[i].value.data,
7670 ea_list[i].value.length);
7673 /* Setting EA's to zero length deletes them. Test this */
7674 printf("Now deleting all EA's - case indepenent....\n");
7677 cli_set_ea_path(cli, fname, "", "", 0);
7679 for (i = 0; i < 20; i++) {
7681 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7682 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7683 if (!NT_STATUS_IS_OK(status)) {
7684 printf("ea_set of name %s failed - %s\n", ea_name,
7686 talloc_destroy(mem_ctx);
7692 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7693 if (!NT_STATUS_IS_OK(status)) {
7694 printf("ea_get list failed - %s\n", nt_errstr(status));
7698 printf("num_eas = %d\n", (int)num_eas);
7699 for (i = 0; i < num_eas; i++) {
7700 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7701 dump_data(0, ea_list[i].value.data,
7702 ea_list[i].value.length);
7706 printf("deleting EA's failed.\n");
7710 /* Try and delete a non existent EA. */
7711 status = cli_set_ea_path(cli, fname, "foo", "", 0);
7712 if (!NT_STATUS_IS_OK(status)) {
7713 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7718 talloc_destroy(mem_ctx);
7719 if (!torture_close_connection(cli)) {
7726 static bool run_dirtest1(int dummy)
7729 static struct cli_state *cli;
7732 bool correct = True;
7734 printf("starting directory test\n");
7736 if (!torture_open_connection(&cli, 0)) {
7740 smbXcli_conn_set_sockopt(cli->conn, sockops);
7742 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7743 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7744 cli_rmdir(cli, "\\LISTDIR");
7745 cli_mkdir(cli, "\\LISTDIR");
7747 /* Create 1000 files and 1000 directories. */
7748 for (i=0;i<1000;i++) {
7750 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7751 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7752 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7753 0, 0, &fnum, NULL))) {
7754 fprintf(stderr,"Failed to open %s\n", fname);
7757 cli_close(cli, fnum);
7759 for (i=0;i<1000;i++) {
7761 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7762 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7763 fprintf(stderr,"Failed to open %s\n", fname);
7768 /* Now ensure that doing an old list sees both files and directories. */
7770 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7771 printf("num_seen = %d\n", num_seen );
7772 /* We should see 100 files + 1000 directories + . and .. */
7773 if (num_seen != 2002)
7776 /* Ensure if we have the "must have" bits we only see the
7780 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7781 printf("num_seen = %d\n", num_seen );
7782 if (num_seen != 1002)
7786 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7787 printf("num_seen = %d\n", num_seen );
7788 if (num_seen != 1000)
7791 /* Delete everything. */
7792 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7793 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7794 cli_rmdir(cli, "\\LISTDIR");
7797 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7798 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7799 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7802 if (!torture_close_connection(cli)) {
7806 printf("finished dirtest1\n");
7811 static bool run_error_map_extract(int dummy) {
7813 static struct cli_state *c_dos;
7814 static struct cli_state *c_nt;
7826 /* NT-Error connection */
7828 disable_spnego = true;
7829 if (!(c_nt = open_nbt_connection())) {
7830 disable_spnego = false;
7833 disable_spnego = false;
7835 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7838 if (!NT_STATUS_IS_OK(status)) {
7839 printf("%s rejected the NT-error negprot (%s)\n", host,
7845 status = cli_session_setup_anon(c_nt);
7846 if (!NT_STATUS_IS_OK(status)) {
7847 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7851 /* DOS-Error connection */
7853 disable_spnego = true;
7854 force_dos_errors = true;
7855 if (!(c_dos = open_nbt_connection())) {
7856 disable_spnego = false;
7857 force_dos_errors = false;
7860 disable_spnego = false;
7861 force_dos_errors = false;
7863 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7865 if (!NT_STATUS_IS_OK(status)) {
7866 printf("%s rejected the DOS-error negprot (%s)\n", host,
7868 cli_shutdown(c_dos);
7872 status = cli_session_setup_anon(c_dos);
7873 if (!NT_STATUS_IS_OK(status)) {
7874 printf("%s rejected the DOS-error initial session setup (%s)\n",
7875 host, nt_errstr(status));
7879 c_nt->map_dos_errors = false;
7880 c_dos->map_dos_errors = false;
7882 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7883 struct cli_credentials *user_creds = NULL;
7885 fstr_sprintf(user, "%X", error);
7887 user_creds = cli_session_creds_init(talloc_tos(),
7892 false, /* use_kerberos */
7893 false, /* fallback_after_kerberos */
7894 false, /* use_ccache */
7895 false); /* password_is_nt_hash */
7896 if (user_creds == NULL) {
7897 printf("cli_session_creds_init(%s) failed\n", user);
7901 status = cli_session_setup_creds(c_nt, user_creds);
7902 if (NT_STATUS_IS_OK(status)) {
7903 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7906 /* Case #1: 32-bit NT errors */
7907 if (!NT_STATUS_IS_DOS(status)) {
7910 printf("/** Dos error on NT connection! (%s) */\n",
7912 nt_status = NT_STATUS(0xc0000000);
7915 status = cli_session_setup_creds(c_dos, user_creds);
7916 if (NT_STATUS_IS_OK(status)) {
7917 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7920 /* Case #1: 32-bit NT errors */
7921 if (NT_STATUS_IS_DOS(status)) {
7922 printf("/** NT error on DOS connection! (%s) */\n",
7924 errnum = errclass = 0;
7926 errclass = NT_STATUS_DOS_CLASS(status);
7927 errnum = NT_STATUS_DOS_CODE(status);
7930 if (NT_STATUS_V(nt_status) != error) {
7931 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7932 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
7933 get_nt_error_c_code(talloc_tos(), nt_status));
7936 printf("\t{%s,\t%s,\t%s},\n",
7937 smb_dos_err_class(errclass),
7938 smb_dos_err_name(errclass, errnum),
7939 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7941 TALLOC_FREE(user_creds);
7946 static bool run_sesssetup_bench(int dummy)
7948 static struct cli_state *c;
7949 const char *fname = "\\file.dat";
7954 if (!torture_open_connection(&c, 0)) {
7958 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7959 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7960 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7961 if (!NT_STATUS_IS_OK(status)) {
7962 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7966 for (i=0; i<torture_numops; i++) {
7967 status = cli_session_setup_creds(c, torture_creds);
7968 if (!NT_STATUS_IS_OK(status)) {
7969 d_printf("(%s) cli_session_setup_creds failed: %s\n",
7970 __location__, nt_errstr(status));
7974 d_printf("\r%d ", (int)cli_state_get_uid(c));
7976 status = cli_ulogoff(c);
7977 if (!NT_STATUS_IS_OK(status)) {
7978 d_printf("(%s) cli_ulogoff failed: %s\n",
7979 __location__, nt_errstr(status));
7987 static bool subst_test(const char *str, const char *user, const char *domain,
7988 uid_t uid, gid_t gid, const char *expected)
7993 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7995 if (strcmp(subst, expected) != 0) {
7996 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7997 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
8006 static void chain1_open_completion(struct tevent_req *req)
8010 status = cli_openx_recv(req, &fnum);
8013 d_printf("cli_openx_recv returned %s: %d\n",
8015 NT_STATUS_IS_OK(status) ? fnum : -1);
8018 static void chain1_write_completion(struct tevent_req *req)
8022 status = cli_write_andx_recv(req, &written);
8025 d_printf("cli_write_andx_recv returned %s: %d\n",
8027 NT_STATUS_IS_OK(status) ? (int)written : -1);
8030 static void chain1_close_completion(struct tevent_req *req)
8033 bool *done = (bool *)tevent_req_callback_data_void(req);
8035 status = cli_close_recv(req);
8040 d_printf("cli_close returned %s\n", nt_errstr(status));
8043 static bool run_chain1(int dummy)
8045 struct cli_state *cli1;
8046 struct tevent_context *evt = samba_tevent_context_init(NULL);
8047 struct tevent_req *reqs[3], *smbreqs[3];
8049 const char *str = "foobar";
8052 printf("starting chain1 test\n");
8053 if (!torture_open_connection(&cli1, 0)) {
8057 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8059 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
8060 O_CREAT|O_RDWR, 0, &smbreqs[0]);
8061 if (reqs[0] == NULL) return false;
8062 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
8065 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
8066 (const uint8_t *)str, 0, strlen(str)+1,
8067 smbreqs, 1, &smbreqs[1]);
8068 if (reqs[1] == NULL) return false;
8069 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
8071 reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
8072 if (reqs[2] == NULL) return false;
8073 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
8075 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8076 if (!NT_STATUS_IS_OK(status)) {
8081 tevent_loop_once(evt);
8084 torture_close_connection(cli1);
8088 static void chain2_sesssetup_completion(struct tevent_req *req)
8091 status = cli_session_setup_guest_recv(req);
8092 d_printf("sesssetup returned %s\n", nt_errstr(status));
8095 static void chain2_tcon_completion(struct tevent_req *req)
8097 bool *done = (bool *)tevent_req_callback_data_void(req);
8099 status = cli_tcon_andx_recv(req);
8100 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
8104 static bool run_chain2(int dummy)
8106 struct cli_state *cli1;
8107 struct tevent_context *evt = samba_tevent_context_init(NULL);
8108 struct tevent_req *reqs[2], *smbreqs[2];
8111 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
8113 printf("starting chain2 test\n");
8114 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
8115 port_to_use, SMB_SIGNING_DEFAULT, flags);
8116 if (!NT_STATUS_IS_OK(status)) {
8120 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8122 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
8124 if (reqs[0] == NULL) return false;
8125 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
8127 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
8128 "?????", NULL, 0, &smbreqs[1]);
8129 if (reqs[1] == NULL) return false;
8130 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
8132 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8133 if (!NT_STATUS_IS_OK(status)) {
8138 tevent_loop_once(evt);
8141 torture_close_connection(cli1);
8146 struct torture_createdel_state {
8147 struct tevent_context *ev;
8148 struct cli_state *cli;
8151 static void torture_createdel_created(struct tevent_req *subreq);
8152 static void torture_createdel_closed(struct tevent_req *subreq);
8154 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8155 struct tevent_context *ev,
8156 struct cli_state *cli,
8159 struct tevent_req *req, *subreq;
8160 struct torture_createdel_state *state;
8162 req = tevent_req_create(mem_ctx, &state,
8163 struct torture_createdel_state);
8170 subreq = cli_ntcreate_send(
8171 state, ev, cli, name, 0,
8172 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8173 FILE_ATTRIBUTE_NORMAL,
8174 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8175 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
8177 if (tevent_req_nomem(subreq, req)) {
8178 return tevent_req_post(req, ev);
8180 tevent_req_set_callback(subreq, torture_createdel_created, req);
8184 static void torture_createdel_created(struct tevent_req *subreq)
8186 struct tevent_req *req = tevent_req_callback_data(
8187 subreq, struct tevent_req);
8188 struct torture_createdel_state *state = tevent_req_data(
8189 req, struct torture_createdel_state);
8193 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8194 TALLOC_FREE(subreq);
8195 if (tevent_req_nterror(req, status)) {
8196 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8197 nt_errstr(status)));
8201 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8202 if (tevent_req_nomem(subreq, req)) {
8205 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8208 static void torture_createdel_closed(struct tevent_req *subreq)
8210 struct tevent_req *req = tevent_req_callback_data(
8211 subreq, struct tevent_req);
8214 status = cli_close_recv(subreq);
8215 if (tevent_req_nterror(req, status)) {
8216 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8219 tevent_req_done(req);
8222 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8224 return tevent_req_simple_recv_ntstatus(req);
8227 struct torture_createdels_state {
8228 struct tevent_context *ev;
8229 struct cli_state *cli;
8230 const char *base_name;
8234 struct tevent_req **reqs;
8237 static void torture_createdels_done(struct tevent_req *subreq);
8239 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8240 struct tevent_context *ev,
8241 struct cli_state *cli,
8242 const char *base_name,
8246 struct tevent_req *req;
8247 struct torture_createdels_state *state;
8250 req = tevent_req_create(mem_ctx, &state,
8251 struct torture_createdels_state);
8257 state->base_name = talloc_strdup(state, base_name);
8258 if (tevent_req_nomem(state->base_name, req)) {
8259 return tevent_req_post(req, ev);
8261 state->num_files = MAX(num_parallel, num_files);
8263 state->received = 0;
8265 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8266 if (tevent_req_nomem(state->reqs, req)) {
8267 return tevent_req_post(req, ev);
8270 for (i=0; i<num_parallel; i++) {
8273 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8275 if (tevent_req_nomem(name, req)) {
8276 return tevent_req_post(req, ev);
8278 state->reqs[i] = torture_createdel_send(
8279 state->reqs, state->ev, state->cli, name);
8280 if (tevent_req_nomem(state->reqs[i], req)) {
8281 return tevent_req_post(req, ev);
8283 name = talloc_move(state->reqs[i], &name);
8284 tevent_req_set_callback(state->reqs[i],
8285 torture_createdels_done, req);
8291 static void torture_createdels_done(struct tevent_req *subreq)
8293 struct tevent_req *req = tevent_req_callback_data(
8294 subreq, struct tevent_req);
8295 struct torture_createdels_state *state = tevent_req_data(
8296 req, struct torture_createdels_state);
8297 size_t num_parallel = talloc_array_length(state->reqs);
8302 status = torture_createdel_recv(subreq);
8303 if (!NT_STATUS_IS_OK(status)){
8304 DEBUG(10, ("torture_createdel_recv returned %s\n",
8305 nt_errstr(status)));
8306 TALLOC_FREE(subreq);
8307 tevent_req_nterror(req, status);
8311 for (i=0; i<num_parallel; i++) {
8312 if (subreq == state->reqs[i]) {
8316 if (i == num_parallel) {
8317 DEBUG(10, ("received something we did not send\n"));
8318 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8321 TALLOC_FREE(state->reqs[i]);
8323 if (state->sent >= state->num_files) {
8324 tevent_req_done(req);
8328 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8330 if (tevent_req_nomem(name, req)) {
8333 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8335 if (tevent_req_nomem(state->reqs[i], req)) {
8338 name = talloc_move(state->reqs[i], &name);
8339 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8343 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8345 return tevent_req_simple_recv_ntstatus(req);
8348 struct swallow_notify_state {
8349 struct tevent_context *ev;
8350 struct cli_state *cli;
8352 uint32_t completion_filter;
8354 bool (*fn)(uint32_t action, const char *name, void *priv);
8358 static void swallow_notify_done(struct tevent_req *subreq);
8360 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8361 struct tevent_context *ev,
8362 struct cli_state *cli,
8364 uint32_t completion_filter,
8366 bool (*fn)(uint32_t action,
8371 struct tevent_req *req, *subreq;
8372 struct swallow_notify_state *state;
8374 req = tevent_req_create(mem_ctx, &state,
8375 struct swallow_notify_state);
8382 state->completion_filter = completion_filter;
8383 state->recursive = recursive;
8387 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8388 0xffff, state->completion_filter,
8390 if (tevent_req_nomem(subreq, req)) {
8391 return tevent_req_post(req, ev);
8393 tevent_req_set_callback(subreq, swallow_notify_done, req);
8397 static void swallow_notify_done(struct tevent_req *subreq)
8399 struct tevent_req *req = tevent_req_callback_data(
8400 subreq, struct tevent_req);
8401 struct swallow_notify_state *state = tevent_req_data(
8402 req, struct swallow_notify_state);
8404 uint32_t i, num_changes;
8405 struct notify_change *changes;
8407 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8408 TALLOC_FREE(subreq);
8409 if (!NT_STATUS_IS_OK(status)) {
8410 DEBUG(10, ("cli_notify_recv returned %s\n",
8411 nt_errstr(status)));
8412 tevent_req_nterror(req, status);
8416 for (i=0; i<num_changes; i++) {
8417 state->fn(changes[i].action, changes[i].name, state->priv);
8419 TALLOC_FREE(changes);
8421 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8422 0xffff, state->completion_filter,
8424 if (tevent_req_nomem(subreq, req)) {
8427 tevent_req_set_callback(subreq, swallow_notify_done, req);
8430 static bool print_notifies(uint32_t action, const char *name, void *priv)
8432 if (DEBUGLEVEL > 5) {
8433 d_printf("%d %s\n", (int)action, name);
8438 static void notify_bench_done(struct tevent_req *req)
8440 int *num_finished = (int *)tevent_req_callback_data_void(req);
8444 static bool run_notify_bench(int dummy)
8446 const char *dname = "\\notify-bench";
8447 struct tevent_context *ev;
8450 struct tevent_req *req1;
8451 struct tevent_req *req2 = NULL;
8452 int i, num_unc_names;
8453 int num_finished = 0;
8455 printf("starting notify-bench test\n");
8457 if (use_multishare_conn) {
8459 unc_list = file_lines_load(multishare_conn_fname,
8460 &num_unc_names, 0, NULL);
8461 if (!unc_list || num_unc_names <= 0) {
8462 d_printf("Failed to load unc names list from '%s'\n",
8463 multishare_conn_fname);
8466 TALLOC_FREE(unc_list);
8471 ev = samba_tevent_context_init(talloc_tos());
8473 d_printf("tevent_context_init failed\n");
8477 for (i=0; i<num_unc_names; i++) {
8478 struct cli_state *cli;
8481 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8483 if (base_fname == NULL) {
8487 if (!torture_open_connection(&cli, i)) {
8491 status = cli_ntcreate(cli, dname, 0,
8492 MAXIMUM_ALLOWED_ACCESS,
8493 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8495 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8498 if (!NT_STATUS_IS_OK(status)) {
8499 d_printf("Could not create %s: %s\n", dname,
8504 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8505 FILE_NOTIFY_CHANGE_FILE_NAME |
8506 FILE_NOTIFY_CHANGE_DIR_NAME |
8507 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8508 FILE_NOTIFY_CHANGE_LAST_WRITE,
8509 false, print_notifies, NULL);
8511 d_printf("Could not create notify request\n");
8515 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8516 base_fname, 10, torture_numops);
8518 d_printf("Could not create createdels request\n");
8521 TALLOC_FREE(base_fname);
8523 tevent_req_set_callback(req2, notify_bench_done,
8527 while (num_finished < num_unc_names) {
8529 ret = tevent_loop_once(ev);
8531 d_printf("tevent_loop_once failed\n");
8536 if (!tevent_req_poll(req2, ev)) {
8537 d_printf("tevent_req_poll failed\n");
8540 status = torture_createdels_recv(req2);
8541 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8546 static bool run_mangle1(int dummy)
8548 struct cli_state *cli;
8549 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8553 time_t change_time, access_time, write_time;
8557 printf("starting mangle1 test\n");
8558 if (!torture_open_connection(&cli, 0)) {
8562 smbXcli_conn_set_sockopt(cli->conn, sockops);
8564 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8565 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8567 if (!NT_STATUS_IS_OK(status)) {
8568 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8571 cli_close(cli, fnum);
8573 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8574 if (!NT_STATUS_IS_OK(status)) {
8575 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8579 d_printf("alt_name: %s\n", alt_name);
8581 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8582 if (!NT_STATUS_IS_OK(status)) {
8583 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8587 cli_close(cli, fnum);
8589 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8590 &write_time, &size, &mode);
8591 if (!NT_STATUS_IS_OK(status)) {
8592 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8600 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8601 struct file_info *f,
8605 if (f->short_name == NULL) {
8606 return NT_STATUS_OK;
8609 if (strlen(f->short_name) == 0) {
8610 return NT_STATUS_OK;
8613 printf("unexpected shortname: %s\n", f->short_name);
8615 return NT_STATUS_OBJECT_NAME_INVALID;
8618 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8619 struct file_info *f,
8625 printf("name: %s\n", f->name);
8626 fstrcpy(name, f->name);
8627 return NT_STATUS_OK;
8630 static bool run_mangle_illegal(int dummy)
8632 struct cli_state *cli = NULL;
8633 struct cli_state *cli_posix = NULL;
8634 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8635 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8636 char *mangled_path = NULL;
8642 printf("starting mangle-illegal test\n");
8644 if (!torture_open_connection(&cli, 0)) {
8648 smbXcli_conn_set_sockopt(cli->conn, sockops);
8650 if (!torture_open_connection(&cli_posix, 0)) {
8654 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8656 status = torture_setup_unix_extensions(cli_posix);
8657 if (!NT_STATUS_IS_OK(status)) {
8661 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8662 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8663 if (!NT_STATUS_IS_OK(status)) {
8664 printf("mkdir1 failed : %s\n", nt_errstr(status));
8669 * Create a file with illegal NTFS characters and test that we
8670 * get a usable mangled name
8673 cli_setatr(cli_posix, illegal_fname, 0, 0);
8674 cli_posix_unlink(cli_posix, illegal_fname);
8676 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8678 if (!NT_STATUS_IS_OK(status)) {
8679 printf("POSIX create of %s failed (%s)\n",
8680 illegal_fname, nt_errstr(status));
8684 status = cli_close(cli_posix, fnum);
8685 if (!NT_STATUS_IS_OK(status)) {
8686 printf("close failed (%s)\n", nt_errstr(status));
8690 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8691 if (!NT_STATUS_IS_OK(status)) {
8692 d_printf("cli_list failed: %s\n", nt_errstr(status));
8696 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8697 if (mangled_path == NULL) {
8701 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8702 if (!NT_STATUS_IS_OK(status)) {
8703 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8704 TALLOC_FREE(mangled_path);
8707 TALLOC_FREE(mangled_path);
8708 cli_close(cli, fnum);
8710 cli_setatr(cli_posix, illegal_fname, 0, 0);
8711 cli_posix_unlink(cli_posix, illegal_fname);
8714 * Create a file with a long name and check that we got *no* short name.
8717 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8718 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8720 if (!NT_STATUS_IS_OK(status)) {
8721 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8724 cli_close(cli, fnum);
8726 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8727 if (!NT_STATUS_IS_OK(status)) {
8728 d_printf("cli_list failed\n");
8732 cli_unlink(cli, fname, 0);
8733 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8735 if (!torture_close_connection(cli_posix)) {
8739 if (!torture_close_connection(cli)) {
8746 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8748 size_t *to_pull = (size_t *)priv;
8749 size_t thistime = *to_pull;
8751 thistime = MIN(thistime, n);
8752 if (thistime == 0) {
8756 memset(buf, 0, thistime);
8757 *to_pull -= thistime;
8761 static bool run_windows_write(int dummy)
8763 struct cli_state *cli1;
8767 const char *fname = "\\writetest.txt";
8768 struct timeval start_time;
8773 printf("starting windows_write test\n");
8774 if (!torture_open_connection(&cli1, 0)) {
8778 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8779 if (!NT_STATUS_IS_OK(status)) {
8780 printf("open failed (%s)\n", nt_errstr(status));
8784 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8786 start_time = timeval_current();
8788 for (i=0; i<torture_numops; i++) {
8790 off_t start = i * torture_blocksize;
8791 size_t to_pull = torture_blocksize - 1;
8793 status = cli_writeall(cli1, fnum, 0, &c,
8794 start + torture_blocksize - 1, 1, NULL);
8795 if (!NT_STATUS_IS_OK(status)) {
8796 printf("cli_write failed: %s\n", nt_errstr(status));
8800 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8801 null_source, &to_pull);
8802 if (!NT_STATUS_IS_OK(status)) {
8803 printf("cli_push returned: %s\n", nt_errstr(status));
8808 seconds = timeval_elapsed(&start_time);
8809 kbytes = (double)torture_blocksize * torture_numops;
8812 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8813 (double)seconds, (int)(kbytes/seconds));
8817 cli_close(cli1, fnum);
8818 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8819 torture_close_connection(cli1);
8823 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8825 size_t max_pdu = 0x1FFFF;
8827 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8831 if (smb1cli_conn_signing_is_active(cli->conn)) {
8835 if (smb1cli_conn_encryption_on(cli->conn)) {
8836 max_pdu = CLI_BUFFER_SIZE;
8839 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8840 len_requested &= 0xFFFF;
8843 return MIN(len_requested,
8844 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8847 static bool check_read_call(struct cli_state *cli,
8850 size_t len_requested)
8853 struct tevent_req *subreq = NULL;
8854 ssize_t len_read = 0;
8855 size_t len_expected = 0;
8856 struct tevent_context *ev = NULL;
8858 ev = samba_tevent_context_init(talloc_tos());
8863 subreq = cli_read_andx_send(talloc_tos(),
8870 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8874 status = cli_read_andx_recv(subreq, &len_read, &buf);
8875 if (!NT_STATUS_IS_OK(status)) {
8876 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8880 TALLOC_FREE(subreq);
8883 len_expected = calc_expected_return(cli, len_requested);
8885 if (len_expected > 0x10000 && len_read == 0x10000) {
8886 /* Windows servers only return a max of 0x10000,
8887 doesn't matter if you set CAP_LARGE_READX in
8888 the client sessionsetupX call or not. */
8889 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8890 (unsigned int)len_requested);
8891 } else if (len_read != len_expected) {
8892 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8893 (unsigned int)len_requested,
8894 (unsigned int)len_read,
8895 (unsigned int)len_expected);
8898 d_printf("Correct read reply.\n");
8904 /* Test large readX variants. */
8905 static bool large_readx_tests(struct cli_state *cli,
8909 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8910 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8913 /* A read of 0x10000 should return 0x10000 bytes. */
8914 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8917 /* A read of 0x10000 should return 0x10001 bytes. */
8918 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8921 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8922 the requested number of bytes. */
8923 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8926 /* A read of 1MB should return 1MB bytes (on Samba). */
8927 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
8931 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
8934 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
8937 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
8943 static bool run_large_readx(int dummy)
8945 uint8_t *buf = NULL;
8946 struct cli_state *cli1 = NULL;
8947 struct cli_state *cli2 = NULL;
8948 bool correct = false;
8949 const char *fname = "\\large_readx.dat";
8951 uint16_t fnum1 = UINT16_MAX;
8952 uint32_t normal_caps = 0;
8953 size_t file_size = 20*1024*1024;
8954 TALLOC_CTX *frame = talloc_stackframe();
8958 enum smb_signing_setting signing_setting;
8959 enum protocol_types protocol;
8963 .signing_setting = SMB_SIGNING_IF_REQUIRED,
8964 .protocol = PROTOCOL_NT1,
8966 .name = "NT1 - SIGNING_REQUIRED",
8967 .signing_setting = SMB_SIGNING_REQUIRED,
8968 .protocol = PROTOCOL_NT1,
8972 printf("starting large_readx test\n");
8974 if (!torture_open_connection(&cli1, 0)) {
8978 normal_caps = smb1cli_conn_capabilities(cli1->conn);
8980 if (!(normal_caps & CAP_LARGE_READX)) {
8981 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8982 (unsigned int)normal_caps);
8986 /* Create a file of size 4MB. */
8987 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
8988 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8989 0, 0, &fnum1, NULL);
8991 if (!NT_STATUS_IS_OK(status)) {
8992 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8996 /* Write file_size bytes. */
8997 buf = talloc_zero_array(frame, uint8_t, file_size);
9002 status = cli_writeall(cli1,
9009 if (!NT_STATUS_IS_OK(status)) {
9010 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9014 status = cli_close(cli1, fnum1);
9015 if (!NT_STATUS_IS_OK(status)) {
9016 d_printf("cli_close failed: %s\n", nt_errstr(status));
9022 for (i=0; i < ARRAY_SIZE(runs); i++) {
9023 enum smb_signing_setting saved_signing_setting = signing_state;
9024 uint16_t fnum2 = -1;
9027 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
9029 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
9033 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
9035 signing_state = runs[i].signing_setting;
9036 cli2 = open_nbt_connection();
9037 signing_state = saved_signing_setting;
9042 status = smbXcli_negprot(cli2->conn,
9046 if (!NT_STATUS_IS_OK(status)) {
9050 status = cli_session_setup_creds(cli2, torture_creds);
9051 if (!NT_STATUS_IS_OK(status)) {
9055 status = cli_tree_connect(cli2,
9059 if (!NT_STATUS_IS_OK(status)) {
9063 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
9065 normal_caps = smb1cli_conn_capabilities(cli2->conn);
9067 if (!(normal_caps & CAP_LARGE_READX)) {
9068 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9069 (unsigned int)normal_caps);
9074 if (force_cli_encryption(cli2, share) == false) {
9077 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
9078 uint16_t major, minor;
9079 uint32_t caplow, caphigh;
9081 status = cli_unix_extensions_version(cli2,
9084 if (!NT_STATUS_IS_OK(status)) {
9089 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
9090 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
9091 0, 0, &fnum2, NULL);
9092 if (!NT_STATUS_IS_OK(status)) {
9093 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
9097 /* All reads must return less than file_size bytes. */
9098 if (!large_readx_tests(cli2, fnum2, buf)) {
9102 status = cli_close(cli2, fnum2);
9103 if (!NT_STATUS_IS_OK(status)) {
9104 d_printf("cli_close failed: %s\n", nt_errstr(status));
9109 if (!torture_close_connection(cli2)) {
9116 printf("Success on large_readx test\n");
9121 if (!torture_close_connection(cli2)) {
9127 if (fnum1 != UINT16_MAX) {
9128 status = cli_close(cli1, fnum1);
9129 if (!NT_STATUS_IS_OK(status)) {
9130 d_printf("cli_close failed: %s\n", nt_errstr(status));
9135 status = cli_unlink(cli1, fname,
9136 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9137 if (!NT_STATUS_IS_OK(status)) {
9138 printf("unlink failed (%s)\n", nt_errstr(status));
9141 if (!torture_close_connection(cli1)) {
9148 printf("finished large_readx test\n");
9152 static bool run_cli_echo(int dummy)
9154 struct cli_state *cli;
9157 printf("starting cli_echo test\n");
9158 if (!torture_open_connection(&cli, 0)) {
9161 smbXcli_conn_set_sockopt(cli->conn, sockops);
9163 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9165 d_printf("cli_echo returned %s\n", nt_errstr(status));
9167 torture_close_connection(cli);
9168 return NT_STATUS_IS_OK(status);
9171 static bool run_uid_regression_test(int dummy)
9173 static struct cli_state *cli;
9176 bool correct = True;
9177 struct smbXcli_tcon *orig_tcon = NULL;
9180 printf("starting uid regression test\n");
9182 if (!torture_open_connection(&cli, 0)) {
9186 smbXcli_conn_set_sockopt(cli->conn, sockops);
9188 /* Ok - now save then logoff our current user. */
9189 old_vuid = cli_state_get_uid(cli);
9191 status = cli_ulogoff(cli);
9192 if (!NT_STATUS_IS_OK(status)) {
9193 d_printf("(%s) cli_ulogoff failed: %s\n",
9194 __location__, nt_errstr(status));
9199 cli_state_set_uid(cli, old_vuid);
9201 /* Try an operation. */
9202 status = cli_mkdir(cli, "\\uid_reg_test");
9203 if (NT_STATUS_IS_OK(status)) {
9204 d_printf("(%s) cli_mkdir succeeded\n",
9209 /* Should be bad uid. */
9210 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9211 NT_STATUS_USER_SESSION_DELETED)) {
9217 old_cnum = cli_state_get_tid(cli);
9218 orig_tcon = cli_state_save_tcon(cli);
9219 if (orig_tcon == NULL) {
9224 /* Now try a SMBtdis with the invald vuid set to zero. */
9225 cli_state_set_uid(cli, 0);
9227 /* This should succeed. */
9228 status = cli_tdis(cli);
9230 if (NT_STATUS_IS_OK(status)) {
9231 d_printf("First tdis with invalid vuid should succeed.\n");
9233 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9235 cli_state_restore_tcon(cli, orig_tcon);
9239 cli_state_restore_tcon(cli, orig_tcon);
9240 cli_state_set_uid(cli, old_vuid);
9241 cli_state_set_tid(cli, old_cnum);
9243 /* This should fail. */
9244 status = cli_tdis(cli);
9245 if (NT_STATUS_IS_OK(status)) {
9246 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9250 /* Should be bad tid. */
9251 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9252 NT_STATUS_NETWORK_NAME_DELETED)) {
9258 cli_rmdir(cli, "\\uid_reg_test");
9267 static const char *illegal_chars = "*\\/?<>|\":";
9268 static char force_shortname_chars[] = " +,.[];=\177";
9270 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9271 const char *mask, void *state)
9273 struct cli_state *pcli = (struct cli_state *)state;
9275 NTSTATUS status = NT_STATUS_OK;
9277 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9279 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9280 return NT_STATUS_OK;
9282 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9283 status = cli_rmdir(pcli, fname);
9284 if (!NT_STATUS_IS_OK(status)) {
9285 printf("del_fn: failed to rmdir %s\n,", fname );
9288 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9289 if (!NT_STATUS_IS_OK(status)) {
9290 printf("del_fn: failed to unlink %s\n,", fname );
9302 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9303 const char *name, void *state)
9305 struct sn_state *s = (struct sn_state *)state;
9309 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9310 i, finfo->name, finfo->short_name);
9313 if (strchr(force_shortname_chars, i)) {
9314 if (!finfo->short_name) {
9315 /* Shortname not created when it should be. */
9316 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9317 __location__, finfo->name, i);
9320 } else if (finfo->short_name){
9321 /* Shortname created when it should not be. */
9322 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9323 __location__, finfo->short_name, finfo->name);
9327 return NT_STATUS_OK;
9330 static bool run_shortname_test(int dummy)
9332 static struct cli_state *cli;
9333 bool correct = True;
9339 printf("starting shortname test\n");
9341 if (!torture_open_connection(&cli, 0)) {
9345 smbXcli_conn_set_sockopt(cli->conn, sockops);
9347 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9348 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9349 cli_rmdir(cli, "\\shortname");
9351 status = cli_mkdir(cli, "\\shortname");
9352 if (!NT_STATUS_IS_OK(status)) {
9353 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9354 __location__, nt_errstr(status));
9359 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9363 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9370 for (i = 32; i < 128; i++) {
9371 uint16_t fnum = (uint16_t)-1;
9375 if (strchr(illegal_chars, i)) {
9380 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9381 FILE_SHARE_READ|FILE_SHARE_WRITE,
9382 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9383 if (!NT_STATUS_IS_OK(status)) {
9384 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9385 __location__, fname, nt_errstr(status));
9389 cli_close(cli, fnum);
9392 status = cli_list(cli, "\\shortname\\test*.*", 0,
9393 shortname_list_fn, &s);
9394 if (s.matched != 1) {
9395 d_printf("(%s) failed to list %s: %s\n",
9396 __location__, fname, nt_errstr(status));
9401 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9402 if (!NT_STATUS_IS_OK(status)) {
9403 d_printf("(%s) failed to delete %s: %s\n",
9404 __location__, fname, nt_errstr(status));
9417 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9418 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9419 cli_rmdir(cli, "\\shortname");
9420 torture_close_connection(cli);
9424 static void pagedsearch_cb(struct tevent_req *req)
9427 struct tldap_message *msg;
9430 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9431 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9432 d_printf("tldap_search_paged_recv failed: %s\n",
9433 tldap_rc2string(rc));
9436 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9440 if (!tldap_entry_dn(msg, &dn)) {
9441 d_printf("tldap_entry_dn failed\n");
9444 d_printf("%s\n", dn);
9448 static bool run_tldap(int dummy)
9450 struct tldap_context *ld;
9454 struct sockaddr_storage addr;
9455 struct tevent_context *ev;
9456 struct tevent_req *req;
9460 if (!resolve_name(host, &addr, 0, false)) {
9461 d_printf("could not find host %s\n", host);
9464 status = open_socket_out(&addr, 389, 9999, &fd);
9465 if (!NT_STATUS_IS_OK(status)) {
9466 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9470 ld = tldap_context_create(talloc_tos(), fd);
9473 d_printf("tldap_context_create failed\n");
9477 rc = tldap_fetch_rootdse(ld);
9478 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9479 d_printf("tldap_fetch_rootdse failed: %s\n",
9480 tldap_errstr(talloc_tos(), ld, rc));
9484 basedn = tldap_talloc_single_attribute(
9485 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9486 if (basedn == NULL) {
9487 d_printf("no defaultNamingContext\n");
9490 d_printf("defaultNamingContext: %s\n", basedn);
9492 ev = samba_tevent_context_init(talloc_tos());
9494 d_printf("tevent_context_init failed\n");
9498 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9499 TLDAP_SCOPE_SUB, "(objectclass=*)",
9501 NULL, 0, NULL, 0, 0, 0, 0, 5);
9503 d_printf("tldap_search_paged_send failed\n");
9506 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9508 tevent_req_poll(req, ev);
9512 /* test search filters against rootDSE */
9513 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9514 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9516 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9517 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9518 talloc_tos(), NULL);
9519 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9520 d_printf("tldap_search with complex filter failed: %s\n",
9521 tldap_errstr(talloc_tos(), ld, rc));
9529 /* Torture test to ensure no regression of :
9530 https://bugzilla.samba.org/show_bug.cgi?id=7084
9533 static bool run_dir_createtime(int dummy)
9535 struct cli_state *cli;
9536 const char *dname = "\\testdir";
9537 const char *fname = "\\testdir\\testfile";
9539 struct timespec create_time;
9540 struct timespec create_time1;
9544 if (!torture_open_connection(&cli, 0)) {
9548 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9549 cli_rmdir(cli, dname);
9551 status = cli_mkdir(cli, dname);
9552 if (!NT_STATUS_IS_OK(status)) {
9553 printf("mkdir failed: %s\n", nt_errstr(status));
9557 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9559 if (!NT_STATUS_IS_OK(status)) {
9560 printf("cli_qpathinfo2 returned %s\n",
9565 /* Sleep 3 seconds, then create a file. */
9568 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9570 if (!NT_STATUS_IS_OK(status)) {
9571 printf("cli_openx failed: %s\n", nt_errstr(status));
9575 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9577 if (!NT_STATUS_IS_OK(status)) {
9578 printf("cli_qpathinfo2 (2) returned %s\n",
9583 if (timespec_compare(&create_time1, &create_time)) {
9584 printf("run_dir_createtime: create time was updated (error)\n");
9586 printf("run_dir_createtime: create time was not updated (correct)\n");
9592 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9593 cli_rmdir(cli, dname);
9594 if (!torture_close_connection(cli)) {
9601 static bool run_streamerror(int dummy)
9603 struct cli_state *cli;
9604 const char *dname = "\\testdir";
9605 const char *streamname =
9606 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9608 time_t change_time, access_time, write_time;
9610 uint16_t mode, fnum;
9613 if (!torture_open_connection(&cli, 0)) {
9617 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9618 cli_rmdir(cli, dname);
9620 status = cli_mkdir(cli, dname);
9621 if (!NT_STATUS_IS_OK(status)) {
9622 printf("mkdir failed: %s\n", nt_errstr(status));
9626 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9627 &write_time, &size, &mode);
9628 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9629 printf("pathinfo returned %s, expected "
9630 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9635 status = cli_ntcreate(cli, streamname, 0x16,
9636 FILE_READ_DATA|FILE_READ_EA|
9637 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9638 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9639 FILE_OPEN, 0, 0, &fnum, NULL);
9641 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9642 printf("ntcreate returned %s, expected "
9643 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9649 cli_rmdir(cli, dname);
9653 struct pidtest_state {
9659 static void pid_echo_done(struct tevent_req *subreq);
9661 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9662 struct tevent_context *ev,
9663 struct cli_state *cli)
9665 struct tevent_req *req, *subreq;
9666 struct pidtest_state *state;
9668 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9673 SSVAL(state->vwv, 0, 1);
9674 state->data = data_blob_const("hello", 5);
9676 subreq = smb1cli_req_send(state,
9681 0, 0, /* *_flags2 */
9683 0xDEADBEEF, /* pid */
9686 ARRAY_SIZE(state->vwv), state->vwv,
9687 state->data.length, state->data.data);
9689 if (tevent_req_nomem(subreq, req)) {
9690 return tevent_req_post(req, ev);
9692 tevent_req_set_callback(subreq, pid_echo_done, req);
9696 static void pid_echo_done(struct tevent_req *subreq)
9698 struct tevent_req *req = tevent_req_callback_data(
9699 subreq, struct tevent_req);
9700 struct pidtest_state *state = tevent_req_data(
9701 req, struct pidtest_state);
9704 uint8_t *bytes = NULL;
9705 struct iovec *recv_iov = NULL;
9706 uint8_t *phdr = NULL;
9707 uint16_t pidlow = 0;
9708 uint16_t pidhigh = 0;
9709 struct smb1cli_req_expected_response expected[] = {
9711 .status = NT_STATUS_OK,
9716 status = smb1cli_req_recv(subreq, state,
9721 NULL, /* pvwv_offset */
9724 NULL, /* pbytes_offset */
9726 expected, ARRAY_SIZE(expected));
9728 TALLOC_FREE(subreq);
9730 if (!NT_STATUS_IS_OK(status)) {
9731 tevent_req_nterror(req, status);
9735 if (num_bytes != state->data.length) {
9736 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9740 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9741 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9745 /* Check pid low/high == DEADBEEF */
9746 pidlow = SVAL(phdr, HDR_PID);
9747 if (pidlow != 0xBEEF){
9748 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9749 (unsigned int)pidlow);
9750 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9753 pidhigh = SVAL(phdr, HDR_PIDHIGH);
9754 if (pidhigh != 0xDEAD){
9755 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9756 (unsigned int)pidhigh);
9757 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9761 tevent_req_done(req);
9764 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9766 return tevent_req_simple_recv_ntstatus(req);
9769 static bool run_pidhigh(int dummy)
9771 bool success = false;
9772 struct cli_state *cli = NULL;
9774 struct tevent_context *ev = NULL;
9775 struct tevent_req *req = NULL;
9776 TALLOC_CTX *frame = talloc_stackframe();
9778 printf("starting pid high test\n");
9779 if (!torture_open_connection(&cli, 0)) {
9782 smbXcli_conn_set_sockopt(cli->conn, sockops);
9784 ev = samba_tevent_context_init(frame);
9789 req = pid_echo_send(frame, ev, cli);
9794 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
9798 status = pid_echo_recv(req);
9799 if (NT_STATUS_IS_OK(status)) {
9800 printf("pid high test ok\n");
9807 torture_close_connection(cli);
9812 Test Windows open on a bad POSIX symlink.
9814 static bool run_symlink_open_test(int dummy)
9816 static struct cli_state *cli;
9817 const char *fname = "non_existant_file";
9818 const char *sname = "dangling_symlink";
9819 uint16_t fnum = (uint16_t)-1;
9820 bool correct = false;
9822 TALLOC_CTX *frame = NULL;
9824 frame = talloc_stackframe();
9826 printf("Starting Windows bad symlink open test\n");
9828 if (!torture_open_connection(&cli, 0)) {
9833 smbXcli_conn_set_sockopt(cli->conn, sockops);
9835 status = torture_setup_unix_extensions(cli);
9836 if (!NT_STATUS_IS_OK(status)) {
9841 /* Ensure nothing exists. */
9842 cli_setatr(cli, fname, 0, 0);
9843 cli_posix_unlink(cli, fname);
9844 cli_setatr(cli, sname, 0, 0);
9845 cli_posix_unlink(cli, sname);
9847 /* Create a symlink pointing nowhere. */
9848 status = cli_posix_symlink(cli, fname, sname);
9849 if (!NT_STATUS_IS_OK(status)) {
9850 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
9857 /* Now ensure that a Windows open doesn't hang. */
9858 status = cli_ntcreate(cli,
9861 FILE_READ_DATA|FILE_WRITE_DATA,
9863 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
9871 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
9872 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
9873 * we use O_NOFOLLOW on the server or not.
9875 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
9876 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
9880 printf("cli_ntcreate of %s returned %s - should return"
9881 " either (%s) or (%s)\n",
9884 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
9885 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
9893 if (fnum != (uint16_t)-1) {
9894 cli_close(cli, fnum);
9895 fnum = (uint16_t)-1;
9898 cli_setatr(cli, sname, 0, 0);
9899 cli_posix_unlink(cli, sname);
9900 cli_setatr(cli, fname, 0, 0);
9901 cli_posix_unlink(cli, fname);
9903 if (!torture_close_connection(cli)) {
9912 * Only testing minimal time strings, as the others
9913 * need (locale-dependent) guessing at what strftime does and
9914 * even may differ in builds.
9916 static bool timesubst_test(void)
9918 TALLOC_CTX *ctx = NULL;
9919 /* Sa 23. Dez 04:33:20 CET 2017 */
9920 const struct timeval tv = { 1514000000, 123 };
9921 const char* expect_minimal = "20171223_033320";
9922 const char* expect_minus = "20171223_033320_000123";
9924 char *env_tz, *orig_tz = NULL;
9927 ctx = talloc_new(NULL);
9929 env_tz = getenv("TZ");
9931 orig_tz = talloc_strdup(ctx, env_tz);
9933 setenv("TZ", "UTC", 1);
9935 s = minimal_timeval_string(ctx, &tv, false);
9937 if(!s || strcmp(s, expect_minimal)) {
9938 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
9939 "[%s]\n", s ? s : "<nil>", expect_minimal);
9943 s = minimal_timeval_string(ctx, &tv, true);
9944 if(!s || strcmp(s, expect_minus)) {
9945 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
9946 "[%s]\n", s ? s : "<nil>", expect_minus);
9952 setenv("TZ", orig_tz, 1);
9959 static bool run_local_substitute(int dummy)
9963 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
9964 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
9965 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
9966 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
9967 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
9968 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
9969 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
9970 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
9971 ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
9972 /* Substitution depends on current time, so better test the underlying
9973 formatting function. At least covers %t. */
9974 ok &= timesubst_test();
9976 /* Different captialization rules in sub_basic... */
9978 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
9984 static bool run_local_base64(int dummy)
9989 for (i=1; i<2000; i++) {
9990 DATA_BLOB blob1, blob2;
9993 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
9995 generate_random_buffer(blob1.data, blob1.length);
9997 b64 = base64_encode_data_blob(talloc_tos(), blob1);
9999 d_fprintf(stderr, "base64_encode_data_blob failed "
10000 "for %d bytes\n", i);
10003 blob2 = base64_decode_data_blob(b64);
10006 if (data_blob_cmp(&blob1, &blob2)) {
10007 d_fprintf(stderr, "data_blob_cmp failed for %d "
10011 TALLOC_FREE(blob1.data);
10012 data_blob_free(&blob2);
10017 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
10022 static bool run_local_gencache(int dummy)
10028 struct memcache *mem;
10031 mem = memcache_init(NULL, 0);
10033 d_printf("%s: memcache_init failed\n", __location__);
10036 memcache_set_global(mem);
10038 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
10039 d_printf("%s: gencache_set() failed\n", __location__);
10043 if (!gencache_get("foo", NULL, NULL, NULL)) {
10044 d_printf("%s: gencache_get() failed\n", __location__);
10048 for (i=0; i<1000000; i++) {
10049 gencache_parse("foo", parse_fn, NULL);
10052 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10053 d_printf("%s: gencache_get() failed\n", __location__);
10058 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10059 d_printf("%s: gencache_get() failed\n", __location__);
10063 if (strcmp(val, "bar") != 0) {
10064 d_printf("%s: gencache_get() returned %s, expected %s\n",
10065 __location__, val, "bar");
10072 if (!gencache_del("foo")) {
10073 d_printf("%s: gencache_del() failed\n", __location__);
10076 if (gencache_del("foo")) {
10077 d_printf("%s: second gencache_del() succeeded\n",
10082 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
10083 d_printf("%s: gencache_get() on deleted entry "
10084 "succeeded\n", __location__);
10088 blob = data_blob_string_const_null("bar");
10089 tm = time(NULL) + 60;
10091 if (!gencache_set_data_blob("foo", blob, tm)) {
10092 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
10096 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10097 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
10101 if (strcmp((const char *)blob.data, "bar") != 0) {
10102 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10103 __location__, (const char *)blob.data, "bar");
10104 data_blob_free(&blob);
10108 data_blob_free(&blob);
10110 if (!gencache_del("foo")) {
10111 d_printf("%s: gencache_del() failed\n", __location__);
10114 if (gencache_del("foo")) {
10115 d_printf("%s: second gencache_del() succeeded\n",
10120 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10121 d_printf("%s: gencache_get_data_blob() on deleted entry "
10122 "succeeded\n", __location__);
10127 blob.data = (uint8_t *)&v;
10128 blob.length = sizeof(v);
10130 if (!gencache_set_data_blob("blob", blob, tm)) {
10131 d_printf("%s: gencache_set_data_blob() failed\n",
10135 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
10136 d_printf("%s: gencache_get succeeded\n", __location__);
10143 static bool rbt_testval(struct db_context *db, const char *key,
10146 struct db_record *rec;
10147 TDB_DATA data = string_tdb_data(value);
10152 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10154 d_fprintf(stderr, "fetch_locked failed\n");
10157 status = dbwrap_record_store(rec, data, 0);
10158 if (!NT_STATUS_IS_OK(status)) {
10159 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
10164 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10166 d_fprintf(stderr, "second fetch_locked failed\n");
10170 dbvalue = dbwrap_record_get_value(rec);
10171 if ((dbvalue.dsize != data.dsize)
10172 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
10173 d_fprintf(stderr, "Got wrong data back\n");
10183 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
10185 int *count2 = (int *)private_data;
10190 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
10192 int *count2 = (int *)private_data;
10194 dbwrap_record_delete(rec);
10198 static bool run_local_rbtree(int dummy)
10200 struct db_context *db;
10207 db = db_open_rbt(NULL);
10210 d_fprintf(stderr, "db_open_rbt failed\n");
10214 for (i=0; i<1000; i++) {
10217 if (asprintf(&key, "key%ld", random()) == -1) {
10220 if (asprintf(&value, "value%ld", random()) == -1) {
10225 if (!rbt_testval(db, key, value)) {
10232 if (asprintf(&value, "value%ld", random()) == -1) {
10237 if (!rbt_testval(db, key, value)) {
10248 count = 0; count2 = 0;
10249 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10251 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10252 if ((count != count2) || (count != 1000)) {
10255 count = 0; count2 = 0;
10256 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10258 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10259 if ((count != count2) || (count != 1000)) {
10262 count = 0; count2 = 0;
10263 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10265 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10266 if ((count != count2) || (count != 0)) {
10277 local test for character set functions
10279 This is a very simple test for the functionality in convert_string_error()
10281 static bool run_local_convert_string(int dummy)
10283 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10284 const char *test_strings[2] = { "March", "M\303\244rz" };
10288 for (i=0; i<2; i++) {
10289 const char *str = test_strings[i];
10290 int len = strlen(str);
10291 size_t converted_size;
10294 memset(dst, 'X', sizeof(dst));
10296 /* first try with real source length */
10297 ret = convert_string_error(CH_UNIX, CH_UTF8,
10302 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10306 if (converted_size != len) {
10307 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10308 str, len, (int)converted_size);
10312 if (strncmp(str, dst, converted_size) != 0) {
10313 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10317 if (strlen(str) != converted_size) {
10318 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10319 (int)strlen(str), (int)converted_size);
10323 if (dst[converted_size] != 'X') {
10324 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10328 /* now with srclen==-1, this causes the nul to be
10330 ret = convert_string_error(CH_UNIX, CH_UTF8,
10335 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10339 if (converted_size != len+1) {
10340 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10341 str, len, (int)converted_size);
10345 if (strncmp(str, dst, converted_size) != 0) {
10346 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10350 if (len+1 != converted_size) {
10351 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10352 len+1, (int)converted_size);
10356 if (dst[converted_size] != 'X') {
10357 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10364 TALLOC_FREE(tmp_ctx);
10367 TALLOC_FREE(tmp_ctx);
10371 static bool run_local_string_to_sid(int dummy) {
10372 struct dom_sid sid;
10374 if (string_to_sid(&sid, "S--1-5-32-545")) {
10375 printf("allowing S--1-5-32-545\n");
10378 if (string_to_sid(&sid, "S-1-5-32-+545")) {
10379 printf("allowing S-1-5-32-+545\n");
10382 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")) {
10383 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10386 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10387 printf("allowing S-1-5-32-545-abc\n");
10390 if (string_to_sid(&sid, "S-300-5-32-545")) {
10391 printf("allowing S-300-5-32-545\n");
10394 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10395 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10398 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10399 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10402 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10403 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10406 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10407 printf("could not parse S-1-5-32-545\n");
10410 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10411 printf("mis-parsed S-1-5-32-545 as %s\n",
10412 sid_string_tos(&sid));
10418 static bool sid_to_string_test(const char *expected) {
10421 struct dom_sid sid;
10423 if (!string_to_sid(&sid, expected)) {
10424 printf("could not parse %s\n", expected);
10428 str = dom_sid_string(NULL, &sid);
10429 if (strcmp(str, expected)) {
10430 printf("Comparison failed (%s != %s)\n", str, expected);
10437 static bool run_local_sid_to_string(int dummy) {
10438 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10440 if (!sid_to_string_test("S-1-545"))
10442 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10447 static bool run_local_binary_to_sid(int dummy) {
10448 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10449 static const uint8_t good_binary_sid[] = {
10450 0x1, /* revision number */
10451 15, /* num auths */
10452 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10453 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10454 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10455 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10456 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10457 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10458 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10459 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10460 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10461 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10462 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10463 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10464 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10465 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10466 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10467 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10470 static const uint8_t long_binary_sid[] = {
10471 0x1, /* revision number */
10472 15, /* num auths */
10473 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10474 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10475 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10476 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10477 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10478 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10479 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10480 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10481 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10482 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10483 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10484 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10485 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10486 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10487 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10488 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10489 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10490 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10491 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10494 static const uint8_t long_binary_sid2[] = {
10495 0x1, /* revision number */
10496 32, /* num auths */
10497 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10498 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10499 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10500 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10501 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10502 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10503 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10504 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10505 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10506 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10507 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10508 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10509 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10510 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10511 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10512 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10513 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10514 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10515 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10516 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10517 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10518 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10519 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10520 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10521 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10522 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10523 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10524 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10525 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10526 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10527 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10528 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10529 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10532 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10535 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10538 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10544 /* Split a path name into filename and stream name components. Canonicalise
10545 * such that an implicit $DATA token is always explicit.
10547 * The "specification" of this function can be found in the
10548 * run_local_stream_name() function in torture.c, I've tried those
10549 * combinations against a W2k3 server.
10552 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10553 char **pbase, char **pstream)
10556 char *stream = NULL;
10557 char *sname; /* stream name */
10558 const char *stype; /* stream type */
10560 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10562 sname = strchr_m(fname, ':');
10564 if (sname == NULL) {
10565 if (pbase != NULL) {
10566 base = talloc_strdup(mem_ctx, fname);
10567 NT_STATUS_HAVE_NO_MEMORY(base);
10572 if (pbase != NULL) {
10573 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10574 NT_STATUS_HAVE_NO_MEMORY(base);
10579 stype = strchr_m(sname, ':');
10581 if (stype == NULL) {
10582 sname = talloc_strdup(mem_ctx, sname);
10586 if (strcasecmp_m(stype, ":$DATA") != 0) {
10588 * If there is an explicit stream type, so far we only
10589 * allow $DATA. Is there anything else allowed? -- vl
10591 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10593 return NT_STATUS_OBJECT_NAME_INVALID;
10595 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10599 if (sname == NULL) {
10601 return NT_STATUS_NO_MEMORY;
10604 if (sname[0] == '\0') {
10606 * no stream name, so no stream
10611 if (pstream != NULL) {
10612 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10613 if (stream == NULL) {
10614 TALLOC_FREE(sname);
10616 return NT_STATUS_NO_MEMORY;
10619 * upper-case the type field
10621 (void)strupper_m(strchr_m(stream, ':')+1);
10625 if (pbase != NULL) {
10628 if (pstream != NULL) {
10631 return NT_STATUS_OK;
10634 static bool test_stream_name(const char *fname, const char *expected_base,
10635 const char *expected_stream,
10636 NTSTATUS expected_status)
10640 char *stream = NULL;
10642 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10643 if (!NT_STATUS_EQUAL(status, expected_status)) {
10647 if (!NT_STATUS_IS_OK(status)) {
10651 if (base == NULL) goto error;
10653 if (strcmp(expected_base, base) != 0) goto error;
10655 if ((expected_stream != NULL) && (stream == NULL)) goto error;
10656 if ((expected_stream == NULL) && (stream != NULL)) goto error;
10658 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10662 TALLOC_FREE(stream);
10666 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10667 fname, expected_base ? expected_base : "<NULL>",
10668 expected_stream ? expected_stream : "<NULL>",
10669 nt_errstr(expected_status));
10670 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10671 base ? base : "<NULL>", stream ? stream : "<NULL>",
10672 nt_errstr(status));
10674 TALLOC_FREE(stream);
10678 static bool run_local_stream_name(int dummy)
10682 ret &= test_stream_name(
10683 "bla", "bla", NULL, NT_STATUS_OK);
10684 ret &= test_stream_name(
10685 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10686 ret &= test_stream_name(
10687 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10688 ret &= test_stream_name(
10689 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10690 ret &= test_stream_name(
10691 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10692 ret &= test_stream_name(
10693 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10694 ret &= test_stream_name(
10695 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10696 ret &= test_stream_name(
10697 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10702 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10704 if (a.length != b.length) {
10705 printf("a.length=%d != b.length=%d\n",
10706 (int)a.length, (int)b.length);
10709 if (memcmp(a.data, b.data, a.length) != 0) {
10710 printf("a.data and b.data differ\n");
10716 static bool run_local_memcache(int dummy)
10718 struct memcache *cache;
10719 DATA_BLOB k1, k2, k3;
10723 TALLOC_CTX *mem_ctx;
10728 size_t size1, size2;
10731 mem_ctx = talloc_init("foo");
10732 if (mem_ctx == NULL) {
10736 /* STAT_CACHE TESTS */
10738 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10740 if (cache == NULL) {
10741 printf("memcache_init failed\n");
10745 d1 = data_blob_const("d1", 2);
10746 d3 = data_blob_const("d3", 2);
10748 k1 = data_blob_const("d1", 2);
10749 k2 = data_blob_const("d2", 2);
10750 k3 = data_blob_const("d3", 2);
10752 memcache_add(cache, STAT_CACHE, k1, d1);
10754 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10755 printf("could not find k1\n");
10758 if (!data_blob_equal(d1, v1)) {
10762 memcache_add(cache, STAT_CACHE, k1, d3);
10764 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10765 printf("could not find replaced k1\n");
10768 if (!data_blob_equal(d3, v3)) {
10772 TALLOC_FREE(cache);
10774 /* GETWD_CACHE TESTS */
10775 str1 = talloc_strdup(mem_ctx, "string1");
10776 if (str1 == NULL) {
10779 ptr2 = str1; /* Keep an alias for comparison. */
10781 str2 = talloc_strdup(mem_ctx, "string2");
10782 if (str2 == NULL) {
10786 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10787 if (cache == NULL) {
10788 printf("memcache_init failed\n");
10792 memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
10793 /* str1 == NULL now. */
10794 ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
10795 if (ptr1 == NULL) {
10796 printf("could not find k2\n");
10799 if (ptr1 != ptr2) {
10800 printf("fetch of k2 got wrong string\n");
10804 /* Add a blob to ensure k2 gets purged. */
10805 d3 = data_blob_talloc_zero(mem_ctx, 180);
10806 memcache_add(cache, STAT_CACHE, k3, d3);
10808 ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
10809 if (ptr2 != NULL) {
10810 printf("Did find k2, should have been purged\n");
10814 TALLOC_FREE(cache);
10815 TALLOC_FREE(mem_ctx);
10817 mem_ctx = talloc_init("foo");
10818 if (mem_ctx == NULL) {
10822 cache = memcache_init(NULL, 0);
10823 if (cache == NULL) {
10827 str1 = talloc_strdup(mem_ctx, "string1");
10828 if (str1 == NULL) {
10831 str2 = talloc_strdup(mem_ctx, "string2");
10832 if (str2 == NULL) {
10835 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10836 data_blob_string_const("torture"), &str1);
10837 size1 = talloc_total_size(cache);
10839 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10840 data_blob_string_const("torture"), &str2);
10841 size2 = talloc_total_size(cache);
10843 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
10845 if (size2 > size1) {
10846 printf("memcache leaks memory!\n");
10852 TALLOC_FREE(cache);
10856 static void wbclient_done(struct tevent_req *req)
10859 struct winbindd_response *wb_resp;
10860 int *i = (int *)tevent_req_callback_data_void(req);
10862 wbc_err = wb_trans_recv(req, req, &wb_resp);
10865 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
10868 static bool run_wbclient_multi_ping(int dummy)
10870 struct tevent_context *ev;
10871 struct wb_context **wb_ctx;
10872 struct winbindd_request wb_req;
10873 bool result = false;
10876 BlockSignals(True, SIGPIPE);
10878 ev = tevent_context_init(talloc_tos());
10883 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
10884 if (wb_ctx == NULL) {
10888 ZERO_STRUCT(wb_req);
10889 wb_req.cmd = WINBINDD_PING;
10891 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
10893 for (i=0; i<torture_nprocs; i++) {
10894 wb_ctx[i] = wb_context_init(ev, NULL);
10895 if (wb_ctx[i] == NULL) {
10898 for (j=0; j<torture_numops; j++) {
10899 struct tevent_req *req;
10900 req = wb_trans_send(ev, ev, wb_ctx[i],
10901 (j % 2) == 0, &wb_req);
10905 tevent_req_set_callback(req, wbclient_done, &i);
10911 while (i < torture_nprocs * torture_numops) {
10912 tevent_loop_once(ev);
10921 static bool dbtrans_inc(struct db_context *db)
10923 struct db_record *rec;
10929 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10931 printf(__location__ "fetch_lock failed\n");
10935 value = dbwrap_record_get_value(rec);
10937 if (value.dsize != sizeof(uint32_t)) {
10938 printf(__location__ "value.dsize = %d\n",
10943 memcpy(&val, value.dptr, sizeof(val));
10946 status = dbwrap_record_store(
10947 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
10948 if (!NT_STATUS_IS_OK(status)) {
10949 printf(__location__ "store failed: %s\n",
10950 nt_errstr(status));
10960 static bool run_local_dbtrans(int dummy)
10962 struct db_context *db;
10963 struct db_record *rec;
10969 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
10970 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
10973 printf("Could not open transtest.db\n");
10977 res = dbwrap_transaction_start(db);
10979 printf(__location__ "transaction_start failed\n");
10983 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10985 printf(__location__ "fetch_lock failed\n");
10989 value = dbwrap_record_get_value(rec);
10991 if (value.dptr == NULL) {
10993 status = dbwrap_record_store(
10994 rec, make_tdb_data((uint8_t *)&initial,
10997 if (!NT_STATUS_IS_OK(status)) {
10998 printf(__location__ "store returned %s\n",
10999 nt_errstr(status));
11006 res = dbwrap_transaction_commit(db);
11008 printf(__location__ "transaction_commit failed\n");
11013 uint32_t val, val2;
11016 res = dbwrap_transaction_start(db);
11018 printf(__location__ "transaction_start failed\n");
11022 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
11023 if (!NT_STATUS_IS_OK(status)) {
11024 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11025 nt_errstr(status));
11029 for (i=0; i<10; i++) {
11030 if (!dbtrans_inc(db)) {
11035 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
11036 if (!NT_STATUS_IS_OK(status)) {
11037 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11038 nt_errstr(status));
11042 if (val2 != val + 10) {
11043 printf(__location__ "val=%d, val2=%d\n",
11044 (int)val, (int)val2);
11048 printf("val2=%d\r", val2);
11050 res = dbwrap_transaction_commit(db);
11052 printf(__location__ "transaction_commit failed\n");
11062 * Just a dummy test to be run under a debugger. There's no real way
11063 * to inspect the tevent_poll specific function from outside of
11067 static bool run_local_tevent_poll(int dummy)
11069 struct tevent_context *ev;
11070 struct tevent_fd *fd1, *fd2;
11071 bool result = false;
11073 ev = tevent_context_init_byname(NULL, "poll");
11075 d_fprintf(stderr, "tevent_context_init_byname failed\n");
11079 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
11081 d_fprintf(stderr, "tevent_add_fd failed\n");
11084 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
11086 d_fprintf(stderr, "tevent_add_fd failed\n");
11091 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
11093 d_fprintf(stderr, "tevent_add_fd failed\n");
11103 static bool run_local_hex_encode_buf(int dummy)
11109 for (i=0; i<sizeof(src); i++) {
11112 hex_encode_buf(buf, src, sizeof(src));
11113 if (strcmp(buf, "0001020304050607") != 0) {
11116 hex_encode_buf(buf, NULL, 0);
11117 if (buf[0] != '\0') {
11123 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11145 "1001:1111:1111:1000:0:1111:1111:1111",
11154 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11168 "1001:1111:1111:1000:0:1111:1111:1111"
11171 static bool run_local_remove_duplicate_addrs2(int dummy)
11173 struct ip_service test_vector[28];
11176 /* Construct the sockaddr_storage test vector. */
11177 for (i = 0; i < 28; i++) {
11178 struct addrinfo hints;
11179 struct addrinfo *res = NULL;
11182 memset(&hints, '\0', sizeof(hints));
11183 hints.ai_flags = AI_NUMERICHOST;
11184 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11189 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11190 remove_duplicate_addrs2_test_strings_vector[i]);
11193 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11194 memcpy(&test_vector[i].ss,
11200 count = remove_duplicate_addrs2(test_vector, i);
11203 fprintf(stderr, "count wrong (%d) should be 14\n",
11208 for (i = 0; i < count; i++) {
11209 char addr[INET6_ADDRSTRLEN];
11211 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11213 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11214 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11217 remove_duplicate_addrs2_test_strings_result[i]);
11222 printf("run_local_remove_duplicate_addrs2: success\n");
11226 static bool run_local_tdb_opener(int dummy)
11232 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11233 O_RDWR|O_CREAT, 0755);
11235 perror("tdb_open failed");
11246 static bool run_local_tdb_writer(int dummy)
11252 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11254 perror("tdb_open failed");
11258 val.dptr = (uint8_t *)&v;
11259 val.dsize = sizeof(v);
11265 ret = tdb_store(t, val, val, 0);
11267 printf("%s\n", tdb_errorstr(t));
11272 data = tdb_fetch(t, val);
11273 if (data.dptr != NULL) {
11274 SAFE_FREE(data.dptr);
11280 static bool run_local_canonicalize_path(int dummy)
11282 const char *src[] = {
11289 ".././././../../../boo",
11293 const char *dst[] = {
11306 for (i = 0; src[i] != NULL; i++) {
11307 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11309 perror("talloc fail\n");
11312 if (strcmp(d, dst[i]) != 0) {
11314 "canonicalize missmatch %s -> %s != %s",
11315 src[i], d, dst[i]);
11323 static bool run_ign_bad_negprot(int dummy)
11325 struct tevent_context *ev;
11326 struct tevent_req *req;
11327 struct smbXcli_conn *conn;
11328 struct sockaddr_storage ss;
11333 printf("starting ignore bad negprot\n");
11335 ok = resolve_name(host, &ss, 0x20, true);
11337 d_fprintf(stderr, "Could not resolve name %s\n", host);
11341 status = open_socket_out(&ss, 445, 10000, &fd);
11342 if (!NT_STATUS_IS_OK(status)) {
11343 d_fprintf(stderr, "open_socket_out failed: %s\n",
11344 nt_errstr(status));
11348 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11350 if (conn == NULL) {
11351 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11355 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11356 if (NT_STATUS_IS_OK(status)) {
11357 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11361 ev = samba_tevent_context_init(talloc_tos());
11363 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11367 req = smb1cli_session_setup_nt1_send(
11368 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11369 data_blob_null, data_blob_null, 0x40,
11370 "Windows 2000 2195", "Windows 2000 5.0");
11372 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11376 ok = tevent_req_poll_ntstatus(req, ev, &status);
11378 d_fprintf(stderr, "tevent_req_poll failed\n");
11382 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11384 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11385 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11386 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11387 nt_errstr(status));
11393 printf("starting ignore bad negprot\n");
11398 static double create_procs(bool (*fn)(int), bool *result)
11401 volatile pid_t *child_status;
11402 volatile bool *child_status_out;
11405 struct timeval start;
11409 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11410 if (!child_status) {
11411 printf("Failed to setup shared memory\n");
11415 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11416 if (!child_status_out) {
11417 printf("Failed to setup result status shared memory\n");
11421 for (i = 0; i < torture_nprocs; i++) {
11422 child_status[i] = 0;
11423 child_status_out[i] = True;
11426 start = timeval_current();
11428 for (i=0;i<torture_nprocs;i++) {
11431 pid_t mypid = getpid();
11432 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11434 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11437 if (torture_open_connection(¤t_cli, i)) break;
11438 if (tries-- == 0) {
11439 printf("pid %d failed to start\n", (int)getpid());
11445 child_status[i] = getpid();
11447 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11449 child_status_out[i] = fn(i);
11456 for (i=0;i<torture_nprocs;i++) {
11457 if (child_status[i]) synccount++;
11459 if (synccount == torture_nprocs) break;
11461 } while (timeval_elapsed(&start) < 30);
11463 if (synccount != torture_nprocs) {
11464 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11466 return timeval_elapsed(&start);
11469 /* start the client load */
11470 start = timeval_current();
11472 for (i=0;i<torture_nprocs;i++) {
11473 child_status[i] = 0;
11476 printf("%d clients started\n", torture_nprocs);
11478 for (i=0;i<torture_nprocs;i++) {
11479 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11484 for (i=0;i<torture_nprocs;i++) {
11485 if (!child_status_out[i]) {
11489 return timeval_elapsed(&start);
11492 #define FLAG_MULTIPROC 1
11498 } torture_ops[] = {
11499 {"FDPASS", run_fdpasstest, 0},
11500 {"LOCK1", run_locktest1, 0},
11501 {"LOCK2", run_locktest2, 0},
11502 {"LOCK3", run_locktest3, 0},
11503 {"LOCK4", run_locktest4, 0},
11504 {"LOCK5", run_locktest5, 0},
11505 {"LOCK6", run_locktest6, 0},
11506 {"LOCK7", run_locktest7, 0},
11507 {"LOCK8", run_locktest8, 0},
11508 {"LOCK9", run_locktest9, 0},
11509 {"UNLINK", run_unlinktest, 0},
11510 {"BROWSE", run_browsetest, 0},
11511 {"ATTR", run_attrtest, 0},
11512 {"TRANS2", run_trans2test, 0},
11513 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
11514 {"TORTURE",run_torture, FLAG_MULTIPROC},
11515 {"RANDOMIPC", run_randomipc, 0},
11516 {"NEGNOWAIT", run_negprot_nowait, 0},
11517 {"NBENCH", run_nbench, 0},
11518 {"NBENCH2", run_nbench2, 0},
11519 {"OPLOCK1", run_oplock1, 0},
11520 {"OPLOCK2", run_oplock2, 0},
11521 {"OPLOCK4", run_oplock4, 0},
11522 {"DIR", run_dirtest, 0},
11523 {"DIR1", run_dirtest1, 0},
11524 {"DIR-CREATETIME", run_dir_createtime, 0},
11525 {"DENY1", torture_denytest1, 0},
11526 {"DENY2", torture_denytest2, 0},
11527 {"TCON", run_tcon_test, 0},
11528 {"TCONDEV", run_tcon_devtype_test, 0},
11529 {"RW1", run_readwritetest, 0},
11530 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
11531 {"RW3", run_readwritelarge, 0},
11532 {"RW-SIGNING", run_readwritelarge_signtest, 0},
11533 {"OPEN", run_opentest, 0},
11534 {"POSIX", run_simple_posix_open_test, 0},
11535 {"POSIX-APPEND", run_posix_append, 0},
11536 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
11537 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
11538 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
11539 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
11540 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
11541 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
11542 {"ASYNC-ECHO", run_async_echo, 0},
11543 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
11544 { "SHORTNAME-TEST", run_shortname_test, 0},
11545 { "ADDRCHANGE", run_addrchange, 0},
11547 {"OPENATTR", run_openattrtest, 0},
11549 {"XCOPY", run_xcopy, 0},
11550 {"RENAME", run_rename, 0},
11551 {"RENAME-ACCESS", run_rename_access, 0},
11552 {"OWNER-RIGHTS", run_owner_rights, 0},
11553 {"DELETE", run_deletetest, 0},
11554 {"WILDDELETE", run_wild_deletetest, 0},
11555 {"DELETE-LN", run_deletetest_ln, 0},
11556 {"PROPERTIES", run_properties, 0},
11557 {"MANGLE", torture_mangle, 0},
11558 {"MANGLE1", run_mangle1, 0},
11559 {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
11560 {"W2K", run_w2ktest, 0},
11561 {"TRANS2SCAN", torture_trans2_scan, 0},
11562 {"NTTRANSSCAN", torture_nttrans_scan, 0},
11563 {"UTABLE", torture_utable, 0},
11564 {"CASETABLE", torture_casetable, 0},
11565 {"ERRMAPEXTRACT", run_error_map_extract, 0},
11566 {"PIPE_NUMBER", run_pipe_number, 0},
11567 {"TCON2", run_tcon2_test, 0},
11568 {"IOCTL", torture_ioctl_test, 0},
11569 {"CHKPATH", torture_chkpath_test, 0},
11570 {"FDSESS", run_fdsesstest, 0},
11571 { "EATEST", run_eatest, 0},
11572 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
11573 { "CHAIN1", run_chain1, 0},
11574 { "CHAIN2", run_chain2, 0},
11575 { "CHAIN3", run_chain3, 0},
11576 { "WINDOWS-WRITE", run_windows_write, 0},
11577 { "LARGE_READX", run_large_readx, 0},
11578 { "NTTRANS-CREATE", run_nttrans_create, 0},
11579 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
11580 { "CLI_ECHO", run_cli_echo, 0},
11581 { "TLDAP", run_tldap },
11582 { "STREAMERROR", run_streamerror },
11583 { "NOTIFY-BENCH", run_notify_bench },
11584 { "NOTIFY-BENCH2", run_notify_bench2 },
11585 { "NOTIFY-BENCH3", run_notify_bench3 },
11586 { "BAD-NBT-SESSION", run_bad_nbt_session },
11587 { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
11588 { "SMB-ANY-CONNECT", run_smb_any_connect },
11589 { "NOTIFY-ONLINE", run_notify_online },
11590 { "SMB2-BASIC", run_smb2_basic },
11591 { "SMB2-NEGPROT", run_smb2_negprot },
11592 { "SMB2-ANONYMOUS", run_smb2_anonymous },
11593 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
11594 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
11595 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
11596 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
11597 { "SMB2-FTRUNCATE", run_smb2_ftruncate },
11598 { "CLEANUP1", run_cleanup1 },
11599 { "CLEANUP2", run_cleanup2 },
11600 { "CLEANUP3", run_cleanup3 },
11601 { "CLEANUP4", run_cleanup4 },
11602 { "OPLOCK-CANCEL", run_oplock_cancel },
11603 { "PIDHIGH", run_pidhigh },
11604 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
11605 { "LOCAL-GENCACHE", run_local_gencache, 0},
11606 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
11607 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2, 0 },
11608 { "LOCAL-DBWRAP-DO-LOCKED1", run_dbwrap_do_locked1, 0 },
11609 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
11610 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
11611 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
11612 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
11613 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
11614 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
11615 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
11616 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
11617 { "LOCAL-MESSAGING-SEND-ALL", run_messaging_send_all, 0 },
11618 { "LOCAL-BASE64", run_local_base64, 0},
11619 { "LOCAL-RBTREE", run_local_rbtree, 0},
11620 { "LOCAL-MEMCACHE", run_local_memcache, 0},
11621 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
11622 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
11623 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
11624 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
11625 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
11626 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
11627 { "LOCAL-TEVENT-POLL", run_local_tevent_poll, 0},
11628 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
11629 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
11630 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
11631 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
11632 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
11633 { "local-tdb-opener", run_local_tdb_opener, 0 },
11634 { "local-tdb-writer", run_local_tdb_writer, 0 },
11635 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
11636 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
11637 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
11638 { "LOCAL-G-LOCK1", run_g_lock1, 0 },
11639 { "LOCAL-G-LOCK2", run_g_lock2, 0 },
11640 { "LOCAL-G-LOCK3", run_g_lock3, 0 },
11641 { "LOCAL-G-LOCK4", run_g_lock4, 0 },
11642 { "LOCAL-G-LOCK5", run_g_lock5, 0 },
11643 { "LOCAL-G-LOCK6", run_g_lock6, 0 },
11644 { "LOCAL-G-LOCK-PING-PONG", run_g_lock_ping_pong, 0 },
11645 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
11646 { "LOCAL-NAMEMAP-CACHE1", run_local_namemap_cache1, 0 },
11647 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
11650 /****************************************************************************
11651 run a specified test or "ALL"
11652 ****************************************************************************/
11653 static bool run_test(const char *name)
11656 bool result = True;
11657 bool found = False;
11660 if (strequal(name,"ALL")) {
11661 for (i=0;torture_ops[i].name;i++) {
11662 run_test(torture_ops[i].name);
11667 for (i=0;torture_ops[i].name;i++) {
11668 fstr_sprintf(randomfname, "\\XX%x",
11669 (unsigned)random());
11671 if (strequal(name, torture_ops[i].name)) {
11673 printf("Running %s\n", name);
11674 if (torture_ops[i].flags & FLAG_MULTIPROC) {
11675 t = create_procs(torture_ops[i].fn, &result);
11678 printf("TEST %s FAILED!\n", name);
11681 struct timeval start;
11682 start = timeval_current();
11683 if (!torture_ops[i].fn(0)) {
11685 printf("TEST %s FAILED!\n", name);
11687 t = timeval_elapsed(&start);
11689 printf("%s took %g secs\n\n", name, t);
11694 printf("Did not find a test named %s\n", name);
11702 static void usage(void)
11706 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11707 printf("Please use samba4 torture.\n\n");
11709 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11711 printf("\t-d debuglevel\n");
11712 printf("\t-U user%%pass\n");
11713 printf("\t-k use kerberos\n");
11714 printf("\t-N numprocs\n");
11715 printf("\t-n my_netbios_name\n");
11716 printf("\t-W workgroup\n");
11717 printf("\t-o num_operations\n");
11718 printf("\t-O socket_options\n");
11719 printf("\t-m maximum protocol\n");
11720 printf("\t-L use oplocks\n");
11721 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11722 printf("\t-A showall\n");
11723 printf("\t-p port\n");
11724 printf("\t-s seed\n");
11725 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11726 printf("\t-f filename filename to test\n");
11727 printf("\t-e encrypt\n");
11730 printf("tests are:");
11731 for (i=0;torture_ops[i].name;i++) {
11732 printf(" %s", torture_ops[i].name);
11736 printf("default test is ALL\n");
11741 /****************************************************************************
11743 ****************************************************************************/
11744 int main(int argc,char *argv[])
11750 bool correct = True;
11751 TALLOC_CTX *frame = talloc_stackframe();
11752 int seed = time(NULL);
11754 #ifdef HAVE_SETBUFFER
11755 setbuffer(stdout, NULL, 0);
11758 setup_logging("smbtorture", DEBUG_STDOUT);
11763 if (is_default_dyn_CONFIGFILE()) {
11764 if(getenv("SMB_CONF_PATH")) {
11765 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11768 lp_load_global(get_dyn_CONFIGFILE());
11775 for(p = argv[1]; *p; p++)
11779 if (strncmp(argv[1], "//", 2)) {
11783 fstrcpy(host, &argv[1][2]);
11784 p = strchr_m(&host[2],'/');
11789 fstrcpy(share, p+1);
11791 fstrcpy(myname, get_myname(talloc_tos()));
11793 fprintf(stderr, "Failed to get my hostname.\n");
11797 if (*username == 0 && getenv("LOGNAME")) {
11798 fstrcpy(username,getenv("LOGNAME"));
11804 fstrcpy(workgroup, lp_workgroup());
11806 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
11810 port_to_use = atoi(optarg);
11813 seed = atoi(optarg);
11816 fstrcpy(workgroup,optarg);
11819 lp_set_cmdline("client max protocol", optarg);
11822 torture_nprocs = atoi(optarg);
11825 torture_numops = atoi(optarg);
11828 lp_set_cmdline("log level", optarg);
11834 use_oplocks = True;
11837 local_path = optarg;
11840 torture_showall = True;
11843 fstrcpy(myname, optarg);
11846 client_txt = optarg;
11853 use_kerberos = True;
11855 d_printf("No kerberos support compiled in\n");
11861 fstrcpy(username,optarg);
11862 p = strchr_m(username,'%');
11865 fstrcpy(password, p+1);
11870 fstrcpy(multishare_conn_fname, optarg);
11871 use_multishare_conn = True;
11874 torture_blocksize = atoi(optarg);
11877 test_filename = SMB_STRDUP(optarg);
11880 printf("Unknown option %c (%d)\n", (char)opt, opt);
11885 d_printf("using seed %d\n", seed);
11889 if(use_kerberos && !gotuser) gotpass = True;
11892 char pwd[256] = {0};
11895 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
11897 fstrcpy(password, pwd);
11902 printf("host=%s share=%s user=%s myname=%s\n",
11903 host, share, username, myname);
11905 torture_creds = cli_session_creds_init(frame,
11911 false, /* fallback_after_kerberos */
11912 false, /* use_ccache */
11913 false); /* password_is_nt_hash */
11914 if (torture_creds == NULL) {
11915 d_printf("cli_session_creds_init() failed.\n");
11919 if (argc == optind) {
11920 correct = run_test("ALL");
11922 for (i=optind;i<argc;i++) {
11923 if (!run_test(argv[i])) {
11929 TALLOC_FREE(frame);