2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
29 #include "../lib/util/memcache.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap/dbwrap.h"
32 #include "dbwrap/dbwrap_open.h"
33 #include "dbwrap/dbwrap_rbt.h"
34 #include "talloc_dict.h"
35 #include "async_smb.h"
36 #include "libsmb/libsmb.h"
37 #include "libsmb/clirap.h"
39 #include "libsmb/nmblib.h"
40 #include "../lib/util/tevent_ntstatus.h"
42 #include "../libcli/smb/read_smb.h"
43 #include "../libcli/smb/smbXcli_base.h"
44 #include "lib/util/sys_rw_data.h"
45 #include "lib/util/base64.h"
50 fstring host, workgroup, share, password, username, myname;
51 struct cli_credentials *torture_creds;
52 static const char *sockops="TCP_NODELAY";
54 static int port_to_use=0;
55 int torture_numops=100;
56 int torture_blocksize=1024*1024;
57 static int procnum; /* records process count number when forking */
58 static struct cli_state *current_cli;
59 static fstring randomfname;
60 static bool use_oplocks;
61 static bool use_level_II_oplocks;
62 static const char *client_txt = "client_oplocks.txt";
63 static bool disable_spnego;
64 static bool use_kerberos;
65 static bool force_dos_errors;
66 static fstring multishare_conn_fname;
67 static bool use_multishare_conn = False;
68 static bool do_encrypt;
69 static const char *local_path = NULL;
70 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
73 bool torture_showall = False;
75 static double create_procs(bool (*fn)(int), bool *result);
77 /********************************************************************
78 Ensure a connection is encrypted.
79 ********************************************************************/
81 static bool force_cli_encryption(struct cli_state *c,
82 const char *sharename)
84 uint16_t major, minor;
85 uint32_t caplow, caphigh;
88 if (!SERVER_HAS_UNIX_CIFS(c)) {
89 d_printf("Encryption required and "
90 "server that doesn't support "
91 "UNIX extensions - failing connect\n");
95 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
97 if (!NT_STATUS_IS_OK(status)) {
98 d_printf("Encryption required and "
99 "can't get UNIX CIFS extensions "
100 "version from server: %s\n", nt_errstr(status));
104 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
105 d_printf("Encryption required and "
106 "share %s doesn't support "
107 "encryption.\n", sharename);
111 status = cli_smb1_setup_encryption(c, torture_creds);
112 if (!NT_STATUS_IS_OK(status)) {
113 d_printf("Encryption required and "
114 "setup failed with error %s.\n",
123 static struct cli_state *open_nbt_connection(void)
129 if (disable_spnego) {
130 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
134 flags |= CLI_FULL_CONNECTION_OPLOCKS;
137 if (use_level_II_oplocks) {
138 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
142 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
145 if (force_dos_errors) {
146 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
149 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
150 signing_state, flags, &c);
151 if (!NT_STATUS_IS_OK(status)) {
152 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
156 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
161 /****************************************************************************
162 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
163 ****************************************************************************/
165 static bool cli_bad_session_request(int fd,
166 struct nmb_name *calling, struct nmb_name *called)
175 uint8_t message_type;
177 struct tevent_context *ev;
178 struct tevent_req *req;
180 frame = talloc_stackframe();
182 iov[0].iov_base = len_buf;
183 iov[0].iov_len = sizeof(len_buf);
185 /* put in the destination name */
187 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
189 if (iov[1].iov_base == NULL) {
192 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
193 talloc_get_size(iov[1].iov_base));
197 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
199 if (iov[2].iov_base == NULL) {
202 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
203 talloc_get_size(iov[2].iov_base));
205 /* Deliberately corrupt the name len (first byte) */
206 *((uint8_t *)iov[2].iov_base) = 100;
208 /* send a session request (RFC 1002) */
209 /* setup the packet length
210 * Remove four bytes from the length count, since the length
211 * field in the NBT Session Service header counts the number
212 * of bytes which follow. The cli_send_smb() function knows
213 * about this and accounts for those four bytes.
217 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
218 SCVAL(len_buf,0,0x81);
220 len = write_data_iov(fd, iov, 3);
225 ev = samba_tevent_context_init(frame);
229 req = read_smb_send(frame, ev, fd);
233 if (!tevent_req_poll(req, ev)) {
236 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
243 message_type = CVAL(inbuf, 0);
244 if (message_type != 0x83) {
245 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
250 if (smb_len(inbuf) != 1) {
251 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
252 (int)smb_len(inbuf));
256 error = CVAL(inbuf, 4);
258 d_fprintf(stderr, "Expected error 0x82, got %d\n",
269 /* Insert a NULL at the first separator of the given path and return a pointer
270 * to the remainder of the string.
273 terminate_path_at_separator(char * path)
281 if ((p = strchr_m(path, '/'))) {
286 if ((p = strchr_m(path, '\\'))) {
296 parse a //server/share type UNC name
298 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
299 char **hostname, char **sharename)
303 *hostname = *sharename = NULL;
305 if (strncmp(unc_name, "\\\\", 2) &&
306 strncmp(unc_name, "//", 2)) {
310 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
311 p = terminate_path_at_separator(*hostname);
314 *sharename = talloc_strdup(mem_ctx, p);
315 terminate_path_at_separator(*sharename);
318 if (*hostname && *sharename) {
322 TALLOC_FREE(*hostname);
323 TALLOC_FREE(*sharename);
327 static bool torture_open_connection_share(struct cli_state **c,
328 const char *hostname,
329 const char *sharename,
334 status = cli_full_connection_creds(c,
344 if (!NT_STATUS_IS_OK(status)) {
345 printf("failed to open share connection: //%s/%s port:%d - %s\n",
346 hostname, sharename, port_to_use, nt_errstr(status));
350 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
353 return force_cli_encryption(*c,
359 bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
361 char **unc_list = NULL;
362 int num_unc_names = 0;
365 if (use_multishare_conn==True) {
367 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
368 if (!unc_list || num_unc_names <= 0) {
369 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
373 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
375 printf("Failed to parse UNC name %s\n",
376 unc_list[conn_index % num_unc_names]);
377 TALLOC_FREE(unc_list);
381 result = torture_open_connection_share(c, h, s, flags);
383 /* h, s were copied earlier */
384 TALLOC_FREE(unc_list);
388 return torture_open_connection_share(c, host, share, flags);
391 bool torture_open_connection(struct cli_state **c, int conn_index)
393 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
396 flags |= CLI_FULL_CONNECTION_OPLOCKS;
398 if (use_level_II_oplocks) {
399 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
402 return torture_open_connection_flags(c, conn_index, flags);
405 bool torture_init_connection(struct cli_state **pcli)
407 struct cli_state *cli;
409 cli = open_nbt_connection();
418 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
420 uint16_t old_vuid = cli_state_get_uid(cli);
424 cli_state_set_uid(cli, 0);
425 status = cli_session_setup_creds(cli, torture_creds);
426 ret = NT_STATUS_IS_OK(status);
427 *new_vuid = cli_state_get_uid(cli);
428 cli_state_set_uid(cli, old_vuid);
433 bool torture_close_connection(struct cli_state *c)
438 status = cli_tdis(c);
439 if (!NT_STATUS_IS_OK(status)) {
440 printf("tdis failed (%s)\n", nt_errstr(status));
450 /* check if the server produced the expected dos or nt error code */
451 static bool check_both_error(int line, NTSTATUS status,
452 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
454 if (NT_STATUS_IS_DOS(status)) {
458 /* Check DOS error */
459 cclass = NT_STATUS_DOS_CLASS(status);
460 num = NT_STATUS_DOS_CODE(status);
462 if (eclass != cclass || ecode != num) {
463 printf("unexpected error code class=%d code=%d\n",
464 (int)cclass, (int)num);
465 printf(" expected %d/%d %s (line=%d)\n",
466 (int)eclass, (int)ecode, nt_errstr(nterr), line);
471 if (!NT_STATUS_EQUAL(nterr, status)) {
472 printf("unexpected error code %s\n",
474 printf(" expected %s (line=%d)\n",
475 nt_errstr(nterr), line);
484 /* check if the server produced the expected error code */
485 static bool check_error(int line, NTSTATUS status,
486 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
488 if (NT_STATUS_IS_DOS(status)) {
492 /* Check DOS error */
494 cclass = NT_STATUS_DOS_CLASS(status);
495 num = NT_STATUS_DOS_CODE(status);
497 if (eclass != cclass || ecode != num) {
498 printf("unexpected error code class=%d code=%d\n",
499 (int)cclass, (int)num);
500 printf(" expected %d/%d %s (line=%d)\n",
501 (int)eclass, (int)ecode, nt_errstr(nterr),
509 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
510 printf("unexpected error code %s\n",
512 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
522 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
526 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
528 while (!NT_STATUS_IS_OK(status)) {
529 if (!check_both_error(__LINE__, status, ERRDOS,
530 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
534 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
541 static bool rw_torture(struct cli_state *c)
543 const char *lockfname = "\\torture.lck";
547 pid_t pid2, pid = getpid();
554 memset(buf, '\0', sizeof(buf));
556 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
558 if (!NT_STATUS_IS_OK(status)) {
559 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
561 if (!NT_STATUS_IS_OK(status)) {
562 printf("open of %s failed (%s)\n",
563 lockfname, nt_errstr(status));
567 for (i=0;i<torture_numops;i++) {
568 unsigned n = (unsigned)sys_random()%10;
571 printf("%d\r", i); fflush(stdout);
573 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
575 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
579 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
581 if (!NT_STATUS_IS_OK(status)) {
582 printf("open failed (%s)\n", nt_errstr(status));
587 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
589 if (!NT_STATUS_IS_OK(status)) {
590 printf("write failed (%s)\n", nt_errstr(status));
595 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
596 sizeof(pid)+(j*sizeof(buf)),
598 if (!NT_STATUS_IS_OK(status)) {
599 printf("write failed (%s)\n",
607 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("read failed (%s)\n", nt_errstr(status));
612 } else if (nread != sizeof(pid)) {
613 printf("read/write compare failed: "
614 "recv %ld req %ld\n", (unsigned long)nread,
615 (unsigned long)sizeof(pid));
620 printf("data corruption!\n");
624 status = cli_close(c, fnum);
625 if (!NT_STATUS_IS_OK(status)) {
626 printf("close failed (%s)\n", nt_errstr(status));
630 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
631 if (!NT_STATUS_IS_OK(status)) {
632 printf("unlink failed (%s)\n", nt_errstr(status));
636 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
637 if (!NT_STATUS_IS_OK(status)) {
638 printf("unlock failed (%s)\n", nt_errstr(status));
644 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
651 static bool run_torture(int dummy)
653 struct cli_state *cli;
658 smbXcli_conn_set_sockopt(cli->conn, sockops);
660 ret = rw_torture(cli);
662 if (!torture_close_connection(cli)) {
669 static bool rw_torture3(struct cli_state *c, char *lockfname)
671 uint16_t fnum = (uint16_t)-1;
676 unsigned countprev = 0;
679 NTSTATUS status = NT_STATUS_OK;
682 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
684 SIVAL(buf, i, sys_random());
691 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
692 if (!NT_STATUS_IS_OK(status)) {
693 printf("unlink failed (%s) (normal, this file should "
694 "not exist)\n", nt_errstr(status));
697 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
699 if (!NT_STATUS_IS_OK(status)) {
700 printf("first open read/write of %s failed (%s)\n",
701 lockfname, nt_errstr(status));
707 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
709 status = cli_openx(c, lockfname, O_RDONLY,
711 if (NT_STATUS_IS_OK(status)) {
716 if (!NT_STATUS_IS_OK(status)) {
717 printf("second open read-only of %s failed (%s)\n",
718 lockfname, nt_errstr(status));
724 for (count = 0; count < sizeof(buf); count += sent)
726 if (count >= countprev) {
727 printf("%d %8d\r", i, count);
730 countprev += (sizeof(buf) / 20);
735 sent = ((unsigned)sys_random()%(20))+ 1;
736 if (sent > sizeof(buf) - count)
738 sent = sizeof(buf) - count;
741 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
743 if (!NT_STATUS_IS_OK(status)) {
744 printf("write failed (%s)\n",
751 status = cli_read(c, fnum, buf_rd+count, count,
752 sizeof(buf)-count, &sent);
753 if(!NT_STATUS_IS_OK(status)) {
754 printf("read failed offset:%d size:%ld (%s)\n",
755 count, (unsigned long)sizeof(buf)-count,
759 } else if (sent > 0) {
760 if (memcmp(buf_rd+count, buf+count, sent) != 0)
762 printf("read/write compare failed\n");
763 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
772 status = cli_close(c, fnum);
773 if (!NT_STATUS_IS_OK(status)) {
774 printf("close failed (%s)\n", nt_errstr(status));
781 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
783 const char *lockfname = "\\torture2.lck";
793 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
794 if (!NT_STATUS_IS_OK(status)) {
795 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
798 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
800 if (!NT_STATUS_IS_OK(status)) {
801 printf("first open read/write of %s failed (%s)\n",
802 lockfname, nt_errstr(status));
806 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
807 if (!NT_STATUS_IS_OK(status)) {
808 printf("second open read-only of %s failed (%s)\n",
809 lockfname, nt_errstr(status));
810 cli_close(c1, fnum1);
814 for (i = 0; i < torture_numops; i++)
816 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
818 printf("%d\r", i); fflush(stdout);
821 generate_random_buffer((unsigned char *)buf, buf_size);
823 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
825 if (!NT_STATUS_IS_OK(status)) {
826 printf("write failed (%s)\n", nt_errstr(status));
831 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
832 if(!NT_STATUS_IS_OK(status)) {
833 printf("read failed (%s)\n", nt_errstr(status));
836 } else if (bytes_read != buf_size) {
837 printf("read failed\n");
838 printf("read %ld, expected %ld\n",
839 (unsigned long)bytes_read,
840 (unsigned long)buf_size);
845 if (memcmp(buf_rd, buf, buf_size) != 0)
847 printf("read/write compare failed\n");
853 status = cli_close(c2, fnum2);
854 if (!NT_STATUS_IS_OK(status)) {
855 printf("close failed (%s)\n", nt_errstr(status));
859 status = cli_close(c1, fnum1);
860 if (!NT_STATUS_IS_OK(status)) {
861 printf("close failed (%s)\n", nt_errstr(status));
865 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
866 if (!NT_STATUS_IS_OK(status)) {
867 printf("unlink failed (%s)\n", nt_errstr(status));
874 static bool run_readwritetest(int dummy)
876 struct cli_state *cli1, *cli2;
877 bool test1, test2 = False;
879 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
882 smbXcli_conn_set_sockopt(cli1->conn, sockops);
883 smbXcli_conn_set_sockopt(cli2->conn, sockops);
885 printf("starting readwritetest\n");
887 test1 = rw_torture2(cli1, cli2);
888 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
891 test2 = rw_torture2(cli1, cli1);
892 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
895 if (!torture_close_connection(cli1)) {
899 if (!torture_close_connection(cli2)) {
903 return (test1 && test2);
906 static bool run_readwritemulti(int dummy)
908 struct cli_state *cli;
913 smbXcli_conn_set_sockopt(cli->conn, sockops);
915 printf("run_readwritemulti: fname %s\n", randomfname);
916 test = rw_torture3(cli, randomfname);
918 if (!torture_close_connection(cli)) {
925 static bool run_readwritelarge_internal(void)
927 static struct cli_state *cli1;
929 const char *lockfname = "\\large.dat";
935 if (!torture_open_connection(&cli1, 0)) {
938 smbXcli_conn_set_sockopt(cli1->conn, sockops);
939 memset(buf,'\0',sizeof(buf));
941 printf("starting readwritelarge_internal\n");
943 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
945 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
947 if (!NT_STATUS_IS_OK(status)) {
948 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
952 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
954 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
956 if (!NT_STATUS_IS_OK(status)) {
957 printf("qfileinfo failed (%s)\n", nt_errstr(status));
961 if (fsize == sizeof(buf))
962 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
963 (unsigned long)fsize);
965 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
966 (unsigned long)fsize);
970 status = cli_close(cli1, fnum1);
971 if (!NT_STATUS_IS_OK(status)) {
972 printf("close failed (%s)\n", nt_errstr(status));
976 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
977 if (!NT_STATUS_IS_OK(status)) {
978 printf("unlink failed (%s)\n", nt_errstr(status));
982 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
984 if (!NT_STATUS_IS_OK(status)) {
985 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
989 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
991 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
993 if (!NT_STATUS_IS_OK(status)) {
994 printf("qfileinfo failed (%s)\n", nt_errstr(status));
998 if (fsize == sizeof(buf))
999 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1000 (unsigned long)fsize);
1002 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1003 (unsigned long)fsize);
1008 /* ToDo - set allocation. JRA */
1009 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1010 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1013 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1015 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1019 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1022 status = cli_close(cli1, fnum1);
1023 if (!NT_STATUS_IS_OK(status)) {
1024 printf("close failed (%s)\n", nt_errstr(status));
1028 if (!torture_close_connection(cli1)) {
1034 static bool run_readwritelarge(int dummy)
1036 return run_readwritelarge_internal();
1039 static bool run_readwritelarge_signtest(int dummy)
1042 signing_state = SMB_SIGNING_REQUIRED;
1043 ret = run_readwritelarge_internal();
1044 signing_state = SMB_SIGNING_DEFAULT;
1051 #define ival(s) strtol(s, NULL, 0)
1053 /* run a test that simulates an approximate netbench client load */
1054 static bool run_netbench(int client)
1056 struct cli_state *cli;
1061 const char *params[20];
1062 bool correct = True;
1068 smbXcli_conn_set_sockopt(cli->conn, sockops);
1072 slprintf(cname,sizeof(cname)-1, "client%d", client);
1074 f = fopen(client_txt, "r");
1081 while (fgets(line, sizeof(line)-1, f)) {
1085 line[strlen(line)-1] = 0;
1087 /* printf("[%d] %s\n", line_count, line); */
1089 all_string_sub(line,"client1", cname, sizeof(line));
1091 /* parse the command parameters */
1092 params[0] = strtok_r(line, " ", &saveptr);
1094 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1098 if (i < 2) continue;
1100 if (!strncmp(params[0],"SMB", 3)) {
1101 printf("ERROR: You are using a dbench 1 load file\n");
1105 if (!strcmp(params[0],"NTCreateX")) {
1106 nb_createx(params[1], ival(params[2]), ival(params[3]),
1108 } else if (!strcmp(params[0],"Close")) {
1109 nb_close(ival(params[1]));
1110 } else if (!strcmp(params[0],"Rename")) {
1111 nb_rename(params[1], params[2]);
1112 } else if (!strcmp(params[0],"Unlink")) {
1113 nb_unlink(params[1]);
1114 } else if (!strcmp(params[0],"Deltree")) {
1115 nb_deltree(params[1]);
1116 } else if (!strcmp(params[0],"Rmdir")) {
1117 nb_rmdir(params[1]);
1118 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1119 nb_qpathinfo(params[1]);
1120 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1121 nb_qfileinfo(ival(params[1]));
1122 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1123 nb_qfsinfo(ival(params[1]));
1124 } else if (!strcmp(params[0],"FIND_FIRST")) {
1125 nb_findfirst(params[1]);
1126 } else if (!strcmp(params[0],"WriteX")) {
1127 nb_writex(ival(params[1]),
1128 ival(params[2]), ival(params[3]), ival(params[4]));
1129 } else if (!strcmp(params[0],"ReadX")) {
1130 nb_readx(ival(params[1]),
1131 ival(params[2]), ival(params[3]), ival(params[4]));
1132 } else if (!strcmp(params[0],"Flush")) {
1133 nb_flush(ival(params[1]));
1135 printf("Unknown operation %s\n", params[0]);
1143 if (!torture_close_connection(cli)) {
1151 /* run a test that simulates an approximate netbench client load */
1152 static bool run_nbench(int dummy)
1155 bool correct = True;
1157 nbio_shmem(torture_nprocs);
1161 signal(SIGALRM, nb_alarm);
1163 t = create_procs(run_netbench, &correct);
1166 printf("\nThroughput %g MB/sec\n",
1167 1.0e-6 * nbio_total() / t);
1173 This test checks for two things:
1175 1) correct support for retaining locks over a close (ie. the server
1176 must not use posix semantics)
1177 2) support for lock timeouts
1179 static bool run_locktest1(int dummy)
1181 struct cli_state *cli1, *cli2;
1182 const char *fname = "\\lockt1.lck";
1183 uint16_t fnum1, fnum2, fnum3;
1185 unsigned lock_timeout;
1188 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1191 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1192 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1194 printf("starting locktest1\n");
1196 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1198 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1200 if (!NT_STATUS_IS_OK(status)) {
1201 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1205 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1206 if (!NT_STATUS_IS_OK(status)) {
1207 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1211 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1212 if (!NT_STATUS_IS_OK(status)) {
1213 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1217 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1218 if (!NT_STATUS_IS_OK(status)) {
1219 printf("lock1 failed (%s)\n", nt_errstr(status));
1223 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1224 if (NT_STATUS_IS_OK(status)) {
1225 printf("lock2 succeeded! This is a locking bug\n");
1228 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1229 NT_STATUS_LOCK_NOT_GRANTED)) {
1234 lock_timeout = (1 + (random() % 20));
1235 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1237 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1238 if (NT_STATUS_IS_OK(status)) {
1239 printf("lock3 succeeded! This is a locking bug\n");
1242 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1243 NT_STATUS_FILE_LOCK_CONFLICT)) {
1249 if (ABS(t2 - t1) < lock_timeout-1) {
1250 printf("error: This server appears not to support timed lock requests\n");
1253 printf("server slept for %u seconds for a %u second timeout\n",
1254 (unsigned int)(t2-t1), lock_timeout);
1256 status = cli_close(cli1, fnum2);
1257 if (!NT_STATUS_IS_OK(status)) {
1258 printf("close1 failed (%s)\n", nt_errstr(status));
1262 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1263 if (NT_STATUS_IS_OK(status)) {
1264 printf("lock4 succeeded! This is a locking bug\n");
1267 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1268 NT_STATUS_FILE_LOCK_CONFLICT)) {
1273 status = cli_close(cli1, fnum1);
1274 if (!NT_STATUS_IS_OK(status)) {
1275 printf("close2 failed (%s)\n", nt_errstr(status));
1279 status = cli_close(cli2, fnum3);
1280 if (!NT_STATUS_IS_OK(status)) {
1281 printf("close3 failed (%s)\n", nt_errstr(status));
1285 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1286 if (!NT_STATUS_IS_OK(status)) {
1287 printf("unlink failed (%s)\n", nt_errstr(status));
1292 if (!torture_close_connection(cli1)) {
1296 if (!torture_close_connection(cli2)) {
1300 printf("Passed locktest1\n");
1305 this checks to see if a secondary tconx can use open files from an
1308 static bool run_tcon_test(int dummy)
1310 static struct cli_state *cli;
1311 const char *fname = "\\tcontest.tmp";
1313 uint32_t cnum1, cnum2, cnum3;
1314 struct smbXcli_tcon *orig_tcon = NULL;
1315 uint16_t vuid1, vuid2;
1320 memset(buf, '\0', sizeof(buf));
1322 if (!torture_open_connection(&cli, 0)) {
1325 smbXcli_conn_set_sockopt(cli->conn, sockops);
1327 printf("starting tcontest\n");
1329 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1331 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1337 cnum1 = cli_state_get_tid(cli);
1338 vuid1 = cli_state_get_uid(cli);
1340 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1341 if (!NT_STATUS_IS_OK(status)) {
1342 printf("initial write failed (%s)", nt_errstr(status));
1346 orig_tcon = cli_state_save_tcon(cli);
1347 if (orig_tcon == NULL) {
1351 status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1352 if (!NT_STATUS_IS_OK(status)) {
1353 printf("%s refused 2nd tree connect (%s)\n", host,
1359 cnum2 = cli_state_get_tid(cli);
1360 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1361 vuid2 = cli_state_get_uid(cli) + 1;
1363 /* try a write with the wrong tid */
1364 cli_state_set_tid(cli, cnum2);
1366 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1367 if (NT_STATUS_IS_OK(status)) {
1368 printf("* server allows write with wrong TID\n");
1371 printf("server fails write with wrong TID : %s\n",
1376 /* try a write with an invalid tid */
1377 cli_state_set_tid(cli, cnum3);
1379 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1380 if (NT_STATUS_IS_OK(status)) {
1381 printf("* server allows write with invalid TID\n");
1384 printf("server fails write with invalid TID : %s\n",
1388 /* try a write with an invalid vuid */
1389 cli_state_set_uid(cli, vuid2);
1390 cli_state_set_tid(cli, cnum1);
1392 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1393 if (NT_STATUS_IS_OK(status)) {
1394 printf("* server allows write with invalid VUID\n");
1397 printf("server fails write with invalid VUID : %s\n",
1401 cli_state_set_tid(cli, cnum1);
1402 cli_state_set_uid(cli, vuid1);
1404 status = cli_close(cli, fnum1);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 printf("close failed (%s)\n", nt_errstr(status));
1410 cli_state_set_tid(cli, cnum2);
1412 status = cli_tdis(cli);
1413 if (!NT_STATUS_IS_OK(status)) {
1414 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1418 cli_state_restore_tcon(cli, orig_tcon);
1420 cli_state_set_tid(cli, cnum1);
1422 if (!torture_close_connection(cli)) {
1431 checks for old style tcon support
1433 static bool run_tcon2_test(int dummy)
1435 static struct cli_state *cli;
1436 uint16_t cnum, max_xmit;
1440 if (!torture_open_connection(&cli, 0)) {
1443 smbXcli_conn_set_sockopt(cli->conn, sockops);
1445 printf("starting tcon2 test\n");
1447 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1451 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1455 if (!NT_STATUS_IS_OK(status)) {
1456 printf("tcon2 failed : %s\n", nt_errstr(status));
1458 printf("tcon OK : max_xmit=%d cnum=%d\n",
1459 (int)max_xmit, (int)cnum);
1462 if (!torture_close_connection(cli)) {
1466 printf("Passed tcon2 test\n");
1470 static bool tcon_devtest(struct cli_state *cli,
1471 const char *myshare, const char *devtype,
1472 const char *return_devtype,
1473 NTSTATUS expected_error)
1478 status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
1480 if (NT_STATUS_IS_OK(expected_error)) {
1481 if (NT_STATUS_IS_OK(status)) {
1482 if (strcmp(cli->dev, return_devtype) == 0) {
1485 printf("tconX to share %s with type %s "
1486 "succeeded but returned the wrong "
1487 "device type (got [%s] but should have got [%s])\n",
1488 myshare, devtype, cli->dev, return_devtype);
1492 printf("tconX to share %s with type %s "
1493 "should have succeeded but failed\n",
1499 if (NT_STATUS_IS_OK(status)) {
1500 printf("tconx to share %s with type %s "
1501 "should have failed but succeeded\n",
1505 if (NT_STATUS_EQUAL(status, expected_error)) {
1508 printf("Returned unexpected error\n");
1517 checks for correct tconX support
1519 static bool run_tcon_devtype_test(int dummy)
1521 static struct cli_state *cli1 = NULL;
1522 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
1526 status = cli_full_connection_creds(&cli1,
1532 NULL, /* service_type */
1537 if (!NT_STATUS_IS_OK(status)) {
1538 printf("could not open connection\n");
1542 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1545 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1548 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1551 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1554 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1557 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1560 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1563 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1566 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1569 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1575 printf("Passed tcondevtest\n");
1582 This test checks that
1584 1) the server supports multiple locking contexts on the one SMB
1585 connection, distinguished by PID.
1587 2) the server correctly fails overlapping locks made by the same PID (this
1588 goes against POSIX behaviour, which is why it is tricky to implement)
1590 3) the server denies unlock requests by an incorrect client PID
1592 static bool run_locktest2(int dummy)
1594 static struct cli_state *cli;
1595 const char *fname = "\\lockt2.lck";
1596 uint16_t fnum1, fnum2, fnum3;
1597 bool correct = True;
1600 if (!torture_open_connection(&cli, 0)) {
1604 smbXcli_conn_set_sockopt(cli->conn, sockops);
1606 printf("starting locktest2\n");
1608 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1612 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1613 if (!NT_STATUS_IS_OK(status)) {
1614 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1618 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1619 if (!NT_STATUS_IS_OK(status)) {
1620 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1626 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1627 if (!NT_STATUS_IS_OK(status)) {
1628 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1634 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1635 if (!NT_STATUS_IS_OK(status)) {
1636 printf("lock1 failed (%s)\n", nt_errstr(status));
1640 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1641 if (NT_STATUS_IS_OK(status)) {
1642 printf("WRITE lock1 succeeded! This is a locking bug\n");
1645 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1646 NT_STATUS_LOCK_NOT_GRANTED)) {
1651 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1652 if (NT_STATUS_IS_OK(status)) {
1653 printf("WRITE lock2 succeeded! This is a locking bug\n");
1656 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1657 NT_STATUS_LOCK_NOT_GRANTED)) {
1662 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1663 if (NT_STATUS_IS_OK(status)) {
1664 printf("READ lock2 succeeded! This is a locking bug\n");
1667 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1668 NT_STATUS_FILE_LOCK_CONFLICT)) {
1673 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1674 if (!NT_STATUS_IS_OK(status)) {
1675 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1678 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1679 printf("unlock at 100 succeeded! This is a locking bug\n");
1683 status = cli_unlock(cli, fnum1, 0, 4);
1684 if (NT_STATUS_IS_OK(status)) {
1685 printf("unlock1 succeeded! This is a locking bug\n");
1688 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1689 NT_STATUS_RANGE_NOT_LOCKED)) {
1694 status = cli_unlock(cli, fnum1, 0, 8);
1695 if (NT_STATUS_IS_OK(status)) {
1696 printf("unlock2 succeeded! This is a locking bug\n");
1699 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1700 NT_STATUS_RANGE_NOT_LOCKED)) {
1705 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1706 if (NT_STATUS_IS_OK(status)) {
1707 printf("lock3 succeeded! This is a locking bug\n");
1710 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1711 NT_STATUS_LOCK_NOT_GRANTED)) {
1718 status = cli_close(cli, fnum1);
1719 if (!NT_STATUS_IS_OK(status)) {
1720 printf("close1 failed (%s)\n", nt_errstr(status));
1724 status = cli_close(cli, fnum2);
1725 if (!NT_STATUS_IS_OK(status)) {
1726 printf("close2 failed (%s)\n", nt_errstr(status));
1730 status = cli_close(cli, fnum3);
1731 if (!NT_STATUS_IS_OK(status)) {
1732 printf("close3 failed (%s)\n", nt_errstr(status));
1736 if (!torture_close_connection(cli)) {
1740 printf("locktest2 finished\n");
1747 This test checks that
1749 1) the server supports the full offset range in lock requests
1751 static bool run_locktest3(int dummy)
1753 static struct cli_state *cli1, *cli2;
1754 const char *fname = "\\lockt3.lck";
1755 uint16_t fnum1, fnum2;
1758 bool correct = True;
1761 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1763 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1766 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1767 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1769 printf("starting locktest3\n");
1771 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1773 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1775 if (!NT_STATUS_IS_OK(status)) {
1776 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1780 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1781 if (!NT_STATUS_IS_OK(status)) {
1782 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1786 for (offset=i=0;i<torture_numops;i++) {
1789 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1790 if (!NT_STATUS_IS_OK(status)) {
1791 printf("lock1 %d failed (%s)\n",
1797 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1798 if (!NT_STATUS_IS_OK(status)) {
1799 printf("lock2 %d failed (%s)\n",
1806 for (offset=i=0;i<torture_numops;i++) {
1809 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1810 if (NT_STATUS_IS_OK(status)) {
1811 printf("error: lock1 %d succeeded!\n", i);
1815 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1816 if (NT_STATUS_IS_OK(status)) {
1817 printf("error: lock2 %d succeeded!\n", i);
1821 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1822 if (NT_STATUS_IS_OK(status)) {
1823 printf("error: lock3 %d succeeded!\n", i);
1827 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1828 if (NT_STATUS_IS_OK(status)) {
1829 printf("error: lock4 %d succeeded!\n", i);
1834 for (offset=i=0;i<torture_numops;i++) {
1837 status = cli_unlock(cli1, fnum1, offset-1, 1);
1838 if (!NT_STATUS_IS_OK(status)) {
1839 printf("unlock1 %d failed (%s)\n",
1845 status = cli_unlock(cli2, fnum2, offset-2, 1);
1846 if (!NT_STATUS_IS_OK(status)) {
1847 printf("unlock2 %d failed (%s)\n",
1854 status = cli_close(cli1, fnum1);
1855 if (!NT_STATUS_IS_OK(status)) {
1856 printf("close1 failed (%s)\n", nt_errstr(status));
1860 status = cli_close(cli2, fnum2);
1861 if (!NT_STATUS_IS_OK(status)) {
1862 printf("close2 failed (%s)\n", nt_errstr(status));
1866 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1867 if (!NT_STATUS_IS_OK(status)) {
1868 printf("unlink failed (%s)\n", nt_errstr(status));
1872 if (!torture_close_connection(cli1)) {
1876 if (!torture_close_connection(cli2)) {
1880 printf("finished locktest3\n");
1885 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1886 char *buf, off_t offset, size_t size,
1887 size_t *nread, size_t expect)
1892 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1894 if(!NT_STATUS_IS_OK(status)) {
1896 } else if (l_nread != expect) {
1907 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1908 printf("** "); correct = False; \
1912 looks at overlapping locks
1914 static bool run_locktest4(int dummy)
1916 static struct cli_state *cli1, *cli2;
1917 const char *fname = "\\lockt4.lck";
1918 uint16_t fnum1, fnum2, f;
1921 bool correct = True;
1924 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1928 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1929 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1931 printf("starting locktest4\n");
1933 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1935 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1936 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1938 memset(buf, 0, sizeof(buf));
1940 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1942 if (!NT_STATUS_IS_OK(status)) {
1943 printf("Failed to create file: %s\n", nt_errstr(status));
1948 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1949 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1950 EXPECTED(ret, False);
1951 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1953 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1954 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1955 EXPECTED(ret, True);
1956 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1958 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1959 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1960 EXPECTED(ret, False);
1961 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1963 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1964 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1965 EXPECTED(ret, True);
1966 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1968 ret = (cli_setpid(cli1, 1),
1969 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1970 (cli_setpid(cli1, 2),
1971 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1972 EXPECTED(ret, False);
1973 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1975 ret = (cli_setpid(cli1, 1),
1976 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1977 (cli_setpid(cli1, 2),
1978 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1979 EXPECTED(ret, True);
1980 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1982 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1983 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1984 EXPECTED(ret, True);
1985 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1987 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1988 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1989 EXPECTED(ret, False);
1990 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1992 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1993 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1994 EXPECTED(ret, False);
1995 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1997 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1998 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
1999 EXPECTED(ret, True);
2000 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2002 ret = (cli_setpid(cli1, 1),
2003 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2004 (cli_setpid(cli1, 2),
2005 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2006 EXPECTED(ret, False);
2007 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2009 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2010 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2011 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2012 EXPECTED(ret, False);
2013 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2016 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2017 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2018 EXPECTED(ret, False);
2019 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2021 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2022 ret = NT_STATUS_IS_OK(status);
2024 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2026 ret = NT_STATUS_IS_OK(status);
2028 EXPECTED(ret, False);
2029 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2032 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2033 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2034 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2035 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2036 EXPECTED(ret, True);
2037 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2040 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2041 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2042 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2043 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2044 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2046 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2047 EXPECTED(ret, True);
2048 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2050 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2051 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2052 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2054 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2055 EXPECTED(ret, True);
2056 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2058 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2059 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2060 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2062 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2063 EXPECTED(ret, True);
2064 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2066 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2067 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2068 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2069 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2071 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2072 EXPECTED(ret, True);
2073 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2075 cli_close(cli1, fnum1);
2076 cli_close(cli2, fnum2);
2077 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2078 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2079 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2080 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2081 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2082 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2083 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2085 cli_close(cli1, fnum1);
2086 EXPECTED(ret, True);
2087 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2090 cli_close(cli1, fnum1);
2091 cli_close(cli2, fnum2);
2092 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2093 torture_close_connection(cli1);
2094 torture_close_connection(cli2);
2096 printf("finished locktest4\n");
2101 looks at lock upgrade/downgrade.
2103 static bool run_locktest5(int dummy)
2105 static struct cli_state *cli1, *cli2;
2106 const char *fname = "\\lockt5.lck";
2107 uint16_t fnum1, fnum2, fnum3;
2110 bool correct = True;
2113 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2117 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2118 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2120 printf("starting locktest5\n");
2122 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2124 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2125 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2126 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2128 memset(buf, 0, sizeof(buf));
2130 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2132 if (!NT_STATUS_IS_OK(status)) {
2133 printf("Failed to create file: %s\n", nt_errstr(status));
2138 /* Check for NT bug... */
2139 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2140 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2141 cli_close(cli1, fnum1);
2142 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2143 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2144 ret = NT_STATUS_IS_OK(status);
2145 EXPECTED(ret, True);
2146 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2147 cli_close(cli1, fnum1);
2148 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2149 cli_unlock(cli1, fnum3, 0, 1);
2151 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2152 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2153 EXPECTED(ret, True);
2154 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2156 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2157 ret = NT_STATUS_IS_OK(status);
2158 EXPECTED(ret, False);
2160 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2162 /* Unlock the process 2 lock. */
2163 cli_unlock(cli2, fnum2, 0, 4);
2165 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2166 ret = NT_STATUS_IS_OK(status);
2167 EXPECTED(ret, False);
2169 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2171 /* Unlock the process 1 fnum3 lock. */
2172 cli_unlock(cli1, fnum3, 0, 4);
2174 /* Stack 2 more locks here. */
2175 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2176 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2178 EXPECTED(ret, True);
2179 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2181 /* Unlock the first process lock, then check this was the WRITE lock that was
2184 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2185 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2187 EXPECTED(ret, True);
2188 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2190 /* Unlock the process 2 lock. */
2191 cli_unlock(cli2, fnum2, 0, 4);
2193 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2195 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2196 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2197 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2199 EXPECTED(ret, True);
2200 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2202 /* Ensure the next unlock fails. */
2203 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2204 EXPECTED(ret, False);
2205 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2207 /* Ensure connection 2 can get a write lock. */
2208 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2209 ret = NT_STATUS_IS_OK(status);
2210 EXPECTED(ret, True);
2212 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2216 cli_close(cli1, fnum1);
2217 cli_close(cli2, fnum2);
2218 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2219 if (!torture_close_connection(cli1)) {
2222 if (!torture_close_connection(cli2)) {
2226 printf("finished locktest5\n");
2232 tries the unusual lockingX locktype bits
2234 static bool run_locktest6(int dummy)
2236 static struct cli_state *cli;
2237 const char *fname[1] = { "\\lock6.txt" };
2242 if (!torture_open_connection(&cli, 0)) {
2246 smbXcli_conn_set_sockopt(cli->conn, sockops);
2248 printf("starting locktest6\n");
2251 printf("Testing %s\n", fname[i]);
2253 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2255 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2256 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2257 cli_close(cli, fnum);
2258 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2260 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2261 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2262 cli_close(cli, fnum);
2263 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2265 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2268 torture_close_connection(cli);
2270 printf("finished locktest6\n");
2274 static bool run_locktest7(int dummy)
2276 struct cli_state *cli1;
2277 const char *fname = "\\lockt7.lck";
2280 bool correct = False;
2284 if (!torture_open_connection(&cli1, 0)) {
2288 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2290 printf("starting locktest7\n");
2292 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2294 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2296 memset(buf, 0, sizeof(buf));
2298 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2300 if (!NT_STATUS_IS_OK(status)) {
2301 printf("Failed to create file: %s\n", nt_errstr(status));
2305 cli_setpid(cli1, 1);
2307 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2308 if (!NT_STATUS_IS_OK(status)) {
2309 printf("Unable to apply read lock on range 130:4, "
2310 "error was %s\n", nt_errstr(status));
2313 printf("pid1 successfully locked range 130:4 for READ\n");
2316 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2317 if (!NT_STATUS_IS_OK(status)) {
2318 printf("pid1 unable to read the range 130:4, error was %s\n",
2321 } else if (nread != 4) {
2322 printf("pid1 unable to read the range 130:4, "
2323 "recv %ld req %d\n", (unsigned long)nread, 4);
2326 printf("pid1 successfully read the range 130:4\n");
2329 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2330 if (!NT_STATUS_IS_OK(status)) {
2331 printf("pid1 unable to write to the range 130:4, error was "
2332 "%s\n", nt_errstr(status));
2333 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2334 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2338 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2342 cli_setpid(cli1, 2);
2344 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2345 if (!NT_STATUS_IS_OK(status)) {
2346 printf("pid2 unable to read the range 130:4, error was %s\n",
2349 } else if (nread != 4) {
2350 printf("pid2 unable to read the range 130:4, "
2351 "recv %ld req %d\n", (unsigned long)nread, 4);
2354 printf("pid2 successfully read the range 130:4\n");
2357 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2358 if (!NT_STATUS_IS_OK(status)) {
2359 printf("pid2 unable to write to the range 130:4, error was "
2360 "%s\n", nt_errstr(status));
2361 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2362 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2366 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2370 cli_setpid(cli1, 1);
2371 cli_unlock(cli1, fnum1, 130, 4);
2373 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2374 if (!NT_STATUS_IS_OK(status)) {
2375 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2378 printf("pid1 successfully locked range 130:4 for WRITE\n");
2381 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2382 if (!NT_STATUS_IS_OK(status)) {
2383 printf("pid1 unable to read the range 130:4, error was %s\n",
2386 } else if (nread != 4) {
2387 printf("pid1 unable to read the range 130:4, "
2388 "recv %ld req %d\n", (unsigned long)nread, 4);
2391 printf("pid1 successfully read the range 130:4\n");
2394 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2395 if (!NT_STATUS_IS_OK(status)) {
2396 printf("pid1 unable to write to the range 130:4, error was "
2397 "%s\n", nt_errstr(status));
2400 printf("pid1 successfully wrote to the range 130:4\n");
2403 cli_setpid(cli1, 2);
2405 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2406 if (!NT_STATUS_IS_OK(status)) {
2407 printf("pid2 unable to read the range 130:4, error was "
2408 "%s\n", nt_errstr(status));
2409 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2410 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2414 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2415 (unsigned long)nread);
2419 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2420 if (!NT_STATUS_IS_OK(status)) {
2421 printf("pid2 unable to write to the range 130:4, error was "
2422 "%s\n", nt_errstr(status));
2423 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2424 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2428 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2432 cli_unlock(cli1, fnum1, 130, 0);
2436 cli_close(cli1, fnum1);
2437 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2438 torture_close_connection(cli1);
2440 printf("finished locktest7\n");
2445 * This demonstrates a problem with our use of GPFS share modes: A file
2446 * descriptor sitting in the pending close queue holding a GPFS share mode
2447 * blocks opening a file another time. Happens with Word 2007 temp files.
2448 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2449 * open is denied with NT_STATUS_SHARING_VIOLATION.
2452 static bool run_locktest8(int dummy)
2454 struct cli_state *cli1;
2455 const char *fname = "\\lockt8.lck";
2456 uint16_t fnum1, fnum2;
2458 bool correct = False;
2461 if (!torture_open_connection(&cli1, 0)) {
2465 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2467 printf("starting locktest8\n");
2469 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2471 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2473 if (!NT_STATUS_IS_OK(status)) {
2474 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2478 memset(buf, 0, sizeof(buf));
2480 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2481 if (!NT_STATUS_IS_OK(status)) {
2482 d_fprintf(stderr, "cli_openx second time returned %s\n",
2487 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2488 if (!NT_STATUS_IS_OK(status)) {
2489 printf("Unable to apply read lock on range 1:1, error was "
2490 "%s\n", nt_errstr(status));
2494 status = cli_close(cli1, fnum1);
2495 if (!NT_STATUS_IS_OK(status)) {
2496 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2500 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2501 if (!NT_STATUS_IS_OK(status)) {
2502 d_fprintf(stderr, "cli_openx third time returned %s\n",
2510 cli_close(cli1, fnum1);
2511 cli_close(cli1, fnum2);
2512 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2513 torture_close_connection(cli1);
2515 printf("finished locktest8\n");
2520 * This test is designed to be run in conjunction with
2521 * external NFS or POSIX locks taken in the filesystem.
2522 * It checks that the smbd server will block until the
2523 * lock is released and then acquire it. JRA.
2526 static bool got_alarm;
2527 static struct cli_state *alarm_cli;
2529 static void alarm_handler(int dummy)
2534 static void alarm_handler_parent(int dummy)
2536 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2539 static void do_local_lock(int read_fd, int write_fd)
2544 const char *local_pathname = NULL;
2547 local_pathname = talloc_asprintf(talloc_tos(),
2548 "%s/lockt9.lck", local_path);
2549 if (!local_pathname) {
2550 printf("child: alloc fail\n");
2554 unlink(local_pathname);
2555 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2557 printf("child: open of %s failed %s.\n",
2558 local_pathname, strerror(errno));
2562 /* Now take a fcntl lock. */
2563 lock.l_type = F_WRLCK;
2564 lock.l_whence = SEEK_SET;
2567 lock.l_pid = getpid();
2569 ret = fcntl(fd,F_SETLK,&lock);
2571 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2572 local_pathname, strerror(errno));
2575 printf("child: got lock 0:4 on file %s.\n",
2580 CatchSignal(SIGALRM, alarm_handler);
2582 /* Signal the parent. */
2583 if (write(write_fd, &c, 1) != 1) {
2584 printf("child: start signal fail %s.\n",
2591 /* Wait for the parent to be ready. */
2592 if (read(read_fd, &c, 1) != 1) {
2593 printf("child: reply signal fail %s.\n",
2601 printf("child: released lock 0:4 on file %s.\n",
2607 static bool run_locktest9(int dummy)
2609 struct cli_state *cli1;
2610 const char *fname = "\\lockt9.lck";
2612 bool correct = False;
2613 int pipe_in[2], pipe_out[2];
2617 struct timeval start;
2621 printf("starting locktest9\n");
2623 if (local_path == NULL) {
2624 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2628 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2633 if (child_pid == -1) {
2637 if (child_pid == 0) {
2639 do_local_lock(pipe_out[0], pipe_in[1]);
2649 ret = read(pipe_in[0], &c, 1);
2651 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2656 if (!torture_open_connection(&cli1, 0)) {
2660 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2662 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2664 if (!NT_STATUS_IS_OK(status)) {
2665 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2669 /* Ensure the child has the lock. */
2670 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2671 if (NT_STATUS_IS_OK(status)) {
2672 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2675 d_printf("Child has the lock.\n");
2678 /* Tell the child to wait 5 seconds then exit. */
2679 ret = write(pipe_out[1], &c, 1);
2681 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2686 /* Wait 20 seconds for the lock. */
2688 CatchSignal(SIGALRM, alarm_handler_parent);
2691 start = timeval_current();
2693 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2694 if (!NT_STATUS_IS_OK(status)) {
2695 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2696 "%s\n", nt_errstr(status));
2701 seconds = timeval_elapsed(&start);
2703 printf("Parent got the lock after %.2f seconds.\n",
2706 status = cli_close(cli1, fnum);
2707 if (!NT_STATUS_IS_OK(status)) {
2708 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2715 cli_close(cli1, fnum);
2716 torture_close_connection(cli1);
2720 printf("finished locktest9\n");
2725 test whether fnums and tids open on one VC are available on another (a major
2728 static bool run_fdpasstest(int dummy)
2730 struct cli_state *cli1, *cli2;
2731 const char *fname = "\\fdpass.tst";
2736 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2739 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2740 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2742 printf("starting fdpasstest\n");
2744 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2746 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2748 if (!NT_STATUS_IS_OK(status)) {
2749 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2753 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2755 if (!NT_STATUS_IS_OK(status)) {
2756 printf("write failed (%s)\n", nt_errstr(status));
2760 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2761 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2762 cli_setpid(cli2, cli_getpid(cli1));
2764 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2765 printf("read succeeded! nasty security hole [%s]\n", buf);
2769 cli_close(cli1, fnum1);
2770 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2772 torture_close_connection(cli1);
2773 torture_close_connection(cli2);
2775 printf("finished fdpasstest\n");
2779 static bool run_fdsesstest(int dummy)
2781 struct cli_state *cli;
2783 uint16_t saved_vuid;
2785 uint32_t saved_cnum;
2786 const char *fname = "\\fdsess.tst";
2787 const char *fname1 = "\\fdsess1.tst";
2794 if (!torture_open_connection(&cli, 0))
2796 smbXcli_conn_set_sockopt(cli->conn, sockops);
2798 if (!torture_cli_session_setup2(cli, &new_vuid))
2801 saved_cnum = cli_state_get_tid(cli);
2802 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
2804 new_cnum = cli_state_get_tid(cli);
2805 cli_state_set_tid(cli, saved_cnum);
2807 printf("starting fdsesstest\n");
2809 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2810 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2812 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2813 if (!NT_STATUS_IS_OK(status)) {
2814 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2818 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2820 if (!NT_STATUS_IS_OK(status)) {
2821 printf("write failed (%s)\n", nt_errstr(status));
2825 saved_vuid = cli_state_get_uid(cli);
2826 cli_state_set_uid(cli, new_vuid);
2828 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2829 printf("read succeeded with different vuid! "
2830 "nasty security hole [%s]\n", buf);
2833 /* Try to open a file with different vuid, samba cnum. */
2834 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2835 printf("create with different vuid, same cnum succeeded.\n");
2836 cli_close(cli, fnum2);
2837 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2839 printf("create with different vuid, same cnum failed.\n");
2840 printf("This will cause problems with service clients.\n");
2844 cli_state_set_uid(cli, saved_vuid);
2846 /* Try with same vuid, different cnum. */
2847 cli_state_set_tid(cli, new_cnum);
2849 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2850 printf("read succeeded with different cnum![%s]\n", buf);
2854 cli_state_set_tid(cli, saved_cnum);
2855 cli_close(cli, fnum1);
2856 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2858 torture_close_connection(cli);
2860 printf("finished fdsesstest\n");
2865 This test checks that
2867 1) the server does not allow an unlink on a file that is open
2869 static bool run_unlinktest(int dummy)
2871 struct cli_state *cli;
2872 const char *fname = "\\unlink.tst";
2874 bool correct = True;
2877 if (!torture_open_connection(&cli, 0)) {
2881 smbXcli_conn_set_sockopt(cli->conn, sockops);
2883 printf("starting unlink test\n");
2885 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2889 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2890 if (!NT_STATUS_IS_OK(status)) {
2891 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2895 status = cli_unlink(cli, fname,
2896 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2897 if (NT_STATUS_IS_OK(status)) {
2898 printf("error: server allowed unlink on an open file\n");
2901 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2902 NT_STATUS_SHARING_VIOLATION);
2905 cli_close(cli, fnum);
2906 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2908 if (!torture_close_connection(cli)) {
2912 printf("unlink test finished\n");
2919 test how many open files this server supports on the one socket
2921 static bool run_maxfidtest(int dummy)
2923 struct cli_state *cli;
2925 uint16_t fnums[0x11000];
2928 bool correct = True;
2934 printf("failed to connect\n");
2938 smbXcli_conn_set_sockopt(cli->conn, sockops);
2940 for (i=0; i<0x11000; i++) {
2941 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2942 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2944 if (!NT_STATUS_IS_OK(status)) {
2945 printf("open of %s failed (%s)\n",
2946 fname, nt_errstr(status));
2947 printf("maximum fnum is %d\n", i);
2955 printf("cleaning up\n");
2957 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2958 cli_close(cli, fnums[i]);
2960 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2961 if (!NT_STATUS_IS_OK(status)) {
2962 printf("unlink of %s failed (%s)\n",
2963 fname, nt_errstr(status));
2970 printf("maxfid test finished\n");
2971 if (!torture_close_connection(cli)) {
2977 /* generate a random buffer */
2978 static void rand_buf(char *buf, int len)
2981 *buf = (char)sys_random();
2986 /* send smb negprot commands, not reading the response */
2987 static bool run_negprot_nowait(int dummy)
2989 struct tevent_context *ev;
2991 struct cli_state *cli;
2992 bool correct = True;
2994 printf("starting negprot nowait test\n");
2996 ev = samba_tevent_context_init(talloc_tos());
3001 if (!(cli = open_nbt_connection())) {
3006 for (i=0;i<50000;i++) {
3007 struct tevent_req *req;
3009 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3010 PROTOCOL_CORE, PROTOCOL_NT1, 0);
3015 if (!tevent_req_poll(req, ev)) {
3016 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3024 if (torture_close_connection(cli)) {
3028 printf("finished negprot nowait test\n");
3033 /* send smb negprot commands, not reading the response */
3034 static bool run_bad_nbt_session(int dummy)
3036 struct nmb_name called, calling;
3037 struct sockaddr_storage ss;
3042 printf("starting bad nbt session test\n");
3044 make_nmb_name(&calling, myname, 0x0);
3045 make_nmb_name(&called , host, 0x20);
3047 if (!resolve_name(host, &ss, 0x20, true)) {
3048 d_fprintf(stderr, "Could not resolve name %s\n", host);
3052 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3053 if (!NT_STATUS_IS_OK(status)) {
3054 d_fprintf(stderr, "open_socket_out failed: %s\n",
3059 ret = cli_bad_session_request(fd, &calling, &called);
3062 d_fprintf(stderr, "open_socket_out failed: %s\n",
3067 printf("finished bad nbt session test\n");
3071 /* send random IPC commands */
3072 static bool run_randomipc(int dummy)
3074 char *rparam = NULL;
3076 unsigned int rdrcnt,rprcnt;
3078 int api, param_len, i;
3079 struct cli_state *cli;
3080 bool correct = True;
3083 printf("starting random ipc test\n");
3085 if (!torture_open_connection(&cli, 0)) {
3089 for (i=0;i<count;i++) {
3090 api = sys_random() % 500;
3091 param_len = (sys_random() % 64);
3093 rand_buf(param, param_len);
3098 param, param_len, 8,
3099 NULL, 0, CLI_BUFFER_SIZE,
3103 printf("%d/%d\r", i,count);
3106 printf("%d/%d\n", i, count);
3108 if (!torture_close_connection(cli)) {
3115 printf("finished random ipc test\n");
3122 static void browse_callback(const char *sname, uint32_t stype,
3123 const char *comment, void *state)
3125 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3131 This test checks the browse list code
3134 static bool run_browsetest(int dummy)
3136 static struct cli_state *cli;
3137 bool correct = True;
3139 printf("starting browse test\n");
3141 if (!torture_open_connection(&cli, 0)) {
3145 printf("domain list:\n");
3146 cli_NetServerEnum(cli, cli->server_domain,
3147 SV_TYPE_DOMAIN_ENUM,
3148 browse_callback, NULL);
3150 printf("machine list:\n");
3151 cli_NetServerEnum(cli, cli->server_domain,
3153 browse_callback, NULL);
3155 if (!torture_close_connection(cli)) {
3159 printf("browse test finished\n");
3165 static bool check_attributes(struct cli_state *cli,
3167 uint16_t expected_attrs)
3170 NTSTATUS status = cli_getatr(cli,
3175 if (!NT_STATUS_IS_OK(status)) {
3176 printf("cli_getatr failed with %s\n",
3180 if (attrs != expected_attrs) {
3181 printf("Attributes incorrect 0x%x, should be 0x%x\n",
3182 (unsigned int)attrs,
3183 (unsigned int)expected_attrs);
3190 This checks how the getatr calls works
3192 static bool run_attrtest(int dummy)
3194 struct cli_state *cli;
3197 const char *fname = "\\attrib123456789.tst";
3198 bool correct = True;
3201 printf("starting attrib test\n");
3203 if (!torture_open_connection(&cli, 0)) {
3207 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3208 cli_openx(cli, fname,
3209 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3210 cli_close(cli, fnum);
3212 status = cli_getatr(cli, fname, NULL, NULL, &t);
3213 if (!NT_STATUS_IS_OK(status)) {
3214 printf("getatr failed (%s)\n", nt_errstr(status));
3218 if (abs(t - time(NULL)) > 60*60*24*10) {
3219 printf("ERROR: SMBgetatr bug. time is %s",
3225 t2 = t-60*60*24; /* 1 day ago */
3227 status = cli_setatr(cli, fname, 0, t2);
3228 if (!NT_STATUS_IS_OK(status)) {
3229 printf("setatr failed (%s)\n", nt_errstr(status));
3233 status = cli_getatr(cli, fname, NULL, NULL, &t);
3234 if (!NT_STATUS_IS_OK(status)) {
3235 printf("getatr failed (%s)\n", nt_errstr(status));
3240 printf("ERROR: getatr/setatr bug. times are\n%s",
3242 printf("%s", ctime(&t2));
3246 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3248 /* Check cli_setpathinfo_basic() */
3249 /* Re-create the file. */
3250 status = cli_openx(cli, fname,
3251 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3252 if (!NT_STATUS_IS_OK(status)) {
3253 printf("Failed to recreate %s (%s)\n",
3254 fname, nt_errstr(status));
3257 cli_close(cli, fnum);
3259 status = cli_setpathinfo_basic(cli,
3265 FILE_ATTRIBUTE_SYSTEM |
3266 FILE_ATTRIBUTE_HIDDEN |
3267 FILE_ATTRIBUTE_READONLY);
3268 if (!NT_STATUS_IS_OK(status)) {
3269 printf("cli_setpathinfo_basic failed with %s\n",
3274 /* Check attributes are correct. */
3275 correct = check_attributes(cli,
3277 FILE_ATTRIBUTE_SYSTEM |
3278 FILE_ATTRIBUTE_HIDDEN |
3279 FILE_ATTRIBUTE_READONLY);
3280 if (correct == false) {
3284 /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
3285 status = cli_setpathinfo_basic(cli,
3291 FILE_ATTRIBUTE_NORMAL);
3292 if (!NT_STATUS_IS_OK(status)) {
3293 printf("cli_setpathinfo_basic failed with %s\n",
3298 /* Check attributes are correct. */
3299 correct = check_attributes(cli,
3301 FILE_ATTRIBUTE_SYSTEM |
3302 FILE_ATTRIBUTE_HIDDEN |
3303 FILE_ATTRIBUTE_READONLY);
3304 if (correct == false) {
3308 /* Setting to (uint16_t)-1 should also be ignored. */
3309 status = cli_setpathinfo_basic(cli,
3316 if (!NT_STATUS_IS_OK(status)) {
3317 printf("cli_setpathinfo_basic failed with %s\n",
3322 /* Check attributes are correct. */
3323 correct = check_attributes(cli,
3325 FILE_ATTRIBUTE_SYSTEM |
3326 FILE_ATTRIBUTE_HIDDEN |
3327 FILE_ATTRIBUTE_READONLY);
3328 if (correct == false) {
3332 /* Setting to 0 should clear them all. */
3333 status = cli_setpathinfo_basic(cli,
3340 if (!NT_STATUS_IS_OK(status)) {
3341 printf("cli_setpathinfo_basic failed with %s\n",
3346 /* Check attributes are correct. */
3347 correct = check_attributes(cli,
3349 FILE_ATTRIBUTE_NORMAL);
3350 if (correct == false) {
3358 FILE_ATTRIBUTE_SYSTEM |
3359 FILE_ATTRIBUTE_HIDDEN|
3360 FILE_ATTRIBUTE_READONLY);
3362 if (!torture_close_connection(cli)) {
3366 printf("attrib test finished\n");
3373 This checks a couple of trans2 calls
3375 static bool run_trans2test(int dummy)
3377 struct cli_state *cli;
3380 time_t c_time, a_time, m_time;
3381 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3382 const char *fname = "\\trans2.tst";
3383 const char *dname = "\\trans2";
3384 const char *fname2 = "\\trans2\\trans2.tst";
3386 bool correct = True;
3390 printf("starting trans2 test\n");
3392 if (!torture_open_connection(&cli, 0)) {
3396 status = cli_get_fs_attr_info(cli, &fs_attr);
3397 if (!NT_STATUS_IS_OK(status)) {
3398 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3403 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3404 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3405 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3406 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3407 if (!NT_STATUS_IS_OK(status)) {
3408 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3412 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3413 if (!NT_STATUS_IS_OK(status)) {
3414 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3417 else if (strcmp(pname, fname)) {
3418 printf("qfilename gave different name? [%s] [%s]\n",
3423 cli_close(cli, fnum);
3427 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3428 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3430 if (!NT_STATUS_IS_OK(status)) {
3431 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3434 cli_close(cli, fnum);
3436 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3438 if (!NT_STATUS_IS_OK(status)) {
3439 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3442 time_t t = time(NULL);
3444 if (c_time != m_time) {
3445 printf("create time=%s", ctime(&c_time));
3446 printf("modify time=%s", ctime(&m_time));
3447 printf("This system appears to have sticky create times\n");
3449 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3450 printf("access time=%s", ctime(&a_time));
3451 printf("This system appears to set a midnight access time\n");
3455 if (abs(m_time - t) > 60*60*24*7) {
3456 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3462 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3463 cli_openx(cli, fname,
3464 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3465 cli_close(cli, fnum);
3466 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3467 &m_time_ts, &size, NULL, NULL);
3468 if (!NT_STATUS_IS_OK(status)) {
3469 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3472 if (w_time_ts.tv_sec < 60*60*24*2) {
3473 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3474 printf("This system appears to set a initial 0 write time\n");
3479 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3482 /* check if the server updates the directory modification time
3483 when creating a new file */
3484 status = cli_mkdir(cli, dname);
3485 if (!NT_STATUS_IS_OK(status)) {
3486 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3490 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3491 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3492 if (!NT_STATUS_IS_OK(status)) {
3493 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3497 cli_openx(cli, fname2,
3498 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3499 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3500 cli_close(cli, fnum);
3501 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3502 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3503 if (!NT_STATUS_IS_OK(status)) {
3504 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3507 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3509 printf("This system does not update directory modification times\n");
3513 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3514 cli_rmdir(cli, dname);
3516 if (!torture_close_connection(cli)) {
3520 printf("trans2 test finished\n");
3526 This checks new W2K calls.
3529 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3531 uint8_t *buf = NULL;
3535 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3536 CLI_BUFFER_SIZE, NULL, &buf, &len);
3537 if (!NT_STATUS_IS_OK(status)) {
3538 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3541 printf("qfileinfo: level %d, len = %u\n", level, len);
3542 dump_data(0, (uint8_t *)buf, len);
3549 static bool run_w2ktest(int dummy)
3551 struct cli_state *cli;
3553 const char *fname = "\\w2ktest\\w2k.tst";
3555 bool correct = True;
3557 printf("starting w2k test\n");
3559 if (!torture_open_connection(&cli, 0)) {
3563 cli_openx(cli, fname,
3564 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3566 for (level = 1004; level < 1040; level++) {
3567 new_trans(cli, fnum, level);
3570 cli_close(cli, fnum);
3572 if (!torture_close_connection(cli)) {
3576 printf("w2k test finished\n");
3583 this is a harness for some oplock tests
3585 static bool run_oplock1(int dummy)
3587 struct cli_state *cli1;
3588 const char *fname = "\\lockt1.lck";
3590 bool correct = True;
3593 printf("starting oplock test 1\n");
3595 if (!torture_open_connection(&cli1, 0)) {
3599 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3601 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3603 cli1->use_oplocks = True;
3605 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3607 if (!NT_STATUS_IS_OK(status)) {
3608 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3612 cli1->use_oplocks = False;
3614 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3615 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3617 status = cli_close(cli1, fnum1);
3618 if (!NT_STATUS_IS_OK(status)) {
3619 printf("close2 failed (%s)\n", nt_errstr(status));
3623 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3624 if (!NT_STATUS_IS_OK(status)) {
3625 printf("unlink failed (%s)\n", nt_errstr(status));
3629 if (!torture_close_connection(cli1)) {
3633 printf("finished oplock test 1\n");
3638 static bool run_oplock2(int dummy)
3640 struct cli_state *cli1, *cli2;
3641 const char *fname = "\\lockt2.lck";
3642 uint16_t fnum1, fnum2;
3643 int saved_use_oplocks = use_oplocks;
3645 bool correct = True;
3646 volatile bool *shared_correct;
3650 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3651 *shared_correct = True;
3653 use_level_II_oplocks = True;
3656 printf("starting oplock test 2\n");
3658 if (!torture_open_connection(&cli1, 0)) {
3659 use_level_II_oplocks = False;
3660 use_oplocks = saved_use_oplocks;
3664 if (!torture_open_connection(&cli2, 1)) {
3665 use_level_II_oplocks = False;
3666 use_oplocks = saved_use_oplocks;
3670 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3672 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3673 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3675 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3677 if (!NT_STATUS_IS_OK(status)) {
3678 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3682 /* Don't need the globals any more. */
3683 use_level_II_oplocks = False;
3684 use_oplocks = saved_use_oplocks;
3688 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3689 if (!NT_STATUS_IS_OK(status)) {
3690 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3691 *shared_correct = False;
3697 status = cli_close(cli2, fnum2);
3698 if (!NT_STATUS_IS_OK(status)) {
3699 printf("close2 failed (%s)\n", nt_errstr(status));
3700 *shared_correct = False;
3708 /* Ensure cli1 processes the break. Empty file should always return 0
3710 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3711 if (!NT_STATUS_IS_OK(status)) {
3712 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3714 } else if (nread != 0) {
3715 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3716 (unsigned long)nread, 0);
3720 /* Should now be at level II. */
3721 /* Test if sending a write locks causes a break to none. */
3722 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3723 if (!NT_STATUS_IS_OK(status)) {
3724 printf("lock failed (%s)\n", nt_errstr(status));
3728 cli_unlock(cli1, fnum1, 0, 4);
3732 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3733 if (!NT_STATUS_IS_OK(status)) {
3734 printf("lock failed (%s)\n", nt_errstr(status));
3738 cli_unlock(cli1, fnum1, 0, 4);
3742 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3744 status = cli_close(cli1, fnum1);
3745 if (!NT_STATUS_IS_OK(status)) {
3746 printf("close1 failed (%s)\n", nt_errstr(status));
3752 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3753 if (!NT_STATUS_IS_OK(status)) {
3754 printf("unlink failed (%s)\n", nt_errstr(status));
3758 if (!torture_close_connection(cli1)) {
3762 if (!*shared_correct) {
3766 printf("finished oplock test 2\n");
3771 struct oplock4_state {
3772 struct tevent_context *ev;
3773 struct cli_state *cli;
3778 static void oplock4_got_break(struct tevent_req *req);
3779 static void oplock4_got_open(struct tevent_req *req);
3781 static bool run_oplock4(int dummy)
3783 struct tevent_context *ev;
3784 struct cli_state *cli1, *cli2;
3785 struct tevent_req *oplock_req, *open_req;
3786 const char *fname = "\\lockt4.lck";
3787 const char *fname_ln = "\\lockt4_ln.lck";
3788 uint16_t fnum1, fnum2;
3789 int saved_use_oplocks = use_oplocks;
3791 bool correct = true;
3795 struct oplock4_state *state;
3797 printf("starting oplock test 4\n");
3799 if (!torture_open_connection(&cli1, 0)) {
3800 use_level_II_oplocks = false;
3801 use_oplocks = saved_use_oplocks;
3805 if (!torture_open_connection(&cli2, 1)) {
3806 use_level_II_oplocks = false;
3807 use_oplocks = saved_use_oplocks;
3811 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3812 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3814 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3815 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3817 /* Create the file. */
3818 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3820 if (!NT_STATUS_IS_OK(status)) {
3821 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3825 status = cli_close(cli1, fnum1);
3826 if (!NT_STATUS_IS_OK(status)) {
3827 printf("close1 failed (%s)\n", nt_errstr(status));
3831 /* Now create a hardlink. */
3832 status = cli_nt_hardlink(cli1, fname, fname_ln);
3833 if (!NT_STATUS_IS_OK(status)) {
3834 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3838 /* Prove that opening hardlinks cause deny modes to conflict. */
3839 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3840 if (!NT_STATUS_IS_OK(status)) {
3841 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3845 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3846 if (NT_STATUS_IS_OK(status)) {
3847 printf("open of %s succeeded - should fail with sharing violation.\n",
3852 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3853 printf("open of %s should fail with sharing violation. Got %s\n",
3854 fname_ln, nt_errstr(status));
3858 status = cli_close(cli1, fnum1);
3859 if (!NT_STATUS_IS_OK(status)) {
3860 printf("close1 failed (%s)\n", nt_errstr(status));
3864 cli1->use_oplocks = true;
3865 cli2->use_oplocks = true;
3867 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3868 if (!NT_STATUS_IS_OK(status)) {
3869 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3873 ev = samba_tevent_context_init(talloc_tos());
3875 printf("tevent_context_init failed\n");
3879 state = talloc(ev, struct oplock4_state);
3880 if (state == NULL) {
3881 printf("talloc failed\n");
3886 state->got_break = &got_break;
3887 state->fnum2 = &fnum2;
3889 oplock_req = cli_smb_oplock_break_waiter_send(
3890 talloc_tos(), ev, cli1);
3891 if (oplock_req == NULL) {
3892 printf("cli_smb_oplock_break_waiter_send failed\n");
3895 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3897 open_req = cli_openx_send(
3898 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3899 if (open_req == NULL) {
3900 printf("cli_openx_send failed\n");
3903 tevent_req_set_callback(open_req, oplock4_got_open, state);
3908 while (!got_break || fnum2 == 0xffff) {
3910 ret = tevent_loop_once(ev);
3912 printf("tevent_loop_once failed: %s\n",
3918 status = cli_close(cli2, fnum2);
3919 if (!NT_STATUS_IS_OK(status)) {
3920 printf("close2 failed (%s)\n", nt_errstr(status));
3924 status = cli_close(cli1, fnum1);
3925 if (!NT_STATUS_IS_OK(status)) {
3926 printf("close1 failed (%s)\n", nt_errstr(status));
3930 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3931 if (!NT_STATUS_IS_OK(status)) {
3932 printf("unlink failed (%s)\n", nt_errstr(status));
3936 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3937 if (!NT_STATUS_IS_OK(status)) {
3938 printf("unlink failed (%s)\n", nt_errstr(status));
3942 if (!torture_close_connection(cli1)) {
3950 printf("finished oplock test 4\n");
3955 static void oplock4_got_break(struct tevent_req *req)
3957 struct oplock4_state *state = tevent_req_callback_data(
3958 req, struct oplock4_state);
3963 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3965 if (!NT_STATUS_IS_OK(status)) {
3966 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3970 *state->got_break = true;
3972 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3975 printf("cli_oplock_ack_send failed\n");
3980 static void oplock4_got_open(struct tevent_req *req)
3982 struct oplock4_state *state = tevent_req_callback_data(
3983 req, struct oplock4_state);
3986 status = cli_openx_recv(req, state->fnum2);
3987 if (!NT_STATUS_IS_OK(status)) {
3988 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3989 *state->fnum2 = 0xffff;
3994 Test delete on close semantics.
3996 static bool run_deletetest(int dummy)
3998 struct cli_state *cli1 = NULL;
3999 struct cli_state *cli2 = NULL;
4000 const char *fname = "\\delete.file";
4001 uint16_t fnum1 = (uint16_t)-1;
4002 uint16_t fnum2 = (uint16_t)-1;
4003 bool correct = false;
4006 printf("starting delete test\n");
4008 if (!torture_open_connection(&cli1, 0)) {
4012 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4014 /* Test 1 - this should delete the file on close. */
4016 cli_setatr(cli1, fname, 0, 0);
4017 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4019 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4020 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4021 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4022 if (!NT_STATUS_IS_OK(status)) {
4023 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
4027 status = cli_close(cli1, fnum1);
4028 if (!NT_STATUS_IS_OK(status)) {
4029 printf("[1] close failed (%s)\n", nt_errstr(status));
4033 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
4034 if (NT_STATUS_IS_OK(status)) {
4035 printf("[1] open of %s succeeded (should fail)\n", fname);
4039 printf("first delete on close test succeeded.\n");
4041 /* Test 2 - this should delete the file on close. */
4043 cli_setatr(cli1, fname, 0, 0);
4044 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4046 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4047 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4048 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4049 if (!NT_STATUS_IS_OK(status)) {
4050 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
4054 status = cli_nt_delete_on_close(cli1, fnum1, true);
4055 if (!NT_STATUS_IS_OK(status)) {
4056 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
4060 status = cli_close(cli1, fnum1);
4061 if (!NT_STATUS_IS_OK(status)) {
4062 printf("[2] close failed (%s)\n", nt_errstr(status));
4066 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4067 if (NT_STATUS_IS_OK(status)) {
4068 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
4069 status = cli_close(cli1, fnum1);
4070 if (!NT_STATUS_IS_OK(status)) {
4071 printf("[2] close failed (%s)\n", nt_errstr(status));
4073 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4077 printf("second delete on close test succeeded.\n");
4080 cli_setatr(cli1, fname, 0, 0);
4081 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4083 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4084 FILE_ATTRIBUTE_NORMAL,
4085 FILE_SHARE_READ|FILE_SHARE_WRITE,
4086 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4087 if (!NT_STATUS_IS_OK(status)) {
4088 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
4092 /* This should fail with a sharing violation - open for delete is only compatible
4093 with SHARE_DELETE. */
4095 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4096 FILE_ATTRIBUTE_NORMAL,
4097 FILE_SHARE_READ|FILE_SHARE_WRITE,
4098 FILE_OPEN, 0, 0, &fnum2, NULL);
4099 if (NT_STATUS_IS_OK(status)) {
4100 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4104 /* This should succeed. */
4105 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4106 FILE_ATTRIBUTE_NORMAL,
4107 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4108 FILE_OPEN, 0, 0, &fnum2, NULL);
4109 if (!NT_STATUS_IS_OK(status)) {
4110 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
4114 status = cli_nt_delete_on_close(cli1, fnum1, true);
4115 if (!NT_STATUS_IS_OK(status)) {
4116 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4120 status = cli_close(cli1, fnum1);
4121 if (!NT_STATUS_IS_OK(status)) {
4122 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4126 status = cli_close(cli1, fnum2);
4127 if (!NT_STATUS_IS_OK(status)) {
4128 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4132 /* This should fail - file should no longer be there. */
4134 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4135 if (NT_STATUS_IS_OK(status)) {
4136 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4137 status = cli_close(cli1, fnum1);
4138 if (!NT_STATUS_IS_OK(status)) {
4139 printf("[3] close failed (%s)\n", nt_errstr(status));
4141 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4145 printf("third delete on close test succeeded.\n");
4148 cli_setatr(cli1, fname, 0, 0);
4149 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4151 status = cli_ntcreate(cli1, fname, 0,
4152 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4153 FILE_ATTRIBUTE_NORMAL,
4154 FILE_SHARE_READ|FILE_SHARE_WRITE,
4155 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4156 if (!NT_STATUS_IS_OK(status)) {
4157 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4161 /* This should succeed. */
4162 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4163 FILE_ATTRIBUTE_NORMAL,
4164 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4165 FILE_OPEN, 0, 0, &fnum2, NULL);
4166 if (!NT_STATUS_IS_OK(status)) {
4167 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4171 status = cli_close(cli1, fnum2);
4172 if (!NT_STATUS_IS_OK(status)) {
4173 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4177 status = cli_nt_delete_on_close(cli1, fnum1, true);
4178 if (!NT_STATUS_IS_OK(status)) {
4179 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4183 /* This should fail - no more opens once delete on close set. */
4184 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4185 FILE_ATTRIBUTE_NORMAL,
4186 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4187 FILE_OPEN, 0, 0, &fnum2, NULL);
4188 if (NT_STATUS_IS_OK(status)) {
4189 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4193 status = cli_close(cli1, fnum1);
4194 if (!NT_STATUS_IS_OK(status)) {
4195 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4199 printf("fourth delete on close test succeeded.\n");
4202 cli_setatr(cli1, fname, 0, 0);
4203 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4205 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4206 if (!NT_STATUS_IS_OK(status)) {
4207 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4211 /* This should fail - only allowed on NT opens with DELETE access. */
4213 status = cli_nt_delete_on_close(cli1, fnum1, true);
4214 if (NT_STATUS_IS_OK(status)) {
4215 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4219 status = cli_close(cli1, fnum1);
4220 if (!NT_STATUS_IS_OK(status)) {
4221 printf("[5] close failed (%s)\n", nt_errstr(status));
4225 printf("fifth delete on close test succeeded.\n");
4228 cli_setatr(cli1, fname, 0, 0);
4229 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4231 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4232 FILE_ATTRIBUTE_NORMAL,
4233 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4234 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4235 if (!NT_STATUS_IS_OK(status)) {
4236 printf("[6] open of %s failed (%s)\n", fname,
4241 /* This should fail - only allowed on NT opens with DELETE access. */
4243 status = cli_nt_delete_on_close(cli1, fnum1, true);
4244 if (NT_STATUS_IS_OK(status)) {
4245 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4249 status = cli_close(cli1, fnum1);
4250 if (!NT_STATUS_IS_OK(status)) {
4251 printf("[6] close failed (%s)\n", nt_errstr(status));
4255 printf("sixth delete on close test succeeded.\n");
4258 cli_setatr(cli1, fname, 0, 0);
4259 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4261 status = cli_ntcreate(cli1, fname, 0,
4262 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4263 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4264 0, 0, &fnum1, NULL);
4265 if (!NT_STATUS_IS_OK(status)) {
4266 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4270 status = cli_nt_delete_on_close(cli1, fnum1, true);
4271 if (!NT_STATUS_IS_OK(status)) {
4272 printf("[7] setting delete_on_close on file failed !\n");
4276 status = cli_nt_delete_on_close(cli1, fnum1, false);
4277 if (!NT_STATUS_IS_OK(status)) {
4278 printf("[7] unsetting delete_on_close on file failed !\n");
4282 status = cli_close(cli1, fnum1);
4283 if (!NT_STATUS_IS_OK(status)) {
4284 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4288 /* This next open should succeed - we reset the flag. */
4289 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4290 if (!NT_STATUS_IS_OK(status)) {
4291 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4295 status = cli_close(cli1, fnum1);
4296 if (!NT_STATUS_IS_OK(status)) {
4297 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4301 printf("seventh delete on close test succeeded.\n");
4304 cli_setatr(cli1, fname, 0, 0);
4305 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4307 if (!torture_open_connection(&cli2, 1)) {
4308 printf("[8] failed to open second connection.\n");
4312 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4314 status = cli_ntcreate(cli1, fname, 0,
4315 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4316 FILE_ATTRIBUTE_NORMAL,
4317 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4318 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4319 if (!NT_STATUS_IS_OK(status)) {
4320 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4324 status = cli_ntcreate(cli2, fname, 0,
4325 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4326 FILE_ATTRIBUTE_NORMAL,
4327 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4328 FILE_OPEN, 0, 0, &fnum2, NULL);
4329 if (!NT_STATUS_IS_OK(status)) {
4330 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4334 status = cli_nt_delete_on_close(cli1, fnum1, true);
4335 if (!NT_STATUS_IS_OK(status)) {
4336 printf("[8] setting delete_on_close on file failed !\n");
4340 status = cli_close(cli1, fnum1);
4341 if (!NT_STATUS_IS_OK(status)) {
4342 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4346 status = cli_close(cli2, fnum2);
4347 if (!NT_STATUS_IS_OK(status)) {
4348 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4352 /* This should fail.. */
4353 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4354 if (NT_STATUS_IS_OK(status)) {
4355 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4359 printf("eighth delete on close test succeeded.\n");
4363 /* This should fail - we need to set DELETE_ACCESS. */
4364 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4365 FILE_ATTRIBUTE_NORMAL,
4368 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4369 if (NT_STATUS_IS_OK(status)) {
4370 printf("[9] open of %s succeeded should have failed!\n", fname);
4374 printf("ninth delete on close test succeeded.\n");
4378 status = cli_ntcreate(cli1, fname, 0,
4379 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4380 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4381 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4383 if (!NT_STATUS_IS_OK(status)) {
4384 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4388 /* This should delete the file. */
4389 status = cli_close(cli1, fnum1);
4390 if (!NT_STATUS_IS_OK(status)) {
4391 printf("[10] close failed (%s)\n", nt_errstr(status));
4395 /* This should fail.. */
4396 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4397 if (NT_STATUS_IS_OK(status)) {
4398 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4402 printf("tenth delete on close test succeeded.\n");
4406 cli_setatr(cli1, fname, 0, 0);
4407 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4409 /* Can we open a read-only file with delete access? */
4411 /* Create a readonly file. */
4412 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4413 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4414 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4415 if (!NT_STATUS_IS_OK(status)) {
4416 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4420 status = cli_close(cli1, fnum1);
4421 if (!NT_STATUS_IS_OK(status)) {
4422 printf("[11] close failed (%s)\n", nt_errstr(status));
4426 /* Now try open for delete access. */
4427 status = cli_ntcreate(cli1, fname, 0,
4428 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4430 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4431 FILE_OPEN, 0, 0, &fnum1, NULL);
4432 if (!NT_STATUS_IS_OK(status)) {
4433 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4437 cli_close(cli1, fnum1);
4439 printf("eleventh delete on close test succeeded.\n");
4443 * like test 4 but with initial delete on close
4446 cli_setatr(cli1, fname, 0, 0);
4447 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4449 status = cli_ntcreate(cli1, fname, 0,
4450 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4451 FILE_ATTRIBUTE_NORMAL,
4452 FILE_SHARE_READ|FILE_SHARE_WRITE,
4454 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4455 if (!NT_STATUS_IS_OK(status)) {
4456 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4460 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4461 FILE_ATTRIBUTE_NORMAL,
4462 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4463 FILE_OPEN, 0, 0, &fnum2, NULL);
4464 if (!NT_STATUS_IS_OK(status)) {
4465 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4469 status = cli_close(cli1, fnum2);
4470 if (!NT_STATUS_IS_OK(status)) {
4471 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4475 status = cli_nt_delete_on_close(cli1, fnum1, true);
4476 if (!NT_STATUS_IS_OK(status)) {
4477 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4481 /* This should fail - no more opens once delete on close set. */
4482 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4483 FILE_ATTRIBUTE_NORMAL,
4484 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4485 FILE_OPEN, 0, 0, &fnum2, NULL);
4486 if (NT_STATUS_IS_OK(status)) {
4487 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4491 status = cli_nt_delete_on_close(cli1, fnum1, false);
4492 if (!NT_STATUS_IS_OK(status)) {
4493 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4497 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4498 FILE_ATTRIBUTE_NORMAL,
4499 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4500 FILE_OPEN, 0, 0, &fnum2, NULL);
4501 if (!NT_STATUS_IS_OK(status)) {
4502 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4506 status = cli_close(cli1, fnum2);
4507 if (!NT_STATUS_IS_OK(status)) {
4508 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4512 status = cli_close(cli1, fnum1);
4513 if (!NT_STATUS_IS_OK(status)) {
4514 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4519 * setting delete on close on the handle does
4520 * not unset the initial delete on close...
4522 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4523 FILE_ATTRIBUTE_NORMAL,
4524 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4525 FILE_OPEN, 0, 0, &fnum2, NULL);
4526 if (NT_STATUS_IS_OK(status)) {
4527 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4529 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4530 printf("ntcreate returned %s, expected "
4531 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4536 printf("twelfth delete on close test succeeded.\n");
4539 printf("finished delete test\n");
4544 /* FIXME: This will crash if we aborted before cli2 got
4545 * intialized, because these functions don't handle
4546 * uninitialized connections. */
4548 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4549 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4550 cli_setatr(cli1, fname, 0, 0);
4551 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4553 if (cli1 && !torture_close_connection(cli1)) {
4556 if (cli2 && !torture_close_connection(cli2)) {
4564 Test wildcard delete.
4566 static bool run_wild_deletetest(int dummy)
4568 struct cli_state *cli = NULL;
4569 const char *dname = "\\WTEST";
4570 const char *fname = "\\WTEST\\A";
4571 const char *wunlink_name = "\\WTEST\\*";
4572 uint16_t fnum1 = (uint16_t)-1;
4573 bool correct = false;
4576 printf("starting wildcard delete test\n");
4578 if (!torture_open_connection(&cli, 0)) {
4582 smbXcli_conn_set_sockopt(cli->conn, sockops);
4584 cli_unlink(cli, fname, 0);
4585 cli_rmdir(cli, dname);
4586 status = cli_mkdir(cli, dname);
4587 if (!NT_STATUS_IS_OK(status)) {
4588 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4591 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4592 if (!NT_STATUS_IS_OK(status)) {
4593 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4596 status = cli_close(cli, fnum1);
4600 * Note the unlink attribute-type of zero. This should
4601 * map into FILE_ATTRIBUTE_NORMAL at the server even
4602 * on a wildcard delete.
4605 status = cli_unlink(cli, wunlink_name, 0);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 printf("unlink of %s failed %s!\n",
4608 wunlink_name, nt_errstr(status));
4612 printf("finished wildcard delete test\n");
4618 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4619 cli_unlink(cli, fname, 0);
4620 cli_rmdir(cli, dname);
4622 if (cli && !torture_close_connection(cli)) {
4628 static bool run_deletetest_ln(int dummy)
4630 struct cli_state *cli;
4631 const char *fname = "\\delete1";
4632 const char *fname_ln = "\\delete1_ln";
4636 bool correct = true;
4639 printf("starting deletetest-ln\n");
4641 if (!torture_open_connection(&cli, 0)) {
4645 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4646 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4648 smbXcli_conn_set_sockopt(cli->conn, sockops);
4650 /* Create the file. */
4651 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4652 if (!NT_STATUS_IS_OK(status)) {
4653 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4657 status = cli_close(cli, fnum);
4658 if (!NT_STATUS_IS_OK(status)) {
4659 printf("close1 failed (%s)\n", nt_errstr(status));
4663 /* Now create a hardlink. */
4664 status = cli_nt_hardlink(cli, fname, fname_ln);
4665 if (!NT_STATUS_IS_OK(status)) {
4666 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4670 /* Open the original file. */
4671 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4672 FILE_ATTRIBUTE_NORMAL,
4673 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4674 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4675 if (!NT_STATUS_IS_OK(status)) {
4676 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4680 /* Unlink the hard link path. */
4681 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4682 FILE_ATTRIBUTE_NORMAL,
4683 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4684 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4685 if (!NT_STATUS_IS_OK(status)) {
4686 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4689 status = cli_nt_delete_on_close(cli, fnum1, true);
4690 if (!NT_STATUS_IS_OK(status)) {
4691 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4692 __location__, fname_ln, nt_errstr(status));
4696 status = cli_close(cli, fnum1);
4697 if (!NT_STATUS_IS_OK(status)) {
4698 printf("close %s failed (%s)\n",
4699 fname_ln, nt_errstr(status));
4703 status = cli_close(cli, fnum);
4704 if (!NT_STATUS_IS_OK(status)) {
4705 printf("close %s failed (%s)\n",
4706 fname, nt_errstr(status));
4710 /* Ensure the original file is still there. */
4711 status = cli_getatr(cli, fname, NULL, NULL, &t);
4712 if (!NT_STATUS_IS_OK(status)) {
4713 printf("%s getatr on file %s failed (%s)\n",
4720 /* Ensure the link path is gone. */
4721 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4722 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4723 printf("%s, getatr for file %s returned wrong error code %s "
4724 "- should have been deleted\n",
4726 fname_ln, nt_errstr(status));
4730 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4731 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4733 if (!torture_close_connection(cli)) {
4737 printf("finished deletetest-ln\n");
4743 print out server properties
4745 static bool run_properties(int dummy)
4747 struct cli_state *cli;
4748 bool correct = True;
4750 printf("starting properties test\n");
4754 if (!torture_open_connection(&cli, 0)) {
4758 smbXcli_conn_set_sockopt(cli->conn, sockops);
4760 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4762 if (!torture_close_connection(cli)) {
4771 /* FIRST_DESIRED_ACCESS 0xf019f */
4772 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4773 FILE_READ_EA| /* 0xf */ \
4774 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4775 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4776 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4777 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4778 /* SECOND_DESIRED_ACCESS 0xe0080 */
4779 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4780 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4781 WRITE_OWNER_ACCESS /* 0xe0000 */
4784 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4785 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4787 WRITE_OWNER_ACCESS /* */
4791 Test ntcreate calls made by xcopy
4793 static bool run_xcopy(int dummy)
4795 static struct cli_state *cli1;
4796 const char *fname = "\\test.txt";
4797 bool correct = True;
4798 uint16_t fnum1, fnum2;
4801 printf("starting xcopy test\n");
4803 if (!torture_open_connection(&cli1, 0)) {
4807 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4808 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4809 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4810 if (!NT_STATUS_IS_OK(status)) {
4811 printf("First open failed - %s\n", nt_errstr(status));
4815 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4816 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4817 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4818 if (!NT_STATUS_IS_OK(status)) {
4819 printf("second open failed - %s\n", nt_errstr(status));
4823 if (!torture_close_connection(cli1)) {
4831 Test rename on files open with share delete and no share delete.
4833 static bool run_rename(int dummy)
4835 static struct cli_state *cli1;
4836 const char *fname = "\\test.txt";
4837 const char *fname1 = "\\test1.txt";
4838 bool correct = True;
4843 printf("starting rename test\n");
4845 if (!torture_open_connection(&cli1, 0)) {
4849 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4850 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4852 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4853 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4854 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4855 if (!NT_STATUS_IS_OK(status)) {
4856 printf("First open failed - %s\n", nt_errstr(status));
4860 status = cli_rename(cli1, fname, fname1, false);
4861 if (!NT_STATUS_IS_OK(status)) {
4862 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4864 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4868 status = cli_close(cli1, fnum1);
4869 if (!NT_STATUS_IS_OK(status)) {
4870 printf("close - 1 failed (%s)\n", nt_errstr(status));
4874 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4875 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4876 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4878 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4880 FILE_SHARE_DELETE|FILE_SHARE_READ,
4882 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4883 if (!NT_STATUS_IS_OK(status)) {
4884 printf("Second open failed - %s\n", nt_errstr(status));
4888 status = cli_rename(cli1, fname, fname1, false);
4889 if (!NT_STATUS_IS_OK(status)) {
4890 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4893 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4896 status = cli_close(cli1, fnum1);
4897 if (!NT_STATUS_IS_OK(status)) {
4898 printf("close - 2 failed (%s)\n", nt_errstr(status));
4902 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4903 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4905 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4906 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4907 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4908 if (!NT_STATUS_IS_OK(status)) {
4909 printf("Third open failed - %s\n", nt_errstr(status));
4918 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4919 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4920 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4923 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4924 printf("[8] setting delete_on_close on file failed !\n");
4928 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4929 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4935 status = cli_rename(cli1, fname, fname1, false);
4936 if (!NT_STATUS_IS_OK(status)) {
4937 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4940 printf("Third rename succeeded (SHARE_NONE)\n");
4943 status = cli_close(cli1, fnum1);
4944 if (!NT_STATUS_IS_OK(status)) {
4945 printf("close - 3 failed (%s)\n", nt_errstr(status));
4949 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4950 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4954 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4955 FILE_ATTRIBUTE_NORMAL,
4956 FILE_SHARE_READ | FILE_SHARE_WRITE,
4957 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4958 if (!NT_STATUS_IS_OK(status)) {
4959 printf("Fourth open failed - %s\n", nt_errstr(status));
4963 status = cli_rename(cli1, fname, fname1, false);
4964 if (!NT_STATUS_IS_OK(status)) {
4965 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4967 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4971 status = cli_close(cli1, fnum1);
4972 if (!NT_STATUS_IS_OK(status)) {
4973 printf("close - 4 failed (%s)\n", nt_errstr(status));
4977 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4978 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4982 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4983 FILE_ATTRIBUTE_NORMAL,
4984 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4985 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4986 if (!NT_STATUS_IS_OK(status)) {
4987 printf("Fifth open failed - %s\n", nt_errstr(status));
4991 status = cli_rename(cli1, fname, fname1, false);
4992 if (!NT_STATUS_IS_OK(status)) {
4993 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4996 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
5000 * Now check if the first name still exists ...
5003 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
5004 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5005 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
5006 printf("Opening original file after rename of open file fails: %s\n",
5010 printf("Opening original file after rename of open file works ...\n");
5011 (void)cli_close(cli1, fnum2);
5015 status = cli_close(cli1, fnum1);
5016 if (!NT_STATUS_IS_OK(status)) {
5017 printf("close - 5 failed (%s)\n", nt_errstr(status));
5021 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
5022 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
5023 if (!NT_STATUS_IS_OK(status)) {
5024 printf("getatr on file %s failed - %s ! \n",
5025 fname1, nt_errstr(status));
5028 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
5029 printf("Renamed file %s has wrong attr 0x%x "
5030 "(should be 0x%x)\n",
5033 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
5036 printf("Renamed file %s has archive bit set\n", fname1);
5040 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5041 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5043 if (!torture_close_connection(cli1)) {
5051 Test rename into a directory with an ACL denying it.
5053 static bool run_rename_access(int dummy)
5055 static struct cli_state *cli = NULL;
5056 static struct cli_state *posix_cli = NULL;
5057 const char *src = "test.txt";
5058 const char *dname = "dir";
5059 const char *dst = "dir\\test.txt";
5060 const char *dsrc = "test.dir";
5061 const char *ddst = "dir\\test.dir";
5062 uint16_t fnum = (uint16_t)-1;
5063 struct security_descriptor *sd = NULL;
5064 struct security_descriptor *newsd = NULL;
5066 TALLOC_CTX *frame = NULL;
5068 frame = talloc_stackframe();
5069 printf("starting rename access test\n");
5071 /* Windows connection. */
5072 if (!torture_open_connection(&cli, 0)) {
5076 smbXcli_conn_set_sockopt(cli->conn, sockops);
5078 /* Posix connection. */
5079 if (!torture_open_connection(&posix_cli, 0)) {
5083 smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
5085 status = torture_setup_unix_extensions(posix_cli);
5086 if (!NT_STATUS_IS_OK(status)) {
5090 /* Start with a clean slate. */
5091 cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5092 cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5093 cli_rmdir(cli, dsrc);
5094 cli_rmdir(cli, ddst);
5095 cli_rmdir(cli, dname);
5098 * Setup the destination directory with a DENY ACE to
5099 * prevent new files within it.
5101 status = cli_ntcreate(cli,
5104 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
5105 WRITE_DAC_ACCESS|FILE_READ_DATA|
5107 FILE_ATTRIBUTE_DIRECTORY,
5108 FILE_SHARE_READ|FILE_SHARE_WRITE,
5110 FILE_DIRECTORY_FILE,
5114 if (!NT_STATUS_IS_OK(status)) {
5115 printf("Create of %s - %s\n", dname, nt_errstr(status));
5119 status = cli_query_secdesc(cli,
5123 if (!NT_STATUS_IS_OK(status)) {
5124 printf("cli_query_secdesc failed for %s (%s)\n",
5125 dname, nt_errstr(status));
5129 newsd = security_descriptor_dacl_create(frame,
5134 SEC_ACE_TYPE_ACCESS_DENIED,
5135 SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
5138 if (newsd == NULL) {
5141 sd->dacl = security_acl_concatenate(frame,
5144 if (sd->dacl == NULL) {
5147 status = cli_set_secdesc(cli, fnum, sd);
5148 if (!NT_STATUS_IS_OK(status)) {
5149 printf("cli_set_secdesc failed for %s (%s)\n",
5150 dname, nt_errstr(status));
5153 status = cli_close(cli, fnum);
5154 if (!NT_STATUS_IS_OK(status)) {
5155 printf("close failed for %s (%s)\n",
5156 dname, nt_errstr(status));
5159 /* Now go around the back and chmod to 777 via POSIX. */
5160 status = cli_posix_chmod(posix_cli, dname, 0777);
5161 if (!NT_STATUS_IS_OK(status)) {
5162 printf("cli_posix_chmod failed for %s (%s)\n",
5163 dname, nt_errstr(status));
5167 /* Check we can't create a file within dname via Windows. */
5168 status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5169 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5170 cli_close(posix_cli, fnum);
5171 printf("Create of %s should be ACCESS denied, was %s\n",
5172 dst, nt_errstr(status));
5176 /* Make the sample file/directory. */
5177 status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5178 if (!NT_STATUS_IS_OK(status)) {
5179 printf("open of %s failed (%s)\n", src, nt_errstr(status));
5182 status = cli_close(cli, fnum);
5183 if (!NT_STATUS_IS_OK(status)) {
5184 printf("cli_close failed (%s)\n", nt_errstr(status));
5188 status = cli_mkdir(cli, dsrc);
5189 if (!NT_STATUS_IS_OK(status)) {
5190 printf("cli_mkdir of %s failed (%s)\n",
5191 dsrc, nt_errstr(status));
5196 * OK - renames of the new file and directory into the
5197 * dst directory should fail.
5200 status = cli_rename(cli, src, dst, false);
5201 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5202 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5203 src, dst, nt_errstr(status));
5206 status = cli_rename(cli, dsrc, ddst, false);
5207 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5208 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5209 src, dst, nt_errstr(status));
5219 torture_close_connection(posix_cli);
5223 if (fnum != (uint64_t)-1) {
5224 cli_close(cli, fnum);
5226 cli_unlink(cli, src,
5227 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5228 cli_unlink(cli, dst,
5229 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5230 cli_rmdir(cli, dsrc);
5231 cli_rmdir(cli, ddst);
5232 cli_rmdir(cli, dname);
5234 torture_close_connection(cli);
5242 Test owner rights ACE.
5244 static bool run_owner_rights(int dummy)
5246 static struct cli_state *cli = NULL;
5247 const char *fname = "owner_rights.txt";
5248 uint16_t fnum = (uint16_t)-1;
5249 struct security_descriptor *sd = NULL;
5250 struct security_descriptor *newsd = NULL;
5252 TALLOC_CTX *frame = NULL;
5254 frame = talloc_stackframe();
5255 printf("starting owner rights test\n");
5257 /* Windows connection. */
5258 if (!torture_open_connection(&cli, 0)) {
5262 smbXcli_conn_set_sockopt(cli->conn, sockops);
5264 /* Start with a clean slate. */
5265 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5267 /* Create the test file. */
5268 /* Now try and open for read and write-dac. */
5269 status = cli_ntcreate(cli,
5273 FILE_ATTRIBUTE_NORMAL,
5274 FILE_SHARE_READ|FILE_SHARE_WRITE|
5281 if (!NT_STATUS_IS_OK(status)) {
5282 printf("Create of %s - %s\n", fname, nt_errstr(status));
5286 /* Get the original SD. */
5287 status = cli_query_secdesc(cli,
5291 if (!NT_STATUS_IS_OK(status)) {
5292 printf("cli_query_secdesc failed for %s (%s)\n",
5293 fname, nt_errstr(status));
5298 * Add an "owner-rights" ACE denying WRITE_DATA,
5299 * and an "owner-rights" ACE allowing READ_DATA.
5302 newsd = security_descriptor_dacl_create(frame,
5307 SEC_ACE_TYPE_ACCESS_DENIED,
5311 SEC_ACE_TYPE_ACCESS_ALLOWED,
5315 if (newsd == NULL) {
5318 sd->dacl = security_acl_concatenate(frame,
5321 if (sd->dacl == NULL) {
5324 status = cli_set_secdesc(cli, fnum, sd);
5325 if (!NT_STATUS_IS_OK(status)) {
5326 printf("cli_set_secdesc failed for %s (%s)\n",
5327 fname, nt_errstr(status));
5330 status = cli_close(cli, fnum);
5331 if (!NT_STATUS_IS_OK(status)) {
5332 printf("close failed for %s (%s)\n",
5333 fname, nt_errstr(status));
5336 fnum = (uint16_t)-1;
5338 /* Try and open for FILE_WRITE_DATA */
5339 status = cli_ntcreate(cli,
5343 FILE_ATTRIBUTE_NORMAL,
5344 FILE_SHARE_READ|FILE_SHARE_WRITE|
5351 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5352 printf("Open of %s - %s\n", fname, nt_errstr(status));
5356 /* Now try and open for FILE_READ_DATA */
5357 status = cli_ntcreate(cli,
5361 FILE_ATTRIBUTE_NORMAL,
5362 FILE_SHARE_READ|FILE_SHARE_WRITE|
5369 if (!NT_STATUS_IS_OK(status)) {
5370 printf("Open of %s - %s\n", fname, nt_errstr(status));
5374 status = cli_close(cli, fnum);
5375 if (!NT_STATUS_IS_OK(status)) {
5376 printf("close failed for %s (%s)\n",
5377 fname, nt_errstr(status));
5381 /* Restore clean slate. */
5383 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5385 /* Create the test file. */
5386 status = cli_ntcreate(cli,
5390 FILE_ATTRIBUTE_NORMAL,
5391 FILE_SHARE_READ|FILE_SHARE_WRITE|
5398 if (!NT_STATUS_IS_OK(status)) {
5399 printf("Create of %s - %s\n", fname, nt_errstr(status));
5403 /* Get the original SD. */
5404 status = cli_query_secdesc(cli,
5408 if (!NT_STATUS_IS_OK(status)) {
5409 printf("cli_query_secdesc failed for %s (%s)\n",
5410 fname, nt_errstr(status));
5415 * Add an "owner-rights ACE denying WRITE_DATA,
5416 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5419 newsd = security_descriptor_dacl_create(frame,
5424 SEC_ACE_TYPE_ACCESS_DENIED,
5428 SEC_ACE_TYPE_ACCESS_ALLOWED,
5429 FILE_READ_DATA|FILE_WRITE_DATA,
5432 if (newsd == NULL) {
5435 sd->dacl = security_acl_concatenate(frame,
5438 if (sd->dacl == NULL) {
5441 status = cli_set_secdesc(cli, fnum, sd);
5442 if (!NT_STATUS_IS_OK(status)) {
5443 printf("cli_set_secdesc failed for %s (%s)\n",
5444 fname, nt_errstr(status));
5447 status = cli_close(cli, fnum);
5448 if (!NT_STATUS_IS_OK(status)) {
5449 printf("close failed for %s (%s)\n",
5450 fname, nt_errstr(status));
5453 fnum = (uint16_t)-1;
5455 /* Try and open for FILE_WRITE_DATA */
5456 status = cli_ntcreate(cli,
5460 FILE_ATTRIBUTE_NORMAL,
5461 FILE_SHARE_READ|FILE_SHARE_WRITE|
5468 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5469 printf("Open of %s - %s\n", fname, nt_errstr(status));
5473 /* Now try and open for FILE_READ_DATA */
5474 status = cli_ntcreate(cli,
5478 FILE_ATTRIBUTE_NORMAL,
5479 FILE_SHARE_READ|FILE_SHARE_WRITE|
5486 if (!NT_STATUS_IS_OK(status)) {
5487 printf("Open of %s - %s\n", fname, nt_errstr(status));
5491 status = cli_close(cli, fnum);
5492 if (!NT_STATUS_IS_OK(status)) {
5493 printf("close failed for %s (%s)\n",
5494 fname, nt_errstr(status));
5498 /* Restore clean slate. */
5500 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5503 /* Create the test file. */
5504 status = cli_ntcreate(cli,
5508 FILE_ATTRIBUTE_NORMAL,
5509 FILE_SHARE_READ|FILE_SHARE_WRITE|
5516 if (!NT_STATUS_IS_OK(status)) {
5517 printf("Create of %s - %s\n", fname, nt_errstr(status));
5521 /* Get the original SD. */
5522 status = cli_query_secdesc(cli,
5526 if (!NT_STATUS_IS_OK(status)) {
5527 printf("cli_query_secdesc failed for %s (%s)\n",
5528 fname, nt_errstr(status));
5533 * Add an "authenticated users" ACE allowing READ_DATA,
5534 * add an "owner-rights" denying READ_DATA,
5535 * and an "authenticated users" ACE allowing WRITE_DATA.
5538 newsd = security_descriptor_dacl_create(frame,
5542 SID_NT_AUTHENTICATED_USERS,
5543 SEC_ACE_TYPE_ACCESS_ALLOWED,
5547 SEC_ACE_TYPE_ACCESS_DENIED,
5550 SID_NT_AUTHENTICATED_USERS,
5551 SEC_ACE_TYPE_ACCESS_ALLOWED,
5555 if (newsd == NULL) {
5556 printf("newsd == NULL\n");
5559 sd->dacl = security_acl_concatenate(frame,
5562 if (sd->dacl == NULL) {
5563 printf("sd->dacl == NULL\n");
5566 status = cli_set_secdesc(cli, fnum, sd);
5567 if (!NT_STATUS_IS_OK(status)) {
5568 printf("cli_set_secdesc failed for %s (%s)\n",
5569 fname, nt_errstr(status));
5572 status = cli_close(cli, fnum);
5573 if (!NT_STATUS_IS_OK(status)) {
5574 printf("close failed for %s (%s)\n",
5575 fname, nt_errstr(status));
5578 fnum = (uint16_t)-1;
5580 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5581 status = cli_ntcreate(cli,
5584 FILE_READ_DATA|FILE_WRITE_DATA,
5585 FILE_ATTRIBUTE_NORMAL,
5586 FILE_SHARE_READ|FILE_SHARE_WRITE|
5593 if (!NT_STATUS_IS_OK(status)) {
5594 printf("Open of %s - %s\n", fname, nt_errstr(status));
5598 status = cli_close(cli, fnum);
5599 if (!NT_STATUS_IS_OK(status)) {
5600 printf("close failed for %s (%s)\n",
5601 fname, nt_errstr(status));
5605 cli_unlink(cli, fname,
5606 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5614 if (fnum != (uint16_t)-1) {
5615 cli_close(cli, fnum);
5617 cli_unlink(cli, fname,
5618 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5619 torture_close_connection(cli);
5626 static bool run_pipe_number(int dummy)
5628 struct cli_state *cli1;
5629 const char *pipe_name = "\\SPOOLSS";
5634 printf("starting pipenumber test\n");
5635 if (!torture_open_connection(&cli1, 0)) {
5639 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5641 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
5642 FILE_ATTRIBUTE_NORMAL,
5643 FILE_SHARE_READ|FILE_SHARE_WRITE,
5644 FILE_OPEN_IF, 0, 0, &fnum, NULL);
5645 if (!NT_STATUS_IS_OK(status)) {
5646 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
5650 printf("\r%6d", num_pipes);
5653 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
5654 torture_close_connection(cli1);
5659 Test open mode returns on read-only files.
5661 static bool run_opentest(int dummy)
5663 static struct cli_state *cli1;
5664 static struct cli_state *cli2;
5665 const char *fname = "\\readonly.file";
5666 uint16_t fnum1, fnum2;
5669 bool correct = True;
5673 printf("starting open test\n");
5675 if (!torture_open_connection(&cli1, 0)) {
5679 cli_setatr(cli1, fname, 0, 0);
5680 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5682 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5684 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5685 if (!NT_STATUS_IS_OK(status)) {
5686 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5690 status = cli_close(cli1, fnum1);
5691 if (!NT_STATUS_IS_OK(status)) {
5692 printf("close2 failed (%s)\n", nt_errstr(status));
5696 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
5697 if (!NT_STATUS_IS_OK(status)) {
5698 printf("cli_setatr failed (%s)\n", nt_errstr(status));
5702 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5703 if (!NT_STATUS_IS_OK(status)) {
5704 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5708 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5709 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5711 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
5712 NT_STATUS_ACCESS_DENIED)) {
5713 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5716 printf("finished open test 1\n");
5718 cli_close(cli1, fnum1);
5720 /* Now try not readonly and ensure ERRbadshare is returned. */
5722 cli_setatr(cli1, fname, 0, 0);
5724 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5725 if (!NT_STATUS_IS_OK(status)) {
5726 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5730 /* This will fail - but the error should be ERRshare. */
5731 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5733 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5734 NT_STATUS_SHARING_VIOLATION)) {
5735 printf("correct error code ERRDOS/ERRbadshare returned\n");
5738 status = cli_close(cli1, fnum1);
5739 if (!NT_STATUS_IS_OK(status)) {
5740 printf("close2 failed (%s)\n", nt_errstr(status));
5744 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5746 printf("finished open test 2\n");
5748 /* Test truncate open disposition on file opened for read. */
5749 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5750 if (!NT_STATUS_IS_OK(status)) {
5751 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5755 /* write 20 bytes. */
5757 memset(buf, '\0', 20);
5759 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5760 if (!NT_STATUS_IS_OK(status)) {
5761 printf("write failed (%s)\n", nt_errstr(status));
5765 status = cli_close(cli1, fnum1);
5766 if (!NT_STATUS_IS_OK(status)) {
5767 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5771 /* Ensure size == 20. */
5772 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5773 if (!NT_STATUS_IS_OK(status)) {
5774 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5779 printf("(3) file size != 20\n");
5783 /* Now test if we can truncate a file opened for readonly. */
5784 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5785 if (!NT_STATUS_IS_OK(status)) {
5786 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5790 status = cli_close(cli1, fnum1);
5791 if (!NT_STATUS_IS_OK(status)) {
5792 printf("close2 failed (%s)\n", nt_errstr(status));
5796 /* Ensure size == 0. */
5797 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5798 if (!NT_STATUS_IS_OK(status)) {
5799 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5804 printf("(3) file size != 0\n");
5807 printf("finished open test 3\n");
5809 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5811 printf("Do ctemp tests\n");
5812 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5813 if (!NT_STATUS_IS_OK(status)) {
5814 printf("ctemp failed (%s)\n", nt_errstr(status));
5818 printf("ctemp gave path %s\n", tmp_path);
5819 status = cli_close(cli1, fnum1);
5820 if (!NT_STATUS_IS_OK(status)) {
5821 printf("close of temp failed (%s)\n", nt_errstr(status));
5824 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5825 if (!NT_STATUS_IS_OK(status)) {
5826 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5829 /* Test the non-io opens... */
5831 if (!torture_open_connection(&cli2, 1)) {
5835 cli_setatr(cli2, fname, 0, 0);
5836 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5838 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5840 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5841 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5842 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5843 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5844 if (!NT_STATUS_IS_OK(status)) {
5845 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5849 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5850 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5851 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5852 if (!NT_STATUS_IS_OK(status)) {
5853 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5857 status = cli_close(cli1, fnum1);
5858 if (!NT_STATUS_IS_OK(status)) {
5859 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5863 status = cli_close(cli2, fnum2);
5864 if (!NT_STATUS_IS_OK(status)) {
5865 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5869 printf("non-io open test #1 passed.\n");
5871 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5873 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5875 status = cli_ntcreate(cli1, fname, 0,
5876 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5877 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5878 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5879 if (!NT_STATUS_IS_OK(status)) {
5880 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5884 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5885 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5886 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5887 if (!NT_STATUS_IS_OK(status)) {
5888 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5892 status = cli_close(cli1, fnum1);
5893 if (!NT_STATUS_IS_OK(status)) {
5894 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5898 status = cli_close(cli2, fnum2);
5899 if (!NT_STATUS_IS_OK(status)) {
5900 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5904 printf("non-io open test #2 passed.\n");
5906 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5908 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5910 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5911 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5912 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5913 if (!NT_STATUS_IS_OK(status)) {
5914 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5918 status = cli_ntcreate(cli2, fname, 0,
5919 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5920 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5921 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5922 if (!NT_STATUS_IS_OK(status)) {
5923 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5927 status = cli_close(cli1, fnum1);
5928 if (!NT_STATUS_IS_OK(status)) {
5929 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5933 status = cli_close(cli2, fnum2);
5934 if (!NT_STATUS_IS_OK(status)) {
5935 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5939 printf("non-io open test #3 passed.\n");
5941 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5943 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5945 status = cli_ntcreate(cli1, fname, 0,
5946 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5947 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5948 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5949 if (!NT_STATUS_IS_OK(status)) {
5950 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5954 status = cli_ntcreate(cli2, fname, 0,
5955 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5956 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5957 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5958 if (NT_STATUS_IS_OK(status)) {
5959 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5963 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5965 status = cli_close(cli1, fnum1);
5966 if (!NT_STATUS_IS_OK(status)) {
5967 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5971 printf("non-io open test #4 passed.\n");
5973 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5975 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5977 status = cli_ntcreate(cli1, fname, 0,
5978 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5979 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5980 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5981 if (!NT_STATUS_IS_OK(status)) {
5982 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5986 status = cli_ntcreate(cli2, fname, 0,
5987 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5988 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5989 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5990 if (!NT_STATUS_IS_OK(status)) {
5991 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5995 status = cli_close(cli1, fnum1);
5996 if (!NT_STATUS_IS_OK(status)) {
5997 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6001 status = cli_close(cli2, fnum2);
6002 if (!NT_STATUS_IS_OK(status)) {
6003 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6007 printf("non-io open test #5 passed.\n");
6009 printf("TEST #6 testing 1 non-io open, one io open\n");
6011 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6013 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6014 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6015 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6016 if (!NT_STATUS_IS_OK(status)) {
6017 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6021 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
6022 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6023 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6024 if (!NT_STATUS_IS_OK(status)) {
6025 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6029 status = cli_close(cli1, fnum1);
6030 if (!NT_STATUS_IS_OK(status)) {
6031 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6035 status = cli_close(cli2, fnum2);
6036 if (!NT_STATUS_IS_OK(status)) {
6037 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6041 printf("non-io open test #6 passed.\n");
6043 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
6045 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6047 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6048 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6049 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6050 if (!NT_STATUS_IS_OK(status)) {
6051 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6055 status = cli_ntcreate(cli2, fname, 0,
6056 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6057 FILE_ATTRIBUTE_NORMAL,
6058 FILE_SHARE_READ|FILE_SHARE_DELETE,
6059 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6060 if (NT_STATUS_IS_OK(status)) {
6061 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
6065 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
6067 status = cli_close(cli1, fnum1);
6068 if (!NT_STATUS_IS_OK(status)) {
6069 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6073 printf("non-io open test #7 passed.\n");
6075 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6077 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
6078 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
6079 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6080 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6081 if (!NT_STATUS_IS_OK(status)) {
6082 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
6087 /* Write to ensure we have to update the file time. */
6088 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6090 if (!NT_STATUS_IS_OK(status)) {
6091 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
6096 status = cli_close(cli1, fnum1);
6097 if (!NT_STATUS_IS_OK(status)) {
6098 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
6104 if (!torture_close_connection(cli1)) {
6107 if (!torture_close_connection(cli2)) {
6114 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
6116 uint16_t major, minor;
6117 uint32_t caplow, caphigh;
6120 if (!SERVER_HAS_UNIX_CIFS(cli)) {
6121 printf("Server doesn't support UNIX CIFS extensions.\n");
6122 return NT_STATUS_NOT_SUPPORTED;
6125 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
6127 if (!NT_STATUS_IS_OK(status)) {
6128 printf("Server didn't return UNIX CIFS extensions: %s\n",
6133 status = cli_set_unix_extensions_capabilities(cli, major, minor,
6135 if (!NT_STATUS_IS_OK(status)) {
6136 printf("Server doesn't support setting UNIX CIFS extensions: "
6137 "%s.\n", nt_errstr(status));
6141 return NT_STATUS_OK;
6145 Test POSIX open /mkdir calls.
6147 static bool run_simple_posix_open_test(int dummy)
6149 static struct cli_state *cli1;
6150 const char *fname = "posix:file";
6151 const char *hname = "posix:hlink";
6152 const char *sname = "posix:symlink";
6153 const char *dname = "posix:dir";
6156 uint16_t fnum1 = (uint16_t)-1;
6157 SMB_STRUCT_STAT sbuf;
6158 bool correct = false;
6161 const char *fname_windows = "windows_file";
6162 uint16_t fnum2 = (uint16_t)-1;
6164 printf("Starting simple POSIX open test\n");
6166 if (!torture_open_connection(&cli1, 0)) {
6170 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6172 status = torture_setup_unix_extensions(cli1);
6173 if (!NT_STATUS_IS_OK(status)) {
6177 cli_setatr(cli1, fname, 0, 0);
6178 cli_posix_unlink(cli1, fname);
6179 cli_setatr(cli1, dname, 0, 0);
6180 cli_posix_rmdir(cli1, dname);
6181 cli_setatr(cli1, hname, 0, 0);
6182 cli_posix_unlink(cli1, hname);
6183 cli_setatr(cli1, sname, 0, 0);
6184 cli_posix_unlink(cli1, sname);
6185 cli_setatr(cli1, fname_windows, 0, 0);
6186 cli_posix_unlink(cli1, fname_windows);
6188 /* Create a directory. */
6189 status = cli_posix_mkdir(cli1, dname, 0777);
6190 if (!NT_STATUS_IS_OK(status)) {
6191 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6195 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6197 if (!NT_STATUS_IS_OK(status)) {
6198 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6202 /* Test ftruncate - set file size. */
6203 status = cli_ftruncate(cli1, fnum1, 1000);
6204 if (!NT_STATUS_IS_OK(status)) {
6205 printf("ftruncate failed (%s)\n", nt_errstr(status));
6209 /* Ensure st_size == 1000 */
6210 status = cli_posix_stat(cli1, fname, &sbuf);
6211 if (!NT_STATUS_IS_OK(status)) {
6212 printf("stat failed (%s)\n", nt_errstr(status));
6216 if (sbuf.st_ex_size != 1000) {
6217 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6221 /* Ensure st_mode == 0600 */
6222 if ((sbuf.st_ex_mode & 07777) != 0600) {
6223 printf("posix_open - bad permissions 0%o != 0600\n",
6224 (unsigned int)(sbuf.st_ex_mode & 07777));
6228 /* Test ftruncate - set file size back to zero. */
6229 status = cli_ftruncate(cli1, fnum1, 0);
6230 if (!NT_STATUS_IS_OK(status)) {
6231 printf("ftruncate failed (%s)\n", nt_errstr(status));
6235 status = cli_close(cli1, fnum1);
6236 if (!NT_STATUS_IS_OK(status)) {
6237 printf("close failed (%s)\n", nt_errstr(status));
6241 /* Now open the file again for read only. */
6242 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6243 if (!NT_STATUS_IS_OK(status)) {
6244 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
6248 /* Now unlink while open. */
6249 status = cli_posix_unlink(cli1, fname);
6250 if (!NT_STATUS_IS_OK(status)) {
6251 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6255 status = cli_close(cli1, fnum1);
6256 if (!NT_STATUS_IS_OK(status)) {
6257 printf("close(2) failed (%s)\n", nt_errstr(status));
6261 /* Ensure the file has gone. */
6262 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6263 if (NT_STATUS_IS_OK(status)) {
6264 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
6268 /* Create again to test open with O_TRUNC. */
6269 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
6270 if (!NT_STATUS_IS_OK(status)) {
6271 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6275 /* Test ftruncate - set file size. */
6276 status = cli_ftruncate(cli1, fnum1, 1000);
6277 if (!NT_STATUS_IS_OK(status)) {
6278 printf("ftruncate failed (%s)\n", nt_errstr(status));
6282 /* Ensure st_size == 1000 */
6283 status = cli_posix_stat(cli1, fname, &sbuf);
6284 if (!NT_STATUS_IS_OK(status)) {
6285 printf("stat failed (%s)\n", nt_errstr(status));
6289 if (sbuf.st_ex_size != 1000) {
6290 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6294 status = cli_close(cli1, fnum1);
6295 if (!NT_STATUS_IS_OK(status)) {
6296 printf("close(2) failed (%s)\n", nt_errstr(status));
6300 /* Re-open with O_TRUNC. */
6301 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
6302 if (!NT_STATUS_IS_OK(status)) {
6303 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6307 /* Ensure st_size == 0 */
6308 status = cli_posix_stat(cli1, fname, &sbuf);
6309 if (!NT_STATUS_IS_OK(status)) {
6310 printf("stat failed (%s)\n", nt_errstr(status));
6314 if (sbuf.st_ex_size != 0) {
6315 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
6319 status = cli_close(cli1, fnum1);
6320 if (!NT_STATUS_IS_OK(status)) {
6321 printf("close failed (%s)\n", nt_errstr(status));
6325 status = cli_posix_unlink(cli1, fname);
6326 if (!NT_STATUS_IS_OK(status)) {
6327 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6331 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
6332 if (!NT_STATUS_IS_OK(status)) {
6333 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6334 dname, nt_errstr(status));
6338 cli_close(cli1, fnum1);
6340 /* What happens when we try and POSIX open a directory for write ? */
6341 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
6342 if (NT_STATUS_IS_OK(status)) {
6343 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
6346 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
6347 NT_STATUS_FILE_IS_A_DIRECTORY)) {
6352 /* Create the file. */
6353 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6355 if (!NT_STATUS_IS_OK(status)) {
6356 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6360 /* Write some data into it. */
6361 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6363 if (!NT_STATUS_IS_OK(status)) {
6364 printf("cli_write failed: %s\n", nt_errstr(status));
6368 cli_close(cli1, fnum1);
6370 /* Now create a hardlink. */
6371 status = cli_posix_hardlink(cli1, fname, hname);
6372 if (!NT_STATUS_IS_OK(status)) {
6373 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
6377 /* Now create a symlink. */
6378 status = cli_posix_symlink(cli1, fname, sname);
6379 if (!NT_STATUS_IS_OK(status)) {
6380 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
6384 /* Open the hardlink for read. */
6385 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
6386 if (!NT_STATUS_IS_OK(status)) {
6387 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
6391 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
6392 if (!NT_STATUS_IS_OK(status)) {
6393 printf("POSIX read of %s failed (%s)\n", hname,
6396 } else if (nread != 10) {
6397 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6398 hname, (unsigned long)nread, 10);
6402 if (memcmp(buf, "TEST DATA\n", 10)) {
6403 printf("invalid data read from hardlink\n");
6407 /* Do a POSIX lock/unlock. */
6408 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
6409 if (!NT_STATUS_IS_OK(status)) {
6410 printf("POSIX lock failed %s\n", nt_errstr(status));
6414 /* Punch a hole in the locked area. */
6415 status = cli_posix_unlock(cli1, fnum1, 10, 80);
6416 if (!NT_STATUS_IS_OK(status)) {
6417 printf("POSIX unlock failed %s\n", nt_errstr(status));
6421 cli_close(cli1, fnum1);
6423 /* Open the symlink for read - this should fail. A POSIX
6424 client should not be doing opens on a symlink. */
6425 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
6426 if (NT_STATUS_IS_OK(status)) {
6427 printf("POSIX open of %s succeeded (should have failed)\n", sname);
6430 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
6431 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
6432 printf("POSIX open of %s should have failed "
6433 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6434 "failed with %s instead.\n",
6435 sname, nt_errstr(status));
6440 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
6441 if (!NT_STATUS_IS_OK(status)) {
6442 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
6446 if (strcmp(namebuf, fname) != 0) {
6447 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6448 sname, fname, namebuf);
6452 status = cli_posix_rmdir(cli1, dname);
6453 if (!NT_STATUS_IS_OK(status)) {
6454 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
6458 /* Check directory opens with a specific permission. */
6459 status = cli_posix_mkdir(cli1, dname, 0700);
6460 if (!NT_STATUS_IS_OK(status)) {
6461 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6465 /* Ensure st_mode == 0700 */
6466 status = cli_posix_stat(cli1, dname, &sbuf);
6467 if (!NT_STATUS_IS_OK(status)) {
6468 printf("stat failed (%s)\n", nt_errstr(status));
6472 if ((sbuf.st_ex_mode & 07777) != 0700) {
6473 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6474 (unsigned int)(sbuf.st_ex_mode & 07777));
6479 * Now create a Windows file, and attempt a POSIX unlink.
6480 * This should fail with a sharing violation but due to:
6482 * [Bug 9571] Unlink after open causes smbd to panic
6484 * ensure we've fixed the lock ordering violation.
6487 status = cli_ntcreate(cli1, fname_windows, 0,
6488 FILE_READ_DATA|FILE_WRITE_DATA, 0,
6489 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6491 0x0, 0x0, &fnum2, NULL);
6492 if (!NT_STATUS_IS_OK(status)) {
6493 printf("Windows create of %s failed (%s)\n", fname_windows,
6498 /* Now try posix_unlink. */
6499 status = cli_posix_unlink(cli1, fname_windows);
6500 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6501 printf("POSIX unlink of %s should fail "
6502 "with NT_STATUS_SHARING_VIOLATION "
6503 "got %s instead !\n",
6509 cli_close(cli1, fnum2);
6511 printf("Simple POSIX open test passed\n");
6516 if (fnum1 != (uint16_t)-1) {
6517 cli_close(cli1, fnum1);
6518 fnum1 = (uint16_t)-1;
6521 if (fnum2 != (uint16_t)-1) {
6522 cli_close(cli1, fnum2);
6523 fnum2 = (uint16_t)-1;
6526 cli_setatr(cli1, sname, 0, 0);
6527 cli_posix_unlink(cli1, sname);
6528 cli_setatr(cli1, hname, 0, 0);
6529 cli_posix_unlink(cli1, hname);
6530 cli_setatr(cli1, fname, 0, 0);
6531 cli_posix_unlink(cli1, fname);
6532 cli_setatr(cli1, dname, 0, 0);
6533 cli_posix_rmdir(cli1, dname);
6534 cli_setatr(cli1, fname_windows, 0, 0);
6535 cli_posix_unlink(cli1, fname_windows);
6537 if (!torture_close_connection(cli1)) {
6545 Test POSIX and Windows ACLs are rejected on symlinks.
6547 static bool run_acl_symlink_test(int dummy)
6549 static struct cli_state *cli;
6550 const char *fname = "posix_file";
6551 const char *sname = "posix_symlink";
6552 uint16_t fnum = (uint16_t)-1;
6553 bool correct = false;
6555 char *posix_acl = NULL;
6556 size_t posix_acl_len = 0;
6557 char *posix_acl_sym = NULL;
6558 size_t posix_acl_len_sym = 0;
6559 struct security_descriptor *sd = NULL;
6560 struct security_descriptor *sd_sym = NULL;
6561 TALLOC_CTX *frame = NULL;
6563 frame = talloc_stackframe();
6565 printf("Starting acl symlink test\n");
6567 if (!torture_open_connection(&cli, 0)) {
6572 smbXcli_conn_set_sockopt(cli->conn, sockops);
6574 status = torture_setup_unix_extensions(cli);
6575 if (!NT_STATUS_IS_OK(status)) {
6580 cli_setatr(cli, fname, 0, 0);
6581 cli_posix_unlink(cli, fname);
6582 cli_setatr(cli, sname, 0, 0);
6583 cli_posix_unlink(cli, sname);
6585 status = cli_ntcreate(cli,
6588 READ_CONTROL_ACCESS,
6590 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6597 if (!NT_STATUS_IS_OK(status)) {
6598 printf("cli_ntcreate of %s failed (%s)\n",
6604 /* Get the Windows ACL on the file. */
6605 status = cli_query_secdesc(cli,
6609 if (!NT_STATUS_IS_OK(status)) {
6610 printf("cli_query_secdesc failed (%s)\n",
6615 /* Get the POSIX ACL on the file. */
6616 status = cli_posix_getacl(cli,
6622 if (!NT_STATUS_IS_OK(status)) {
6623 printf("cli_posix_getacl failed (%s)\n",
6628 status = cli_close(cli, fnum);
6629 if (!NT_STATUS_IS_OK(status)) {
6630 printf("close failed (%s)\n", nt_errstr(status));
6633 fnum = (uint16_t)-1;
6635 /* Now create a symlink. */
6636 status = cli_posix_symlink(cli, fname, sname);
6637 if (!NT_STATUS_IS_OK(status)) {
6638 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6645 /* Open a handle on the symlink. */
6646 status = cli_ntcreate(cli,
6649 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
6651 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6658 if (!NT_STATUS_IS_OK(status)) {
6659 printf("cli_posix_open of %s failed (%s)\n",
6665 /* Get the Windows ACL on the symlink handle. Should fail */
6666 status = cli_query_secdesc(cli,
6671 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6672 printf("cli_query_secdesc on a symlink gave %s. "
6673 "Should be NT_STATUS_ACCESS_DENIED.\n",
6678 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6679 status = cli_posix_getacl(cli,
6685 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6686 printf("cli_posix_getacl on a symlink gave %s. "
6687 "Should be NT_STATUS_ACCESS_DENIED.\n",
6692 /* Set the Windows ACL on the symlink handle. Should fail */
6693 status = cli_set_security_descriptor(cli,
6698 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6699 printf("cli_query_secdesc on a symlink gave %s. "
6700 "Should be NT_STATUS_ACCESS_DENIED.\n",
6705 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6706 status = cli_posix_setacl(cli,
6711 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6712 printf("cli_posix_getacl on a symlink gave %s. "
6713 "Should be NT_STATUS_ACCESS_DENIED.\n",
6718 printf("ACL symlink test passed\n");
6723 if (fnum != (uint16_t)-1) {
6724 cli_close(cli, fnum);
6725 fnum = (uint16_t)-1;
6728 cli_setatr(cli, sname, 0, 0);
6729 cli_posix_unlink(cli, sname);
6730 cli_setatr(cli, fname, 0, 0);
6731 cli_posix_unlink(cli, fname);
6733 if (!torture_close_connection(cli)) {
6742 Test POSIX can delete a file containing streams.
6744 static bool run_posix_stream_delete(int dummy)
6746 struct cli_state *cli1 = NULL;
6747 struct cli_state *cli2 = NULL;
6748 const char *fname = "streamfile";
6749 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6750 uint16_t fnum1 = (uint16_t)-1;
6751 bool correct = false;
6753 TALLOC_CTX *frame = NULL;
6755 frame = talloc_stackframe();
6757 printf("Starting POSIX stream delete test\n");
6759 if (!torture_open_connection(&cli1, 0) ||
6760 !torture_open_connection(&cli2, 1)) {
6765 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6766 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6768 status = torture_setup_unix_extensions(cli2);
6769 if (!NT_STATUS_IS_OK(status)) {
6773 cli_setatr(cli1, fname, 0, 0);
6774 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6776 /* Create the file. */
6777 status = cli_ntcreate(cli1,
6780 READ_CONTROL_ACCESS,
6782 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6789 if (!NT_STATUS_IS_OK(status)) {
6790 printf("cli_ntcreate of %s failed (%s)\n",
6796 status = cli_close(cli1, fnum1);
6797 if (!NT_STATUS_IS_OK(status)) {
6798 printf("cli_close of %s failed (%s)\n",
6803 fnum1 = (uint16_t)-1;
6805 /* Now create the stream. */
6806 status = cli_ntcreate(cli1,
6811 FILE_SHARE_READ|FILE_SHARE_WRITE,
6818 if (!NT_STATUS_IS_OK(status)) {
6819 printf("cli_ntcreate of %s failed (%s)\n",
6825 /* Leave the stream handle open... */
6827 /* POSIX unlink should fail. */
6828 status = cli_posix_unlink(cli2, fname);
6829 if (NT_STATUS_IS_OK(status)) {
6830 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6835 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6836 printf("cli_posix_unlink of %s failed with (%s) "
6837 "should have been NT_STATUS_SHARING_VIOLATION\n",
6843 /* Close the stream handle. */
6844 status = cli_close(cli1, fnum1);
6845 if (!NT_STATUS_IS_OK(status)) {
6846 printf("cli_close of %s failed (%s)\n",
6851 fnum1 = (uint16_t)-1;
6853 /* POSIX unlink after stream handle closed should succeed. */
6854 status = cli_posix_unlink(cli2, fname);
6855 if (!NT_STATUS_IS_OK(status)) {
6856 printf("cli_posix_unlink of %s failed (%s)\n",
6862 printf("POSIX stream delete test passed\n");
6867 if (fnum1 != (uint16_t)-1) {
6868 cli_close(cli1, fnum1);
6869 fnum1 = (uint16_t)-1;
6872 cli_setatr(cli1, fname, 0, 0);
6873 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6875 if (!torture_close_connection(cli1)) {
6878 if (!torture_close_connection(cli2)) {
6887 Test setting EA's are rejected on symlinks.
6889 static bool run_ea_symlink_test(int dummy)
6891 static struct cli_state *cli;
6892 const char *fname = "posix_file_ea";
6893 const char *sname = "posix_symlink_ea";
6894 const char *ea_name = "testea_name";
6895 const char *ea_value = "testea_value";
6896 uint16_t fnum = (uint16_t)-1;
6897 bool correct = false;
6900 struct ea_struct *eas = NULL;
6901 TALLOC_CTX *frame = NULL;
6903 frame = talloc_stackframe();
6905 printf("Starting EA symlink test\n");
6907 if (!torture_open_connection(&cli, 0)) {
6912 smbXcli_conn_set_sockopt(cli->conn, sockops);
6914 status = torture_setup_unix_extensions(cli);
6915 if (!NT_STATUS_IS_OK(status)) {
6920 cli_setatr(cli, fname, 0, 0);
6921 cli_posix_unlink(cli, fname);
6922 cli_setatr(cli, sname, 0, 0);
6923 cli_posix_unlink(cli, sname);
6925 status = cli_ntcreate(cli,
6928 READ_CONTROL_ACCESS,
6930 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6937 if (!NT_STATUS_IS_OK(status)) {
6938 printf("cli_ntcreate of %s failed (%s)\n",
6944 status = cli_close(cli, fnum);
6945 if (!NT_STATUS_IS_OK(status)) {
6946 printf("close failed (%s)\n",
6950 fnum = (uint16_t)-1;
6952 /* Set an EA on the path. */
6953 status = cli_set_ea_path(cli,
6957 strlen(ea_value)+1);
6959 if (!NT_STATUS_IS_OK(status)) {
6960 printf("cli_set_ea_path failed (%s)\n",
6965 /* Now create a symlink. */
6966 status = cli_posix_symlink(cli, fname, sname);
6967 if (!NT_STATUS_IS_OK(status)) {
6968 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6975 /* Get the EA list on the path. Should return value set. */
6976 status = cli_get_ea_list_path(cli,
6982 if (!NT_STATUS_IS_OK(status)) {
6983 printf("cli_get_ea_list_path failed (%s)\n",
6988 /* Ensure the EA we set is there. */
6989 for (i=0; i<num_eas; i++) {
6990 if (strcmp(eas[i].name, ea_name) == 0 &&
6991 eas[i].value.length == strlen(ea_value)+1 &&
6992 memcmp(eas[i].value.data,
6994 eas[i].value.length) == 0) {
7000 printf("Didn't find EA on pathname %s\n",
7008 /* Get the EA list on the symlink. Should return empty list. */
7009 status = cli_get_ea_list_path(cli,
7015 if (!NT_STATUS_IS_OK(status)) {
7016 printf("cli_get_ea_list_path failed (%s)\n",
7022 printf("cli_get_ea_list_path failed (%s)\n",
7027 /* Set an EA on the symlink. Should fail. */
7028 status = cli_set_ea_path(cli,
7032 strlen(ea_value)+1);
7034 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7035 printf("cli_set_ea_path on a symlink gave %s. "
7036 "Should be NT_STATUS_ACCESS_DENIED.\n",
7041 printf("EA symlink test passed\n");
7046 if (fnum != (uint16_t)-1) {
7047 cli_close(cli, fnum);
7048 fnum = (uint16_t)-1;
7051 cli_setatr(cli, sname, 0, 0);
7052 cli_posix_unlink(cli, sname);
7053 cli_setatr(cli, fname, 0, 0);
7054 cli_posix_unlink(cli, fname);
7056 if (!torture_close_connection(cli)) {
7065 Test POSIX locks are OFD-locks.
7067 static bool run_posix_ofd_lock_test(int dummy)
7069 static struct cli_state *cli;
7070 const char *fname = "posix_file";
7071 uint16_t fnum1 = (uint16_t)-1;
7072 uint16_t fnum2 = (uint16_t)-1;
7073 bool correct = false;
7075 TALLOC_CTX *frame = NULL;
7077 frame = talloc_stackframe();
7079 printf("Starting POSIX ofd-lock test\n");
7081 if (!torture_open_connection(&cli, 0)) {
7086 smbXcli_conn_set_sockopt(cli->conn, sockops);
7088 status = torture_setup_unix_extensions(cli);
7089 if (!NT_STATUS_IS_OK(status)) {
7094 cli_setatr(cli, fname, 0, 0);
7095 cli_posix_unlink(cli, fname);
7097 /* Open the file twice. */
7098 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
7100 if (!NT_STATUS_IS_OK(status)) {
7101 printf("First POSIX open of %s failed\n", fname);
7105 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
7106 if (!NT_STATUS_IS_OK(status)) {
7107 printf("First POSIX open of %s failed\n", fname);
7111 /* Set a 0-50 lock on fnum1. */
7112 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7113 if (!NT_STATUS_IS_OK(status)) {
7114 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
7118 /* Set a 60-100 lock on fnum2. */
7119 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
7120 if (!NT_STATUS_IS_OK(status)) {
7121 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
7125 /* close fnum1 - 0-50 lock should go away. */
7126 status = cli_close(cli, fnum1);
7127 if (!NT_STATUS_IS_OK(status)) {
7128 printf("close failed (%s)\n",
7132 fnum1 = (uint16_t)-1;
7134 /* Change the lock context. */
7135 cli_setpid(cli, cli_getpid(cli) + 1);
7137 /* Re-open fnum1. */
7138 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
7139 if (!NT_STATUS_IS_OK(status)) {
7140 printf("Third POSIX open of %s failed\n", fname);
7144 /* 60-100 lock should still be there. */
7145 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
7146 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
7147 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
7151 /* 0-50 lock should be gone. */
7152 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7153 if (!NT_STATUS_IS_OK(status)) {
7154 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
7158 printf("POSIX OFD lock test passed\n");
7163 if (fnum1 != (uint16_t)-1) {
7164 cli_close(cli, fnum1);
7165 fnum1 = (uint16_t)-1;
7167 if (fnum2 != (uint16_t)-1) {
7168 cli_close(cli, fnum2);
7169 fnum2 = (uint16_t)-1;
7172 cli_setatr(cli, fname, 0, 0);
7173 cli_posix_unlink(cli, fname);
7175 if (!torture_close_connection(cli)) {
7183 static uint32_t open_attrs_table[] = {
7184 FILE_ATTRIBUTE_NORMAL,
7185 FILE_ATTRIBUTE_ARCHIVE,
7186 FILE_ATTRIBUTE_READONLY,
7187 FILE_ATTRIBUTE_HIDDEN,
7188 FILE_ATTRIBUTE_SYSTEM,
7190 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7191 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7192 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7193 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7194 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7195 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7197 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7198 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7199 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7200 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7203 struct trunc_open_results {
7206 uint32_t trunc_attr;
7207 uint32_t result_attr;
7210 static struct trunc_open_results attr_results[] = {
7211 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7212 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7213 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7214 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7215 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7216 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7217 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7218 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7219 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7220 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7221 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7222 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7223 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7224 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7225 { 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 },
7226 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7227 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7228 { 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 },
7229 { 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 },
7230 { 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 },
7231 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7232 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7233 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7234 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7235 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7236 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7239 static bool run_openattrtest(int dummy)
7241 static struct cli_state *cli1;
7242 const char *fname = "\\openattr.file";
7244 bool correct = True;
7246 unsigned int i, j, k, l;
7249 printf("starting open attr test\n");
7251 if (!torture_open_connection(&cli1, 0)) {
7255 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7257 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7258 cli_setatr(cli1, fname, 0, 0);
7259 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7261 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7262 open_attrs_table[i], FILE_SHARE_NONE,
7263 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7264 if (!NT_STATUS_IS_OK(status)) {
7265 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7269 status = cli_close(cli1, fnum1);
7270 if (!NT_STATUS_IS_OK(status)) {
7271 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7275 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7276 status = cli_ntcreate(cli1, fname, 0,
7277 FILE_READ_DATA|FILE_WRITE_DATA,
7278 open_attrs_table[j],
7279 FILE_SHARE_NONE, FILE_OVERWRITE,
7280 0, 0, &fnum1, NULL);
7281 if (!NT_STATUS_IS_OK(status)) {
7282 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7283 if (attr_results[l].num == k) {
7284 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7285 k, open_attrs_table[i],
7286 open_attrs_table[j],
7287 fname, NT_STATUS_V(status), nt_errstr(status));
7292 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7293 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7294 k, open_attrs_table[i], open_attrs_table[j],
7299 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7305 status = cli_close(cli1, fnum1);
7306 if (!NT_STATUS_IS_OK(status)) {
7307 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7311 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7312 if (!NT_STATUS_IS_OK(status)) {
7313 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7318 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7319 k, open_attrs_table[i], open_attrs_table[j], attr );
7322 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7323 if (attr_results[l].num == k) {
7324 if (attr != attr_results[l].result_attr ||
7325 open_attrs_table[i] != attr_results[l].init_attr ||
7326 open_attrs_table[j] != attr_results[l].trunc_attr) {
7327 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7328 open_attrs_table[i],
7329 open_attrs_table[j],
7331 attr_results[l].result_attr);
7341 cli_setatr(cli1, fname, 0, 0);
7342 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7344 printf("open attr test %s.\n", correct ? "passed" : "failed");
7346 if (!torture_close_connection(cli1)) {
7352 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7353 const char *name, void *state)
7355 int *matched = (int *)state;
7356 if (matched != NULL) {
7359 return NT_STATUS_OK;
7363 test directory listing speed
7365 static bool run_dirtest(int dummy)
7368 static struct cli_state *cli;
7370 struct timeval core_start;
7371 bool correct = True;
7374 printf("starting directory test\n");
7376 if (!torture_open_connection(&cli, 0)) {
7380 smbXcli_conn_set_sockopt(cli->conn, sockops);
7383 for (i=0;i<torture_numops;i++) {
7385 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7386 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7387 fprintf(stderr,"Failed to open %s\n", fname);
7390 cli_close(cli, fnum);
7393 core_start = timeval_current();
7396 cli_list(cli, "a*.*", 0, list_fn, &matched);
7397 printf("Matched %d\n", matched);
7400 cli_list(cli, "b*.*", 0, list_fn, &matched);
7401 printf("Matched %d\n", matched);
7404 cli_list(cli, "xyzabc", 0, list_fn, &matched);
7405 printf("Matched %d\n", matched);
7407 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7410 for (i=0;i<torture_numops;i++) {
7412 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7413 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7416 if (!torture_close_connection(cli)) {
7420 printf("finished dirtest\n");
7425 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7428 struct cli_state *pcli = (struct cli_state *)state;
7430 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7432 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7433 return NT_STATUS_OK;
7435 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7436 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7437 printf("del_fn: failed to rmdir %s\n,", fname );
7439 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7440 printf("del_fn: failed to unlink %s\n,", fname );
7442 return NT_STATUS_OK;
7447 sees what IOCTLs are supported
7449 bool torture_ioctl_test(int dummy)
7451 static struct cli_state *cli;
7452 uint16_t device, function;
7454 const char *fname = "\\ioctl.dat";
7458 if (!torture_open_connection(&cli, 0)) {
7462 printf("starting ioctl test\n");
7464 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7466 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7467 if (!NT_STATUS_IS_OK(status)) {
7468 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7472 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7473 printf("ioctl device info: %s\n", nt_errstr(status));
7475 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7476 printf("ioctl job info: %s\n", nt_errstr(status));
7478 for (device=0;device<0x100;device++) {
7479 printf("ioctl test with device = 0x%x\n", device);
7480 for (function=0;function<0x100;function++) {
7481 uint32_t code = (device<<16) | function;
7483 status = cli_raw_ioctl(cli, fnum, code, &blob);
7485 if (NT_STATUS_IS_OK(status)) {
7486 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7488 data_blob_free(&blob);
7493 if (!torture_close_connection(cli)) {
7502 tries varients of chkpath
7504 bool torture_chkpath_test(int dummy)
7506 static struct cli_state *cli;
7511 if (!torture_open_connection(&cli, 0)) {
7515 printf("starting chkpath test\n");
7517 /* cleanup from an old run */
7518 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7519 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7520 cli_rmdir(cli, "\\chkpath.dir");
7522 status = cli_mkdir(cli, "\\chkpath.dir");
7523 if (!NT_STATUS_IS_OK(status)) {
7524 printf("mkdir1 failed : %s\n", nt_errstr(status));
7528 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7529 if (!NT_STATUS_IS_OK(status)) {
7530 printf("mkdir2 failed : %s\n", nt_errstr(status));
7534 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7536 if (!NT_STATUS_IS_OK(status)) {
7537 printf("open1 failed (%s)\n", nt_errstr(status));
7540 cli_close(cli, fnum);
7542 status = cli_chkpath(cli, "\\chkpath.dir");
7543 if (!NT_STATUS_IS_OK(status)) {
7544 printf("chkpath1 failed: %s\n", nt_errstr(status));
7548 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7549 if (!NT_STATUS_IS_OK(status)) {
7550 printf("chkpath2 failed: %s\n", nt_errstr(status));
7554 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7555 if (!NT_STATUS_IS_OK(status)) {
7556 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7557 NT_STATUS_NOT_A_DIRECTORY);
7559 printf("* chkpath on a file should fail\n");
7563 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7564 if (!NT_STATUS_IS_OK(status)) {
7565 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7566 NT_STATUS_OBJECT_NAME_NOT_FOUND);
7568 printf("* chkpath on a non existent file should fail\n");
7572 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7573 if (!NT_STATUS_IS_OK(status)) {
7574 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7575 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7577 printf("* chkpath on a non existent component should fail\n");
7581 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7582 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7583 cli_rmdir(cli, "\\chkpath.dir");
7585 if (!torture_close_connection(cli)) {
7592 static bool run_eatest(int dummy)
7594 static struct cli_state *cli;
7595 const char *fname = "\\eatest.txt";
7596 bool correct = True;
7600 struct ea_struct *ea_list = NULL;
7601 TALLOC_CTX *mem_ctx = talloc_init("eatest");
7604 printf("starting eatest\n");
7606 if (!torture_open_connection(&cli, 0)) {
7607 talloc_destroy(mem_ctx);
7611 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7613 status = cli_ntcreate(cli, fname, 0,
7614 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7615 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7616 0x4044, 0, &fnum, NULL);
7617 if (!NT_STATUS_IS_OK(status)) {
7618 printf("open failed - %s\n", nt_errstr(status));
7619 talloc_destroy(mem_ctx);
7623 for (i = 0; i < 10; i++) {
7624 fstring ea_name, ea_val;
7626 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7627 memset(ea_val, (char)i+1, i+1);
7628 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7629 if (!NT_STATUS_IS_OK(status)) {
7630 printf("ea_set of name %s failed - %s\n", ea_name,
7632 talloc_destroy(mem_ctx);
7637 cli_close(cli, fnum);
7638 for (i = 0; i < 10; i++) {
7639 fstring ea_name, ea_val;
7641 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7642 memset(ea_val, (char)i+1, i+1);
7643 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7644 if (!NT_STATUS_IS_OK(status)) {
7645 printf("ea_set of name %s failed - %s\n", ea_name,
7647 talloc_destroy(mem_ctx);
7652 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7653 if (!NT_STATUS_IS_OK(status)) {
7654 printf("ea_get list failed - %s\n", nt_errstr(status));
7658 printf("num_eas = %d\n", (int)num_eas);
7660 if (num_eas != 20) {
7661 printf("Should be 20 EA's stored... failing.\n");
7665 for (i = 0; i < num_eas; i++) {
7666 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7667 dump_data(0, ea_list[i].value.data,
7668 ea_list[i].value.length);
7671 /* Setting EA's to zero length deletes them. Test this */
7672 printf("Now deleting all EA's - case indepenent....\n");
7675 cli_set_ea_path(cli, fname, "", "", 0);
7677 for (i = 0; i < 20; i++) {
7679 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7680 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7681 if (!NT_STATUS_IS_OK(status)) {
7682 printf("ea_set of name %s failed - %s\n", ea_name,
7684 talloc_destroy(mem_ctx);
7690 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7691 if (!NT_STATUS_IS_OK(status)) {
7692 printf("ea_get list failed - %s\n", nt_errstr(status));
7696 printf("num_eas = %d\n", (int)num_eas);
7697 for (i = 0; i < num_eas; i++) {
7698 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7699 dump_data(0, ea_list[i].value.data,
7700 ea_list[i].value.length);
7704 printf("deleting EA's failed.\n");
7708 /* Try and delete a non existent EA. */
7709 status = cli_set_ea_path(cli, fname, "foo", "", 0);
7710 if (!NT_STATUS_IS_OK(status)) {
7711 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7716 talloc_destroy(mem_ctx);
7717 if (!torture_close_connection(cli)) {
7724 static bool run_dirtest1(int dummy)
7727 static struct cli_state *cli;
7730 bool correct = True;
7732 printf("starting directory test\n");
7734 if (!torture_open_connection(&cli, 0)) {
7738 smbXcli_conn_set_sockopt(cli->conn, sockops);
7740 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7741 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7742 cli_rmdir(cli, "\\LISTDIR");
7743 cli_mkdir(cli, "\\LISTDIR");
7745 /* Create 1000 files and 1000 directories. */
7746 for (i=0;i<1000;i++) {
7748 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7749 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7750 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7751 0, 0, &fnum, NULL))) {
7752 fprintf(stderr,"Failed to open %s\n", fname);
7755 cli_close(cli, fnum);
7757 for (i=0;i<1000;i++) {
7759 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7760 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7761 fprintf(stderr,"Failed to open %s\n", fname);
7766 /* Now ensure that doing an old list sees both files and directories. */
7768 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7769 printf("num_seen = %d\n", num_seen );
7770 /* We should see 100 files + 1000 directories + . and .. */
7771 if (num_seen != 2002)
7774 /* Ensure if we have the "must have" bits we only see the
7778 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7779 printf("num_seen = %d\n", num_seen );
7780 if (num_seen != 1002)
7784 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7785 printf("num_seen = %d\n", num_seen );
7786 if (num_seen != 1000)
7789 /* Delete everything. */
7790 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7791 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7792 cli_rmdir(cli, "\\LISTDIR");
7795 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7796 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7797 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7800 if (!torture_close_connection(cli)) {
7804 printf("finished dirtest1\n");
7809 static bool run_error_map_extract(int dummy) {
7811 static struct cli_state *c_dos;
7812 static struct cli_state *c_nt;
7824 /* NT-Error connection */
7826 disable_spnego = true;
7827 if (!(c_nt = open_nbt_connection())) {
7828 disable_spnego = false;
7831 disable_spnego = false;
7833 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7836 if (!NT_STATUS_IS_OK(status)) {
7837 printf("%s rejected the NT-error negprot (%s)\n", host,
7843 status = cli_session_setup_anon(c_nt);
7844 if (!NT_STATUS_IS_OK(status)) {
7845 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7849 /* DOS-Error connection */
7851 disable_spnego = true;
7852 force_dos_errors = true;
7853 if (!(c_dos = open_nbt_connection())) {
7854 disable_spnego = false;
7855 force_dos_errors = false;
7858 disable_spnego = false;
7859 force_dos_errors = false;
7861 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7863 if (!NT_STATUS_IS_OK(status)) {
7864 printf("%s rejected the DOS-error negprot (%s)\n", host,
7866 cli_shutdown(c_dos);
7870 status = cli_session_setup_anon(c_dos);
7871 if (!NT_STATUS_IS_OK(status)) {
7872 printf("%s rejected the DOS-error initial session setup (%s)\n",
7873 host, nt_errstr(status));
7877 c_nt->map_dos_errors = false;
7878 c_dos->map_dos_errors = false;
7880 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7881 struct cli_credentials *user_creds = NULL;
7883 fstr_sprintf(user, "%X", error);
7885 user_creds = cli_session_creds_init(talloc_tos(),
7890 false, /* use_kerberos */
7891 false, /* fallback_after_kerberos */
7892 false, /* use_ccache */
7893 false); /* password_is_nt_hash */
7894 if (user_creds == NULL) {
7895 printf("cli_session_creds_init(%s) failed\n", user);
7899 status = cli_session_setup_creds(c_nt, user_creds);
7900 if (NT_STATUS_IS_OK(status)) {
7901 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7904 /* Case #1: 32-bit NT errors */
7905 if (!NT_STATUS_IS_DOS(status)) {
7908 printf("/** Dos error on NT connection! (%s) */\n",
7910 nt_status = NT_STATUS(0xc0000000);
7913 status = cli_session_setup_creds(c_dos, user_creds);
7914 if (NT_STATUS_IS_OK(status)) {
7915 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7918 /* Case #1: 32-bit NT errors */
7919 if (NT_STATUS_IS_DOS(status)) {
7920 printf("/** NT error on DOS connection! (%s) */\n",
7922 errnum = errclass = 0;
7924 errclass = NT_STATUS_DOS_CLASS(status);
7925 errnum = NT_STATUS_DOS_CODE(status);
7928 if (NT_STATUS_V(nt_status) != error) {
7929 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7930 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
7931 get_nt_error_c_code(talloc_tos(), nt_status));
7934 printf("\t{%s,\t%s,\t%s},\n",
7935 smb_dos_err_class(errclass),
7936 smb_dos_err_name(errclass, errnum),
7937 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7939 TALLOC_FREE(user_creds);
7944 static bool run_sesssetup_bench(int dummy)
7946 static struct cli_state *c;
7947 const char *fname = "\\file.dat";
7952 if (!torture_open_connection(&c, 0)) {
7956 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7957 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7958 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7959 if (!NT_STATUS_IS_OK(status)) {
7960 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7964 for (i=0; i<torture_numops; i++) {
7965 status = cli_session_setup_creds(c, torture_creds);
7966 if (!NT_STATUS_IS_OK(status)) {
7967 d_printf("(%s) cli_session_setup_creds failed: %s\n",
7968 __location__, nt_errstr(status));
7972 d_printf("\r%d ", (int)cli_state_get_uid(c));
7974 status = cli_ulogoff(c);
7975 if (!NT_STATUS_IS_OK(status)) {
7976 d_printf("(%s) cli_ulogoff failed: %s\n",
7977 __location__, nt_errstr(status));
7985 static bool subst_test(const char *str, const char *user, const char *domain,
7986 uid_t uid, gid_t gid, const char *expected)
7991 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7993 if (strcmp(subst, expected) != 0) {
7994 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7995 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
8004 static void chain1_open_completion(struct tevent_req *req)
8008 status = cli_openx_recv(req, &fnum);
8011 d_printf("cli_openx_recv returned %s: %d\n",
8013 NT_STATUS_IS_OK(status) ? fnum : -1);
8016 static void chain1_write_completion(struct tevent_req *req)
8020 status = cli_write_andx_recv(req, &written);
8023 d_printf("cli_write_andx_recv returned %s: %d\n",
8025 NT_STATUS_IS_OK(status) ? (int)written : -1);
8028 static void chain1_close_completion(struct tevent_req *req)
8031 bool *done = (bool *)tevent_req_callback_data_void(req);
8033 status = cli_close_recv(req);
8038 d_printf("cli_close returned %s\n", nt_errstr(status));
8041 static bool run_chain1(int dummy)
8043 struct cli_state *cli1;
8044 struct tevent_context *evt = samba_tevent_context_init(NULL);
8045 struct tevent_req *reqs[3], *smbreqs[3];
8047 const char *str = "foobar";
8050 printf("starting chain1 test\n");
8051 if (!torture_open_connection(&cli1, 0)) {
8055 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8057 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
8058 O_CREAT|O_RDWR, 0, &smbreqs[0]);
8059 if (reqs[0] == NULL) return false;
8060 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
8063 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
8064 (const uint8_t *)str, 0, strlen(str)+1,
8065 smbreqs, 1, &smbreqs[1]);
8066 if (reqs[1] == NULL) return false;
8067 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
8069 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
8070 if (reqs[2] == NULL) return false;
8071 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
8073 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8074 if (!NT_STATUS_IS_OK(status)) {
8079 tevent_loop_once(evt);
8082 torture_close_connection(cli1);
8086 static void chain2_sesssetup_completion(struct tevent_req *req)
8089 status = cli_session_setup_guest_recv(req);
8090 d_printf("sesssetup returned %s\n", nt_errstr(status));
8093 static void chain2_tcon_completion(struct tevent_req *req)
8095 bool *done = (bool *)tevent_req_callback_data_void(req);
8097 status = cli_tcon_andx_recv(req);
8098 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
8102 static bool run_chain2(int dummy)
8104 struct cli_state *cli1;
8105 struct tevent_context *evt = samba_tevent_context_init(NULL);
8106 struct tevent_req *reqs[2], *smbreqs[2];
8109 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
8111 printf("starting chain2 test\n");
8112 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
8113 port_to_use, SMB_SIGNING_DEFAULT, flags);
8114 if (!NT_STATUS_IS_OK(status)) {
8118 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8120 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
8122 if (reqs[0] == NULL) return false;
8123 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
8125 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
8126 "?????", NULL, 0, &smbreqs[1]);
8127 if (reqs[1] == NULL) return false;
8128 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
8130 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8131 if (!NT_STATUS_IS_OK(status)) {
8136 tevent_loop_once(evt);
8139 torture_close_connection(cli1);
8144 struct torture_createdel_state {
8145 struct tevent_context *ev;
8146 struct cli_state *cli;
8149 static void torture_createdel_created(struct tevent_req *subreq);
8150 static void torture_createdel_closed(struct tevent_req *subreq);
8152 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8153 struct tevent_context *ev,
8154 struct cli_state *cli,
8157 struct tevent_req *req, *subreq;
8158 struct torture_createdel_state *state;
8160 req = tevent_req_create(mem_ctx, &state,
8161 struct torture_createdel_state);
8168 subreq = cli_ntcreate_send(
8169 state, ev, cli, name, 0,
8170 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8171 FILE_ATTRIBUTE_NORMAL,
8172 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8173 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
8175 if (tevent_req_nomem(subreq, req)) {
8176 return tevent_req_post(req, ev);
8178 tevent_req_set_callback(subreq, torture_createdel_created, req);
8182 static void torture_createdel_created(struct tevent_req *subreq)
8184 struct tevent_req *req = tevent_req_callback_data(
8185 subreq, struct tevent_req);
8186 struct torture_createdel_state *state = tevent_req_data(
8187 req, struct torture_createdel_state);
8191 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8192 TALLOC_FREE(subreq);
8193 if (tevent_req_nterror(req, status)) {
8194 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8195 nt_errstr(status)));
8199 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8200 if (tevent_req_nomem(subreq, req)) {
8203 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8206 static void torture_createdel_closed(struct tevent_req *subreq)
8208 struct tevent_req *req = tevent_req_callback_data(
8209 subreq, struct tevent_req);
8212 status = cli_close_recv(subreq);
8213 if (tevent_req_nterror(req, status)) {
8214 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8217 tevent_req_done(req);
8220 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8222 return tevent_req_simple_recv_ntstatus(req);
8225 struct torture_createdels_state {
8226 struct tevent_context *ev;
8227 struct cli_state *cli;
8228 const char *base_name;
8232 struct tevent_req **reqs;
8235 static void torture_createdels_done(struct tevent_req *subreq);
8237 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8238 struct tevent_context *ev,
8239 struct cli_state *cli,
8240 const char *base_name,
8244 struct tevent_req *req;
8245 struct torture_createdels_state *state;
8248 req = tevent_req_create(mem_ctx, &state,
8249 struct torture_createdels_state);
8255 state->base_name = talloc_strdup(state, base_name);
8256 if (tevent_req_nomem(state->base_name, req)) {
8257 return tevent_req_post(req, ev);
8259 state->num_files = MAX(num_parallel, num_files);
8261 state->received = 0;
8263 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8264 if (tevent_req_nomem(state->reqs, req)) {
8265 return tevent_req_post(req, ev);
8268 for (i=0; i<num_parallel; i++) {
8271 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8273 if (tevent_req_nomem(name, req)) {
8274 return tevent_req_post(req, ev);
8276 state->reqs[i] = torture_createdel_send(
8277 state->reqs, state->ev, state->cli, name);
8278 if (tevent_req_nomem(state->reqs[i], req)) {
8279 return tevent_req_post(req, ev);
8281 name = talloc_move(state->reqs[i], &name);
8282 tevent_req_set_callback(state->reqs[i],
8283 torture_createdels_done, req);
8289 static void torture_createdels_done(struct tevent_req *subreq)
8291 struct tevent_req *req = tevent_req_callback_data(
8292 subreq, struct tevent_req);
8293 struct torture_createdels_state *state = tevent_req_data(
8294 req, struct torture_createdels_state);
8295 size_t num_parallel = talloc_array_length(state->reqs);
8300 status = torture_createdel_recv(subreq);
8301 if (!NT_STATUS_IS_OK(status)){
8302 DEBUG(10, ("torture_createdel_recv returned %s\n",
8303 nt_errstr(status)));
8304 TALLOC_FREE(subreq);
8305 tevent_req_nterror(req, status);
8309 for (i=0; i<num_parallel; i++) {
8310 if (subreq == state->reqs[i]) {
8314 if (i == num_parallel) {
8315 DEBUG(10, ("received something we did not send\n"));
8316 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8319 TALLOC_FREE(state->reqs[i]);
8321 if (state->sent >= state->num_files) {
8322 tevent_req_done(req);
8326 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8328 if (tevent_req_nomem(name, req)) {
8331 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8333 if (tevent_req_nomem(state->reqs[i], req)) {
8336 name = talloc_move(state->reqs[i], &name);
8337 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8341 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8343 return tevent_req_simple_recv_ntstatus(req);
8346 struct swallow_notify_state {
8347 struct tevent_context *ev;
8348 struct cli_state *cli;
8350 uint32_t completion_filter;
8352 bool (*fn)(uint32_t action, const char *name, void *priv);
8356 static void swallow_notify_done(struct tevent_req *subreq);
8358 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8359 struct tevent_context *ev,
8360 struct cli_state *cli,
8362 uint32_t completion_filter,
8364 bool (*fn)(uint32_t action,
8369 struct tevent_req *req, *subreq;
8370 struct swallow_notify_state *state;
8372 req = tevent_req_create(mem_ctx, &state,
8373 struct swallow_notify_state);
8380 state->completion_filter = completion_filter;
8381 state->recursive = recursive;
8385 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8386 0xffff, state->completion_filter,
8388 if (tevent_req_nomem(subreq, req)) {
8389 return tevent_req_post(req, ev);
8391 tevent_req_set_callback(subreq, swallow_notify_done, req);
8395 static void swallow_notify_done(struct tevent_req *subreq)
8397 struct tevent_req *req = tevent_req_callback_data(
8398 subreq, struct tevent_req);
8399 struct swallow_notify_state *state = tevent_req_data(
8400 req, struct swallow_notify_state);
8402 uint32_t i, num_changes;
8403 struct notify_change *changes;
8405 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8406 TALLOC_FREE(subreq);
8407 if (!NT_STATUS_IS_OK(status)) {
8408 DEBUG(10, ("cli_notify_recv returned %s\n",
8409 nt_errstr(status)));
8410 tevent_req_nterror(req, status);
8414 for (i=0; i<num_changes; i++) {
8415 state->fn(changes[i].action, changes[i].name, state->priv);
8417 TALLOC_FREE(changes);
8419 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8420 0xffff, state->completion_filter,
8422 if (tevent_req_nomem(subreq, req)) {
8425 tevent_req_set_callback(subreq, swallow_notify_done, req);
8428 static bool print_notifies(uint32_t action, const char *name, void *priv)
8430 if (DEBUGLEVEL > 5) {
8431 d_printf("%d %s\n", (int)action, name);
8436 static void notify_bench_done(struct tevent_req *req)
8438 int *num_finished = (int *)tevent_req_callback_data_void(req);
8442 static bool run_notify_bench(int dummy)
8444 const char *dname = "\\notify-bench";
8445 struct tevent_context *ev;
8448 struct tevent_req *req1;
8449 struct tevent_req *req2 = NULL;
8450 int i, num_unc_names;
8451 int num_finished = 0;
8453 printf("starting notify-bench test\n");
8455 if (use_multishare_conn) {
8457 unc_list = file_lines_load(multishare_conn_fname,
8458 &num_unc_names, 0, NULL);
8459 if (!unc_list || num_unc_names <= 0) {
8460 d_printf("Failed to load unc names list from '%s'\n",
8461 multishare_conn_fname);
8464 TALLOC_FREE(unc_list);
8469 ev = samba_tevent_context_init(talloc_tos());
8471 d_printf("tevent_context_init failed\n");
8475 for (i=0; i<num_unc_names; i++) {
8476 struct cli_state *cli;
8479 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8481 if (base_fname == NULL) {
8485 if (!torture_open_connection(&cli, i)) {
8489 status = cli_ntcreate(cli, dname, 0,
8490 MAXIMUM_ALLOWED_ACCESS,
8491 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8493 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8496 if (!NT_STATUS_IS_OK(status)) {
8497 d_printf("Could not create %s: %s\n", dname,
8502 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8503 FILE_NOTIFY_CHANGE_FILE_NAME |
8504 FILE_NOTIFY_CHANGE_DIR_NAME |
8505 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8506 FILE_NOTIFY_CHANGE_LAST_WRITE,
8507 false, print_notifies, NULL);
8509 d_printf("Could not create notify request\n");
8513 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8514 base_fname, 10, torture_numops);
8516 d_printf("Could not create createdels request\n");
8519 TALLOC_FREE(base_fname);
8521 tevent_req_set_callback(req2, notify_bench_done,
8525 while (num_finished < num_unc_names) {
8527 ret = tevent_loop_once(ev);
8529 d_printf("tevent_loop_once failed\n");
8534 if (!tevent_req_poll(req2, ev)) {
8535 d_printf("tevent_req_poll failed\n");
8538 status = torture_createdels_recv(req2);
8539 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8544 static bool run_mangle1(int dummy)
8546 struct cli_state *cli;
8547 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8551 time_t change_time, access_time, write_time;
8555 printf("starting mangle1 test\n");
8556 if (!torture_open_connection(&cli, 0)) {
8560 smbXcli_conn_set_sockopt(cli->conn, sockops);
8562 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8563 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8565 if (!NT_STATUS_IS_OK(status)) {
8566 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8569 cli_close(cli, fnum);
8571 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8572 if (!NT_STATUS_IS_OK(status)) {
8573 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8577 d_printf("alt_name: %s\n", alt_name);
8579 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8580 if (!NT_STATUS_IS_OK(status)) {
8581 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8585 cli_close(cli, fnum);
8587 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8588 &write_time, &size, &mode);
8589 if (!NT_STATUS_IS_OK(status)) {
8590 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8598 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8599 struct file_info *f,
8603 if (f->short_name == NULL) {
8604 return NT_STATUS_OK;
8607 if (strlen(f->short_name) == 0) {
8608 return NT_STATUS_OK;
8611 printf("unexpected shortname: %s\n", f->short_name);
8613 return NT_STATUS_OBJECT_NAME_INVALID;
8616 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8617 struct file_info *f,
8623 printf("name: %s\n", f->name);
8624 fstrcpy(name, f->name);
8625 return NT_STATUS_OK;
8628 static bool run_mangle_illegal(int dummy)
8630 struct cli_state *cli = NULL;
8631 struct cli_state *cli_posix = NULL;
8632 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8633 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8634 char *mangled_path = NULL;
8640 printf("starting mangle-illegal test\n");
8642 if (!torture_open_connection(&cli, 0)) {
8646 smbXcli_conn_set_sockopt(cli->conn, sockops);
8648 if (!torture_open_connection(&cli_posix, 0)) {
8652 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8654 status = torture_setup_unix_extensions(cli_posix);
8655 if (!NT_STATUS_IS_OK(status)) {
8659 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8660 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8661 if (!NT_STATUS_IS_OK(status)) {
8662 printf("mkdir1 failed : %s\n", nt_errstr(status));
8667 * Create a file with illegal NTFS characters and test that we
8668 * get a usable mangled name
8671 cli_setatr(cli_posix, illegal_fname, 0, 0);
8672 cli_posix_unlink(cli_posix, illegal_fname);
8674 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8676 if (!NT_STATUS_IS_OK(status)) {
8677 printf("POSIX create of %s failed (%s)\n",
8678 illegal_fname, nt_errstr(status));
8682 status = cli_close(cli_posix, fnum);
8683 if (!NT_STATUS_IS_OK(status)) {
8684 printf("close failed (%s)\n", nt_errstr(status));
8688 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8689 if (!NT_STATUS_IS_OK(status)) {
8690 d_printf("cli_list failed: %s\n", nt_errstr(status));
8694 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8695 if (mangled_path == NULL) {
8699 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8700 if (!NT_STATUS_IS_OK(status)) {
8701 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8702 TALLOC_FREE(mangled_path);
8705 TALLOC_FREE(mangled_path);
8706 cli_close(cli, fnum);
8708 cli_setatr(cli_posix, illegal_fname, 0, 0);
8709 cli_posix_unlink(cli_posix, illegal_fname);
8712 * Create a file with a long name and check that we got *no* short name.
8715 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8716 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8718 if (!NT_STATUS_IS_OK(status)) {
8719 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8722 cli_close(cli, fnum);
8724 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8725 if (!NT_STATUS_IS_OK(status)) {
8726 d_printf("cli_list failed\n");
8730 cli_unlink(cli, fname, 0);
8731 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8733 if (!torture_close_connection(cli_posix)) {
8737 if (!torture_close_connection(cli)) {
8744 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8746 size_t *to_pull = (size_t *)priv;
8747 size_t thistime = *to_pull;
8749 thistime = MIN(thistime, n);
8750 if (thistime == 0) {
8754 memset(buf, 0, thistime);
8755 *to_pull -= thistime;
8759 static bool run_windows_write(int dummy)
8761 struct cli_state *cli1;
8765 const char *fname = "\\writetest.txt";
8766 struct timeval start_time;
8771 printf("starting windows_write test\n");
8772 if (!torture_open_connection(&cli1, 0)) {
8776 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8777 if (!NT_STATUS_IS_OK(status)) {
8778 printf("open failed (%s)\n", nt_errstr(status));
8782 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8784 start_time = timeval_current();
8786 for (i=0; i<torture_numops; i++) {
8788 off_t start = i * torture_blocksize;
8789 size_t to_pull = torture_blocksize - 1;
8791 status = cli_writeall(cli1, fnum, 0, &c,
8792 start + torture_blocksize - 1, 1, NULL);
8793 if (!NT_STATUS_IS_OK(status)) {
8794 printf("cli_write failed: %s\n", nt_errstr(status));
8798 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8799 null_source, &to_pull);
8800 if (!NT_STATUS_IS_OK(status)) {
8801 printf("cli_push returned: %s\n", nt_errstr(status));
8806 seconds = timeval_elapsed(&start_time);
8807 kbytes = (double)torture_blocksize * torture_numops;
8810 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8811 (double)seconds, (int)(kbytes/seconds));
8815 cli_close(cli1, fnum);
8816 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8817 torture_close_connection(cli1);
8821 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8823 size_t max_pdu = 0x1FFFF;
8825 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8829 if (smb1cli_conn_signing_is_active(cli->conn)) {
8833 if (smb1cli_conn_encryption_on(cli->conn)) {
8834 max_pdu = CLI_BUFFER_SIZE;
8837 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8838 len_requested &= 0xFFFF;
8841 return MIN(len_requested,
8842 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8845 static bool check_read_call(struct cli_state *cli,
8848 size_t len_requested)
8851 struct tevent_req *subreq = NULL;
8852 ssize_t len_read = 0;
8853 size_t len_expected = 0;
8854 struct tevent_context *ev = NULL;
8856 ev = samba_tevent_context_init(talloc_tos());
8861 subreq = cli_read_andx_send(talloc_tos(),
8868 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8872 status = cli_read_andx_recv(subreq, &len_read, &buf);
8873 if (!NT_STATUS_IS_OK(status)) {
8874 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8878 TALLOC_FREE(subreq);
8881 len_expected = calc_expected_return(cli, len_requested);
8883 if (len_expected > 0x10000 && len_read == 0x10000) {
8884 /* Windows servers only return a max of 0x10000,
8885 doesn't matter if you set CAP_LARGE_READX in
8886 the client sessionsetupX call or not. */
8887 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8888 (unsigned int)len_requested);
8889 } else if (len_read != len_expected) {
8890 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8891 (unsigned int)len_requested,
8892 (unsigned int)len_read,
8893 (unsigned int)len_expected);
8896 d_printf("Correct read reply.\n");
8902 /* Test large readX variants. */
8903 static bool large_readx_tests(struct cli_state *cli,
8907 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8908 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8911 /* A read of 0x10000 should return 0x10000 bytes. */
8912 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8915 /* A read of 0x10000 should return 0x10001 bytes. */
8916 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8919 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8920 the requested number of bytes. */
8921 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8924 /* A read of 1MB should return 1MB bytes (on Samba). */
8925 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
8929 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
8932 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
8935 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
8941 static bool run_large_readx(int dummy)
8943 uint8_t *buf = NULL;
8944 struct cli_state *cli1 = NULL;
8945 struct cli_state *cli2 = NULL;
8946 bool correct = false;
8947 const char *fname = "\\large_readx.dat";
8949 uint16_t fnum1 = UINT16_MAX;
8950 uint32_t normal_caps = 0;
8951 size_t file_size = 20*1024*1024;
8952 TALLOC_CTX *frame = talloc_stackframe();
8956 enum smb_signing_setting signing_setting;
8957 enum protocol_types protocol;
8961 .signing_setting = SMB_SIGNING_IF_REQUIRED,
8962 .protocol = PROTOCOL_NT1,
8964 .name = "NT1 - SIGNING_REQUIRED",
8965 .signing_setting = SMB_SIGNING_REQUIRED,
8966 .protocol = PROTOCOL_NT1,
8970 printf("starting large_readx test\n");
8972 if (!torture_open_connection(&cli1, 0)) {
8976 normal_caps = smb1cli_conn_capabilities(cli1->conn);
8978 if (!(normal_caps & CAP_LARGE_READX)) {
8979 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8980 (unsigned int)normal_caps);
8984 /* Create a file of size 4MB. */
8985 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
8986 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8987 0, 0, &fnum1, NULL);
8989 if (!NT_STATUS_IS_OK(status)) {
8990 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8994 /* Write file_size bytes. */
8995 buf = talloc_zero_array(frame, uint8_t, file_size);
9000 status = cli_writeall(cli1,
9007 if (!NT_STATUS_IS_OK(status)) {
9008 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9012 status = cli_close(cli1, fnum1);
9013 if (!NT_STATUS_IS_OK(status)) {
9014 d_printf("cli_close failed: %s\n", nt_errstr(status));
9020 for (i=0; i < ARRAY_SIZE(runs); i++) {
9021 enum smb_signing_setting saved_signing_setting = signing_state;
9022 uint16_t fnum2 = -1;
9025 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
9027 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
9031 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
9033 signing_state = runs[i].signing_setting;
9034 cli2 = open_nbt_connection();
9035 signing_state = saved_signing_setting;
9040 status = smbXcli_negprot(cli2->conn,
9044 if (!NT_STATUS_IS_OK(status)) {
9048 status = cli_session_setup_creds(cli2, torture_creds);
9049 if (!NT_STATUS_IS_OK(status)) {
9053 status = cli_tree_connect(cli2,
9057 if (!NT_STATUS_IS_OK(status)) {
9061 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
9063 normal_caps = smb1cli_conn_capabilities(cli2->conn);
9065 if (!(normal_caps & CAP_LARGE_READX)) {
9066 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9067 (unsigned int)normal_caps);
9072 if (force_cli_encryption(cli2, share) == false) {
9075 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
9076 uint16_t major, minor;
9077 uint32_t caplow, caphigh;
9079 status = cli_unix_extensions_version(cli2,
9082 if (!NT_STATUS_IS_OK(status)) {
9087 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
9088 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
9089 0, 0, &fnum2, NULL);
9090 if (!NT_STATUS_IS_OK(status)) {
9091 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
9095 /* All reads must return less than file_size bytes. */
9096 if (!large_readx_tests(cli2, fnum2, buf)) {
9100 status = cli_close(cli2, fnum2);
9101 if (!NT_STATUS_IS_OK(status)) {
9102 d_printf("cli_close failed: %s\n", nt_errstr(status));
9107 if (!torture_close_connection(cli2)) {
9114 printf("Success on large_readx test\n");
9119 if (!torture_close_connection(cli2)) {
9125 if (fnum1 != UINT16_MAX) {
9126 status = cli_close(cli1, fnum1);
9127 if (!NT_STATUS_IS_OK(status)) {
9128 d_printf("cli_close failed: %s\n", nt_errstr(status));
9133 status = cli_unlink(cli1, fname,
9134 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9135 if (!NT_STATUS_IS_OK(status)) {
9136 printf("unlink failed (%s)\n", nt_errstr(status));
9139 if (!torture_close_connection(cli1)) {
9146 printf("finished large_readx test\n");
9150 static bool run_cli_echo(int dummy)
9152 struct cli_state *cli;
9155 printf("starting cli_echo test\n");
9156 if (!torture_open_connection(&cli, 0)) {
9159 smbXcli_conn_set_sockopt(cli->conn, sockops);
9161 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9163 d_printf("cli_echo returned %s\n", nt_errstr(status));
9165 torture_close_connection(cli);
9166 return NT_STATUS_IS_OK(status);
9169 static bool run_uid_regression_test(int dummy)
9171 static struct cli_state *cli;
9174 bool correct = True;
9175 struct smbXcli_tcon *orig_tcon = NULL;
9178 printf("starting uid regression test\n");
9180 if (!torture_open_connection(&cli, 0)) {
9184 smbXcli_conn_set_sockopt(cli->conn, sockops);
9186 /* Ok - now save then logoff our current user. */
9187 old_vuid = cli_state_get_uid(cli);
9189 status = cli_ulogoff(cli);
9190 if (!NT_STATUS_IS_OK(status)) {
9191 d_printf("(%s) cli_ulogoff failed: %s\n",
9192 __location__, nt_errstr(status));
9197 cli_state_set_uid(cli, old_vuid);
9199 /* Try an operation. */
9200 status = cli_mkdir(cli, "\\uid_reg_test");
9201 if (NT_STATUS_IS_OK(status)) {
9202 d_printf("(%s) cli_mkdir succeeded\n",
9207 /* Should be bad uid. */
9208 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9209 NT_STATUS_USER_SESSION_DELETED)) {
9215 old_cnum = cli_state_get_tid(cli);
9216 orig_tcon = cli_state_save_tcon(cli);
9217 if (orig_tcon == NULL) {
9222 /* Now try a SMBtdis with the invald vuid set to zero. */
9223 cli_state_set_uid(cli, 0);
9225 /* This should succeed. */
9226 status = cli_tdis(cli);
9228 if (NT_STATUS_IS_OK(status)) {
9229 d_printf("First tdis with invalid vuid should succeed.\n");
9231 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9233 cli_state_restore_tcon(cli, orig_tcon);
9237 cli_state_restore_tcon(cli, orig_tcon);
9238 cli_state_set_uid(cli, old_vuid);
9239 cli_state_set_tid(cli, old_cnum);
9241 /* This should fail. */
9242 status = cli_tdis(cli);
9243 if (NT_STATUS_IS_OK(status)) {
9244 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9248 /* Should be bad tid. */
9249 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9250 NT_STATUS_NETWORK_NAME_DELETED)) {
9256 cli_rmdir(cli, "\\uid_reg_test");
9265 static const char *illegal_chars = "*\\/?<>|\":";
9266 static char force_shortname_chars[] = " +,.[];=\177";
9268 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9269 const char *mask, void *state)
9271 struct cli_state *pcli = (struct cli_state *)state;
9273 NTSTATUS status = NT_STATUS_OK;
9275 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9277 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9278 return NT_STATUS_OK;
9280 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9281 status = cli_rmdir(pcli, fname);
9282 if (!NT_STATUS_IS_OK(status)) {
9283 printf("del_fn: failed to rmdir %s\n,", fname );
9286 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9287 if (!NT_STATUS_IS_OK(status)) {
9288 printf("del_fn: failed to unlink %s\n,", fname );
9300 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9301 const char *name, void *state)
9303 struct sn_state *s = (struct sn_state *)state;
9307 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9308 i, finfo->name, finfo->short_name);
9311 if (strchr(force_shortname_chars, i)) {
9312 if (!finfo->short_name) {
9313 /* Shortname not created when it should be. */
9314 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9315 __location__, finfo->name, i);
9318 } else if (finfo->short_name){
9319 /* Shortname created when it should not be. */
9320 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9321 __location__, finfo->short_name, finfo->name);
9325 return NT_STATUS_OK;
9328 static bool run_shortname_test(int dummy)
9330 static struct cli_state *cli;
9331 bool correct = True;
9337 printf("starting shortname test\n");
9339 if (!torture_open_connection(&cli, 0)) {
9343 smbXcli_conn_set_sockopt(cli->conn, sockops);
9345 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9346 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9347 cli_rmdir(cli, "\\shortname");
9349 status = cli_mkdir(cli, "\\shortname");
9350 if (!NT_STATUS_IS_OK(status)) {
9351 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9352 __location__, nt_errstr(status));
9357 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9361 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9368 for (i = 32; i < 128; i++) {
9369 uint16_t fnum = (uint16_t)-1;
9373 if (strchr(illegal_chars, i)) {
9378 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9379 FILE_SHARE_READ|FILE_SHARE_WRITE,
9380 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9381 if (!NT_STATUS_IS_OK(status)) {
9382 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9383 __location__, fname, nt_errstr(status));
9387 cli_close(cli, fnum);
9390 status = cli_list(cli, "\\shortname\\test*.*", 0,
9391 shortname_list_fn, &s);
9392 if (s.matched != 1) {
9393 d_printf("(%s) failed to list %s: %s\n",
9394 __location__, fname, nt_errstr(status));
9399 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9400 if (!NT_STATUS_IS_OK(status)) {
9401 d_printf("(%s) failed to delete %s: %s\n",
9402 __location__, fname, nt_errstr(status));
9415 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9416 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9417 cli_rmdir(cli, "\\shortname");
9418 torture_close_connection(cli);
9422 static void pagedsearch_cb(struct tevent_req *req)
9425 struct tldap_message *msg;
9428 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9429 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9430 d_printf("tldap_search_paged_recv failed: %s\n",
9431 tldap_rc2string(rc));
9434 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9438 if (!tldap_entry_dn(msg, &dn)) {
9439 d_printf("tldap_entry_dn failed\n");
9442 d_printf("%s\n", dn);
9446 static bool run_tldap(int dummy)
9448 struct tldap_context *ld;
9452 struct sockaddr_storage addr;
9453 struct tevent_context *ev;
9454 struct tevent_req *req;
9458 if (!resolve_name(host, &addr, 0, false)) {
9459 d_printf("could not find host %s\n", host);
9462 status = open_socket_out(&addr, 389, 9999, &fd);
9463 if (!NT_STATUS_IS_OK(status)) {
9464 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9468 ld = tldap_context_create(talloc_tos(), fd);
9471 d_printf("tldap_context_create failed\n");
9475 rc = tldap_fetch_rootdse(ld);
9476 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9477 d_printf("tldap_fetch_rootdse failed: %s\n",
9478 tldap_errstr(talloc_tos(), ld, rc));
9482 basedn = tldap_talloc_single_attribute(
9483 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9484 if (basedn == NULL) {
9485 d_printf("no defaultNamingContext\n");
9488 d_printf("defaultNamingContext: %s\n", basedn);
9490 ev = samba_tevent_context_init(talloc_tos());
9492 d_printf("tevent_context_init failed\n");
9496 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9497 TLDAP_SCOPE_SUB, "(objectclass=*)",
9499 NULL, 0, NULL, 0, 0, 0, 0, 5);
9501 d_printf("tldap_search_paged_send failed\n");
9504 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9506 tevent_req_poll(req, ev);
9510 /* test search filters against rootDSE */
9511 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9512 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9514 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9515 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9516 talloc_tos(), NULL);
9517 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9518 d_printf("tldap_search with complex filter failed: %s\n",
9519 tldap_errstr(talloc_tos(), ld, rc));
9527 /* Torture test to ensure no regression of :
9528 https://bugzilla.samba.org/show_bug.cgi?id=7084
9531 static bool run_dir_createtime(int dummy)
9533 struct cli_state *cli;
9534 const char *dname = "\\testdir";
9535 const char *fname = "\\testdir\\testfile";
9537 struct timespec create_time;
9538 struct timespec create_time1;
9542 if (!torture_open_connection(&cli, 0)) {
9546 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9547 cli_rmdir(cli, dname);
9549 status = cli_mkdir(cli, dname);
9550 if (!NT_STATUS_IS_OK(status)) {
9551 printf("mkdir failed: %s\n", nt_errstr(status));
9555 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9557 if (!NT_STATUS_IS_OK(status)) {
9558 printf("cli_qpathinfo2 returned %s\n",
9563 /* Sleep 3 seconds, then create a file. */
9566 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9568 if (!NT_STATUS_IS_OK(status)) {
9569 printf("cli_openx failed: %s\n", nt_errstr(status));
9573 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9575 if (!NT_STATUS_IS_OK(status)) {
9576 printf("cli_qpathinfo2 (2) returned %s\n",
9581 if (timespec_compare(&create_time1, &create_time)) {
9582 printf("run_dir_createtime: create time was updated (error)\n");
9584 printf("run_dir_createtime: create time was not updated (correct)\n");
9590 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9591 cli_rmdir(cli, dname);
9592 if (!torture_close_connection(cli)) {
9599 static bool run_streamerror(int dummy)
9601 struct cli_state *cli;
9602 const char *dname = "\\testdir";
9603 const char *streamname =
9604 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9606 time_t change_time, access_time, write_time;
9608 uint16_t mode, fnum;
9611 if (!torture_open_connection(&cli, 0)) {
9615 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9616 cli_rmdir(cli, dname);
9618 status = cli_mkdir(cli, dname);
9619 if (!NT_STATUS_IS_OK(status)) {
9620 printf("mkdir failed: %s\n", nt_errstr(status));
9624 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9625 &write_time, &size, &mode);
9626 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9627 printf("pathinfo returned %s, expected "
9628 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9633 status = cli_ntcreate(cli, streamname, 0x16,
9634 FILE_READ_DATA|FILE_READ_EA|
9635 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9636 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9637 FILE_OPEN, 0, 0, &fnum, NULL);
9639 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9640 printf("ntcreate returned %s, expected "
9641 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9647 cli_rmdir(cli, dname);
9651 struct pidtest_state {
9657 static void pid_echo_done(struct tevent_req *subreq);
9659 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9660 struct tevent_context *ev,
9661 struct cli_state *cli)
9663 struct tevent_req *req, *subreq;
9664 struct pidtest_state *state;
9666 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9671 SSVAL(state->vwv, 0, 1);
9672 state->data = data_blob_const("hello", 5);
9674 subreq = smb1cli_req_send(state,
9679 0, 0, /* *_flags2 */
9681 0xDEADBEEF, /* pid */
9684 ARRAY_SIZE(state->vwv), state->vwv,
9685 state->data.length, state->data.data);
9687 if (tevent_req_nomem(subreq, req)) {
9688 return tevent_req_post(req, ev);
9690 tevent_req_set_callback(subreq, pid_echo_done, req);
9694 static void pid_echo_done(struct tevent_req *subreq)
9696 struct tevent_req *req = tevent_req_callback_data(
9697 subreq, struct tevent_req);
9698 struct pidtest_state *state = tevent_req_data(
9699 req, struct pidtest_state);
9702 uint8_t *bytes = NULL;
9703 struct iovec *recv_iov = NULL;
9704 uint8_t *phdr = NULL;
9705 uint16_t pidlow = 0;
9706 uint16_t pidhigh = 0;
9707 struct smb1cli_req_expected_response expected[] = {
9709 .status = NT_STATUS_OK,
9714 status = smb1cli_req_recv(subreq, state,
9719 NULL, /* pvwv_offset */
9722 NULL, /* pbytes_offset */
9724 expected, ARRAY_SIZE(expected));
9726 TALLOC_FREE(subreq);
9728 if (!NT_STATUS_IS_OK(status)) {
9729 tevent_req_nterror(req, status);
9733 if (num_bytes != state->data.length) {
9734 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9738 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9739 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9743 /* Check pid low/high == DEADBEEF */
9744 pidlow = SVAL(phdr, HDR_PID);
9745 if (pidlow != 0xBEEF){
9746 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9747 (unsigned int)pidlow);
9748 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9751 pidhigh = SVAL(phdr, HDR_PIDHIGH);
9752 if (pidhigh != 0xDEAD){
9753 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9754 (unsigned int)pidhigh);
9755 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9759 tevent_req_done(req);
9762 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9764 return tevent_req_simple_recv_ntstatus(req);
9767 static bool run_pidhigh(int dummy)
9769 bool success = false;
9770 struct cli_state *cli = NULL;
9772 struct tevent_context *ev = NULL;
9773 struct tevent_req *req = NULL;
9774 TALLOC_CTX *frame = talloc_stackframe();
9776 printf("starting pid high test\n");
9777 if (!torture_open_connection(&cli, 0)) {
9780 smbXcli_conn_set_sockopt(cli->conn, sockops);
9782 ev = samba_tevent_context_init(frame);
9787 req = pid_echo_send(frame, ev, cli);
9792 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
9796 status = pid_echo_recv(req);
9797 if (NT_STATUS_IS_OK(status)) {
9798 printf("pid high test ok\n");
9805 torture_close_connection(cli);
9810 Test Windows open on a bad POSIX symlink.
9812 static bool run_symlink_open_test(int dummy)
9814 static struct cli_state *cli;
9815 const char *fname = "non_existant_file";
9816 const char *sname = "dangling_symlink";
9817 uint16_t fnum = (uint16_t)-1;
9818 bool correct = false;
9820 TALLOC_CTX *frame = NULL;
9822 frame = talloc_stackframe();
9824 printf("Starting Windows bad symlink open test\n");
9826 if (!torture_open_connection(&cli, 0)) {
9831 smbXcli_conn_set_sockopt(cli->conn, sockops);
9833 status = torture_setup_unix_extensions(cli);
9834 if (!NT_STATUS_IS_OK(status)) {
9839 /* Ensure nothing exists. */
9840 cli_setatr(cli, fname, 0, 0);
9841 cli_posix_unlink(cli, fname);
9842 cli_setatr(cli, sname, 0, 0);
9843 cli_posix_unlink(cli, sname);
9845 /* Create a symlink pointing nowhere. */
9846 status = cli_posix_symlink(cli, fname, sname);
9847 if (!NT_STATUS_IS_OK(status)) {
9848 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
9855 /* Now ensure that a Windows open doesn't hang. */
9856 status = cli_ntcreate(cli,
9859 FILE_READ_DATA|FILE_WRITE_DATA,
9861 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
9869 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
9870 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
9871 * we use O_NOFOLLOW on the server or not.
9873 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
9874 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
9878 printf("cli_ntcreate of %s returned %s - should return"
9879 " either (%s) or (%s)\n",
9882 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
9883 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
9891 if (fnum != (uint16_t)-1) {
9892 cli_close(cli, fnum);
9893 fnum = (uint16_t)-1;
9896 cli_setatr(cli, sname, 0, 0);
9897 cli_posix_unlink(cli, sname);
9898 cli_setatr(cli, fname, 0, 0);
9899 cli_posix_unlink(cli, fname);
9901 if (!torture_close_connection(cli)) {
9909 static bool run_local_substitute(int dummy)
9913 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
9914 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
9915 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
9916 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
9917 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
9918 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
9919 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
9920 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
9922 /* Different captialization rules in sub_basic... */
9924 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
9930 static bool run_local_base64(int dummy)
9935 for (i=1; i<2000; i++) {
9936 DATA_BLOB blob1, blob2;
9939 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
9941 generate_random_buffer(blob1.data, blob1.length);
9943 b64 = base64_encode_data_blob(talloc_tos(), blob1);
9945 d_fprintf(stderr, "base64_encode_data_blob failed "
9946 "for %d bytes\n", i);
9949 blob2 = base64_decode_data_blob(b64);
9952 if (data_blob_cmp(&blob1, &blob2)) {
9953 d_fprintf(stderr, "data_blob_cmp failed for %d "
9957 TALLOC_FREE(blob1.data);
9958 data_blob_free(&blob2);
9963 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
9968 static bool run_local_gencache(int dummy)
9974 struct memcache *mem;
9977 mem = memcache_init(NULL, 0);
9979 d_printf("%s: memcache_init failed\n", __location__);
9982 memcache_set_global(mem);
9984 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
9985 d_printf("%s: gencache_set() failed\n", __location__);
9989 if (!gencache_get("foo", NULL, NULL, NULL)) {
9990 d_printf("%s: gencache_get() failed\n", __location__);
9994 for (i=0; i<1000000; i++) {
9995 gencache_parse("foo", parse_fn, NULL);
9998 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9999 d_printf("%s: gencache_get() failed\n", __location__);
10004 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10005 d_printf("%s: gencache_get() failed\n", __location__);
10009 if (strcmp(val, "bar") != 0) {
10010 d_printf("%s: gencache_get() returned %s, expected %s\n",
10011 __location__, val, "bar");
10018 if (!gencache_del("foo")) {
10019 d_printf("%s: gencache_del() failed\n", __location__);
10022 if (gencache_del("foo")) {
10023 d_printf("%s: second gencache_del() succeeded\n",
10028 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
10029 d_printf("%s: gencache_get() on deleted entry "
10030 "succeeded\n", __location__);
10034 blob = data_blob_string_const_null("bar");
10035 tm = time(NULL) + 60;
10037 if (!gencache_set_data_blob("foo", &blob, tm)) {
10038 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
10042 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10043 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
10047 if (strcmp((const char *)blob.data, "bar") != 0) {
10048 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10049 __location__, (const char *)blob.data, "bar");
10050 data_blob_free(&blob);
10054 data_blob_free(&blob);
10056 if (!gencache_del("foo")) {
10057 d_printf("%s: gencache_del() failed\n", __location__);
10060 if (gencache_del("foo")) {
10061 d_printf("%s: second gencache_del() succeeded\n",
10066 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10067 d_printf("%s: gencache_get_data_blob() on deleted entry "
10068 "succeeded\n", __location__);
10073 blob.data = (uint8_t *)&v;
10074 blob.length = sizeof(v);
10076 if (!gencache_set_data_blob("blob", &blob, tm)) {
10077 d_printf("%s: gencache_set_data_blob() failed\n",
10081 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
10082 d_printf("%s: gencache_get succeeded\n", __location__);
10089 static bool rbt_testval(struct db_context *db, const char *key,
10092 struct db_record *rec;
10093 TDB_DATA data = string_tdb_data(value);
10098 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10100 d_fprintf(stderr, "fetch_locked failed\n");
10103 status = dbwrap_record_store(rec, data, 0);
10104 if (!NT_STATUS_IS_OK(status)) {
10105 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
10110 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10112 d_fprintf(stderr, "second fetch_locked failed\n");
10116 dbvalue = dbwrap_record_get_value(rec);
10117 if ((dbvalue.dsize != data.dsize)
10118 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
10119 d_fprintf(stderr, "Got wrong data back\n");
10129 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
10131 int *count2 = (int *)private_data;
10136 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
10138 int *count2 = (int *)private_data;
10140 dbwrap_record_delete(rec);
10144 static bool run_local_rbtree(int dummy)
10146 struct db_context *db;
10153 db = db_open_rbt(NULL);
10156 d_fprintf(stderr, "db_open_rbt failed\n");
10160 for (i=0; i<1000; i++) {
10163 if (asprintf(&key, "key%ld", random()) == -1) {
10166 if (asprintf(&value, "value%ld", random()) == -1) {
10171 if (!rbt_testval(db, key, value)) {
10178 if (asprintf(&value, "value%ld", random()) == -1) {
10183 if (!rbt_testval(db, key, value)) {
10194 count = 0; count2 = 0;
10195 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10197 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10198 if ((count != count2) || (count != 1000)) {
10201 count = 0; count2 = 0;
10202 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10204 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10205 if ((count != count2) || (count != 1000)) {
10208 count = 0; count2 = 0;
10209 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10211 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10212 if ((count != count2) || (count != 0)) {
10223 local test for character set functions
10225 This is a very simple test for the functionality in convert_string_error()
10227 static bool run_local_convert_string(int dummy)
10229 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10230 const char *test_strings[2] = { "March", "M\303\244rz" };
10234 for (i=0; i<2; i++) {
10235 const char *str = test_strings[i];
10236 int len = strlen(str);
10237 size_t converted_size;
10240 memset(dst, 'X', sizeof(dst));
10242 /* first try with real source length */
10243 ret = convert_string_error(CH_UNIX, CH_UTF8,
10248 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10252 if (converted_size != len) {
10253 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10254 str, len, (int)converted_size);
10258 if (strncmp(str, dst, converted_size) != 0) {
10259 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10263 if (strlen(str) != converted_size) {
10264 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10265 (int)strlen(str), (int)converted_size);
10269 if (dst[converted_size] != 'X') {
10270 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10274 /* now with srclen==-1, this causes the nul to be
10276 ret = convert_string_error(CH_UNIX, CH_UTF8,
10281 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10285 if (converted_size != len+1) {
10286 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10287 str, len, (int)converted_size);
10291 if (strncmp(str, dst, converted_size) != 0) {
10292 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10296 if (len+1 != converted_size) {
10297 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10298 len+1, (int)converted_size);
10302 if (dst[converted_size] != 'X') {
10303 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10310 TALLOC_FREE(tmp_ctx);
10313 TALLOC_FREE(tmp_ctx);
10318 struct talloc_dict_test {
10322 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
10324 int *count = (int *)priv;
10329 static bool run_local_talloc_dict(int dummy)
10331 struct talloc_dict *dict;
10332 struct talloc_dict_test *t;
10333 int key, count, res;
10336 dict = talloc_dict_init(talloc_tos());
10337 if (dict == NULL) {
10341 t = talloc(talloc_tos(), struct talloc_dict_test);
10348 ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
10354 res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
10363 if (count != res) {
10372 static bool run_local_string_to_sid(int dummy) {
10373 struct dom_sid sid;
10375 if (string_to_sid(&sid, "S--1-5-32-545")) {
10376 printf("allowing S--1-5-32-545\n");
10379 if (string_to_sid(&sid, "S-1-5-32-+545")) {
10380 printf("allowing S-1-5-32-+545\n");
10383 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")) {
10384 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10387 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10388 printf("allowing S-1-5-32-545-abc\n");
10391 if (string_to_sid(&sid, "S-300-5-32-545")) {
10392 printf("allowing S-300-5-32-545\n");
10395 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10396 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10399 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10400 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10403 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10404 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10407 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10408 printf("could not parse S-1-5-32-545\n");
10411 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10412 printf("mis-parsed S-1-5-32-545 as %s\n",
10413 sid_string_tos(&sid));
10419 static bool sid_to_string_test(const char *expected) {
10422 struct dom_sid sid;
10424 if (!string_to_sid(&sid, expected)) {
10425 printf("could not parse %s\n", expected);
10429 str = dom_sid_string(NULL, &sid);
10430 if (strcmp(str, expected)) {
10431 printf("Comparison failed (%s != %s)\n", str, expected);
10438 static bool run_local_sid_to_string(int dummy) {
10439 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10441 if (!sid_to_string_test("S-1-545"))
10443 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10448 static bool run_local_binary_to_sid(int dummy) {
10449 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10450 static const uint8_t good_binary_sid[] = {
10451 0x1, /* revision number */
10452 15, /* num auths */
10453 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10454 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10455 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10456 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10457 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10458 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10459 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10460 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10461 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10462 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10463 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10464 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10465 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10466 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10467 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10468 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10471 static const uint8_t long_binary_sid[] = {
10472 0x1, /* revision number */
10473 15, /* num auths */
10474 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10475 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10476 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10477 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10478 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10479 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10480 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10481 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10482 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10483 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10484 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10485 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10486 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10487 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10488 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10489 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10490 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10491 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10492 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10495 static const uint8_t long_binary_sid2[] = {
10496 0x1, /* revision number */
10497 32, /* num auths */
10498 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10499 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10500 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10501 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10502 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10503 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10504 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10505 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10506 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10507 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10508 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10509 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10510 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10511 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10512 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10513 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10514 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10515 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10516 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10517 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10518 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10519 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10520 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10521 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10522 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10523 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10524 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10525 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10526 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10527 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10528 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10529 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10530 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10533 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10536 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10539 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10545 /* Split a path name into filename and stream name components. Canonicalise
10546 * such that an implicit $DATA token is always explicit.
10548 * The "specification" of this function can be found in the
10549 * run_local_stream_name() function in torture.c, I've tried those
10550 * combinations against a W2k3 server.
10553 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10554 char **pbase, char **pstream)
10557 char *stream = NULL;
10558 char *sname; /* stream name */
10559 const char *stype; /* stream type */
10561 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10563 sname = strchr_m(fname, ':');
10565 if (sname == NULL) {
10566 if (pbase != NULL) {
10567 base = talloc_strdup(mem_ctx, fname);
10568 NT_STATUS_HAVE_NO_MEMORY(base);
10573 if (pbase != NULL) {
10574 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10575 NT_STATUS_HAVE_NO_MEMORY(base);
10580 stype = strchr_m(sname, ':');
10582 if (stype == NULL) {
10583 sname = talloc_strdup(mem_ctx, sname);
10587 if (strcasecmp_m(stype, ":$DATA") != 0) {
10589 * If there is an explicit stream type, so far we only
10590 * allow $DATA. Is there anything else allowed? -- vl
10592 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10594 return NT_STATUS_OBJECT_NAME_INVALID;
10596 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10600 if (sname == NULL) {
10602 return NT_STATUS_NO_MEMORY;
10605 if (sname[0] == '\0') {
10607 * no stream name, so no stream
10612 if (pstream != NULL) {
10613 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10614 if (stream == NULL) {
10615 TALLOC_FREE(sname);
10617 return NT_STATUS_NO_MEMORY;
10620 * upper-case the type field
10622 (void)strupper_m(strchr_m(stream, ':')+1);
10626 if (pbase != NULL) {
10629 if (pstream != NULL) {
10632 return NT_STATUS_OK;
10635 static bool test_stream_name(const char *fname, const char *expected_base,
10636 const char *expected_stream,
10637 NTSTATUS expected_status)
10641 char *stream = NULL;
10643 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10644 if (!NT_STATUS_EQUAL(status, expected_status)) {
10648 if (!NT_STATUS_IS_OK(status)) {
10652 if (base == NULL) goto error;
10654 if (strcmp(expected_base, base) != 0) goto error;
10656 if ((expected_stream != NULL) && (stream == NULL)) goto error;
10657 if ((expected_stream == NULL) && (stream != NULL)) goto error;
10659 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10663 TALLOC_FREE(stream);
10667 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10668 fname, expected_base ? expected_base : "<NULL>",
10669 expected_stream ? expected_stream : "<NULL>",
10670 nt_errstr(expected_status));
10671 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10672 base ? base : "<NULL>", stream ? stream : "<NULL>",
10673 nt_errstr(status));
10675 TALLOC_FREE(stream);
10679 static bool run_local_stream_name(int dummy)
10683 ret &= test_stream_name(
10684 "bla", "bla", NULL, NT_STATUS_OK);
10685 ret &= test_stream_name(
10686 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10687 ret &= test_stream_name(
10688 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10689 ret &= test_stream_name(
10690 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10691 ret &= test_stream_name(
10692 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10693 ret &= test_stream_name(
10694 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10695 ret &= test_stream_name(
10696 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10697 ret &= test_stream_name(
10698 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10703 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10705 if (a.length != b.length) {
10706 printf("a.length=%d != b.length=%d\n",
10707 (int)a.length, (int)b.length);
10710 if (memcmp(a.data, b.data, a.length) != 0) {
10711 printf("a.data and b.data differ\n");
10717 static bool run_local_memcache(int dummy)
10719 struct memcache *cache;
10720 DATA_BLOB k1, k2, k3;
10724 TALLOC_CTX *mem_ctx;
10729 size_t size1, size2;
10732 mem_ctx = talloc_init("foo");
10733 if (mem_ctx == NULL) {
10737 /* STAT_CACHE TESTS */
10739 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10741 if (cache == NULL) {
10742 printf("memcache_init failed\n");
10746 d1 = data_blob_const("d1", 2);
10747 d3 = data_blob_const("d3", 2);
10749 k1 = data_blob_const("d1", 2);
10750 k2 = data_blob_const("d2", 2);
10751 k3 = data_blob_const("d3", 2);
10753 memcache_add(cache, STAT_CACHE, k1, d1);
10755 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10756 printf("could not find k1\n");
10759 if (!data_blob_equal(d1, v1)) {
10763 memcache_add(cache, STAT_CACHE, k1, d3);
10765 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10766 printf("could not find replaced k1\n");
10769 if (!data_blob_equal(d3, v3)) {
10773 TALLOC_FREE(cache);
10775 /* GETWD_CACHE TESTS */
10776 str1 = talloc_strdup(mem_ctx, "string1");
10777 if (str1 == NULL) {
10780 ptr2 = str1; /* Keep an alias for comparison. */
10782 str2 = talloc_strdup(mem_ctx, "string2");
10783 if (str2 == NULL) {
10787 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10788 if (cache == NULL) {
10789 printf("memcache_init failed\n");
10793 memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
10794 /* str1 == NULL now. */
10795 ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
10796 if (ptr1 == NULL) {
10797 printf("could not find k2\n");
10800 if (ptr1 != ptr2) {
10801 printf("fetch of k2 got wrong string\n");
10805 /* Add a blob to ensure k2 gets purged. */
10806 d3 = data_blob_talloc_zero(mem_ctx, 180);
10807 memcache_add(cache, STAT_CACHE, k3, d3);
10809 ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
10810 if (ptr2 != NULL) {
10811 printf("Did find k2, should have been purged\n");
10815 TALLOC_FREE(cache);
10816 TALLOC_FREE(mem_ctx);
10818 mem_ctx = talloc_init("foo");
10819 if (mem_ctx == NULL) {
10823 cache = memcache_init(NULL, 0);
10824 if (cache == NULL) {
10828 str1 = talloc_strdup(mem_ctx, "string1");
10829 if (str1 == NULL) {
10832 str2 = talloc_strdup(mem_ctx, "string2");
10833 if (str2 == NULL) {
10836 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10837 data_blob_string_const("torture"), &str1);
10838 size1 = talloc_total_size(cache);
10840 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10841 data_blob_string_const("torture"), &str2);
10842 size2 = talloc_total_size(cache);
10844 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
10846 if (size2 > size1) {
10847 printf("memcache leaks memory!\n");
10853 TALLOC_FREE(cache);
10857 static void wbclient_done(struct tevent_req *req)
10860 struct winbindd_response *wb_resp;
10861 int *i = (int *)tevent_req_callback_data_void(req);
10863 wbc_err = wb_trans_recv(req, req, &wb_resp);
10866 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
10869 static bool run_wbclient_multi_ping(int dummy)
10871 struct tevent_context *ev;
10872 struct wb_context **wb_ctx;
10873 struct winbindd_request wb_req;
10874 bool result = false;
10877 BlockSignals(True, SIGPIPE);
10879 ev = tevent_context_init(talloc_tos());
10884 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
10885 if (wb_ctx == NULL) {
10889 ZERO_STRUCT(wb_req);
10890 wb_req.cmd = WINBINDD_PING;
10892 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
10894 for (i=0; i<torture_nprocs; i++) {
10895 wb_ctx[i] = wb_context_init(ev, NULL);
10896 if (wb_ctx[i] == NULL) {
10899 for (j=0; j<torture_numops; j++) {
10900 struct tevent_req *req;
10901 req = wb_trans_send(ev, ev, wb_ctx[i],
10902 (j % 2) == 0, &wb_req);
10906 tevent_req_set_callback(req, wbclient_done, &i);
10912 while (i < torture_nprocs * torture_numops) {
10913 tevent_loop_once(ev);
10922 static void getaddrinfo_finished(struct tevent_req *req)
10924 char *name = (char *)tevent_req_callback_data_void(req);
10925 struct addrinfo *ainfo;
10928 res = getaddrinfo_recv(req, &ainfo);
10930 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
10933 d_printf("gai(%s) succeeded\n", name);
10934 freeaddrinfo(ainfo);
10937 static bool run_getaddrinfo_send(int dummy)
10939 TALLOC_CTX *frame = talloc_stackframe();
10940 struct fncall_context *ctx;
10941 struct tevent_context *ev;
10942 bool result = false;
10943 const char *names[4] = { "www.samba.org", "notfound.samba.org",
10944 "www.slashdot.org", "heise.de" };
10945 struct tevent_req *reqs[4];
10948 ev = samba_tevent_context_init(frame);
10953 ctx = fncall_context_init(frame, 4);
10955 for (i=0; i<ARRAY_SIZE(names); i++) {
10956 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
10958 if (reqs[i] == NULL) {
10961 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
10962 discard_const_p(void, names[i]));
10965 for (i=0; i<ARRAY_SIZE(reqs); i++) {
10966 tevent_loop_once(ev);
10971 TALLOC_FREE(frame);
10975 static bool dbtrans_inc(struct db_context *db)
10977 struct db_record *rec;
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.dsize != sizeof(uint32_t)) {
10992 printf(__location__ "value.dsize = %d\n",
10997 memcpy(&val, value.dptr, sizeof(val));
11000 status = dbwrap_record_store(
11001 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
11002 if (!NT_STATUS_IS_OK(status)) {
11003 printf(__location__ "store failed: %s\n",
11004 nt_errstr(status));
11014 static bool run_local_dbtrans(int dummy)
11016 struct db_context *db;
11017 struct db_record *rec;
11023 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
11024 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
11027 printf("Could not open transtest.db\n");
11031 res = dbwrap_transaction_start(db);
11033 printf(__location__ "transaction_start failed\n");
11037 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11039 printf(__location__ "fetch_lock failed\n");
11043 value = dbwrap_record_get_value(rec);
11045 if (value.dptr == NULL) {
11047 status = dbwrap_record_store(
11048 rec, make_tdb_data((uint8_t *)&initial,
11051 if (!NT_STATUS_IS_OK(status)) {
11052 printf(__location__ "store returned %s\n",
11053 nt_errstr(status));
11060 res = dbwrap_transaction_commit(db);
11062 printf(__location__ "transaction_commit failed\n");
11067 uint32_t val, val2;
11070 res = dbwrap_transaction_start(db);
11072 printf(__location__ "transaction_start failed\n");
11076 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
11077 if (!NT_STATUS_IS_OK(status)) {
11078 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11079 nt_errstr(status));
11083 for (i=0; i<10; i++) {
11084 if (!dbtrans_inc(db)) {
11089 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
11090 if (!NT_STATUS_IS_OK(status)) {
11091 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11092 nt_errstr(status));
11096 if (val2 != val + 10) {
11097 printf(__location__ "val=%d, val2=%d\n",
11098 (int)val, (int)val2);
11102 printf("val2=%d\r", val2);
11104 res = dbwrap_transaction_commit(db);
11106 printf(__location__ "transaction_commit failed\n");
11116 * Just a dummy test to be run under a debugger. There's no real way
11117 * to inspect the tevent_select specific function from outside of
11121 static bool run_local_tevent_select(int dummy)
11123 struct tevent_context *ev;
11124 struct tevent_fd *fd1, *fd2;
11125 bool result = false;
11127 ev = tevent_context_init_byname(NULL, "select");
11129 d_fprintf(stderr, "tevent_context_init_byname failed\n");
11133 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
11135 d_fprintf(stderr, "tevent_add_fd failed\n");
11138 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
11140 d_fprintf(stderr, "tevent_add_fd failed\n");
11145 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
11147 d_fprintf(stderr, "tevent_add_fd failed\n");
11157 static bool run_local_hex_encode_buf(int dummy)
11163 for (i=0; i<sizeof(src); i++) {
11166 hex_encode_buf(buf, src, sizeof(src));
11167 if (strcmp(buf, "0001020304050607") != 0) {
11170 hex_encode_buf(buf, NULL, 0);
11171 if (buf[0] != '\0') {
11177 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11199 "1001:1111:1111:1000:0:1111:1111:1111",
11208 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11222 "1001:1111:1111:1000:0:1111:1111:1111"
11225 static bool run_local_remove_duplicate_addrs2(int dummy)
11227 struct ip_service test_vector[28];
11230 /* Construct the sockaddr_storage test vector. */
11231 for (i = 0; i < 28; i++) {
11232 struct addrinfo hints;
11233 struct addrinfo *res = NULL;
11236 memset(&hints, '\0', sizeof(hints));
11237 hints.ai_flags = AI_NUMERICHOST;
11238 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11243 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11244 remove_duplicate_addrs2_test_strings_vector[i]);
11247 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11248 memcpy(&test_vector[i].ss,
11254 count = remove_duplicate_addrs2(test_vector, i);
11257 fprintf(stderr, "count wrong (%d) should be 14\n",
11262 for (i = 0; i < count; i++) {
11263 char addr[INET6_ADDRSTRLEN];
11265 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11267 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11268 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11271 remove_duplicate_addrs2_test_strings_result[i]);
11276 printf("run_local_remove_duplicate_addrs2: success\n");
11280 static bool run_local_tdb_opener(int dummy)
11286 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11287 O_RDWR|O_CREAT, 0755);
11289 perror("tdb_open failed");
11300 static bool run_local_tdb_writer(int dummy)
11306 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11308 perror("tdb_open failed");
11312 val.dptr = (uint8_t *)&v;
11313 val.dsize = sizeof(v);
11319 ret = tdb_store(t, val, val, 0);
11321 printf("%s\n", tdb_errorstr(t));
11326 data = tdb_fetch(t, val);
11327 if (data.dptr != NULL) {
11328 SAFE_FREE(data.dptr);
11334 static bool run_local_canonicalize_path(int dummy)
11336 const char *src[] = {
11343 ".././././../../../boo",
11347 const char *dst[] = {
11360 for (i = 0; src[i] != NULL; i++) {
11361 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11363 perror("talloc fail\n");
11366 if (strcmp(d, dst[i]) != 0) {
11368 "canonicalize missmatch %s -> %s != %s",
11369 src[i], d, dst[i]);
11377 static bool run_ign_bad_negprot(int dummy)
11379 struct tevent_context *ev;
11380 struct tevent_req *req;
11381 struct smbXcli_conn *conn;
11382 struct sockaddr_storage ss;
11387 printf("starting ignore bad negprot\n");
11389 ok = resolve_name(host, &ss, 0x20, true);
11391 d_fprintf(stderr, "Could not resolve name %s\n", host);
11395 status = open_socket_out(&ss, 445, 10000, &fd);
11396 if (!NT_STATUS_IS_OK(status)) {
11397 d_fprintf(stderr, "open_socket_out failed: %s\n",
11398 nt_errstr(status));
11402 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11404 if (conn == NULL) {
11405 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11409 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11410 if (NT_STATUS_IS_OK(status)) {
11411 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11415 ev = samba_tevent_context_init(talloc_tos());
11417 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11421 req = smb1cli_session_setup_nt1_send(
11422 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11423 data_blob_null, data_blob_null, 0x40,
11424 "Windows 2000 2195", "Windows 2000 5.0");
11426 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11430 ok = tevent_req_poll_ntstatus(req, ev, &status);
11432 d_fprintf(stderr, "tevent_req_poll failed\n");
11436 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11438 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11439 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11440 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11441 nt_errstr(status));
11447 printf("starting ignore bad negprot\n");
11452 static double create_procs(bool (*fn)(int), bool *result)
11455 volatile pid_t *child_status;
11456 volatile bool *child_status_out;
11459 struct timeval start;
11463 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11464 if (!child_status) {
11465 printf("Failed to setup shared memory\n");
11469 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11470 if (!child_status_out) {
11471 printf("Failed to setup result status shared memory\n");
11475 for (i = 0; i < torture_nprocs; i++) {
11476 child_status[i] = 0;
11477 child_status_out[i] = True;
11480 start = timeval_current();
11482 for (i=0;i<torture_nprocs;i++) {
11485 pid_t mypid = getpid();
11486 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11488 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11491 if (torture_open_connection(¤t_cli, i)) break;
11492 if (tries-- == 0) {
11493 printf("pid %d failed to start\n", (int)getpid());
11499 child_status[i] = getpid();
11501 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11503 child_status_out[i] = fn(i);
11510 for (i=0;i<torture_nprocs;i++) {
11511 if (child_status[i]) synccount++;
11513 if (synccount == torture_nprocs) break;
11515 } while (timeval_elapsed(&start) < 30);
11517 if (synccount != torture_nprocs) {
11518 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11520 return timeval_elapsed(&start);
11523 /* start the client load */
11524 start = timeval_current();
11526 for (i=0;i<torture_nprocs;i++) {
11527 child_status[i] = 0;
11530 printf("%d clients started\n", torture_nprocs);
11532 for (i=0;i<torture_nprocs;i++) {
11533 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11538 for (i=0;i<torture_nprocs;i++) {
11539 if (!child_status_out[i]) {
11543 return timeval_elapsed(&start);
11546 #define FLAG_MULTIPROC 1
11552 } torture_ops[] = {
11553 {"FDPASS", run_fdpasstest, 0},
11554 {"LOCK1", run_locktest1, 0},
11555 {"LOCK2", run_locktest2, 0},
11556 {"LOCK3", run_locktest3, 0},
11557 {"LOCK4", run_locktest4, 0},
11558 {"LOCK5", run_locktest5, 0},
11559 {"LOCK6", run_locktest6, 0},
11560 {"LOCK7", run_locktest7, 0},
11561 {"LOCK8", run_locktest8, 0},
11562 {"LOCK9", run_locktest9, 0},
11563 {"UNLINK", run_unlinktest, 0},
11564 {"BROWSE", run_browsetest, 0},
11565 {"ATTR", run_attrtest, 0},
11566 {"TRANS2", run_trans2test, 0},
11567 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
11568 {"TORTURE",run_torture, FLAG_MULTIPROC},
11569 {"RANDOMIPC", run_randomipc, 0},
11570 {"NEGNOWAIT", run_negprot_nowait, 0},
11571 {"NBENCH", run_nbench, 0},
11572 {"NBENCH2", run_nbench2, 0},
11573 {"OPLOCK1", run_oplock1, 0},
11574 {"OPLOCK2", run_oplock2, 0},
11575 {"OPLOCK4", run_oplock4, 0},
11576 {"DIR", run_dirtest, 0},
11577 {"DIR1", run_dirtest1, 0},
11578 {"DIR-CREATETIME", run_dir_createtime, 0},
11579 {"DENY1", torture_denytest1, 0},
11580 {"DENY2", torture_denytest2, 0},
11581 {"TCON", run_tcon_test, 0},
11582 {"TCONDEV", run_tcon_devtype_test, 0},
11583 {"RW1", run_readwritetest, 0},
11584 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
11585 {"RW3", run_readwritelarge, 0},
11586 {"RW-SIGNING", run_readwritelarge_signtest, 0},
11587 {"OPEN", run_opentest, 0},
11588 {"POSIX", run_simple_posix_open_test, 0},
11589 {"POSIX-APPEND", run_posix_append, 0},
11590 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
11591 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
11592 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
11593 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
11594 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
11595 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
11596 {"ASYNC-ECHO", run_async_echo, 0},
11597 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
11598 { "SHORTNAME-TEST", run_shortname_test, 0},
11599 { "ADDRCHANGE", run_addrchange, 0},
11601 {"OPENATTR", run_openattrtest, 0},
11603 {"XCOPY", run_xcopy, 0},
11604 {"RENAME", run_rename, 0},
11605 {"RENAME-ACCESS", run_rename_access, 0},
11606 {"OWNER-RIGHTS", run_owner_rights, 0},
11607 {"DELETE", run_deletetest, 0},
11608 {"WILDDELETE", run_wild_deletetest, 0},
11609 {"DELETE-LN", run_deletetest_ln, 0},
11610 {"PROPERTIES", run_properties, 0},
11611 {"MANGLE", torture_mangle, 0},
11612 {"MANGLE1", run_mangle1, 0},
11613 {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
11614 {"W2K", run_w2ktest, 0},
11615 {"TRANS2SCAN", torture_trans2_scan, 0},
11616 {"NTTRANSSCAN", torture_nttrans_scan, 0},
11617 {"UTABLE", torture_utable, 0},
11618 {"CASETABLE", torture_casetable, 0},
11619 {"ERRMAPEXTRACT", run_error_map_extract, 0},
11620 {"PIPE_NUMBER", run_pipe_number, 0},
11621 {"TCON2", run_tcon2_test, 0},
11622 {"IOCTL", torture_ioctl_test, 0},
11623 {"CHKPATH", torture_chkpath_test, 0},
11624 {"FDSESS", run_fdsesstest, 0},
11625 { "EATEST", run_eatest, 0},
11626 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
11627 { "CHAIN1", run_chain1, 0},
11628 { "CHAIN2", run_chain2, 0},
11629 { "CHAIN3", run_chain3, 0},
11630 { "WINDOWS-WRITE", run_windows_write, 0},
11631 { "LARGE_READX", run_large_readx, 0},
11632 { "NTTRANS-CREATE", run_nttrans_create, 0},
11633 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
11634 { "CLI_ECHO", run_cli_echo, 0},
11635 { "GETADDRINFO", run_getaddrinfo_send, 0},
11636 { "TLDAP", run_tldap },
11637 { "STREAMERROR", run_streamerror },
11638 { "NOTIFY-BENCH", run_notify_bench },
11639 { "NOTIFY-BENCH2", run_notify_bench2 },
11640 { "NOTIFY-BENCH3", run_notify_bench3 },
11641 { "BAD-NBT-SESSION", run_bad_nbt_session },
11642 { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
11643 { "SMB-ANY-CONNECT", run_smb_any_connect },
11644 { "NOTIFY-ONLINE", run_notify_online },
11645 { "SMB2-BASIC", run_smb2_basic },
11646 { "SMB2-NEGPROT", run_smb2_negprot },
11647 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
11648 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
11649 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
11650 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
11651 { "SMB2-FTRUNCATE", run_smb2_ftruncate },
11652 { "CLEANUP1", run_cleanup1 },
11653 { "CLEANUP2", run_cleanup2 },
11654 { "CLEANUP3", run_cleanup3 },
11655 { "CLEANUP4", run_cleanup4 },
11656 { "OPLOCK-CANCEL", run_oplock_cancel },
11657 { "PIDHIGH", run_pidhigh },
11658 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
11659 { "LOCAL-GENCACHE", run_local_gencache, 0},
11660 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
11661 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
11662 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2, 0 },
11663 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
11664 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
11665 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
11666 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
11667 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
11668 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
11669 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
11670 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
11671 { "LOCAL-BASE64", run_local_base64, 0},
11672 { "LOCAL-RBTREE", run_local_rbtree, 0},
11673 { "LOCAL-MEMCACHE", run_local_memcache, 0},
11674 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
11675 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
11676 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
11677 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
11678 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
11679 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
11680 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
11681 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
11682 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
11683 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
11684 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
11685 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
11686 { "local-tdb-opener", run_local_tdb_opener, 0 },
11687 { "local-tdb-writer", run_local_tdb_writer, 0 },
11688 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
11689 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
11690 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
11691 { "LOCAL-G-LOCK1", run_g_lock1, 0 },
11692 { "LOCAL-G-LOCK2", run_g_lock2, 0 },
11693 { "LOCAL-G-LOCK3", run_g_lock3, 0 },
11694 { "LOCAL-G-LOCK4", run_g_lock4, 0 },
11695 { "LOCAL-G-LOCK5", run_g_lock5, 0 },
11696 { "LOCAL-G-LOCK-PING-PONG", run_g_lock_ping_pong, 0 },
11697 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
11698 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
11702 * dummy function to satisfy linker dependency
11704 struct tevent_context *winbind_event_context(void);
11705 struct tevent_context *winbind_event_context(void)
11710 /****************************************************************************
11711 run a specified test or "ALL"
11712 ****************************************************************************/
11713 static bool run_test(const char *name)
11716 bool result = True;
11717 bool found = False;
11720 if (strequal(name,"ALL")) {
11721 for (i=0;torture_ops[i].name;i++) {
11722 run_test(torture_ops[i].name);
11727 for (i=0;torture_ops[i].name;i++) {
11728 fstr_sprintf(randomfname, "\\XX%x",
11729 (unsigned)random());
11731 if (strequal(name, torture_ops[i].name)) {
11733 printf("Running %s\n", name);
11734 if (torture_ops[i].flags & FLAG_MULTIPROC) {
11735 t = create_procs(torture_ops[i].fn, &result);
11738 printf("TEST %s FAILED!\n", name);
11741 struct timeval start;
11742 start = timeval_current();
11743 if (!torture_ops[i].fn(0)) {
11745 printf("TEST %s FAILED!\n", name);
11747 t = timeval_elapsed(&start);
11749 printf("%s took %g secs\n\n", name, t);
11754 printf("Did not find a test named %s\n", name);
11762 static void usage(void)
11766 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11767 printf("Please use samba4 torture.\n\n");
11769 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11771 printf("\t-d debuglevel\n");
11772 printf("\t-U user%%pass\n");
11773 printf("\t-k use kerberos\n");
11774 printf("\t-N numprocs\n");
11775 printf("\t-n my_netbios_name\n");
11776 printf("\t-W workgroup\n");
11777 printf("\t-o num_operations\n");
11778 printf("\t-O socket_options\n");
11779 printf("\t-m maximum protocol\n");
11780 printf("\t-L use oplocks\n");
11781 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11782 printf("\t-A showall\n");
11783 printf("\t-p port\n");
11784 printf("\t-s seed\n");
11785 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11786 printf("\t-f filename filename to test\n");
11787 printf("\t-e encrypt\n");
11790 printf("tests are:");
11791 for (i=0;torture_ops[i].name;i++) {
11792 printf(" %s", torture_ops[i].name);
11796 printf("default test is ALL\n");
11801 /****************************************************************************
11803 ****************************************************************************/
11804 int main(int argc,char *argv[])
11810 bool correct = True;
11811 TALLOC_CTX *frame = talloc_stackframe();
11812 int seed = time(NULL);
11814 #ifdef HAVE_SETBUFFER
11815 setbuffer(stdout, NULL, 0);
11818 setup_logging("smbtorture", DEBUG_STDOUT);
11823 if (is_default_dyn_CONFIGFILE()) {
11824 if(getenv("SMB_CONF_PATH")) {
11825 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11828 lp_load_global(get_dyn_CONFIGFILE());
11835 for(p = argv[1]; *p; p++)
11839 if (strncmp(argv[1], "//", 2)) {
11843 fstrcpy(host, &argv[1][2]);
11844 p = strchr_m(&host[2],'/');
11849 fstrcpy(share, p+1);
11851 fstrcpy(myname, get_myname(talloc_tos()));
11853 fprintf(stderr, "Failed to get my hostname.\n");
11857 if (*username == 0 && getenv("LOGNAME")) {
11858 fstrcpy(username,getenv("LOGNAME"));
11864 fstrcpy(workgroup, lp_workgroup());
11866 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
11870 port_to_use = atoi(optarg);
11873 seed = atoi(optarg);
11876 fstrcpy(workgroup,optarg);
11879 lp_set_cmdline("client max protocol", optarg);
11882 torture_nprocs = atoi(optarg);
11885 torture_numops = atoi(optarg);
11888 lp_set_cmdline("log level", optarg);
11894 use_oplocks = True;
11897 local_path = optarg;
11900 torture_showall = True;
11903 fstrcpy(myname, optarg);
11906 client_txt = optarg;
11913 use_kerberos = True;
11915 d_printf("No kerberos support compiled in\n");
11921 fstrcpy(username,optarg);
11922 p = strchr_m(username,'%');
11925 fstrcpy(password, p+1);
11930 fstrcpy(multishare_conn_fname, optarg);
11931 use_multishare_conn = True;
11934 torture_blocksize = atoi(optarg);
11937 test_filename = SMB_STRDUP(optarg);
11940 printf("Unknown option %c (%d)\n", (char)opt, opt);
11945 d_printf("using seed %d\n", seed);
11949 if(use_kerberos && !gotuser) gotpass = True;
11952 char pwd[256] = {0};
11955 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
11957 fstrcpy(password, pwd);
11962 printf("host=%s share=%s user=%s myname=%s\n",
11963 host, share, username, myname);
11965 torture_creds = cli_session_creds_init(frame,
11971 false, /* fallback_after_kerberos */
11972 false, /* use_ccache */
11973 false); /* password_is_nt_hash */
11974 if (torture_creds == NULL) {
11975 d_printf("cli_session_creds_init() failed.\n");
11979 if (argc == optind) {
11980 correct = run_test("ALL");
11982 for (i=optind;i<argc;i++) {
11983 if (!run_test(argv[i])) {
11989 TALLOC_FREE(frame);