2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "libsmb/namequery.h"
24 #include "wbc_async.h"
25 #include "torture/proto.h"
26 #include "libcli/security/security.h"
28 #include "tldap_util.h"
29 #include "../librpc/gen_ndr/svcctl.h"
30 #include "../lib/util/memcache.h"
31 #include "nsswitch/winbind_client.h"
32 #include "dbwrap/dbwrap.h"
33 #include "dbwrap/dbwrap_open.h"
34 #include "dbwrap/dbwrap_rbt.h"
35 #include "async_smb.h"
36 #include "libsmb/libsmb.h"
37 #include "libsmb/clirap.h"
39 #include "libsmb/nmblib.h"
40 #include "../lib/util/tevent_ntstatus.h"
42 #include "../libcli/smb/read_smb.h"
43 #include "../libcli/smb/smbXcli_base.h"
44 #include "lib/util/sys_rw_data.h"
45 #include "lib/util/base64.h"
46 #include "lib/util/time.h"
47 #include "lib/crypto/md5.h"
48 #include "lib/gencache.h"
53 fstring host, workgroup, share, password, username, myname;
54 struct cli_credentials *torture_creds;
55 static const char *sockops="TCP_NODELAY";
57 static int port_to_use=0;
58 int torture_numops=100;
59 int torture_blocksize=1024*1024;
60 static int procnum; /* records process count number when forking */
61 static struct cli_state *current_cli;
62 static fstring randomfname;
63 static bool use_oplocks;
64 static bool use_level_II_oplocks;
65 static const char *client_txt = "client_oplocks.txt";
66 static bool disable_spnego;
67 static bool use_kerberos;
68 static bool force_dos_errors;
69 static fstring multishare_conn_fname;
70 static bool use_multishare_conn = False;
71 static bool do_encrypt;
72 static const char *local_path = NULL;
73 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
76 bool torture_showall = False;
78 static double create_procs(bool (*fn)(int), bool *result);
80 /********************************************************************
81 Ensure a connection is encrypted.
82 ********************************************************************/
84 static bool force_cli_encryption(struct cli_state *c,
85 const char *sharename)
87 uint16_t major, minor;
88 uint32_t caplow, caphigh;
91 if (!SERVER_HAS_UNIX_CIFS(c)) {
92 d_printf("Encryption required and "
93 "server that doesn't support "
94 "UNIX extensions - failing connect\n");
98 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
100 if (!NT_STATUS_IS_OK(status)) {
101 d_printf("Encryption required and "
102 "can't get UNIX CIFS extensions "
103 "version from server: %s\n", nt_errstr(status));
107 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
108 d_printf("Encryption required and "
109 "share %s doesn't support "
110 "encryption.\n", sharename);
114 status = cli_smb1_setup_encryption(c, torture_creds);
115 if (!NT_STATUS_IS_OK(status)) {
116 d_printf("Encryption required and "
117 "setup failed with error %s.\n",
126 static struct cli_state *open_nbt_connection(void)
132 if (disable_spnego) {
133 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
137 flags |= CLI_FULL_CONNECTION_OPLOCKS;
140 if (use_level_II_oplocks) {
141 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
145 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
148 if (force_dos_errors) {
149 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
152 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
153 signing_state, flags, &c);
154 if (!NT_STATUS_IS_OK(status)) {
155 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
159 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
164 /****************************************************************************
165 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
166 ****************************************************************************/
168 static bool cli_bad_session_request(int fd,
169 struct nmb_name *calling, struct nmb_name *called)
178 uint8_t message_type;
180 struct tevent_context *ev;
181 struct tevent_req *req;
183 frame = talloc_stackframe();
185 iov[0].iov_base = len_buf;
186 iov[0].iov_len = sizeof(len_buf);
188 /* put in the destination name */
190 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
192 if (iov[1].iov_base == NULL) {
195 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
196 talloc_get_size(iov[1].iov_base));
200 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
202 if (iov[2].iov_base == NULL) {
205 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
206 talloc_get_size(iov[2].iov_base));
208 /* Deliberately corrupt the name len (first byte) */
209 *((uint8_t *)iov[2].iov_base) = 100;
211 /* send a session request (RFC 1002) */
212 /* setup the packet length
213 * Remove four bytes from the length count, since the length
214 * field in the NBT Session Service header counts the number
215 * of bytes which follow. The cli_send_smb() function knows
216 * about this and accounts for those four bytes.
220 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
221 SCVAL(len_buf,0,0x81);
223 len = write_data_iov(fd, iov, 3);
228 ev = samba_tevent_context_init(frame);
232 req = read_smb_send(frame, ev, fd);
236 if (!tevent_req_poll(req, ev)) {
239 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
246 message_type = CVAL(inbuf, 0);
247 if (message_type != 0x83) {
248 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
253 if (smb_len(inbuf) != 1) {
254 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
255 (int)smb_len(inbuf));
259 error = CVAL(inbuf, 4);
261 d_fprintf(stderr, "Expected error 0x82, got %d\n",
272 /* Insert a NULL at the first separator of the given path and return a pointer
273 * to the remainder of the string.
276 terminate_path_at_separator(char * path)
284 if ((p = strchr_m(path, '/'))) {
289 if ((p = strchr_m(path, '\\'))) {
299 parse a //server/share type UNC name
301 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
302 char **hostname, char **sharename)
306 *hostname = *sharename = NULL;
308 if (strncmp(unc_name, "\\\\", 2) &&
309 strncmp(unc_name, "//", 2)) {
313 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
314 p = terminate_path_at_separator(*hostname);
317 *sharename = talloc_strdup(mem_ctx, p);
318 terminate_path_at_separator(*sharename);
321 if (*hostname && *sharename) {
325 TALLOC_FREE(*hostname);
326 TALLOC_FREE(*sharename);
330 static bool torture_open_connection_share(struct cli_state **c,
331 const char *hostname,
332 const char *sharename,
337 status = cli_full_connection_creds(c,
347 if (!NT_STATUS_IS_OK(status)) {
348 printf("failed to open share connection: //%s/%s port:%d - %s\n",
349 hostname, sharename, port_to_use, nt_errstr(status));
353 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
356 return force_cli_encryption(*c,
362 bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
364 char **unc_list = NULL;
365 int num_unc_names = 0;
368 if (use_multishare_conn==True) {
370 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
371 if (!unc_list || num_unc_names <= 0) {
372 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
376 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
378 printf("Failed to parse UNC name %s\n",
379 unc_list[conn_index % num_unc_names]);
380 TALLOC_FREE(unc_list);
384 result = torture_open_connection_share(c, h, s, flags);
386 /* h, s were copied earlier */
387 TALLOC_FREE(unc_list);
391 return torture_open_connection_share(c, host, share, flags);
394 bool torture_open_connection(struct cli_state **c, int conn_index)
396 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
399 flags |= CLI_FULL_CONNECTION_OPLOCKS;
401 if (use_level_II_oplocks) {
402 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
405 return torture_open_connection_flags(c, conn_index, flags);
408 bool torture_init_connection(struct cli_state **pcli)
410 struct cli_state *cli;
412 cli = open_nbt_connection();
421 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
423 uint16_t old_vuid = cli_state_get_uid(cli);
427 cli_state_set_uid(cli, 0);
428 status = cli_session_setup_creds(cli, torture_creds);
429 ret = NT_STATUS_IS_OK(status);
430 *new_vuid = cli_state_get_uid(cli);
431 cli_state_set_uid(cli, old_vuid);
436 bool torture_close_connection(struct cli_state *c)
441 status = cli_tdis(c);
442 if (!NT_STATUS_IS_OK(status)) {
443 printf("tdis failed (%s)\n", nt_errstr(status));
453 /* check if the server produced the expected dos or nt error code */
454 static bool check_both_error(int line, NTSTATUS status,
455 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
457 if (NT_STATUS_IS_DOS(status)) {
461 /* Check DOS error */
462 cclass = NT_STATUS_DOS_CLASS(status);
463 num = NT_STATUS_DOS_CODE(status);
465 if (eclass != cclass || ecode != num) {
466 printf("unexpected error code class=%d code=%d\n",
467 (int)cclass, (int)num);
468 printf(" expected %d/%d %s (line=%d)\n",
469 (int)eclass, (int)ecode, nt_errstr(nterr), line);
474 if (!NT_STATUS_EQUAL(nterr, status)) {
475 printf("unexpected error code %s\n",
477 printf(" expected %s (line=%d)\n",
478 nt_errstr(nterr), line);
487 /* check if the server produced the expected error code */
488 static bool check_error(int line, NTSTATUS status,
489 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
491 if (NT_STATUS_IS_DOS(status)) {
495 /* Check DOS error */
497 cclass = NT_STATUS_DOS_CLASS(status);
498 num = NT_STATUS_DOS_CODE(status);
500 if (eclass != cclass || ecode != num) {
501 printf("unexpected error code class=%d code=%d\n",
502 (int)cclass, (int)num);
503 printf(" expected %d/%d %s (line=%d)\n",
504 (int)eclass, (int)ecode, nt_errstr(nterr),
512 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
513 printf("unexpected error code %s\n",
515 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
525 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
529 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
531 while (!NT_STATUS_IS_OK(status)) {
532 if (!check_both_error(__LINE__, status, ERRDOS,
533 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
537 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
544 static bool rw_torture(struct cli_state *c)
546 const char *lockfname = "\\torture.lck";
550 pid_t pid2, pid = getpid();
557 memset(buf, '\0', sizeof(buf));
559 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
561 if (!NT_STATUS_IS_OK(status)) {
562 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
564 if (!NT_STATUS_IS_OK(status)) {
565 printf("open of %s failed (%s)\n",
566 lockfname, nt_errstr(status));
570 for (i=0;i<torture_numops;i++) {
571 unsigned n = (unsigned)sys_random()%10;
574 printf("%d\r", i); fflush(stdout);
576 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
578 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
582 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
584 if (!NT_STATUS_IS_OK(status)) {
585 printf("open failed (%s)\n", nt_errstr(status));
590 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
592 if (!NT_STATUS_IS_OK(status)) {
593 printf("write failed (%s)\n", nt_errstr(status));
598 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
599 sizeof(pid)+(j*sizeof(buf)),
601 if (!NT_STATUS_IS_OK(status)) {
602 printf("write failed (%s)\n",
610 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
612 if (!NT_STATUS_IS_OK(status)) {
613 printf("read failed (%s)\n", nt_errstr(status));
615 } else if (nread != sizeof(pid)) {
616 printf("read/write compare failed: "
617 "recv %ld req %ld\n", (unsigned long)nread,
618 (unsigned long)sizeof(pid));
623 printf("data corruption!\n");
627 status = cli_close(c, fnum);
628 if (!NT_STATUS_IS_OK(status)) {
629 printf("close failed (%s)\n", nt_errstr(status));
633 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
634 if (!NT_STATUS_IS_OK(status)) {
635 printf("unlink failed (%s)\n", nt_errstr(status));
639 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
640 if (!NT_STATUS_IS_OK(status)) {
641 printf("unlock failed (%s)\n", nt_errstr(status));
647 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
654 static bool run_torture(int dummy)
656 struct cli_state *cli;
661 smbXcli_conn_set_sockopt(cli->conn, sockops);
663 ret = rw_torture(cli);
665 if (!torture_close_connection(cli)) {
672 static bool rw_torture3(struct cli_state *c, char *lockfname)
674 uint16_t fnum = (uint16_t)-1;
679 unsigned countprev = 0;
682 NTSTATUS status = NT_STATUS_OK;
685 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
687 SIVAL(buf, i, sys_random());
694 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
695 if (!NT_STATUS_IS_OK(status)) {
696 printf("unlink failed (%s) (normal, this file should "
697 "not exist)\n", nt_errstr(status));
700 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
702 if (!NT_STATUS_IS_OK(status)) {
703 printf("first open read/write of %s failed (%s)\n",
704 lockfname, nt_errstr(status));
710 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
712 status = cli_openx(c, lockfname, O_RDONLY,
714 if (NT_STATUS_IS_OK(status)) {
719 if (!NT_STATUS_IS_OK(status)) {
720 printf("second open read-only of %s failed (%s)\n",
721 lockfname, nt_errstr(status));
727 for (count = 0; count < sizeof(buf); count += sent)
729 if (count >= countprev) {
730 printf("%d %8d\r", i, count);
733 countprev += (sizeof(buf) / 20);
738 sent = ((unsigned)sys_random()%(20))+ 1;
739 if (sent > sizeof(buf) - count)
741 sent = sizeof(buf) - count;
744 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
746 if (!NT_STATUS_IS_OK(status)) {
747 printf("write failed (%s)\n",
754 status = cli_read(c, fnum, buf_rd+count, count,
755 sizeof(buf)-count, &sent);
756 if(!NT_STATUS_IS_OK(status)) {
757 printf("read failed offset:%d size:%ld (%s)\n",
758 count, (unsigned long)sizeof(buf)-count,
762 } else if (sent > 0) {
763 if (memcmp(buf_rd+count, buf+count, sent) != 0)
765 printf("read/write compare failed\n");
766 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
775 status = cli_close(c, fnum);
776 if (!NT_STATUS_IS_OK(status)) {
777 printf("close failed (%s)\n", nt_errstr(status));
784 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
786 const char *lockfname = "\\torture2.lck";
796 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
797 if (!NT_STATUS_IS_OK(status)) {
798 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
801 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
803 if (!NT_STATUS_IS_OK(status)) {
804 printf("first open read/write of %s failed (%s)\n",
805 lockfname, nt_errstr(status));
809 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
810 if (!NT_STATUS_IS_OK(status)) {
811 printf("second open read-only of %s failed (%s)\n",
812 lockfname, nt_errstr(status));
813 cli_close(c1, fnum1);
817 for (i = 0; i < torture_numops; i++)
819 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
821 printf("%d\r", i); fflush(stdout);
824 generate_random_buffer((unsigned char *)buf, buf_size);
826 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
828 if (!NT_STATUS_IS_OK(status)) {
829 printf("write failed (%s)\n", nt_errstr(status));
834 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
835 if(!NT_STATUS_IS_OK(status)) {
836 printf("read failed (%s)\n", nt_errstr(status));
839 } else if (bytes_read != buf_size) {
840 printf("read failed\n");
841 printf("read %ld, expected %ld\n",
842 (unsigned long)bytes_read,
843 (unsigned long)buf_size);
848 if (memcmp(buf_rd, buf, buf_size) != 0)
850 printf("read/write compare failed\n");
856 status = cli_close(c2, fnum2);
857 if (!NT_STATUS_IS_OK(status)) {
858 printf("close failed (%s)\n", nt_errstr(status));
862 status = cli_close(c1, fnum1);
863 if (!NT_STATUS_IS_OK(status)) {
864 printf("close failed (%s)\n", nt_errstr(status));
868 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
869 if (!NT_STATUS_IS_OK(status)) {
870 printf("unlink failed (%s)\n", nt_errstr(status));
877 static bool run_readwritetest(int dummy)
879 struct cli_state *cli1, *cli2;
880 bool test1, test2 = False;
882 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
885 smbXcli_conn_set_sockopt(cli1->conn, sockops);
886 smbXcli_conn_set_sockopt(cli2->conn, sockops);
888 printf("starting readwritetest\n");
890 test1 = rw_torture2(cli1, cli2);
891 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
894 test2 = rw_torture2(cli1, cli1);
895 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
898 if (!torture_close_connection(cli1)) {
902 if (!torture_close_connection(cli2)) {
906 return (test1 && test2);
909 static bool run_readwritemulti(int dummy)
911 struct cli_state *cli;
916 smbXcli_conn_set_sockopt(cli->conn, sockops);
918 printf("run_readwritemulti: fname %s\n", randomfname);
919 test = rw_torture3(cli, randomfname);
921 if (!torture_close_connection(cli)) {
928 static bool run_readwritelarge_internal(void)
930 static struct cli_state *cli1;
932 const char *lockfname = "\\large.dat";
938 if (!torture_open_connection(&cli1, 0)) {
941 smbXcli_conn_set_sockopt(cli1->conn, sockops);
942 memset(buf,'\0',sizeof(buf));
944 printf("starting readwritelarge_internal\n");
946 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
948 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
950 if (!NT_STATUS_IS_OK(status)) {
951 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
955 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
957 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
959 if (!NT_STATUS_IS_OK(status)) {
960 printf("qfileinfo failed (%s)\n", nt_errstr(status));
964 if (fsize == sizeof(buf))
965 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
966 (unsigned long)fsize);
968 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
969 (unsigned long)fsize);
973 status = cli_close(cli1, fnum1);
974 if (!NT_STATUS_IS_OK(status)) {
975 printf("close failed (%s)\n", nt_errstr(status));
979 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
980 if (!NT_STATUS_IS_OK(status)) {
981 printf("unlink failed (%s)\n", nt_errstr(status));
985 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
987 if (!NT_STATUS_IS_OK(status)) {
988 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
992 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
994 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
996 if (!NT_STATUS_IS_OK(status)) {
997 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1001 if (fsize == sizeof(buf))
1002 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1003 (unsigned long)fsize);
1005 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1006 (unsigned long)fsize);
1011 /* ToDo - set allocation. JRA */
1012 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1013 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1016 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1018 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1022 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1025 status = cli_close(cli1, fnum1);
1026 if (!NT_STATUS_IS_OK(status)) {
1027 printf("close failed (%s)\n", nt_errstr(status));
1031 if (!torture_close_connection(cli1)) {
1037 static bool run_readwritelarge(int dummy)
1039 return run_readwritelarge_internal();
1042 static bool run_readwritelarge_signtest(int dummy)
1045 signing_state = SMB_SIGNING_REQUIRED;
1046 ret = run_readwritelarge_internal();
1047 signing_state = SMB_SIGNING_DEFAULT;
1054 #define ival(s) strtol(s, NULL, 0)
1056 /* run a test that simulates an approximate netbench client load */
1057 static bool run_netbench(int client)
1059 struct cli_state *cli;
1064 const char *params[20];
1065 bool correct = True;
1071 smbXcli_conn_set_sockopt(cli->conn, sockops);
1075 slprintf(cname,sizeof(cname)-1, "client%d", client);
1077 f = fopen(client_txt, "r");
1084 while (fgets(line, sizeof(line)-1, f)) {
1088 line[strlen(line)-1] = 0;
1090 /* printf("[%d] %s\n", line_count, line); */
1092 all_string_sub(line,"client1", cname, sizeof(line));
1094 /* parse the command parameters */
1095 params[0] = strtok_r(line, " ", &saveptr);
1097 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1101 if (i < 2) continue;
1103 if (!strncmp(params[0],"SMB", 3)) {
1104 printf("ERROR: You are using a dbench 1 load file\n");
1108 if (!strcmp(params[0],"NTCreateX")) {
1109 nb_createx(params[1], ival(params[2]), ival(params[3]),
1111 } else if (!strcmp(params[0],"Close")) {
1112 nb_close(ival(params[1]));
1113 } else if (!strcmp(params[0],"Rename")) {
1114 nb_rename(params[1], params[2]);
1115 } else if (!strcmp(params[0],"Unlink")) {
1116 nb_unlink(params[1]);
1117 } else if (!strcmp(params[0],"Deltree")) {
1118 nb_deltree(params[1]);
1119 } else if (!strcmp(params[0],"Rmdir")) {
1120 nb_rmdir(params[1]);
1121 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1122 nb_qpathinfo(params[1]);
1123 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1124 nb_qfileinfo(ival(params[1]));
1125 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1126 nb_qfsinfo(ival(params[1]));
1127 } else if (!strcmp(params[0],"FIND_FIRST")) {
1128 nb_findfirst(params[1]);
1129 } else if (!strcmp(params[0],"WriteX")) {
1130 nb_writex(ival(params[1]),
1131 ival(params[2]), ival(params[3]), ival(params[4]));
1132 } else if (!strcmp(params[0],"ReadX")) {
1133 nb_readx(ival(params[1]),
1134 ival(params[2]), ival(params[3]), ival(params[4]));
1135 } else if (!strcmp(params[0],"Flush")) {
1136 nb_flush(ival(params[1]));
1138 printf("Unknown operation %s\n", params[0]);
1146 if (!torture_close_connection(cli)) {
1154 /* run a test that simulates an approximate netbench client load */
1155 static bool run_nbench(int dummy)
1158 bool correct = True;
1160 nbio_shmem(torture_nprocs);
1164 signal(SIGALRM, nb_alarm);
1166 t = create_procs(run_netbench, &correct);
1169 printf("\nThroughput %g MB/sec\n",
1170 1.0e-6 * nbio_total() / t);
1176 This test checks for two things:
1178 1) correct support for retaining locks over a close (ie. the server
1179 must not use posix semantics)
1180 2) support for lock timeouts
1182 static bool run_locktest1(int dummy)
1184 struct cli_state *cli1, *cli2;
1185 const char *fname = "\\lockt1.lck";
1186 uint16_t fnum1, fnum2, fnum3;
1188 unsigned lock_timeout;
1191 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1194 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1195 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1197 printf("starting locktest1\n");
1199 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1201 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1203 if (!NT_STATUS_IS_OK(status)) {
1204 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1208 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1209 if (!NT_STATUS_IS_OK(status)) {
1210 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1214 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1215 if (!NT_STATUS_IS_OK(status)) {
1216 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1220 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1221 if (!NT_STATUS_IS_OK(status)) {
1222 printf("lock1 failed (%s)\n", nt_errstr(status));
1226 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1227 if (NT_STATUS_IS_OK(status)) {
1228 printf("lock2 succeeded! This is a locking bug\n");
1231 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1232 NT_STATUS_LOCK_NOT_GRANTED)) {
1237 lock_timeout = (1 + (random() % 20));
1238 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1240 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1241 if (NT_STATUS_IS_OK(status)) {
1242 printf("lock3 succeeded! This is a locking bug\n");
1245 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1246 NT_STATUS_FILE_LOCK_CONFLICT)) {
1252 if (ABS(t2 - t1) < lock_timeout-1) {
1253 printf("error: This server appears not to support timed lock requests\n");
1256 printf("server slept for %u seconds for a %u second timeout\n",
1257 (unsigned int)(t2-t1), lock_timeout);
1259 status = cli_close(cli1, fnum2);
1260 if (!NT_STATUS_IS_OK(status)) {
1261 printf("close1 failed (%s)\n", nt_errstr(status));
1265 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1266 if (NT_STATUS_IS_OK(status)) {
1267 printf("lock4 succeeded! This is a locking bug\n");
1270 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1271 NT_STATUS_FILE_LOCK_CONFLICT)) {
1276 status = cli_close(cli1, fnum1);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 printf("close2 failed (%s)\n", nt_errstr(status));
1282 status = cli_close(cli2, fnum3);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 printf("close3 failed (%s)\n", nt_errstr(status));
1288 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 printf("unlink failed (%s)\n", nt_errstr(status));
1295 if (!torture_close_connection(cli1)) {
1299 if (!torture_close_connection(cli2)) {
1303 printf("Passed locktest1\n");
1308 this checks to see if a secondary tconx can use open files from an
1311 static bool run_tcon_test(int dummy)
1313 static struct cli_state *cli;
1314 const char *fname = "\\tcontest.tmp";
1316 uint32_t cnum1, cnum2, cnum3;
1317 struct smbXcli_tcon *orig_tcon = NULL;
1318 uint16_t vuid1, vuid2;
1323 memset(buf, '\0', sizeof(buf));
1325 if (!torture_open_connection(&cli, 0)) {
1328 smbXcli_conn_set_sockopt(cli->conn, sockops);
1330 printf("starting tcontest\n");
1332 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1334 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1335 if (!NT_STATUS_IS_OK(status)) {
1336 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1340 cnum1 = cli_state_get_tid(cli);
1341 vuid1 = cli_state_get_uid(cli);
1343 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1344 if (!NT_STATUS_IS_OK(status)) {
1345 printf("initial write failed (%s)", nt_errstr(status));
1349 orig_tcon = cli_state_save_tcon(cli);
1350 if (orig_tcon == NULL) {
1354 status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1355 if (!NT_STATUS_IS_OK(status)) {
1356 printf("%s refused 2nd tree connect (%s)\n", host,
1362 cnum2 = cli_state_get_tid(cli);
1363 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1364 vuid2 = cli_state_get_uid(cli) + 1;
1366 /* try a write with the wrong tid */
1367 cli_state_set_tid(cli, cnum2);
1369 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1370 if (NT_STATUS_IS_OK(status)) {
1371 printf("* server allows write with wrong TID\n");
1374 printf("server fails write with wrong TID : %s\n",
1379 /* try a write with an invalid tid */
1380 cli_state_set_tid(cli, cnum3);
1382 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1383 if (NT_STATUS_IS_OK(status)) {
1384 printf("* server allows write with invalid TID\n");
1387 printf("server fails write with invalid TID : %s\n",
1391 /* try a write with an invalid vuid */
1392 cli_state_set_uid(cli, vuid2);
1393 cli_state_set_tid(cli, cnum1);
1395 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1396 if (NT_STATUS_IS_OK(status)) {
1397 printf("* server allows write with invalid VUID\n");
1400 printf("server fails write with invalid VUID : %s\n",
1404 cli_state_set_tid(cli, cnum1);
1405 cli_state_set_uid(cli, vuid1);
1407 status = cli_close(cli, fnum1);
1408 if (!NT_STATUS_IS_OK(status)) {
1409 printf("close failed (%s)\n", nt_errstr(status));
1413 cli_state_set_tid(cli, cnum2);
1415 status = cli_tdis(cli);
1416 if (!NT_STATUS_IS_OK(status)) {
1417 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1421 cli_state_restore_tcon(cli, orig_tcon);
1423 cli_state_set_tid(cli, cnum1);
1425 if (!torture_close_connection(cli)) {
1434 checks for old style tcon support
1436 static bool run_tcon2_test(int dummy)
1438 static struct cli_state *cli;
1439 uint16_t cnum, max_xmit;
1443 if (!torture_open_connection(&cli, 0)) {
1446 smbXcli_conn_set_sockopt(cli->conn, sockops);
1448 printf("starting tcon2 test\n");
1450 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1454 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1458 if (!NT_STATUS_IS_OK(status)) {
1459 printf("tcon2 failed : %s\n", nt_errstr(status));
1461 printf("tcon OK : max_xmit=%d cnum=%d\n",
1462 (int)max_xmit, (int)cnum);
1465 if (!torture_close_connection(cli)) {
1469 printf("Passed tcon2 test\n");
1473 static bool tcon_devtest(struct cli_state *cli,
1474 const char *myshare, const char *devtype,
1475 const char *return_devtype,
1476 NTSTATUS expected_error)
1481 status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
1483 if (NT_STATUS_IS_OK(expected_error)) {
1484 if (NT_STATUS_IS_OK(status)) {
1485 if (return_devtype != NULL &&
1486 strequal(cli->dev, return_devtype)) {
1489 printf("tconX to share %s with type %s "
1490 "succeeded but returned the wrong "
1491 "device type (got [%s] but should have got [%s])\n",
1492 myshare, devtype, cli->dev, return_devtype);
1496 printf("tconX to share %s with type %s "
1497 "should have succeeded but failed\n",
1503 if (NT_STATUS_IS_OK(status)) {
1504 printf("tconx to share %s with type %s "
1505 "should have failed but succeeded\n",
1509 if (NT_STATUS_EQUAL(status, expected_error)) {
1512 printf("Returned unexpected error\n");
1521 checks for correct tconX support
1523 static bool run_tcon_devtype_test(int dummy)
1525 static struct cli_state *cli1 = NULL;
1526 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
1530 status = cli_full_connection_creds(&cli1,
1536 NULL, /* service_type */
1541 if (!NT_STATUS_IS_OK(status)) {
1542 printf("could not open connection\n");
1546 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1549 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1552 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1555 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1558 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1561 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1564 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1567 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1570 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1573 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1579 printf("Passed tcondevtest\n");
1586 This test checks that
1588 1) the server supports multiple locking contexts on the one SMB
1589 connection, distinguished by PID.
1591 2) the server correctly fails overlapping locks made by the same PID (this
1592 goes against POSIX behaviour, which is why it is tricky to implement)
1594 3) the server denies unlock requests by an incorrect client PID
1596 static bool run_locktest2(int dummy)
1598 static struct cli_state *cli;
1599 const char *fname = "\\lockt2.lck";
1600 uint16_t fnum1, fnum2, fnum3;
1601 bool correct = True;
1604 if (!torture_open_connection(&cli, 0)) {
1608 smbXcli_conn_set_sockopt(cli->conn, sockops);
1610 printf("starting locktest2\n");
1612 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1616 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1622 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1623 if (!NT_STATUS_IS_OK(status)) {
1624 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1630 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1631 if (!NT_STATUS_IS_OK(status)) {
1632 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1638 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1639 if (!NT_STATUS_IS_OK(status)) {
1640 printf("lock1 failed (%s)\n", nt_errstr(status));
1644 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1645 if (NT_STATUS_IS_OK(status)) {
1646 printf("WRITE lock1 succeeded! This is a locking bug\n");
1649 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1650 NT_STATUS_LOCK_NOT_GRANTED)) {
1655 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1656 if (NT_STATUS_IS_OK(status)) {
1657 printf("WRITE lock2 succeeded! This is a locking bug\n");
1660 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1661 NT_STATUS_LOCK_NOT_GRANTED)) {
1666 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1667 if (NT_STATUS_IS_OK(status)) {
1668 printf("READ lock2 succeeded! This is a locking bug\n");
1671 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1672 NT_STATUS_FILE_LOCK_CONFLICT)) {
1677 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1678 if (!NT_STATUS_IS_OK(status)) {
1679 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1682 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1683 printf("unlock at 100 succeeded! This is a locking bug\n");
1687 status = cli_unlock(cli, fnum1, 0, 4);
1688 if (NT_STATUS_IS_OK(status)) {
1689 printf("unlock1 succeeded! This is a locking bug\n");
1692 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1693 NT_STATUS_RANGE_NOT_LOCKED)) {
1698 status = cli_unlock(cli, fnum1, 0, 8);
1699 if (NT_STATUS_IS_OK(status)) {
1700 printf("unlock2 succeeded! This is a locking bug\n");
1703 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1704 NT_STATUS_RANGE_NOT_LOCKED)) {
1709 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1710 if (NT_STATUS_IS_OK(status)) {
1711 printf("lock3 succeeded! This is a locking bug\n");
1714 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1715 NT_STATUS_LOCK_NOT_GRANTED)) {
1722 status = cli_close(cli, fnum1);
1723 if (!NT_STATUS_IS_OK(status)) {
1724 printf("close1 failed (%s)\n", nt_errstr(status));
1728 status = cli_close(cli, fnum2);
1729 if (!NT_STATUS_IS_OK(status)) {
1730 printf("close2 failed (%s)\n", nt_errstr(status));
1734 status = cli_close(cli, fnum3);
1735 if (!NT_STATUS_IS_OK(status)) {
1736 printf("close3 failed (%s)\n", nt_errstr(status));
1740 if (!torture_close_connection(cli)) {
1744 printf("locktest2 finished\n");
1751 This test checks that
1753 1) the server supports the full offset range in lock requests
1755 static bool run_locktest3(int dummy)
1757 static struct cli_state *cli1, *cli2;
1758 const char *fname = "\\lockt3.lck";
1759 uint16_t fnum1, fnum2;
1762 bool correct = True;
1765 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1767 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1770 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1771 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1773 printf("starting locktest3\n");
1775 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1777 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1779 if (!NT_STATUS_IS_OK(status)) {
1780 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1784 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1785 if (!NT_STATUS_IS_OK(status)) {
1786 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1790 for (offset=i=0;i<torture_numops;i++) {
1793 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1794 if (!NT_STATUS_IS_OK(status)) {
1795 printf("lock1 %d failed (%s)\n",
1801 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1802 if (!NT_STATUS_IS_OK(status)) {
1803 printf("lock2 %d failed (%s)\n",
1810 for (offset=i=0;i<torture_numops;i++) {
1813 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1814 if (NT_STATUS_IS_OK(status)) {
1815 printf("error: lock1 %d succeeded!\n", i);
1819 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1820 if (NT_STATUS_IS_OK(status)) {
1821 printf("error: lock2 %d succeeded!\n", i);
1825 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1826 if (NT_STATUS_IS_OK(status)) {
1827 printf("error: lock3 %d succeeded!\n", i);
1831 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1832 if (NT_STATUS_IS_OK(status)) {
1833 printf("error: lock4 %d succeeded!\n", i);
1838 for (offset=i=0;i<torture_numops;i++) {
1841 status = cli_unlock(cli1, fnum1, offset-1, 1);
1842 if (!NT_STATUS_IS_OK(status)) {
1843 printf("unlock1 %d failed (%s)\n",
1849 status = cli_unlock(cli2, fnum2, offset-2, 1);
1850 if (!NT_STATUS_IS_OK(status)) {
1851 printf("unlock2 %d failed (%s)\n",
1858 status = cli_close(cli1, fnum1);
1859 if (!NT_STATUS_IS_OK(status)) {
1860 printf("close1 failed (%s)\n", nt_errstr(status));
1864 status = cli_close(cli2, fnum2);
1865 if (!NT_STATUS_IS_OK(status)) {
1866 printf("close2 failed (%s)\n", nt_errstr(status));
1870 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1871 if (!NT_STATUS_IS_OK(status)) {
1872 printf("unlink failed (%s)\n", nt_errstr(status));
1876 if (!torture_close_connection(cli1)) {
1880 if (!torture_close_connection(cli2)) {
1884 printf("finished locktest3\n");
1889 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1890 char *buf, off_t offset, size_t size,
1891 size_t *nread, size_t expect)
1896 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1898 if(!NT_STATUS_IS_OK(status)) {
1900 } else if (l_nread != expect) {
1911 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1912 printf("** "); correct = False; \
1916 looks at overlapping locks
1918 static bool run_locktest4(int dummy)
1920 static struct cli_state *cli1, *cli2;
1921 const char *fname = "\\lockt4.lck";
1922 uint16_t fnum1, fnum2, f;
1925 bool correct = True;
1928 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1932 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1933 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1935 printf("starting locktest4\n");
1937 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1939 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1940 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1942 memset(buf, 0, sizeof(buf));
1944 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1946 if (!NT_STATUS_IS_OK(status)) {
1947 printf("Failed to create file: %s\n", nt_errstr(status));
1952 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1953 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1954 EXPECTED(ret, False);
1955 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1957 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1958 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1959 EXPECTED(ret, True);
1960 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1962 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1963 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1964 EXPECTED(ret, False);
1965 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1967 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1968 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1969 EXPECTED(ret, True);
1970 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1972 ret = (cli_setpid(cli1, 1),
1973 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1974 (cli_setpid(cli1, 2),
1975 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1976 EXPECTED(ret, False);
1977 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1979 ret = (cli_setpid(cli1, 1),
1980 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1981 (cli_setpid(cli1, 2),
1982 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1983 EXPECTED(ret, True);
1984 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1986 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1987 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1988 EXPECTED(ret, True);
1989 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1991 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1992 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1993 EXPECTED(ret, False);
1994 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1996 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1997 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1998 EXPECTED(ret, False);
1999 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
2001 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
2002 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2003 EXPECTED(ret, True);
2004 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2006 ret = (cli_setpid(cli1, 1),
2007 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2008 (cli_setpid(cli1, 2),
2009 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2010 EXPECTED(ret, False);
2011 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2013 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2014 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2015 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2016 EXPECTED(ret, False);
2017 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2020 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2021 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2022 EXPECTED(ret, False);
2023 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2025 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2026 ret = NT_STATUS_IS_OK(status);
2028 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2030 ret = NT_STATUS_IS_OK(status);
2032 EXPECTED(ret, False);
2033 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2036 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2037 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2038 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2039 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2040 EXPECTED(ret, True);
2041 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2044 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2045 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2046 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2047 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2048 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2050 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2051 EXPECTED(ret, True);
2052 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2054 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2055 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2056 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2058 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2059 EXPECTED(ret, True);
2060 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2062 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2063 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2064 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2066 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2067 EXPECTED(ret, True);
2068 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2070 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2071 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2072 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2073 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2075 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2076 EXPECTED(ret, True);
2077 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2079 cli_close(cli1, fnum1);
2080 cli_close(cli2, fnum2);
2081 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2082 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2083 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2084 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2085 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2086 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2087 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2089 cli_close(cli1, fnum1);
2090 EXPECTED(ret, True);
2091 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2094 cli_close(cli1, fnum1);
2095 cli_close(cli2, fnum2);
2096 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2097 torture_close_connection(cli1);
2098 torture_close_connection(cli2);
2100 printf("finished locktest4\n");
2105 looks at lock upgrade/downgrade.
2107 static bool run_locktest5(int dummy)
2109 static struct cli_state *cli1, *cli2;
2110 const char *fname = "\\lockt5.lck";
2111 uint16_t fnum1, fnum2, fnum3;
2114 bool correct = True;
2117 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2121 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2122 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2124 printf("starting locktest5\n");
2126 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2128 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2129 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2130 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2132 memset(buf, 0, sizeof(buf));
2134 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2136 if (!NT_STATUS_IS_OK(status)) {
2137 printf("Failed to create file: %s\n", nt_errstr(status));
2142 /* Check for NT bug... */
2143 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2144 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2145 cli_close(cli1, fnum1);
2146 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2147 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2148 ret = NT_STATUS_IS_OK(status);
2149 EXPECTED(ret, True);
2150 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2151 cli_close(cli1, fnum1);
2152 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2153 cli_unlock(cli1, fnum3, 0, 1);
2155 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2156 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2157 EXPECTED(ret, True);
2158 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2160 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2161 ret = NT_STATUS_IS_OK(status);
2162 EXPECTED(ret, False);
2164 printf("a different process %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2166 /* Unlock the process 2 lock. */
2167 cli_unlock(cli2, fnum2, 0, 4);
2169 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2170 ret = NT_STATUS_IS_OK(status);
2171 EXPECTED(ret, False);
2173 printf("the same process on a different fnum %s get a read lock\n", ret?"can":"cannot");
2175 /* Unlock the process 1 fnum3 lock. */
2176 cli_unlock(cli1, fnum3, 0, 4);
2178 /* Stack 2 more locks here. */
2179 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2180 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2182 EXPECTED(ret, True);
2183 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2185 /* Unlock the first process lock, then check this was the WRITE lock that was
2188 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2189 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2191 EXPECTED(ret, True);
2192 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2194 /* Unlock the process 2 lock. */
2195 cli_unlock(cli2, fnum2, 0, 4);
2197 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2199 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2200 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2201 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2203 EXPECTED(ret, True);
2204 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2206 /* Ensure the next unlock fails. */
2207 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2208 EXPECTED(ret, False);
2209 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2211 /* Ensure connection 2 can get a write lock. */
2212 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2213 ret = NT_STATUS_IS_OK(status);
2214 EXPECTED(ret, True);
2216 printf("a different process %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2220 cli_close(cli1, fnum1);
2221 cli_close(cli2, fnum2);
2222 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2223 if (!torture_close_connection(cli1)) {
2226 if (!torture_close_connection(cli2)) {
2230 printf("finished locktest5\n");
2236 tries the unusual lockingX locktype bits
2238 static bool run_locktest6(int dummy)
2240 static struct cli_state *cli;
2241 const char *fname[1] = { "\\lock6.txt" };
2246 if (!torture_open_connection(&cli, 0)) {
2250 smbXcli_conn_set_sockopt(cli->conn, sockops);
2252 printf("starting locktest6\n");
2255 printf("Testing %s\n", fname[i]);
2257 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2259 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2260 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2261 cli_close(cli, fnum);
2262 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2264 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2265 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2266 cli_close(cli, fnum);
2267 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2269 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2272 torture_close_connection(cli);
2274 printf("finished locktest6\n");
2278 static bool run_locktest7(int dummy)
2280 struct cli_state *cli1;
2281 const char *fname = "\\lockt7.lck";
2284 bool correct = False;
2288 if (!torture_open_connection(&cli1, 0)) {
2292 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2294 printf("starting locktest7\n");
2296 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2298 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2300 memset(buf, 0, sizeof(buf));
2302 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2304 if (!NT_STATUS_IS_OK(status)) {
2305 printf("Failed to create file: %s\n", nt_errstr(status));
2309 cli_setpid(cli1, 1);
2311 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2312 if (!NT_STATUS_IS_OK(status)) {
2313 printf("Unable to apply read lock on range 130:4, "
2314 "error was %s\n", nt_errstr(status));
2317 printf("pid1 successfully locked range 130:4 for READ\n");
2320 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2321 if (!NT_STATUS_IS_OK(status)) {
2322 printf("pid1 unable to read the range 130:4, error was %s\n",
2325 } else if (nread != 4) {
2326 printf("pid1 unable to read the range 130:4, "
2327 "recv %ld req %d\n", (unsigned long)nread, 4);
2330 printf("pid1 successfully read the range 130:4\n");
2333 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2334 if (!NT_STATUS_IS_OK(status)) {
2335 printf("pid1 unable to write to the range 130:4, error was "
2336 "%s\n", nt_errstr(status));
2337 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2338 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2342 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2346 cli_setpid(cli1, 2);
2348 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2349 if (!NT_STATUS_IS_OK(status)) {
2350 printf("pid2 unable to read the range 130:4, error was %s\n",
2353 } else if (nread != 4) {
2354 printf("pid2 unable to read the range 130:4, "
2355 "recv %ld req %d\n", (unsigned long)nread, 4);
2358 printf("pid2 successfully read the range 130:4\n");
2361 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 printf("pid2 unable to write to the range 130:4, error was "
2364 "%s\n", nt_errstr(status));
2365 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2366 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2370 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2374 cli_setpid(cli1, 1);
2375 cli_unlock(cli1, fnum1, 130, 4);
2377 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2378 if (!NT_STATUS_IS_OK(status)) {
2379 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2382 printf("pid1 successfully locked range 130:4 for WRITE\n");
2385 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 printf("pid1 unable to read the range 130:4, error was %s\n",
2390 } else if (nread != 4) {
2391 printf("pid1 unable to read the range 130:4, "
2392 "recv %ld req %d\n", (unsigned long)nread, 4);
2395 printf("pid1 successfully read the range 130:4\n");
2398 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2399 if (!NT_STATUS_IS_OK(status)) {
2400 printf("pid1 unable to write to the range 130:4, error was "
2401 "%s\n", nt_errstr(status));
2404 printf("pid1 successfully wrote to the range 130:4\n");
2407 cli_setpid(cli1, 2);
2409 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2410 if (!NT_STATUS_IS_OK(status)) {
2411 printf("pid2 unable to read the range 130:4, error was "
2412 "%s\n", nt_errstr(status));
2413 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2414 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2418 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2419 (unsigned long)nread);
2423 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2424 if (!NT_STATUS_IS_OK(status)) {
2425 printf("pid2 unable to write to the range 130:4, error was "
2426 "%s\n", nt_errstr(status));
2427 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2428 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2432 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2436 cli_unlock(cli1, fnum1, 130, 0);
2440 cli_close(cli1, fnum1);
2441 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2442 torture_close_connection(cli1);
2444 printf("finished locktest7\n");
2449 * This demonstrates a problem with our use of GPFS share modes: A file
2450 * descriptor sitting in the pending close queue holding a GPFS share mode
2451 * blocks opening a file another time. Happens with Word 2007 temp files.
2452 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2453 * open is denied with NT_STATUS_SHARING_VIOLATION.
2456 static bool run_locktest8(int dummy)
2458 struct cli_state *cli1;
2459 const char *fname = "\\lockt8.lck";
2460 uint16_t fnum1, fnum2;
2462 bool correct = False;
2465 if (!torture_open_connection(&cli1, 0)) {
2469 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2471 printf("starting locktest8\n");
2473 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2475 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2477 if (!NT_STATUS_IS_OK(status)) {
2478 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2482 memset(buf, 0, sizeof(buf));
2484 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2485 if (!NT_STATUS_IS_OK(status)) {
2486 d_fprintf(stderr, "cli_openx second time returned %s\n",
2491 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2492 if (!NT_STATUS_IS_OK(status)) {
2493 printf("Unable to apply read lock on range 1:1, error was "
2494 "%s\n", nt_errstr(status));
2498 status = cli_close(cli1, fnum1);
2499 if (!NT_STATUS_IS_OK(status)) {
2500 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2504 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2505 if (!NT_STATUS_IS_OK(status)) {
2506 d_fprintf(stderr, "cli_openx third time returned %s\n",
2514 cli_close(cli1, fnum1);
2515 cli_close(cli1, fnum2);
2516 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2517 torture_close_connection(cli1);
2519 printf("finished locktest8\n");
2524 * This test is designed to be run in conjunction with
2525 * external NFS or POSIX locks taken in the filesystem.
2526 * It checks that the smbd server will block until the
2527 * lock is released and then acquire it. JRA.
2530 static bool got_alarm;
2531 static struct cli_state *alarm_cli;
2533 static void alarm_handler(int dummy)
2538 static void alarm_handler_parent(int dummy)
2540 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2543 static void do_local_lock(int read_fd, int write_fd)
2548 const char *local_pathname = NULL;
2551 local_pathname = talloc_asprintf(talloc_tos(),
2552 "%s/lockt9.lck", local_path);
2553 if (!local_pathname) {
2554 printf("child: alloc fail\n");
2558 unlink(local_pathname);
2559 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2561 printf("child: open of %s failed %s.\n",
2562 local_pathname, strerror(errno));
2566 /* Now take a fcntl lock. */
2567 lock.l_type = F_WRLCK;
2568 lock.l_whence = SEEK_SET;
2571 lock.l_pid = getpid();
2573 ret = fcntl(fd,F_SETLK,&lock);
2575 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2576 local_pathname, strerror(errno));
2579 printf("child: got lock 0:4 on file %s.\n",
2584 CatchSignal(SIGALRM, alarm_handler);
2586 /* Signal the parent. */
2587 if (write(write_fd, &c, 1) != 1) {
2588 printf("child: start signal fail %s.\n",
2595 /* Wait for the parent to be ready. */
2596 if (read(read_fd, &c, 1) != 1) {
2597 printf("child: reply signal fail %s.\n",
2605 printf("child: released lock 0:4 on file %s.\n",
2611 static bool run_locktest9(int dummy)
2613 struct cli_state *cli1;
2614 const char *fname = "\\lockt9.lck";
2616 bool correct = False;
2617 int pipe_in[2], pipe_out[2];
2621 struct timeval start;
2625 printf("starting locktest9\n");
2627 if (local_path == NULL) {
2628 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2632 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2637 if (child_pid == -1) {
2641 if (child_pid == 0) {
2643 do_local_lock(pipe_out[0], pipe_in[1]);
2653 ret = read(pipe_in[0], &c, 1);
2655 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2660 if (!torture_open_connection(&cli1, 0)) {
2664 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2666 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2668 if (!NT_STATUS_IS_OK(status)) {
2669 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2673 /* Ensure the child has the lock. */
2674 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2675 if (NT_STATUS_IS_OK(status)) {
2676 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2679 d_printf("Child has the lock.\n");
2682 /* Tell the child to wait 5 seconds then exit. */
2683 ret = write(pipe_out[1], &c, 1);
2685 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2690 /* Wait 20 seconds for the lock. */
2692 CatchSignal(SIGALRM, alarm_handler_parent);
2695 start = timeval_current();
2697 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2698 if (!NT_STATUS_IS_OK(status)) {
2699 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2700 "%s\n", nt_errstr(status));
2705 seconds = timeval_elapsed(&start);
2707 printf("Parent got the lock after %.2f seconds.\n",
2710 status = cli_close(cli1, fnum);
2711 if (!NT_STATUS_IS_OK(status)) {
2712 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2719 cli_close(cli1, fnum);
2720 torture_close_connection(cli1);
2724 printf("finished locktest9\n");
2729 test whether fnums and tids open on one VC are available on another (a major
2732 static bool run_fdpasstest(int dummy)
2734 struct cli_state *cli1, *cli2;
2735 const char *fname = "\\fdpass.tst";
2740 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2743 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2744 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2746 printf("starting fdpasstest\n");
2748 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2750 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2752 if (!NT_STATUS_IS_OK(status)) {
2753 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2757 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2759 if (!NT_STATUS_IS_OK(status)) {
2760 printf("write failed (%s)\n", nt_errstr(status));
2764 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2765 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2766 cli_setpid(cli2, cli_getpid(cli1));
2768 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2769 printf("read succeeded! nasty security hole [%s]\n", buf);
2773 cli_close(cli1, fnum1);
2774 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2776 torture_close_connection(cli1);
2777 torture_close_connection(cli2);
2779 printf("finished fdpasstest\n");
2783 static bool run_fdsesstest(int dummy)
2785 struct cli_state *cli;
2787 uint16_t saved_vuid;
2789 uint32_t saved_cnum;
2790 const char *fname = "\\fdsess.tst";
2791 const char *fname1 = "\\fdsess1.tst";
2798 if (!torture_open_connection(&cli, 0))
2800 smbXcli_conn_set_sockopt(cli->conn, sockops);
2802 if (!torture_cli_session_setup2(cli, &new_vuid))
2805 saved_cnum = cli_state_get_tid(cli);
2806 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
2808 new_cnum = cli_state_get_tid(cli);
2809 cli_state_set_tid(cli, saved_cnum);
2811 printf("starting fdsesstest\n");
2813 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2814 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2816 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2817 if (!NT_STATUS_IS_OK(status)) {
2818 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2822 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2824 if (!NT_STATUS_IS_OK(status)) {
2825 printf("write failed (%s)\n", nt_errstr(status));
2829 saved_vuid = cli_state_get_uid(cli);
2830 cli_state_set_uid(cli, new_vuid);
2832 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2833 printf("read succeeded with different vuid! "
2834 "nasty security hole [%s]\n", buf);
2837 /* Try to open a file with different vuid, samba cnum. */
2838 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2839 printf("create with different vuid, same cnum succeeded.\n");
2840 cli_close(cli, fnum2);
2841 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2843 printf("create with different vuid, same cnum failed.\n");
2844 printf("This will cause problems with service clients.\n");
2848 cli_state_set_uid(cli, saved_vuid);
2850 /* Try with same vuid, different cnum. */
2851 cli_state_set_tid(cli, new_cnum);
2853 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2854 printf("read succeeded with different cnum![%s]\n", buf);
2858 cli_state_set_tid(cli, saved_cnum);
2859 cli_close(cli, fnum1);
2860 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2862 torture_close_connection(cli);
2864 printf("finished fdsesstest\n");
2869 This test checks that
2871 1) the server does not allow an unlink on a file that is open
2873 static bool run_unlinktest(int dummy)
2875 struct cli_state *cli;
2876 const char *fname = "\\unlink.tst";
2878 bool correct = True;
2881 if (!torture_open_connection(&cli, 0)) {
2885 smbXcli_conn_set_sockopt(cli->conn, sockops);
2887 printf("starting unlink test\n");
2889 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2893 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2894 if (!NT_STATUS_IS_OK(status)) {
2895 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2899 status = cli_unlink(cli, fname,
2900 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2901 if (NT_STATUS_IS_OK(status)) {
2902 printf("error: server allowed unlink on an open file\n");
2905 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2906 NT_STATUS_SHARING_VIOLATION);
2909 cli_close(cli, fnum);
2910 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2912 if (!torture_close_connection(cli)) {
2916 printf("unlink test finished\n");
2923 test how many open files this server supports on the one socket
2925 static bool run_maxfidtest(int dummy)
2927 struct cli_state *cli;
2929 uint16_t fnums[0x11000];
2932 bool correct = True;
2938 printf("failed to connect\n");
2942 smbXcli_conn_set_sockopt(cli->conn, sockops);
2944 for (i=0; i<0x11000; i++) {
2945 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2946 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2948 if (!NT_STATUS_IS_OK(status)) {
2949 printf("open of %s failed (%s)\n",
2950 fname, nt_errstr(status));
2951 printf("maximum fnum is %d\n", i);
2959 printf("cleaning up\n");
2961 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2962 cli_close(cli, fnums[i]);
2964 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2965 if (!NT_STATUS_IS_OK(status)) {
2966 printf("unlink of %s failed (%s)\n",
2967 fname, nt_errstr(status));
2974 printf("maxfid test finished\n");
2975 if (!torture_close_connection(cli)) {
2981 /* generate a random buffer */
2982 static void rand_buf(char *buf, int len)
2985 *buf = (char)sys_random();
2990 /* send smb negprot commands, not reading the response */
2991 static bool run_negprot_nowait(int dummy)
2993 struct tevent_context *ev;
2995 struct cli_state *cli;
2996 bool correct = True;
2998 printf("starting negprot nowait test\n");
3000 ev = samba_tevent_context_init(talloc_tos());
3005 if (!(cli = open_nbt_connection())) {
3010 for (i=0;i<50000;i++) {
3011 struct tevent_req *req;
3013 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3014 PROTOCOL_CORE, PROTOCOL_NT1, 0);
3019 if (!tevent_req_poll(req, ev)) {
3020 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3028 if (torture_close_connection(cli)) {
3032 printf("finished negprot nowait test\n");
3037 /* send smb negprot commands, not reading the response */
3038 static bool run_bad_nbt_session(int dummy)
3040 struct nmb_name called, calling;
3041 struct sockaddr_storage ss;
3046 printf("starting bad nbt session test\n");
3048 make_nmb_name(&calling, myname, 0x0);
3049 make_nmb_name(&called , host, 0x20);
3051 if (!resolve_name(host, &ss, 0x20, true)) {
3052 d_fprintf(stderr, "Could not resolve name %s\n", host);
3056 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3057 if (!NT_STATUS_IS_OK(status)) {
3058 d_fprintf(stderr, "open_socket_out failed: %s\n",
3063 ret = cli_bad_session_request(fd, &calling, &called);
3066 d_fprintf(stderr, "open_socket_out failed: %s\n",
3071 printf("finished bad nbt session test\n");
3075 /* send random IPC commands */
3076 static bool run_randomipc(int dummy)
3078 char *rparam = NULL;
3080 unsigned int rdrcnt,rprcnt;
3082 int api, param_len, i;
3083 struct cli_state *cli;
3084 bool correct = True;
3087 printf("starting random ipc test\n");
3089 if (!torture_open_connection(&cli, 0)) {
3093 for (i=0;i<count;i++) {
3094 api = sys_random() % 500;
3095 param_len = (sys_random() % 64);
3097 rand_buf(param, param_len);
3102 param, param_len, 8,
3103 NULL, 0, CLI_BUFFER_SIZE,
3107 printf("%d/%d\r", i,count);
3110 printf("%d/%d\n", i, count);
3112 if (!torture_close_connection(cli)) {
3119 printf("finished random ipc test\n");
3126 static void browse_callback(const char *sname, uint32_t stype,
3127 const char *comment, void *state)
3129 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3135 This test checks the browse list code
3138 static bool run_browsetest(int dummy)
3140 static struct cli_state *cli;
3141 bool correct = True;
3143 printf("starting browse test\n");
3145 if (!torture_open_connection(&cli, 0)) {
3149 printf("domain list:\n");
3150 cli_NetServerEnum(cli, cli->server_domain,
3151 SV_TYPE_DOMAIN_ENUM,
3152 browse_callback, NULL);
3154 printf("machine list:\n");
3155 cli_NetServerEnum(cli, cli->server_domain,
3157 browse_callback, NULL);
3159 if (!torture_close_connection(cli)) {
3163 printf("browse test finished\n");
3169 static bool check_attributes(struct cli_state *cli,
3171 uint16_t expected_attrs)
3174 NTSTATUS status = cli_getatr(cli,
3179 if (!NT_STATUS_IS_OK(status)) {
3180 printf("cli_getatr failed with %s\n",
3184 if (attrs != expected_attrs) {
3185 printf("Attributes incorrect 0x%x, should be 0x%x\n",
3186 (unsigned int)attrs,
3187 (unsigned int)expected_attrs);
3194 This checks how the getatr calls works
3196 static bool run_attrtest(int dummy)
3198 struct cli_state *cli;
3201 const char *fname = "\\attrib123456789.tst";
3202 bool correct = True;
3205 printf("starting attrib test\n");
3207 if (!torture_open_connection(&cli, 0)) {
3211 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3212 cli_openx(cli, fname,
3213 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3214 cli_close(cli, fnum);
3216 status = cli_getatr(cli, fname, NULL, NULL, &t);
3217 if (!NT_STATUS_IS_OK(status)) {
3218 printf("getatr failed (%s)\n", nt_errstr(status));
3222 if (labs(t - time(NULL)) > 60*60*24*10) {
3223 printf("ERROR: SMBgetatr bug. time is %s",
3229 t2 = t-60*60*24; /* 1 day ago */
3231 status = cli_setatr(cli, fname, 0, t2);
3232 if (!NT_STATUS_IS_OK(status)) {
3233 printf("setatr failed (%s)\n", nt_errstr(status));
3237 status = cli_getatr(cli, fname, NULL, NULL, &t);
3238 if (!NT_STATUS_IS_OK(status)) {
3239 printf("getatr failed (%s)\n", nt_errstr(status));
3244 printf("ERROR: getatr/setatr bug. times are\n%s",
3246 printf("%s", ctime(&t2));
3250 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3252 /* Check cli_setpathinfo_basic() */
3253 /* Re-create the file. */
3254 status = cli_openx(cli, fname,
3255 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3256 if (!NT_STATUS_IS_OK(status)) {
3257 printf("Failed to recreate %s (%s)\n",
3258 fname, nt_errstr(status));
3261 cli_close(cli, fnum);
3263 status = cli_setpathinfo_basic(cli,
3269 FILE_ATTRIBUTE_SYSTEM |
3270 FILE_ATTRIBUTE_HIDDEN |
3271 FILE_ATTRIBUTE_READONLY);
3272 if (!NT_STATUS_IS_OK(status)) {
3273 printf("cli_setpathinfo_basic failed with %s\n",
3278 /* Check attributes are correct. */
3279 correct = check_attributes(cli,
3281 FILE_ATTRIBUTE_SYSTEM |
3282 FILE_ATTRIBUTE_HIDDEN |
3283 FILE_ATTRIBUTE_READONLY);
3284 if (correct == false) {
3288 /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
3289 status = cli_setpathinfo_basic(cli,
3295 FILE_ATTRIBUTE_NORMAL);
3296 if (!NT_STATUS_IS_OK(status)) {
3297 printf("cli_setpathinfo_basic failed with %s\n",
3302 /* Check attributes are correct. */
3303 correct = check_attributes(cli,
3305 FILE_ATTRIBUTE_SYSTEM |
3306 FILE_ATTRIBUTE_HIDDEN |
3307 FILE_ATTRIBUTE_READONLY);
3308 if (correct == false) {
3312 /* Setting to (uint16_t)-1 should also be ignored. */
3313 status = cli_setpathinfo_basic(cli,
3320 if (!NT_STATUS_IS_OK(status)) {
3321 printf("cli_setpathinfo_basic failed with %s\n",
3326 /* Check attributes are correct. */
3327 correct = check_attributes(cli,
3329 FILE_ATTRIBUTE_SYSTEM |
3330 FILE_ATTRIBUTE_HIDDEN |
3331 FILE_ATTRIBUTE_READONLY);
3332 if (correct == false) {
3336 /* Setting to 0 should clear them all. */
3337 status = cli_setpathinfo_basic(cli,
3344 if (!NT_STATUS_IS_OK(status)) {
3345 printf("cli_setpathinfo_basic failed with %s\n",
3350 /* Check attributes are correct. */
3351 correct = check_attributes(cli,
3353 FILE_ATTRIBUTE_NORMAL);
3354 if (correct == false) {
3362 FILE_ATTRIBUTE_SYSTEM |
3363 FILE_ATTRIBUTE_HIDDEN|
3364 FILE_ATTRIBUTE_READONLY);
3366 if (!torture_close_connection(cli)) {
3370 printf("attrib test finished\n");
3377 This checks a couple of trans2 calls
3379 static bool run_trans2test(int dummy)
3381 struct cli_state *cli;
3384 time_t c_time, a_time, m_time;
3385 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3386 const char *fname = "\\trans2.tst";
3387 const char *dname = "\\trans2";
3388 const char *fname2 = "\\trans2\\trans2.tst";
3390 bool correct = True;
3394 printf("starting trans2 test\n");
3396 if (!torture_open_connection(&cli, 0)) {
3400 status = cli_get_fs_attr_info(cli, &fs_attr);
3401 if (!NT_STATUS_IS_OK(status)) {
3402 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3407 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3408 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3409 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3410 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3411 if (!NT_STATUS_IS_OK(status)) {
3412 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3416 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3417 if (!NT_STATUS_IS_OK(status)) {
3418 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3421 else if (strcmp(pname, fname)) {
3422 printf("qfilename gave different name? [%s] [%s]\n",
3427 cli_close(cli, fnum);
3431 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3432 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3434 if (!NT_STATUS_IS_OK(status)) {
3435 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3438 cli_close(cli, fnum);
3440 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3442 if (!NT_STATUS_IS_OK(status)) {
3443 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3446 time_t t = time(NULL);
3448 if (c_time != m_time) {
3449 printf("create time=%s", ctime(&c_time));
3450 printf("modify time=%s", ctime(&m_time));
3451 printf("This system appears to have sticky create times\n");
3453 if ((labs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3454 printf("access time=%s", ctime(&a_time));
3455 printf("This system appears to set a midnight access time\n");
3459 if (labs(m_time - t) > 60*60*24*7) {
3460 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3466 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3467 cli_openx(cli, fname,
3468 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3469 cli_close(cli, fnum);
3470 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3471 &m_time_ts, &size, NULL, NULL);
3472 if (!NT_STATUS_IS_OK(status)) {
3473 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3476 if (w_time_ts.tv_sec < 60*60*24*2) {
3477 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3478 printf("This system appears to set a initial 0 write time\n");
3483 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3486 /* check if the server updates the directory modification time
3487 when creating a new file */
3488 status = cli_mkdir(cli, dname);
3489 if (!NT_STATUS_IS_OK(status)) {
3490 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3494 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3495 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3496 if (!NT_STATUS_IS_OK(status)) {
3497 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3501 cli_openx(cli, fname2,
3502 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3503 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3504 cli_close(cli, fnum);
3505 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3506 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3507 if (!NT_STATUS_IS_OK(status)) {
3508 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3511 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3513 printf("This system does not update directory modification times\n");
3517 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3518 cli_rmdir(cli, dname);
3520 if (!torture_close_connection(cli)) {
3524 printf("trans2 test finished\n");
3530 This checks new W2K calls.
3533 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3535 uint8_t *buf = NULL;
3539 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3540 CLI_BUFFER_SIZE, NULL, &buf, &len);
3541 if (!NT_STATUS_IS_OK(status)) {
3542 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3545 printf("qfileinfo: level %d, len = %u\n", level, len);
3546 dump_data(0, (uint8_t *)buf, len);
3553 static bool run_w2ktest(int dummy)
3555 struct cli_state *cli;
3557 const char *fname = "\\w2ktest\\w2k.tst";
3559 bool correct = True;
3561 printf("starting w2k test\n");
3563 if (!torture_open_connection(&cli, 0)) {
3567 cli_openx(cli, fname,
3568 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3570 for (level = 1004; level < 1040; level++) {
3571 new_trans(cli, fnum, level);
3574 cli_close(cli, fnum);
3576 if (!torture_close_connection(cli)) {
3580 printf("w2k test finished\n");
3587 this is a harness for some oplock tests
3589 static bool run_oplock1(int dummy)
3591 struct cli_state *cli1;
3592 const char *fname = "\\lockt1.lck";
3594 bool correct = True;
3597 printf("starting oplock test 1\n");
3599 if (!torture_open_connection(&cli1, 0)) {
3603 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3605 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3607 cli1->use_oplocks = True;
3609 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3611 if (!NT_STATUS_IS_OK(status)) {
3612 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3616 cli1->use_oplocks = False;
3618 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3619 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3621 status = cli_close(cli1, fnum1);
3622 if (!NT_STATUS_IS_OK(status)) {
3623 printf("close2 failed (%s)\n", nt_errstr(status));
3627 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3628 if (!NT_STATUS_IS_OK(status)) {
3629 printf("unlink failed (%s)\n", nt_errstr(status));
3633 if (!torture_close_connection(cli1)) {
3637 printf("finished oplock test 1\n");
3642 static bool run_oplock2(int dummy)
3644 struct cli_state *cli1, *cli2;
3645 const char *fname = "\\lockt2.lck";
3646 uint16_t fnum1, fnum2;
3647 int saved_use_oplocks = use_oplocks;
3649 bool correct = True;
3650 volatile bool *shared_correct;
3654 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3655 *shared_correct = True;
3657 use_level_II_oplocks = True;
3660 printf("starting oplock test 2\n");
3662 if (!torture_open_connection(&cli1, 0)) {
3663 use_level_II_oplocks = False;
3664 use_oplocks = saved_use_oplocks;
3668 if (!torture_open_connection(&cli2, 1)) {
3669 use_level_II_oplocks = False;
3670 use_oplocks = saved_use_oplocks;
3674 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3676 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3677 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3679 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3681 if (!NT_STATUS_IS_OK(status)) {
3682 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3686 /* Don't need the globals any more. */
3687 use_level_II_oplocks = False;
3688 use_oplocks = saved_use_oplocks;
3692 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3693 if (!NT_STATUS_IS_OK(status)) {
3694 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3695 *shared_correct = False;
3701 status = cli_close(cli2, fnum2);
3702 if (!NT_STATUS_IS_OK(status)) {
3703 printf("close2 failed (%s)\n", nt_errstr(status));
3704 *shared_correct = False;
3712 /* Ensure cli1 processes the break. Empty file should always return 0
3714 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3715 if (!NT_STATUS_IS_OK(status)) {
3716 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3718 } else if (nread != 0) {
3719 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3720 (unsigned long)nread, 0);
3724 /* Should now be at level II. */
3725 /* Test if sending a write locks causes a break to none. */
3726 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3727 if (!NT_STATUS_IS_OK(status)) {
3728 printf("lock failed (%s)\n", nt_errstr(status));
3732 cli_unlock(cli1, fnum1, 0, 4);
3736 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3737 if (!NT_STATUS_IS_OK(status)) {
3738 printf("lock failed (%s)\n", nt_errstr(status));
3742 cli_unlock(cli1, fnum1, 0, 4);
3746 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3748 status = cli_close(cli1, fnum1);
3749 if (!NT_STATUS_IS_OK(status)) {
3750 printf("close1 failed (%s)\n", nt_errstr(status));
3756 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3757 if (!NT_STATUS_IS_OK(status)) {
3758 printf("unlink failed (%s)\n", nt_errstr(status));
3762 if (!torture_close_connection(cli1)) {
3766 if (!*shared_correct) {
3770 printf("finished oplock test 2\n");
3775 struct oplock4_state {
3776 struct tevent_context *ev;
3777 struct cli_state *cli;
3782 static void oplock4_got_break(struct tevent_req *req);
3783 static void oplock4_got_open(struct tevent_req *req);
3785 static bool run_oplock4(int dummy)
3787 struct tevent_context *ev;
3788 struct cli_state *cli1, *cli2;
3789 struct tevent_req *oplock_req, *open_req;
3790 const char *fname = "\\lockt4.lck";
3791 const char *fname_ln = "\\lockt4_ln.lck";
3792 uint16_t fnum1, fnum2;
3793 int saved_use_oplocks = use_oplocks;
3795 bool correct = true;
3799 struct oplock4_state *state;
3801 printf("starting oplock test 4\n");
3803 if (!torture_open_connection(&cli1, 0)) {
3804 use_level_II_oplocks = false;
3805 use_oplocks = saved_use_oplocks;
3809 if (!torture_open_connection(&cli2, 1)) {
3810 use_level_II_oplocks = false;
3811 use_oplocks = saved_use_oplocks;
3815 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3816 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3818 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3819 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3821 /* Create the file. */
3822 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3824 if (!NT_STATUS_IS_OK(status)) {
3825 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3829 status = cli_close(cli1, fnum1);
3830 if (!NT_STATUS_IS_OK(status)) {
3831 printf("close1 failed (%s)\n", nt_errstr(status));
3835 /* Now create a hardlink. */
3836 status = cli_nt_hardlink(cli1, fname, fname_ln);
3837 if (!NT_STATUS_IS_OK(status)) {
3838 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3842 /* Prove that opening hardlinks cause deny modes to conflict. */
3843 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3844 if (!NT_STATUS_IS_OK(status)) {
3845 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3849 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3850 if (NT_STATUS_IS_OK(status)) {
3851 printf("open of %s succeeded - should fail with sharing violation.\n",
3856 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3857 printf("open of %s should fail with sharing violation. Got %s\n",
3858 fname_ln, nt_errstr(status));
3862 status = cli_close(cli1, fnum1);
3863 if (!NT_STATUS_IS_OK(status)) {
3864 printf("close1 failed (%s)\n", nt_errstr(status));
3868 cli1->use_oplocks = true;
3869 cli2->use_oplocks = true;
3871 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3872 if (!NT_STATUS_IS_OK(status)) {
3873 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3877 ev = samba_tevent_context_init(talloc_tos());
3879 printf("tevent_context_init failed\n");
3883 state = talloc(ev, struct oplock4_state);
3884 if (state == NULL) {
3885 printf("talloc failed\n");
3890 state->got_break = &got_break;
3891 state->fnum2 = &fnum2;
3893 oplock_req = cli_smb_oplock_break_waiter_send(
3894 talloc_tos(), ev, cli1);
3895 if (oplock_req == NULL) {
3896 printf("cli_smb_oplock_break_waiter_send failed\n");
3899 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3901 open_req = cli_openx_send(
3902 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3903 if (open_req == NULL) {
3904 printf("cli_openx_send failed\n");
3907 tevent_req_set_callback(open_req, oplock4_got_open, state);
3912 while (!got_break || fnum2 == 0xffff) {
3914 ret = tevent_loop_once(ev);
3916 printf("tevent_loop_once failed: %s\n",
3922 status = cli_close(cli2, fnum2);
3923 if (!NT_STATUS_IS_OK(status)) {
3924 printf("close2 failed (%s)\n", nt_errstr(status));
3928 status = cli_close(cli1, fnum1);
3929 if (!NT_STATUS_IS_OK(status)) {
3930 printf("close1 failed (%s)\n", nt_errstr(status));
3934 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3935 if (!NT_STATUS_IS_OK(status)) {
3936 printf("unlink failed (%s)\n", nt_errstr(status));
3940 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3941 if (!NT_STATUS_IS_OK(status)) {
3942 printf("unlink failed (%s)\n", nt_errstr(status));
3946 if (!torture_close_connection(cli1)) {
3954 printf("finished oplock test 4\n");
3959 static void oplock4_got_break(struct tevent_req *req)
3961 struct oplock4_state *state = tevent_req_callback_data(
3962 req, struct oplock4_state);
3967 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3969 if (!NT_STATUS_IS_OK(status)) {
3970 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3974 *state->got_break = true;
3976 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3979 printf("cli_oplock_ack_send failed\n");
3984 static void oplock4_got_open(struct tevent_req *req)
3986 struct oplock4_state *state = tevent_req_callback_data(
3987 req, struct oplock4_state);
3990 status = cli_openx_recv(req, state->fnum2);
3991 if (!NT_STATUS_IS_OK(status)) {
3992 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3993 *state->fnum2 = 0xffff;
3998 Test delete on close semantics.
4000 static bool run_deletetest(int dummy)
4002 struct cli_state *cli1 = NULL;
4003 struct cli_state *cli2 = NULL;
4004 const char *fname = "\\delete.file";
4005 uint16_t fnum1 = (uint16_t)-1;
4006 uint16_t fnum2 = (uint16_t)-1;
4007 bool correct = false;
4010 printf("starting delete test\n");
4012 if (!torture_open_connection(&cli1, 0)) {
4016 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4018 /* Test 1 - this should delete the file on close. */
4020 cli_setatr(cli1, fname, 0, 0);
4021 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4023 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4024 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4025 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4026 if (!NT_STATUS_IS_OK(status)) {
4027 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
4031 status = cli_close(cli1, fnum1);
4032 if (!NT_STATUS_IS_OK(status)) {
4033 printf("[1] close failed (%s)\n", nt_errstr(status));
4037 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
4038 if (NT_STATUS_IS_OK(status)) {
4039 printf("[1] open of %s succeeded (should fail)\n", fname);
4043 printf("first delete on close test succeeded.\n");
4045 /* Test 2 - this should delete the file on close. */
4047 cli_setatr(cli1, fname, 0, 0);
4048 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4050 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4051 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4052 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4053 if (!NT_STATUS_IS_OK(status)) {
4054 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
4058 status = cli_nt_delete_on_close(cli1, fnum1, true);
4059 if (!NT_STATUS_IS_OK(status)) {
4060 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
4064 status = cli_close(cli1, fnum1);
4065 if (!NT_STATUS_IS_OK(status)) {
4066 printf("[2] close failed (%s)\n", nt_errstr(status));
4070 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4071 if (NT_STATUS_IS_OK(status)) {
4072 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
4073 status = cli_close(cli1, fnum1);
4074 if (!NT_STATUS_IS_OK(status)) {
4075 printf("[2] close failed (%s)\n", nt_errstr(status));
4077 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4081 printf("second delete on close test succeeded.\n");
4084 cli_setatr(cli1, fname, 0, 0);
4085 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4087 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4088 FILE_ATTRIBUTE_NORMAL,
4089 FILE_SHARE_READ|FILE_SHARE_WRITE,
4090 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4091 if (!NT_STATUS_IS_OK(status)) {
4092 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
4096 /* This should fail with a sharing violation - open for delete is only compatible
4097 with SHARE_DELETE. */
4099 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4100 FILE_ATTRIBUTE_NORMAL,
4101 FILE_SHARE_READ|FILE_SHARE_WRITE,
4102 FILE_OPEN, 0, 0, &fnum2, NULL);
4103 if (NT_STATUS_IS_OK(status)) {
4104 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4108 /* This should succeed. */
4109 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4110 FILE_ATTRIBUTE_NORMAL,
4111 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4112 FILE_OPEN, 0, 0, &fnum2, NULL);
4113 if (!NT_STATUS_IS_OK(status)) {
4114 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
4118 status = cli_nt_delete_on_close(cli1, fnum1, true);
4119 if (!NT_STATUS_IS_OK(status)) {
4120 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4124 status = cli_close(cli1, fnum1);
4125 if (!NT_STATUS_IS_OK(status)) {
4126 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4130 status = cli_close(cli1, fnum2);
4131 if (!NT_STATUS_IS_OK(status)) {
4132 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4136 /* This should fail - file should no longer be there. */
4138 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4139 if (NT_STATUS_IS_OK(status)) {
4140 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4141 status = cli_close(cli1, fnum1);
4142 if (!NT_STATUS_IS_OK(status)) {
4143 printf("[3] close failed (%s)\n", nt_errstr(status));
4145 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4149 printf("third delete on close test succeeded.\n");
4152 cli_setatr(cli1, fname, 0, 0);
4153 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4155 status = cli_ntcreate(cli1, fname, 0,
4156 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4157 FILE_ATTRIBUTE_NORMAL,
4158 FILE_SHARE_READ|FILE_SHARE_WRITE,
4159 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4160 if (!NT_STATUS_IS_OK(status)) {
4161 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4165 /* This should succeed. */
4166 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4167 FILE_ATTRIBUTE_NORMAL,
4168 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4169 FILE_OPEN, 0, 0, &fnum2, NULL);
4170 if (!NT_STATUS_IS_OK(status)) {
4171 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4175 status = cli_close(cli1, fnum2);
4176 if (!NT_STATUS_IS_OK(status)) {
4177 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4181 status = cli_nt_delete_on_close(cli1, fnum1, true);
4182 if (!NT_STATUS_IS_OK(status)) {
4183 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4187 /* This should fail - no more opens once delete on close set. */
4188 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4189 FILE_ATTRIBUTE_NORMAL,
4190 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4191 FILE_OPEN, 0, 0, &fnum2, NULL);
4192 if (NT_STATUS_IS_OK(status)) {
4193 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4197 status = cli_close(cli1, fnum1);
4198 if (!NT_STATUS_IS_OK(status)) {
4199 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4203 printf("fourth delete on close test succeeded.\n");
4206 cli_setatr(cli1, fname, 0, 0);
4207 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4209 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4210 if (!NT_STATUS_IS_OK(status)) {
4211 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4215 /* This should fail - only allowed on NT opens with DELETE access. */
4217 status = cli_nt_delete_on_close(cli1, fnum1, true);
4218 if (NT_STATUS_IS_OK(status)) {
4219 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4223 status = cli_close(cli1, fnum1);
4224 if (!NT_STATUS_IS_OK(status)) {
4225 printf("[5] close failed (%s)\n", nt_errstr(status));
4229 printf("fifth delete on close test succeeded.\n");
4232 cli_setatr(cli1, fname, 0, 0);
4233 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4235 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4236 FILE_ATTRIBUTE_NORMAL,
4237 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4238 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4239 if (!NT_STATUS_IS_OK(status)) {
4240 printf("[6] open of %s failed (%s)\n", fname,
4245 /* This should fail - only allowed on NT opens with DELETE access. */
4247 status = cli_nt_delete_on_close(cli1, fnum1, true);
4248 if (NT_STATUS_IS_OK(status)) {
4249 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4253 status = cli_close(cli1, fnum1);
4254 if (!NT_STATUS_IS_OK(status)) {
4255 printf("[6] close failed (%s)\n", nt_errstr(status));
4259 printf("sixth delete on close test succeeded.\n");
4262 cli_setatr(cli1, fname, 0, 0);
4263 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4265 status = cli_ntcreate(cli1, fname, 0,
4266 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4267 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4268 0, 0, &fnum1, NULL);
4269 if (!NT_STATUS_IS_OK(status)) {
4270 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4274 status = cli_nt_delete_on_close(cli1, fnum1, true);
4275 if (!NT_STATUS_IS_OK(status)) {
4276 printf("[7] setting delete_on_close on file failed !\n");
4280 status = cli_nt_delete_on_close(cli1, fnum1, false);
4281 if (!NT_STATUS_IS_OK(status)) {
4282 printf("[7] unsetting delete_on_close on file failed !\n");
4286 status = cli_close(cli1, fnum1);
4287 if (!NT_STATUS_IS_OK(status)) {
4288 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4292 /* This next open should succeed - we reset the flag. */
4293 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4294 if (!NT_STATUS_IS_OK(status)) {
4295 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4299 status = cli_close(cli1, fnum1);
4300 if (!NT_STATUS_IS_OK(status)) {
4301 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4305 printf("seventh delete on close test succeeded.\n");
4308 cli_setatr(cli1, fname, 0, 0);
4309 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4311 if (!torture_open_connection(&cli2, 1)) {
4312 printf("[8] failed to open second connection.\n");
4316 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4318 status = cli_ntcreate(cli1, fname, 0,
4319 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4320 FILE_ATTRIBUTE_NORMAL,
4321 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4322 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4323 if (!NT_STATUS_IS_OK(status)) {
4324 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4328 status = cli_ntcreate(cli2, fname, 0,
4329 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4330 FILE_ATTRIBUTE_NORMAL,
4331 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4332 FILE_OPEN, 0, 0, &fnum2, NULL);
4333 if (!NT_STATUS_IS_OK(status)) {
4334 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4338 status = cli_nt_delete_on_close(cli1, fnum1, true);
4339 if (!NT_STATUS_IS_OK(status)) {
4340 printf("[8] setting delete_on_close on file failed !\n");
4344 status = cli_close(cli1, fnum1);
4345 if (!NT_STATUS_IS_OK(status)) {
4346 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4350 status = cli_close(cli2, fnum2);
4351 if (!NT_STATUS_IS_OK(status)) {
4352 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4356 /* This should fail.. */
4357 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4358 if (NT_STATUS_IS_OK(status)) {
4359 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4363 printf("eighth delete on close test succeeded.\n");
4367 /* This should fail - we need to set DELETE_ACCESS. */
4368 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4369 FILE_ATTRIBUTE_NORMAL,
4372 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4373 if (NT_STATUS_IS_OK(status)) {
4374 printf("[9] open of %s succeeded should have failed!\n", fname);
4378 printf("ninth delete on close test succeeded.\n");
4382 status = cli_ntcreate(cli1, fname, 0,
4383 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4384 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4385 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4387 if (!NT_STATUS_IS_OK(status)) {
4388 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4392 /* This should delete the file. */
4393 status = cli_close(cli1, fnum1);
4394 if (!NT_STATUS_IS_OK(status)) {
4395 printf("[10] close failed (%s)\n", nt_errstr(status));
4399 /* This should fail.. */
4400 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4401 if (NT_STATUS_IS_OK(status)) {
4402 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4406 printf("tenth delete on close test succeeded.\n");
4410 cli_setatr(cli1, fname, 0, 0);
4411 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4413 /* Can we open a read-only file with delete access? */
4415 /* Create a readonly file. */
4416 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4417 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4418 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4419 if (!NT_STATUS_IS_OK(status)) {
4420 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4424 status = cli_close(cli1, fnum1);
4425 if (!NT_STATUS_IS_OK(status)) {
4426 printf("[11] close failed (%s)\n", nt_errstr(status));
4430 /* Now try open for delete access. */
4431 status = cli_ntcreate(cli1, fname, 0,
4432 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4434 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4435 FILE_OPEN, 0, 0, &fnum1, NULL);
4436 if (!NT_STATUS_IS_OK(status)) {
4437 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4441 cli_close(cli1, fnum1);
4443 printf("eleventh delete on close test succeeded.\n");
4447 * like test 4 but with initial delete on close
4450 cli_setatr(cli1, fname, 0, 0);
4451 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4453 status = cli_ntcreate(cli1, fname, 0,
4454 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4455 FILE_ATTRIBUTE_NORMAL,
4456 FILE_SHARE_READ|FILE_SHARE_WRITE,
4458 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4459 if (!NT_STATUS_IS_OK(status)) {
4460 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4464 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4465 FILE_ATTRIBUTE_NORMAL,
4466 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4467 FILE_OPEN, 0, 0, &fnum2, NULL);
4468 if (!NT_STATUS_IS_OK(status)) {
4469 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4473 status = cli_close(cli1, fnum2);
4474 if (!NT_STATUS_IS_OK(status)) {
4475 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4479 status = cli_nt_delete_on_close(cli1, fnum1, true);
4480 if (!NT_STATUS_IS_OK(status)) {
4481 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4485 /* This should fail - no more opens once delete on close set. */
4486 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4487 FILE_ATTRIBUTE_NORMAL,
4488 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4489 FILE_OPEN, 0, 0, &fnum2, NULL);
4490 if (NT_STATUS_IS_OK(status)) {
4491 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4495 status = cli_nt_delete_on_close(cli1, fnum1, false);
4496 if (!NT_STATUS_IS_OK(status)) {
4497 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4501 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4502 FILE_ATTRIBUTE_NORMAL,
4503 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4504 FILE_OPEN, 0, 0, &fnum2, NULL);
4505 if (!NT_STATUS_IS_OK(status)) {
4506 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4510 status = cli_close(cli1, fnum2);
4511 if (!NT_STATUS_IS_OK(status)) {
4512 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4516 status = cli_close(cli1, fnum1);
4517 if (!NT_STATUS_IS_OK(status)) {
4518 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4523 * setting delete on close on the handle does
4524 * not unset the initial delete on close...
4526 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4527 FILE_ATTRIBUTE_NORMAL,
4528 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4529 FILE_OPEN, 0, 0, &fnum2, NULL);
4530 if (NT_STATUS_IS_OK(status)) {
4531 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4533 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4534 printf("ntcreate returned %s, expected "
4535 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4540 printf("twelfth delete on close test succeeded.\n");
4543 printf("finished delete test\n");
4548 /* FIXME: This will crash if we aborted before cli2 got
4549 * intialized, because these functions don't handle
4550 * uninitialized connections. */
4552 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4553 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4554 cli_setatr(cli1, fname, 0, 0);
4555 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4557 if (cli1 && !torture_close_connection(cli1)) {
4560 if (cli2 && !torture_close_connection(cli2)) {
4567 Exercise delete on close semantics - use on the PRINT1 share in torture
4570 static bool run_delete_print_test(int dummy)
4572 struct cli_state *cli1 = NULL;
4573 const char *fname = "print_delete.file";
4574 uint16_t fnum1 = (uint16_t)-1;
4575 bool correct = false;
4576 const char *buf = "print file data\n";
4579 printf("starting print delete test\n");
4581 if (!torture_open_connection(&cli1, 0)) {
4585 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4587 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4588 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4589 0, 0, &fnum1, NULL);
4590 if (!NT_STATUS_IS_OK(status)) {
4591 printf("open of %s failed (%s)\n",
4597 status = cli_writeall(cli1,
4600 (const uint8_t *)buf,
4602 strlen(buf), /* size */
4604 if (!NT_STATUS_IS_OK(status)) {
4605 printf("writing print file data failed (%s)\n",
4610 status = cli_nt_delete_on_close(cli1, fnum1, true);
4611 if (!NT_STATUS_IS_OK(status)) {
4612 printf("setting delete_on_close failed (%s)\n",
4617 status = cli_close(cli1, fnum1);
4618 if (!NT_STATUS_IS_OK(status)) {
4619 printf("close failed (%s)\n", nt_errstr(status));
4623 printf("finished print delete test\n");
4629 if (fnum1 != (uint16_t)-1) {
4630 cli_close(cli1, fnum1);
4633 if (cli1 && !torture_close_connection(cli1)) {
4640 Test wildcard delete.
4642 static bool run_wild_deletetest(int dummy)
4644 struct cli_state *cli = NULL;
4645 const char *dname = "\\WTEST";
4646 const char *fname = "\\WTEST\\A";
4647 const char *wunlink_name = "\\WTEST\\*";
4648 uint16_t fnum1 = (uint16_t)-1;
4649 bool correct = false;
4652 printf("starting wildcard delete test\n");
4654 if (!torture_open_connection(&cli, 0)) {
4658 smbXcli_conn_set_sockopt(cli->conn, sockops);
4660 cli_unlink(cli, fname, 0);
4661 cli_rmdir(cli, dname);
4662 status = cli_mkdir(cli, dname);
4663 if (!NT_STATUS_IS_OK(status)) {
4664 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4667 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4668 if (!NT_STATUS_IS_OK(status)) {
4669 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4672 status = cli_close(cli, fnum1);
4676 * Note the unlink attribute-type of zero. This should
4677 * map into FILE_ATTRIBUTE_NORMAL at the server even
4678 * on a wildcard delete.
4681 status = cli_unlink(cli, wunlink_name, 0);
4682 if (!NT_STATUS_IS_OK(status)) {
4683 printf("unlink of %s failed %s!\n",
4684 wunlink_name, nt_errstr(status));
4688 printf("finished wildcard delete test\n");
4694 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4695 cli_unlink(cli, fname, 0);
4696 cli_rmdir(cli, dname);
4698 if (cli && !torture_close_connection(cli)) {
4704 static bool run_deletetest_ln(int dummy)
4706 struct cli_state *cli;
4707 const char *fname = "\\delete1";
4708 const char *fname_ln = "\\delete1_ln";
4712 bool correct = true;
4715 printf("starting deletetest-ln\n");
4717 if (!torture_open_connection(&cli, 0)) {
4721 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4722 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4724 smbXcli_conn_set_sockopt(cli->conn, sockops);
4726 /* Create the file. */
4727 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4728 if (!NT_STATUS_IS_OK(status)) {
4729 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4733 status = cli_close(cli, fnum);
4734 if (!NT_STATUS_IS_OK(status)) {
4735 printf("close1 failed (%s)\n", nt_errstr(status));
4739 /* Now create a hardlink. */
4740 status = cli_nt_hardlink(cli, fname, fname_ln);
4741 if (!NT_STATUS_IS_OK(status)) {
4742 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4746 /* Open the original file. */
4747 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4748 FILE_ATTRIBUTE_NORMAL,
4749 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4750 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4751 if (!NT_STATUS_IS_OK(status)) {
4752 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4756 /* Unlink the hard link path. */
4757 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4758 FILE_ATTRIBUTE_NORMAL,
4759 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4760 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4761 if (!NT_STATUS_IS_OK(status)) {
4762 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4765 status = cli_nt_delete_on_close(cli, fnum1, true);
4766 if (!NT_STATUS_IS_OK(status)) {
4767 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4768 __location__, fname_ln, nt_errstr(status));
4772 status = cli_close(cli, fnum1);
4773 if (!NT_STATUS_IS_OK(status)) {
4774 printf("close %s failed (%s)\n",
4775 fname_ln, nt_errstr(status));
4779 status = cli_close(cli, fnum);
4780 if (!NT_STATUS_IS_OK(status)) {
4781 printf("close %s failed (%s)\n",
4782 fname, nt_errstr(status));
4786 /* Ensure the original file is still there. */
4787 status = cli_getatr(cli, fname, NULL, NULL, &t);
4788 if (!NT_STATUS_IS_OK(status)) {
4789 printf("%s getatr on file %s failed (%s)\n",
4796 /* Ensure the link path is gone. */
4797 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4798 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4799 printf("%s, getatr for file %s returned wrong error code %s "
4800 "- should have been deleted\n",
4802 fname_ln, nt_errstr(status));
4806 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4807 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4809 if (!torture_close_connection(cli)) {
4813 printf("finished deletetest-ln\n");
4819 print out server properties
4821 static bool run_properties(int dummy)
4823 struct cli_state *cli;
4824 bool correct = True;
4826 printf("starting properties test\n");
4830 if (!torture_open_connection(&cli, 0)) {
4834 smbXcli_conn_set_sockopt(cli->conn, sockops);
4836 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4838 if (!torture_close_connection(cli)) {
4847 /* FIRST_DESIRED_ACCESS 0xf019f */
4848 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4849 FILE_READ_EA| /* 0xf */ \
4850 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4851 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4852 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4853 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4854 /* SECOND_DESIRED_ACCESS 0xe0080 */
4855 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4856 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4857 WRITE_OWNER_ACCESS /* 0xe0000 */
4860 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4861 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4863 WRITE_OWNER_ACCESS /* */
4867 Test ntcreate calls made by xcopy
4869 static bool run_xcopy(int dummy)
4871 static struct cli_state *cli1;
4872 const char *fname = "\\test.txt";
4873 bool correct = True;
4874 uint16_t fnum1, fnum2;
4877 printf("starting xcopy test\n");
4879 if (!torture_open_connection(&cli1, 0)) {
4883 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4884 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4885 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4886 if (!NT_STATUS_IS_OK(status)) {
4887 printf("First open failed - %s\n", nt_errstr(status));
4891 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4892 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4893 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4894 if (!NT_STATUS_IS_OK(status)) {
4895 printf("second open failed - %s\n", nt_errstr(status));
4899 if (!torture_close_connection(cli1)) {
4907 Test rename on files open with share delete and no share delete.
4909 static bool run_rename(int dummy)
4911 static struct cli_state *cli1;
4912 const char *fname = "\\test.txt";
4913 const char *fname1 = "\\test1.txt";
4914 bool correct = True;
4919 printf("starting rename test\n");
4921 if (!torture_open_connection(&cli1, 0)) {
4925 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4926 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4928 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4929 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4930 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4931 if (!NT_STATUS_IS_OK(status)) {
4932 printf("First open failed - %s\n", nt_errstr(status));
4936 status = cli_rename(cli1, fname, fname1, false);
4937 if (!NT_STATUS_IS_OK(status)) {
4938 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4940 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4944 status = cli_close(cli1, fnum1);
4945 if (!NT_STATUS_IS_OK(status)) {
4946 printf("close - 1 failed (%s)\n", nt_errstr(status));
4950 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4951 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4952 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4954 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4956 FILE_SHARE_DELETE|FILE_SHARE_READ,
4958 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4959 if (!NT_STATUS_IS_OK(status)) {
4960 printf("Second open failed - %s\n", nt_errstr(status));
4964 status = cli_rename(cli1, fname, fname1, false);
4965 if (!NT_STATUS_IS_OK(status)) {
4966 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4969 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4972 status = cli_close(cli1, fnum1);
4973 if (!NT_STATUS_IS_OK(status)) {
4974 printf("close - 2 failed (%s)\n", nt_errstr(status));
4978 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4979 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4981 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4982 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4983 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4984 if (!NT_STATUS_IS_OK(status)) {
4985 printf("Third open failed - %s\n", nt_errstr(status));
4994 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4995 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4996 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4999 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
5000 printf("[8] setting delete_on_close on file failed !\n");
5004 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
5005 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
5011 status = cli_rename(cli1, fname, fname1, false);
5012 if (!NT_STATUS_IS_OK(status)) {
5013 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
5016 printf("Third rename succeeded (SHARE_NONE)\n");
5019 status = cli_close(cli1, fnum1);
5020 if (!NT_STATUS_IS_OK(status)) {
5021 printf("close - 3 failed (%s)\n", nt_errstr(status));
5025 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5026 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5030 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5031 FILE_ATTRIBUTE_NORMAL,
5032 FILE_SHARE_READ | FILE_SHARE_WRITE,
5033 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5034 if (!NT_STATUS_IS_OK(status)) {
5035 printf("Fourth open failed - %s\n", nt_errstr(status));
5039 status = cli_rename(cli1, fname, fname1, false);
5040 if (!NT_STATUS_IS_OK(status)) {
5041 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
5043 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
5047 status = cli_close(cli1, fnum1);
5048 if (!NT_STATUS_IS_OK(status)) {
5049 printf("close - 4 failed (%s)\n", nt_errstr(status));
5053 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5054 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5058 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
5059 FILE_ATTRIBUTE_NORMAL,
5060 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5061 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5062 if (!NT_STATUS_IS_OK(status)) {
5063 printf("Fifth open failed - %s\n", nt_errstr(status));
5067 status = cli_rename(cli1, fname, fname1, false);
5068 if (!NT_STATUS_IS_OK(status)) {
5069 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
5072 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
5076 * Now check if the first name still exists ...
5079 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
5080 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5081 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
5082 printf("Opening original file after rename of open file fails: %s\n",
5086 printf("Opening original file after rename of open file works ...\n");
5087 (void)cli_close(cli1, fnum2);
5091 status = cli_close(cli1, fnum1);
5092 if (!NT_STATUS_IS_OK(status)) {
5093 printf("close - 5 failed (%s)\n", nt_errstr(status));
5097 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
5098 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
5099 if (!NT_STATUS_IS_OK(status)) {
5100 printf("getatr on file %s failed - %s ! \n",
5101 fname1, nt_errstr(status));
5104 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
5105 printf("Renamed file %s has wrong attr 0x%x "
5106 "(should be 0x%x)\n",
5109 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
5112 printf("Renamed file %s has archive bit set\n", fname1);
5116 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5117 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5119 if (!torture_close_connection(cli1)) {
5127 Test rename into a directory with an ACL denying it.
5129 static bool run_rename_access(int dummy)
5131 static struct cli_state *cli = NULL;
5132 static struct cli_state *posix_cli = NULL;
5133 const char *src = "test.txt";
5134 const char *dname = "dir";
5135 const char *dst = "dir\\test.txt";
5136 const char *dsrc = "test.dir";
5137 const char *ddst = "dir\\test.dir";
5138 uint16_t fnum = (uint16_t)-1;
5139 struct security_descriptor *sd = NULL;
5140 struct security_descriptor *newsd = NULL;
5142 TALLOC_CTX *frame = NULL;
5144 frame = talloc_stackframe();
5145 printf("starting rename access test\n");
5147 /* Windows connection. */
5148 if (!torture_open_connection(&cli, 0)) {
5152 smbXcli_conn_set_sockopt(cli->conn, sockops);
5154 /* Posix connection. */
5155 if (!torture_open_connection(&posix_cli, 0)) {
5159 smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
5161 status = torture_setup_unix_extensions(posix_cli);
5162 if (!NT_STATUS_IS_OK(status)) {
5166 /* Start with a clean slate. */
5167 cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5168 cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5169 cli_rmdir(cli, dsrc);
5170 cli_rmdir(cli, ddst);
5171 cli_rmdir(cli, dname);
5174 * Setup the destination directory with a DENY ACE to
5175 * prevent new files within it.
5177 status = cli_ntcreate(cli,
5180 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
5181 WRITE_DAC_ACCESS|FILE_READ_DATA|
5183 FILE_ATTRIBUTE_DIRECTORY,
5184 FILE_SHARE_READ|FILE_SHARE_WRITE,
5186 FILE_DIRECTORY_FILE,
5190 if (!NT_STATUS_IS_OK(status)) {
5191 printf("Create of %s - %s\n", dname, nt_errstr(status));
5195 status = cli_query_secdesc(cli,
5199 if (!NT_STATUS_IS_OK(status)) {
5200 printf("cli_query_secdesc failed for %s (%s)\n",
5201 dname, nt_errstr(status));
5205 newsd = security_descriptor_dacl_create(frame,
5210 SEC_ACE_TYPE_ACCESS_DENIED,
5211 SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
5214 if (newsd == NULL) {
5217 sd->dacl = security_acl_concatenate(frame,
5220 if (sd->dacl == NULL) {
5223 status = cli_set_secdesc(cli, fnum, sd);
5224 if (!NT_STATUS_IS_OK(status)) {
5225 printf("cli_set_secdesc failed for %s (%s)\n",
5226 dname, nt_errstr(status));
5229 status = cli_close(cli, fnum);
5230 if (!NT_STATUS_IS_OK(status)) {
5231 printf("close failed for %s (%s)\n",
5232 dname, nt_errstr(status));
5235 /* Now go around the back and chmod to 777 via POSIX. */
5236 status = cli_posix_chmod(posix_cli, dname, 0777);
5237 if (!NT_STATUS_IS_OK(status)) {
5238 printf("cli_posix_chmod failed for %s (%s)\n",
5239 dname, nt_errstr(status));
5243 /* Check we can't create a file within dname via Windows. */
5244 status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5245 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5246 cli_close(posix_cli, fnum);
5247 printf("Create of %s should be ACCESS denied, was %s\n",
5248 dst, nt_errstr(status));
5252 /* Make the sample file/directory. */
5253 status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5254 if (!NT_STATUS_IS_OK(status)) {
5255 printf("open of %s failed (%s)\n", src, nt_errstr(status));
5258 status = cli_close(cli, fnum);
5259 if (!NT_STATUS_IS_OK(status)) {
5260 printf("cli_close failed (%s)\n", nt_errstr(status));
5264 status = cli_mkdir(cli, dsrc);
5265 if (!NT_STATUS_IS_OK(status)) {
5266 printf("cli_mkdir of %s failed (%s)\n",
5267 dsrc, nt_errstr(status));
5272 * OK - renames of the new file and directory into the
5273 * dst directory should fail.
5276 status = cli_rename(cli, src, dst, false);
5277 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5278 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5279 src, dst, nt_errstr(status));
5282 status = cli_rename(cli, dsrc, ddst, false);
5283 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5284 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5285 src, dst, nt_errstr(status));
5295 torture_close_connection(posix_cli);
5299 if (fnum != (uint16_t)-1) {
5300 cli_close(cli, fnum);
5302 cli_unlink(cli, src,
5303 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5304 cli_unlink(cli, dst,
5305 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5306 cli_rmdir(cli, dsrc);
5307 cli_rmdir(cli, ddst);
5308 cli_rmdir(cli, dname);
5310 torture_close_connection(cli);
5318 Test owner rights ACE.
5320 static bool run_owner_rights(int dummy)
5322 static struct cli_state *cli = NULL;
5323 const char *fname = "owner_rights.txt";
5324 uint16_t fnum = (uint16_t)-1;
5325 struct security_descriptor *sd = NULL;
5326 struct security_descriptor *newsd = NULL;
5328 TALLOC_CTX *frame = NULL;
5330 frame = talloc_stackframe();
5331 printf("starting owner rights test\n");
5333 /* Windows connection. */
5334 if (!torture_open_connection(&cli, 0)) {
5338 smbXcli_conn_set_sockopt(cli->conn, sockops);
5340 /* Start with a clean slate. */
5341 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5343 /* Create the test file. */
5344 /* Now try and open for read and write-dac. */
5345 status = cli_ntcreate(cli,
5349 FILE_ATTRIBUTE_NORMAL,
5350 FILE_SHARE_READ|FILE_SHARE_WRITE|
5357 if (!NT_STATUS_IS_OK(status)) {
5358 printf("Create of %s - %s\n", fname, nt_errstr(status));
5362 /* Get the original SD. */
5363 status = cli_query_secdesc(cli,
5367 if (!NT_STATUS_IS_OK(status)) {
5368 printf("cli_query_secdesc failed for %s (%s)\n",
5369 fname, nt_errstr(status));
5374 * Add an "owner-rights" ACE denying WRITE_DATA,
5375 * and an "owner-rights" ACE allowing READ_DATA.
5378 newsd = security_descriptor_dacl_create(frame,
5383 SEC_ACE_TYPE_ACCESS_DENIED,
5387 SEC_ACE_TYPE_ACCESS_ALLOWED,
5391 if (newsd == NULL) {
5394 sd->dacl = security_acl_concatenate(frame,
5397 if (sd->dacl == NULL) {
5400 status = cli_set_secdesc(cli, fnum, sd);
5401 if (!NT_STATUS_IS_OK(status)) {
5402 printf("cli_set_secdesc failed for %s (%s)\n",
5403 fname, nt_errstr(status));
5406 status = cli_close(cli, fnum);
5407 if (!NT_STATUS_IS_OK(status)) {
5408 printf("close failed for %s (%s)\n",
5409 fname, nt_errstr(status));
5412 fnum = (uint16_t)-1;
5414 /* Try and open for FILE_WRITE_DATA */
5415 status = cli_ntcreate(cli,
5419 FILE_ATTRIBUTE_NORMAL,
5420 FILE_SHARE_READ|FILE_SHARE_WRITE|
5427 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5428 printf("Open of %s - %s\n", fname, nt_errstr(status));
5432 /* Now try and open for FILE_READ_DATA */
5433 status = cli_ntcreate(cli,
5437 FILE_ATTRIBUTE_NORMAL,
5438 FILE_SHARE_READ|FILE_SHARE_WRITE|
5445 if (!NT_STATUS_IS_OK(status)) {
5446 printf("Open of %s - %s\n", fname, nt_errstr(status));
5450 status = cli_close(cli, fnum);
5451 if (!NT_STATUS_IS_OK(status)) {
5452 printf("close failed for %s (%s)\n",
5453 fname, nt_errstr(status));
5457 /* Restore clean slate. */
5459 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5461 /* Create the test file. */
5462 status = cli_ntcreate(cli,
5466 FILE_ATTRIBUTE_NORMAL,
5467 FILE_SHARE_READ|FILE_SHARE_WRITE|
5474 if (!NT_STATUS_IS_OK(status)) {
5475 printf("Create of %s - %s\n", fname, nt_errstr(status));
5479 /* Get the original SD. */
5480 status = cli_query_secdesc(cli,
5484 if (!NT_STATUS_IS_OK(status)) {
5485 printf("cli_query_secdesc failed for %s (%s)\n",
5486 fname, nt_errstr(status));
5491 * Add an "owner-rights ACE denying WRITE_DATA,
5492 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5495 newsd = security_descriptor_dacl_create(frame,
5500 SEC_ACE_TYPE_ACCESS_DENIED,
5504 SEC_ACE_TYPE_ACCESS_ALLOWED,
5505 FILE_READ_DATA|FILE_WRITE_DATA,
5508 if (newsd == NULL) {
5511 sd->dacl = security_acl_concatenate(frame,
5514 if (sd->dacl == NULL) {
5517 status = cli_set_secdesc(cli, fnum, sd);
5518 if (!NT_STATUS_IS_OK(status)) {
5519 printf("cli_set_secdesc failed for %s (%s)\n",
5520 fname, nt_errstr(status));
5523 status = cli_close(cli, fnum);
5524 if (!NT_STATUS_IS_OK(status)) {
5525 printf("close failed for %s (%s)\n",
5526 fname, nt_errstr(status));
5529 fnum = (uint16_t)-1;
5531 /* Try and open for FILE_WRITE_DATA */
5532 status = cli_ntcreate(cli,
5536 FILE_ATTRIBUTE_NORMAL,
5537 FILE_SHARE_READ|FILE_SHARE_WRITE|
5544 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5545 printf("Open of %s - %s\n", fname, nt_errstr(status));
5549 /* Now try and open for FILE_READ_DATA */
5550 status = cli_ntcreate(cli,
5554 FILE_ATTRIBUTE_NORMAL,
5555 FILE_SHARE_READ|FILE_SHARE_WRITE|
5562 if (!NT_STATUS_IS_OK(status)) {
5563 printf("Open of %s - %s\n", fname, nt_errstr(status));
5567 status = cli_close(cli, fnum);
5568 if (!NT_STATUS_IS_OK(status)) {
5569 printf("close failed for %s (%s)\n",
5570 fname, nt_errstr(status));
5574 /* Restore clean slate. */
5576 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5579 /* Create the test file. */
5580 status = cli_ntcreate(cli,
5584 FILE_ATTRIBUTE_NORMAL,
5585 FILE_SHARE_READ|FILE_SHARE_WRITE|
5592 if (!NT_STATUS_IS_OK(status)) {
5593 printf("Create of %s - %s\n", fname, nt_errstr(status));
5597 /* Get the original SD. */
5598 status = cli_query_secdesc(cli,
5602 if (!NT_STATUS_IS_OK(status)) {
5603 printf("cli_query_secdesc failed for %s (%s)\n",
5604 fname, nt_errstr(status));
5609 * Add an "authenticated users" ACE allowing READ_DATA,
5610 * add an "owner-rights" denying READ_DATA,
5611 * and an "authenticated users" ACE allowing WRITE_DATA.
5614 newsd = security_descriptor_dacl_create(frame,
5618 SID_NT_AUTHENTICATED_USERS,
5619 SEC_ACE_TYPE_ACCESS_ALLOWED,
5623 SEC_ACE_TYPE_ACCESS_DENIED,
5626 SID_NT_AUTHENTICATED_USERS,
5627 SEC_ACE_TYPE_ACCESS_ALLOWED,
5631 if (newsd == NULL) {
5632 printf("newsd == NULL\n");
5635 sd->dacl = security_acl_concatenate(frame,
5638 if (sd->dacl == NULL) {
5639 printf("sd->dacl == NULL\n");
5642 status = cli_set_secdesc(cli, fnum, sd);
5643 if (!NT_STATUS_IS_OK(status)) {
5644 printf("cli_set_secdesc failed for %s (%s)\n",
5645 fname, nt_errstr(status));
5648 status = cli_close(cli, fnum);
5649 if (!NT_STATUS_IS_OK(status)) {
5650 printf("close failed for %s (%s)\n",
5651 fname, nt_errstr(status));
5654 fnum = (uint16_t)-1;
5656 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5657 status = cli_ntcreate(cli,
5660 FILE_READ_DATA|FILE_WRITE_DATA,
5661 FILE_ATTRIBUTE_NORMAL,
5662 FILE_SHARE_READ|FILE_SHARE_WRITE|
5669 if (!NT_STATUS_IS_OK(status)) {
5670 printf("Open of %s - %s\n", fname, nt_errstr(status));
5674 status = cli_close(cli, fnum);
5675 if (!NT_STATUS_IS_OK(status)) {
5676 printf("close failed for %s (%s)\n",
5677 fname, nt_errstr(status));
5681 cli_unlink(cli, fname,
5682 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5690 if (fnum != (uint16_t)-1) {
5691 cli_close(cli, fnum);
5693 cli_unlink(cli, fname,
5694 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5695 torture_close_connection(cli);
5702 static bool run_pipe_number(int dummy)
5704 struct cli_state *cli1;
5705 const char *pipe_name = "\\SPOOLSS";
5710 printf("starting pipenumber test\n");
5711 if (!torture_open_connection(&cli1, 0)) {
5715 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5717 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
5718 FILE_ATTRIBUTE_NORMAL,
5719 FILE_SHARE_READ|FILE_SHARE_WRITE,
5720 FILE_OPEN_IF, 0, 0, &fnum, NULL);
5721 if (!NT_STATUS_IS_OK(status)) {
5722 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
5726 printf("\r%6d", num_pipes);
5729 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
5730 torture_close_connection(cli1);
5735 Test open mode returns on read-only files.
5737 static bool run_opentest(int dummy)
5739 static struct cli_state *cli1;
5740 static struct cli_state *cli2;
5741 const char *fname = "\\readonly.file";
5742 uint16_t fnum1, fnum2;
5745 bool correct = True;
5749 printf("starting open test\n");
5751 if (!torture_open_connection(&cli1, 0)) {
5755 cli_setatr(cli1, fname, 0, 0);
5756 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5758 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5760 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5761 if (!NT_STATUS_IS_OK(status)) {
5762 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5766 status = cli_close(cli1, fnum1);
5767 if (!NT_STATUS_IS_OK(status)) {
5768 printf("close2 failed (%s)\n", nt_errstr(status));
5772 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
5773 if (!NT_STATUS_IS_OK(status)) {
5774 printf("cli_setatr failed (%s)\n", nt_errstr(status));
5778 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5779 if (!NT_STATUS_IS_OK(status)) {
5780 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5784 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5785 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5787 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
5788 NT_STATUS_ACCESS_DENIED)) {
5789 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5792 printf("finished open test 1\n");
5794 cli_close(cli1, fnum1);
5796 /* Now try not readonly and ensure ERRbadshare is returned. */
5798 cli_setatr(cli1, fname, 0, 0);
5800 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5801 if (!NT_STATUS_IS_OK(status)) {
5802 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5806 /* This will fail - but the error should be ERRshare. */
5807 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5809 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5810 NT_STATUS_SHARING_VIOLATION)) {
5811 printf("correct error code ERRDOS/ERRbadshare returned\n");
5814 status = cli_close(cli1, fnum1);
5815 if (!NT_STATUS_IS_OK(status)) {
5816 printf("close2 failed (%s)\n", nt_errstr(status));
5820 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5822 printf("finished open test 2\n");
5824 /* Test truncate open disposition on file opened for read. */
5825 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5826 if (!NT_STATUS_IS_OK(status)) {
5827 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5831 /* write 20 bytes. */
5833 memset(buf, '\0', 20);
5835 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5836 if (!NT_STATUS_IS_OK(status)) {
5837 printf("write failed (%s)\n", nt_errstr(status));
5841 status = cli_close(cli1, fnum1);
5842 if (!NT_STATUS_IS_OK(status)) {
5843 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5847 /* Ensure size == 20. */
5848 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5849 if (!NT_STATUS_IS_OK(status)) {
5850 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5855 printf("(3) file size != 20\n");
5859 /* Now test if we can truncate a file opened for readonly. */
5860 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5861 if (!NT_STATUS_IS_OK(status)) {
5862 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5866 status = cli_close(cli1, fnum1);
5867 if (!NT_STATUS_IS_OK(status)) {
5868 printf("close2 failed (%s)\n", nt_errstr(status));
5872 /* Ensure size == 0. */
5873 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5874 if (!NT_STATUS_IS_OK(status)) {
5875 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5880 printf("(3) file size != 0\n");
5883 printf("finished open test 3\n");
5885 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5887 printf("Do ctemp tests\n");
5888 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5889 if (!NT_STATUS_IS_OK(status)) {
5890 printf("ctemp failed (%s)\n", nt_errstr(status));
5894 printf("ctemp gave path %s\n", tmp_path);
5895 status = cli_close(cli1, fnum1);
5896 if (!NT_STATUS_IS_OK(status)) {
5897 printf("close of temp failed (%s)\n", nt_errstr(status));
5900 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5901 if (!NT_STATUS_IS_OK(status)) {
5902 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5905 /* Test the non-io opens... */
5907 if (!torture_open_connection(&cli2, 1)) {
5911 cli_setatr(cli2, fname, 0, 0);
5912 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5914 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5916 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5917 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5918 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5919 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5920 if (!NT_STATUS_IS_OK(status)) {
5921 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5925 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5926 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5927 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5928 if (!NT_STATUS_IS_OK(status)) {
5929 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5933 status = cli_close(cli1, fnum1);
5934 if (!NT_STATUS_IS_OK(status)) {
5935 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5939 status = cli_close(cli2, fnum2);
5940 if (!NT_STATUS_IS_OK(status)) {
5941 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5945 printf("non-io open test #1 passed.\n");
5947 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5949 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5951 status = cli_ntcreate(cli1, fname, 0,
5952 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5953 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5954 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5955 if (!NT_STATUS_IS_OK(status)) {
5956 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5960 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5961 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5962 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5963 if (!NT_STATUS_IS_OK(status)) {
5964 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5968 status = cli_close(cli1, fnum1);
5969 if (!NT_STATUS_IS_OK(status)) {
5970 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5974 status = cli_close(cli2, fnum2);
5975 if (!NT_STATUS_IS_OK(status)) {
5976 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5980 printf("non-io open test #2 passed.\n");
5982 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5984 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5986 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5987 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5988 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5989 if (!NT_STATUS_IS_OK(status)) {
5990 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5994 status = cli_ntcreate(cli2, fname, 0,
5995 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5996 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5997 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5998 if (!NT_STATUS_IS_OK(status)) {
5999 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6003 status = cli_close(cli1, fnum1);
6004 if (!NT_STATUS_IS_OK(status)) {
6005 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6009 status = cli_close(cli2, fnum2);
6010 if (!NT_STATUS_IS_OK(status)) {
6011 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6015 printf("non-io open test #3 passed.\n");
6017 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6019 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
6021 status = cli_ntcreate(cli1, fname, 0,
6022 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6023 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6024 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6025 if (!NT_STATUS_IS_OK(status)) {
6026 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6030 status = cli_ntcreate(cli2, fname, 0,
6031 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6032 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6033 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6034 if (NT_STATUS_IS_OK(status)) {
6035 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
6039 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
6041 status = cli_close(cli1, fnum1);
6042 if (!NT_STATUS_IS_OK(status)) {
6043 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6047 printf("non-io open test #4 passed.\n");
6049 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6051 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
6053 status = cli_ntcreate(cli1, fname, 0,
6054 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6055 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
6056 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6057 if (!NT_STATUS_IS_OK(status)) {
6058 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6062 status = cli_ntcreate(cli2, fname, 0,
6063 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6064 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
6065 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6066 if (!NT_STATUS_IS_OK(status)) {
6067 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6071 status = cli_close(cli1, fnum1);
6072 if (!NT_STATUS_IS_OK(status)) {
6073 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6077 status = cli_close(cli2, fnum2);
6078 if (!NT_STATUS_IS_OK(status)) {
6079 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6083 printf("non-io open test #5 passed.\n");
6085 printf("TEST #6 testing 1 non-io open, one io open\n");
6087 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6089 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6090 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6091 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6092 if (!NT_STATUS_IS_OK(status)) {
6093 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6097 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
6098 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6099 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6100 if (!NT_STATUS_IS_OK(status)) {
6101 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6105 status = cli_close(cli1, fnum1);
6106 if (!NT_STATUS_IS_OK(status)) {
6107 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6111 status = cli_close(cli2, fnum2);
6112 if (!NT_STATUS_IS_OK(status)) {
6113 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6117 printf("non-io open test #6 passed.\n");
6119 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
6121 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6123 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6124 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6125 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6126 if (!NT_STATUS_IS_OK(status)) {
6127 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6131 status = cli_ntcreate(cli2, fname, 0,
6132 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6133 FILE_ATTRIBUTE_NORMAL,
6134 FILE_SHARE_READ|FILE_SHARE_DELETE,
6135 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6136 if (NT_STATUS_IS_OK(status)) {
6137 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
6141 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
6143 status = cli_close(cli1, fnum1);
6144 if (!NT_STATUS_IS_OK(status)) {
6145 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6149 printf("non-io open test #7 passed.\n");
6151 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6153 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
6154 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
6155 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6156 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6157 if (!NT_STATUS_IS_OK(status)) {
6158 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
6163 /* Write to ensure we have to update the file time. */
6164 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6166 if (!NT_STATUS_IS_OK(status)) {
6167 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
6172 status = cli_close(cli1, fnum1);
6173 if (!NT_STATUS_IS_OK(status)) {
6174 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
6180 if (!torture_close_connection(cli1)) {
6183 if (!torture_close_connection(cli2)) {
6190 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
6192 uint16_t major, minor;
6193 uint32_t caplow, caphigh;
6196 if (!SERVER_HAS_UNIX_CIFS(cli)) {
6197 printf("Server doesn't support UNIX CIFS extensions.\n");
6198 return NT_STATUS_NOT_SUPPORTED;
6201 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
6203 if (!NT_STATUS_IS_OK(status)) {
6204 printf("Server didn't return UNIX CIFS extensions: %s\n",
6209 status = cli_set_unix_extensions_capabilities(cli, major, minor,
6211 if (!NT_STATUS_IS_OK(status)) {
6212 printf("Server doesn't support setting UNIX CIFS extensions: "
6213 "%s.\n", nt_errstr(status));
6217 return NT_STATUS_OK;
6221 Test POSIX open /mkdir calls.
6223 static bool run_simple_posix_open_test(int dummy)
6225 static struct cli_state *cli1;
6226 const char *fname = "posix:file";
6227 const char *hname = "posix:hlink";
6228 const char *sname = "posix:symlink";
6229 const char *dname = "posix:dir";
6232 uint16_t fnum1 = (uint16_t)-1;
6233 SMB_STRUCT_STAT sbuf;
6234 bool correct = false;
6237 const char *fname_windows = "windows_file";
6238 uint16_t fnum2 = (uint16_t)-1;
6240 printf("Starting simple POSIX open test\n");
6242 if (!torture_open_connection(&cli1, 0)) {
6246 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6248 status = torture_setup_unix_extensions(cli1);
6249 if (!NT_STATUS_IS_OK(status)) {
6253 cli_setatr(cli1, fname, 0, 0);
6254 cli_posix_unlink(cli1, fname);
6255 cli_setatr(cli1, dname, 0, 0);
6256 cli_posix_rmdir(cli1, dname);
6257 cli_setatr(cli1, hname, 0, 0);
6258 cli_posix_unlink(cli1, hname);
6259 cli_setatr(cli1, sname, 0, 0);
6260 cli_posix_unlink(cli1, sname);
6261 cli_setatr(cli1, fname_windows, 0, 0);
6262 cli_posix_unlink(cli1, fname_windows);
6264 /* Create a directory. */
6265 status = cli_posix_mkdir(cli1, dname, 0777);
6266 if (!NT_STATUS_IS_OK(status)) {
6267 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6271 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6273 if (!NT_STATUS_IS_OK(status)) {
6274 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6278 /* Test ftruncate - set file size. */
6279 status = cli_ftruncate(cli1, fnum1, 1000);
6280 if (!NT_STATUS_IS_OK(status)) {
6281 printf("ftruncate failed (%s)\n", nt_errstr(status));
6285 /* Ensure st_size == 1000 */
6286 status = cli_posix_stat(cli1, fname, &sbuf);
6287 if (!NT_STATUS_IS_OK(status)) {
6288 printf("stat failed (%s)\n", nt_errstr(status));
6292 if (sbuf.st_ex_size != 1000) {
6293 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6297 /* Ensure st_mode == 0600 */
6298 if ((sbuf.st_ex_mode & 07777) != 0600) {
6299 printf("posix_open - bad permissions 0%o != 0600\n",
6300 (unsigned int)(sbuf.st_ex_mode & 07777));
6304 /* Test ftruncate - set file size back to zero. */
6305 status = cli_ftruncate(cli1, fnum1, 0);
6306 if (!NT_STATUS_IS_OK(status)) {
6307 printf("ftruncate failed (%s)\n", nt_errstr(status));
6311 status = cli_close(cli1, fnum1);
6312 if (!NT_STATUS_IS_OK(status)) {
6313 printf("close failed (%s)\n", nt_errstr(status));
6317 /* Now open the file again for read only. */
6318 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6319 if (!NT_STATUS_IS_OK(status)) {
6320 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
6324 /* Now unlink while open. */
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_close(cli1, fnum1);
6332 if (!NT_STATUS_IS_OK(status)) {
6333 printf("close(2) failed (%s)\n", nt_errstr(status));
6337 /* Ensure the file has gone. */
6338 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6339 if (NT_STATUS_IS_OK(status)) {
6340 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
6344 /* Create again to test open with O_TRUNC. */
6345 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
6346 if (!NT_STATUS_IS_OK(status)) {
6347 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6351 /* Test ftruncate - set file size. */
6352 status = cli_ftruncate(cli1, fnum1, 1000);
6353 if (!NT_STATUS_IS_OK(status)) {
6354 printf("ftruncate failed (%s)\n", nt_errstr(status));
6358 /* Ensure st_size == 1000 */
6359 status = cli_posix_stat(cli1, fname, &sbuf);
6360 if (!NT_STATUS_IS_OK(status)) {
6361 printf("stat failed (%s)\n", nt_errstr(status));
6365 if (sbuf.st_ex_size != 1000) {
6366 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6370 status = cli_close(cli1, fnum1);
6371 if (!NT_STATUS_IS_OK(status)) {
6372 printf("close(2) failed (%s)\n", nt_errstr(status));
6376 /* Re-open with O_TRUNC. */
6377 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
6378 if (!NT_STATUS_IS_OK(status)) {
6379 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6383 /* Ensure st_size == 0 */
6384 status = cli_posix_stat(cli1, fname, &sbuf);
6385 if (!NT_STATUS_IS_OK(status)) {
6386 printf("stat failed (%s)\n", nt_errstr(status));
6390 if (sbuf.st_ex_size != 0) {
6391 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
6395 status = cli_close(cli1, fnum1);
6396 if (!NT_STATUS_IS_OK(status)) {
6397 printf("close failed (%s)\n", nt_errstr(status));
6401 status = cli_posix_unlink(cli1, fname);
6402 if (!NT_STATUS_IS_OK(status)) {
6403 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6407 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
6408 if (!NT_STATUS_IS_OK(status)) {
6409 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6410 dname, nt_errstr(status));
6414 cli_close(cli1, fnum1);
6416 /* What happens when we try and POSIX open a directory for write ? */
6417 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
6418 if (NT_STATUS_IS_OK(status)) {
6419 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
6422 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
6423 NT_STATUS_FILE_IS_A_DIRECTORY)) {
6428 /* Create the file. */
6429 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6431 if (!NT_STATUS_IS_OK(status)) {
6432 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6436 /* Write some data into it. */
6437 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6439 if (!NT_STATUS_IS_OK(status)) {
6440 printf("cli_write failed: %s\n", nt_errstr(status));
6444 cli_close(cli1, fnum1);
6446 /* Now create a hardlink. */
6447 status = cli_posix_hardlink(cli1, fname, hname);
6448 if (!NT_STATUS_IS_OK(status)) {
6449 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
6453 /* Now create a symlink. */
6454 status = cli_posix_symlink(cli1, fname, sname);
6455 if (!NT_STATUS_IS_OK(status)) {
6456 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
6460 /* Open the hardlink for read. */
6461 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
6462 if (!NT_STATUS_IS_OK(status)) {
6463 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
6467 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
6468 if (!NT_STATUS_IS_OK(status)) {
6469 printf("POSIX read of %s failed (%s)\n", hname,
6472 } else if (nread != 10) {
6473 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6474 hname, (unsigned long)nread, 10);
6478 if (memcmp(buf, "TEST DATA\n", 10)) {
6479 printf("invalid data read from hardlink\n");
6483 /* Do a POSIX lock/unlock. */
6484 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
6485 if (!NT_STATUS_IS_OK(status)) {
6486 printf("POSIX lock failed %s\n", nt_errstr(status));
6490 /* Punch a hole in the locked area. */
6491 status = cli_posix_unlock(cli1, fnum1, 10, 80);
6492 if (!NT_STATUS_IS_OK(status)) {
6493 printf("POSIX unlock failed %s\n", nt_errstr(status));
6497 cli_close(cli1, fnum1);
6499 /* Open the symlink for read - this should fail. A POSIX
6500 client should not be doing opens on a symlink. */
6501 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
6502 if (NT_STATUS_IS_OK(status)) {
6503 printf("POSIX open of %s succeeded (should have failed)\n", sname);
6506 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
6507 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
6508 printf("POSIX open of %s should have failed "
6509 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6510 "failed with %s instead.\n",
6511 sname, nt_errstr(status));
6516 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
6517 if (!NT_STATUS_IS_OK(status)) {
6518 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
6522 if (strcmp(namebuf, fname) != 0) {
6523 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6524 sname, fname, namebuf);
6528 status = cli_posix_rmdir(cli1, dname);
6529 if (!NT_STATUS_IS_OK(status)) {
6530 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
6534 /* Check directory opens with a specific permission. */
6535 status = cli_posix_mkdir(cli1, dname, 0700);
6536 if (!NT_STATUS_IS_OK(status)) {
6537 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6541 /* Ensure st_mode == 0700 */
6542 status = cli_posix_stat(cli1, dname, &sbuf);
6543 if (!NT_STATUS_IS_OK(status)) {
6544 printf("stat failed (%s)\n", nt_errstr(status));
6548 if ((sbuf.st_ex_mode & 07777) != 0700) {
6549 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6550 (unsigned int)(sbuf.st_ex_mode & 07777));
6555 * Now create a Windows file, and attempt a POSIX unlink.
6556 * This should fail with a sharing violation but due to:
6558 * [Bug 9571] Unlink after open causes smbd to panic
6560 * ensure we've fixed the lock ordering violation.
6563 status = cli_ntcreate(cli1, fname_windows, 0,
6564 FILE_READ_DATA|FILE_WRITE_DATA, 0,
6565 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6567 0x0, 0x0, &fnum2, NULL);
6568 if (!NT_STATUS_IS_OK(status)) {
6569 printf("Windows create of %s failed (%s)\n", fname_windows,
6574 /* Now try posix_unlink. */
6575 status = cli_posix_unlink(cli1, fname_windows);
6576 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6577 printf("POSIX unlink of %s should fail "
6578 "with NT_STATUS_SHARING_VIOLATION "
6579 "got %s instead !\n",
6585 cli_close(cli1, fnum2);
6587 printf("Simple POSIX open test passed\n");
6592 if (fnum1 != (uint16_t)-1) {
6593 cli_close(cli1, fnum1);
6594 fnum1 = (uint16_t)-1;
6597 if (fnum2 != (uint16_t)-1) {
6598 cli_close(cli1, fnum2);
6599 fnum2 = (uint16_t)-1;
6602 cli_setatr(cli1, sname, 0, 0);
6603 cli_posix_unlink(cli1, sname);
6604 cli_setatr(cli1, hname, 0, 0);
6605 cli_posix_unlink(cli1, hname);
6606 cli_setatr(cli1, fname, 0, 0);
6607 cli_posix_unlink(cli1, fname);
6608 cli_setatr(cli1, dname, 0, 0);
6609 cli_posix_rmdir(cli1, dname);
6610 cli_setatr(cli1, fname_windows, 0, 0);
6611 cli_posix_unlink(cli1, fname_windows);
6613 if (!torture_close_connection(cli1)) {
6621 Test POSIX and Windows ACLs are rejected on symlinks.
6623 static bool run_acl_symlink_test(int dummy)
6625 static struct cli_state *cli;
6626 const char *fname = "posix_file";
6627 const char *sname = "posix_symlink";
6628 uint16_t fnum = (uint16_t)-1;
6629 bool correct = false;
6631 char *posix_acl = NULL;
6632 size_t posix_acl_len = 0;
6633 char *posix_acl_sym = NULL;
6634 size_t posix_acl_len_sym = 0;
6635 struct security_descriptor *sd = NULL;
6636 struct security_descriptor *sd_sym = NULL;
6637 TALLOC_CTX *frame = NULL;
6639 frame = talloc_stackframe();
6641 printf("Starting acl symlink test\n");
6643 if (!torture_open_connection(&cli, 0)) {
6648 smbXcli_conn_set_sockopt(cli->conn, sockops);
6650 status = torture_setup_unix_extensions(cli);
6651 if (!NT_STATUS_IS_OK(status)) {
6656 cli_setatr(cli, fname, 0, 0);
6657 cli_posix_unlink(cli, fname);
6658 cli_setatr(cli, sname, 0, 0);
6659 cli_posix_unlink(cli, sname);
6661 status = cli_ntcreate(cli,
6664 READ_CONTROL_ACCESS,
6666 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6673 if (!NT_STATUS_IS_OK(status)) {
6674 printf("cli_ntcreate of %s failed (%s)\n",
6680 /* Get the Windows ACL on the file. */
6681 status = cli_query_secdesc(cli,
6685 if (!NT_STATUS_IS_OK(status)) {
6686 printf("cli_query_secdesc failed (%s)\n",
6691 /* Get the POSIX ACL on the file. */
6692 status = cli_posix_getacl(cli,
6698 if (!NT_STATUS_IS_OK(status)) {
6699 printf("cli_posix_getacl failed (%s)\n",
6704 status = cli_close(cli, fnum);
6705 if (!NT_STATUS_IS_OK(status)) {
6706 printf("close failed (%s)\n", nt_errstr(status));
6709 fnum = (uint16_t)-1;
6711 /* Now create a symlink. */
6712 status = cli_posix_symlink(cli, fname, sname);
6713 if (!NT_STATUS_IS_OK(status)) {
6714 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6721 /* Open a handle on the symlink. */
6722 status = cli_ntcreate(cli,
6725 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
6727 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6734 if (!NT_STATUS_IS_OK(status)) {
6735 printf("cli_posix_open of %s failed (%s)\n",
6741 /* Get the Windows ACL on the symlink handle. Should fail */
6742 status = cli_query_secdesc(cli,
6747 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6748 printf("cli_query_secdesc on a symlink gave %s. "
6749 "Should be NT_STATUS_ACCESS_DENIED.\n",
6754 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6755 status = cli_posix_getacl(cli,
6761 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6762 printf("cli_posix_getacl on a symlink gave %s. "
6763 "Should be NT_STATUS_ACCESS_DENIED.\n",
6768 /* Set the Windows ACL on the symlink handle. Should fail */
6769 status = cli_set_security_descriptor(cli,
6774 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6775 printf("cli_query_secdesc on a symlink gave %s. "
6776 "Should be NT_STATUS_ACCESS_DENIED.\n",
6781 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6782 status = cli_posix_setacl(cli,
6787 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6788 printf("cli_posix_getacl on a symlink gave %s. "
6789 "Should be NT_STATUS_ACCESS_DENIED.\n",
6794 printf("ACL symlink test passed\n");
6799 if (fnum != (uint16_t)-1) {
6800 cli_close(cli, fnum);
6801 fnum = (uint16_t)-1;
6804 cli_setatr(cli, sname, 0, 0);
6805 cli_posix_unlink(cli, sname);
6806 cli_setatr(cli, fname, 0, 0);
6807 cli_posix_unlink(cli, fname);
6809 if (!torture_close_connection(cli)) {
6818 Test POSIX can delete a file containing streams.
6820 static bool run_posix_stream_delete(int dummy)
6822 struct cli_state *cli1 = NULL;
6823 struct cli_state *cli2 = NULL;
6824 const char *fname = "streamfile";
6825 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6826 uint16_t fnum1 = (uint16_t)-1;
6827 bool correct = false;
6829 TALLOC_CTX *frame = NULL;
6831 frame = talloc_stackframe();
6833 printf("Starting POSIX stream delete test\n");
6835 if (!torture_open_connection(&cli1, 0) ||
6836 !torture_open_connection(&cli2, 1)) {
6841 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6842 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6844 status = torture_setup_unix_extensions(cli2);
6845 if (!NT_STATUS_IS_OK(status)) {
6849 cli_setatr(cli1, fname, 0, 0);
6850 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6852 /* Create the file. */
6853 status = cli_ntcreate(cli1,
6856 READ_CONTROL_ACCESS,
6858 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6865 if (!NT_STATUS_IS_OK(status)) {
6866 printf("cli_ntcreate of %s failed (%s)\n",
6872 status = cli_close(cli1, fnum1);
6873 if (!NT_STATUS_IS_OK(status)) {
6874 printf("cli_close of %s failed (%s)\n",
6879 fnum1 = (uint16_t)-1;
6881 /* Now create the stream. */
6882 status = cli_ntcreate(cli1,
6887 FILE_SHARE_READ|FILE_SHARE_WRITE,
6894 if (!NT_STATUS_IS_OK(status)) {
6895 printf("cli_ntcreate of %s failed (%s)\n",
6901 /* Leave the stream handle open... */
6903 /* POSIX unlink should fail. */
6904 status = cli_posix_unlink(cli2, fname);
6905 if (NT_STATUS_IS_OK(status)) {
6906 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6911 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6912 printf("cli_posix_unlink of %s failed with (%s) "
6913 "should have been NT_STATUS_SHARING_VIOLATION\n",
6919 /* Close the stream handle. */
6920 status = cli_close(cli1, fnum1);
6921 if (!NT_STATUS_IS_OK(status)) {
6922 printf("cli_close of %s failed (%s)\n",
6927 fnum1 = (uint16_t)-1;
6929 /* POSIX unlink after stream handle closed should succeed. */
6930 status = cli_posix_unlink(cli2, fname);
6931 if (!NT_STATUS_IS_OK(status)) {
6932 printf("cli_posix_unlink of %s failed (%s)\n",
6938 printf("POSIX stream delete test passed\n");
6943 if (fnum1 != (uint16_t)-1) {
6944 cli_close(cli1, fnum1);
6945 fnum1 = (uint16_t)-1;
6948 cli_setatr(cli1, fname, 0, 0);
6949 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6951 if (!torture_close_connection(cli1)) {
6954 if (!torture_close_connection(cli2)) {
6963 Test setting EA's are rejected on symlinks.
6965 static bool run_ea_symlink_test(int dummy)
6967 static struct cli_state *cli;
6968 const char *fname = "posix_file_ea";
6969 const char *sname = "posix_symlink_ea";
6970 const char *ea_name = "testea_name";
6971 const char *ea_value = "testea_value";
6972 uint16_t fnum = (uint16_t)-1;
6973 bool correct = false;
6976 struct ea_struct *eas = NULL;
6977 TALLOC_CTX *frame = NULL;
6979 frame = talloc_stackframe();
6981 printf("Starting EA symlink test\n");
6983 if (!torture_open_connection(&cli, 0)) {
6988 smbXcli_conn_set_sockopt(cli->conn, sockops);
6990 status = torture_setup_unix_extensions(cli);
6991 if (!NT_STATUS_IS_OK(status)) {
6996 cli_setatr(cli, fname, 0, 0);
6997 cli_posix_unlink(cli, fname);
6998 cli_setatr(cli, sname, 0, 0);
6999 cli_posix_unlink(cli, sname);
7001 status = cli_ntcreate(cli,
7004 READ_CONTROL_ACCESS,
7006 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7013 if (!NT_STATUS_IS_OK(status)) {
7014 printf("cli_ntcreate of %s failed (%s)\n",
7020 status = cli_close(cli, fnum);
7021 if (!NT_STATUS_IS_OK(status)) {
7022 printf("close failed (%s)\n",
7026 fnum = (uint16_t)-1;
7028 /* Set an EA on the path. */
7029 status = cli_set_ea_path(cli,
7033 strlen(ea_value)+1);
7035 if (!NT_STATUS_IS_OK(status)) {
7036 printf("cli_set_ea_path failed (%s)\n",
7041 /* Now create a symlink. */
7042 status = cli_posix_symlink(cli, fname, sname);
7043 if (!NT_STATUS_IS_OK(status)) {
7044 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
7051 /* Get the EA list on the path. Should return value set. */
7052 status = cli_get_ea_list_path(cli,
7058 if (!NT_STATUS_IS_OK(status)) {
7059 printf("cli_get_ea_list_path failed (%s)\n",
7064 /* Ensure the EA we set is there. */
7065 for (i=0; i<num_eas; i++) {
7066 if (strcmp(eas[i].name, ea_name) == 0 &&
7067 eas[i].value.length == strlen(ea_value)+1 &&
7068 memcmp(eas[i].value.data,
7070 eas[i].value.length) == 0) {
7076 printf("Didn't find EA on pathname %s\n",
7084 /* Get the EA list on the symlink. Should return empty list. */
7085 status = cli_get_ea_list_path(cli,
7091 if (!NT_STATUS_IS_OK(status)) {
7092 printf("cli_get_ea_list_path failed (%s)\n",
7098 printf("cli_get_ea_list_path failed (%s)\n",
7103 /* Set an EA on the symlink. Should fail. */
7104 status = cli_set_ea_path(cli,
7108 strlen(ea_value)+1);
7110 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7111 printf("cli_set_ea_path on a symlink gave %s. "
7112 "Should be NT_STATUS_ACCESS_DENIED.\n",
7117 printf("EA symlink test passed\n");
7122 if (fnum != (uint16_t)-1) {
7123 cli_close(cli, fnum);
7124 fnum = (uint16_t)-1;
7127 cli_setatr(cli, sname, 0, 0);
7128 cli_posix_unlink(cli, sname);
7129 cli_setatr(cli, fname, 0, 0);
7130 cli_posix_unlink(cli, fname);
7132 if (!torture_close_connection(cli)) {
7141 Test POSIX locks are OFD-locks.
7143 static bool run_posix_ofd_lock_test(int dummy)
7145 static struct cli_state *cli;
7146 const char *fname = "posix_file";
7147 uint16_t fnum1 = (uint16_t)-1;
7148 uint16_t fnum2 = (uint16_t)-1;
7149 bool correct = false;
7151 TALLOC_CTX *frame = NULL;
7153 frame = talloc_stackframe();
7155 printf("Starting POSIX ofd-lock test\n");
7157 if (!torture_open_connection(&cli, 0)) {
7162 smbXcli_conn_set_sockopt(cli->conn, sockops);
7164 status = torture_setup_unix_extensions(cli);
7165 if (!NT_STATUS_IS_OK(status)) {
7170 cli_setatr(cli, fname, 0, 0);
7171 cli_posix_unlink(cli, fname);
7173 /* Open the file twice. */
7174 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
7176 if (!NT_STATUS_IS_OK(status)) {
7177 printf("First POSIX open of %s failed\n", fname);
7181 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
7182 if (!NT_STATUS_IS_OK(status)) {
7183 printf("First POSIX open of %s failed\n", fname);
7187 /* Set a 0-50 lock on fnum1. */
7188 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7189 if (!NT_STATUS_IS_OK(status)) {
7190 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
7194 /* Set a 60-100 lock on fnum2. */
7195 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
7196 if (!NT_STATUS_IS_OK(status)) {
7197 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
7201 /* close fnum1 - 0-50 lock should go away. */
7202 status = cli_close(cli, fnum1);
7203 if (!NT_STATUS_IS_OK(status)) {
7204 printf("close failed (%s)\n",
7208 fnum1 = (uint16_t)-1;
7210 /* Change the lock context. */
7211 cli_setpid(cli, cli_getpid(cli) + 1);
7213 /* Re-open fnum1. */
7214 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
7215 if (!NT_STATUS_IS_OK(status)) {
7216 printf("Third POSIX open of %s failed\n", fname);
7220 /* 60-100 lock should still be there. */
7221 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
7222 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
7223 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
7227 /* 0-50 lock should be gone. */
7228 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7229 if (!NT_STATUS_IS_OK(status)) {
7230 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
7234 printf("POSIX OFD lock test passed\n");
7239 if (fnum1 != (uint16_t)-1) {
7240 cli_close(cli, fnum1);
7241 fnum1 = (uint16_t)-1;
7243 if (fnum2 != (uint16_t)-1) {
7244 cli_close(cli, fnum2);
7245 fnum2 = (uint16_t)-1;
7248 cli_setatr(cli, fname, 0, 0);
7249 cli_posix_unlink(cli, fname);
7251 if (!torture_close_connection(cli)) {
7259 static uint32_t open_attrs_table[] = {
7260 FILE_ATTRIBUTE_NORMAL,
7261 FILE_ATTRIBUTE_ARCHIVE,
7262 FILE_ATTRIBUTE_READONLY,
7263 FILE_ATTRIBUTE_HIDDEN,
7264 FILE_ATTRIBUTE_SYSTEM,
7266 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7267 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7268 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7269 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7270 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7271 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7273 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7274 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7275 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7276 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7279 struct trunc_open_results {
7282 uint32_t trunc_attr;
7283 uint32_t result_attr;
7286 static struct trunc_open_results attr_results[] = {
7287 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7288 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7289 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7290 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7291 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7292 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7293 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7294 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7295 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7296 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7297 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7298 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7299 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7300 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7301 { 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 },
7302 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7303 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7304 { 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 },
7305 { 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 },
7306 { 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 },
7307 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7308 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7309 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7310 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7311 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7312 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7315 static bool run_openattrtest(int dummy)
7317 static struct cli_state *cli1;
7318 const char *fname = "\\openattr.file";
7320 bool correct = True;
7322 unsigned int i, j, k, l;
7325 printf("starting open attr test\n");
7327 if (!torture_open_connection(&cli1, 0)) {
7331 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7333 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7334 cli_setatr(cli1, fname, 0, 0);
7335 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7337 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7338 open_attrs_table[i], FILE_SHARE_NONE,
7339 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7340 if (!NT_STATUS_IS_OK(status)) {
7341 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7345 status = cli_close(cli1, fnum1);
7346 if (!NT_STATUS_IS_OK(status)) {
7347 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7351 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7352 status = cli_ntcreate(cli1, fname, 0,
7353 FILE_READ_DATA|FILE_WRITE_DATA,
7354 open_attrs_table[j],
7355 FILE_SHARE_NONE, FILE_OVERWRITE,
7356 0, 0, &fnum1, NULL);
7357 if (!NT_STATUS_IS_OK(status)) {
7358 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7359 if (attr_results[l].num == k) {
7360 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7361 k, open_attrs_table[i],
7362 open_attrs_table[j],
7363 fname, NT_STATUS_V(status), nt_errstr(status));
7368 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7369 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7370 k, open_attrs_table[i], open_attrs_table[j],
7375 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7381 status = cli_close(cli1, fnum1);
7382 if (!NT_STATUS_IS_OK(status)) {
7383 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7387 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7388 if (!NT_STATUS_IS_OK(status)) {
7389 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7394 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7395 k, open_attrs_table[i], open_attrs_table[j], attr );
7398 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7399 if (attr_results[l].num == k) {
7400 if (attr != attr_results[l].result_attr ||
7401 open_attrs_table[i] != attr_results[l].init_attr ||
7402 open_attrs_table[j] != attr_results[l].trunc_attr) {
7403 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7404 open_attrs_table[i],
7405 open_attrs_table[j],
7407 attr_results[l].result_attr);
7417 cli_setatr(cli1, fname, 0, 0);
7418 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7420 printf("open attr test %s.\n", correct ? "passed" : "failed");
7422 if (!torture_close_connection(cli1)) {
7428 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7429 const char *name, void *state)
7431 int *matched = (int *)state;
7432 if (matched != NULL) {
7435 return NT_STATUS_OK;
7439 test directory listing speed
7441 static bool run_dirtest(int dummy)
7444 static struct cli_state *cli;
7446 struct timeval core_start;
7447 bool correct = True;
7450 printf("starting directory test\n");
7452 if (!torture_open_connection(&cli, 0)) {
7456 smbXcli_conn_set_sockopt(cli->conn, sockops);
7459 for (i=0;i<torture_numops;i++) {
7461 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7462 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7463 fprintf(stderr,"Failed to open %s\n", fname);
7466 cli_close(cli, fnum);
7469 core_start = timeval_current();
7472 cli_list(cli, "a*.*", 0, list_fn, &matched);
7473 printf("Matched %d\n", matched);
7476 cli_list(cli, "b*.*", 0, list_fn, &matched);
7477 printf("Matched %d\n", matched);
7480 cli_list(cli, "xyzabc", 0, list_fn, &matched);
7481 printf("Matched %d\n", matched);
7483 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7486 for (i=0;i<torture_numops;i++) {
7488 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7489 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7492 if (!torture_close_connection(cli)) {
7496 printf("finished dirtest\n");
7501 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7504 struct cli_state *pcli = (struct cli_state *)state;
7506 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7508 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7509 return NT_STATUS_OK;
7511 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7512 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7513 printf("del_fn: failed to rmdir %s\n,", fname );
7515 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7516 printf("del_fn: failed to unlink %s\n,", fname );
7518 return NT_STATUS_OK;
7523 sees what IOCTLs are supported
7525 bool torture_ioctl_test(int dummy)
7527 static struct cli_state *cli;
7528 uint16_t device, function;
7530 const char *fname = "\\ioctl.dat";
7534 if (!torture_open_connection(&cli, 0)) {
7538 printf("starting ioctl test\n");
7540 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7542 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7543 if (!NT_STATUS_IS_OK(status)) {
7544 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7548 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7549 printf("ioctl device info: %s\n", nt_errstr(status));
7551 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7552 printf("ioctl job info: %s\n", nt_errstr(status));
7554 for (device=0;device<0x100;device++) {
7555 printf("ioctl test with device = 0x%x\n", device);
7556 for (function=0;function<0x100;function++) {
7557 uint32_t code = (device<<16) | function;
7559 status = cli_raw_ioctl(cli, fnum, code, &blob);
7561 if (NT_STATUS_IS_OK(status)) {
7562 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7564 data_blob_free(&blob);
7569 if (!torture_close_connection(cli)) {
7578 tries varients of chkpath
7580 bool torture_chkpath_test(int dummy)
7582 static struct cli_state *cli;
7587 if (!torture_open_connection(&cli, 0)) {
7591 printf("starting chkpath test\n");
7593 /* cleanup from an old run */
7594 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7595 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7596 cli_rmdir(cli, "\\chkpath.dir");
7598 status = cli_mkdir(cli, "\\chkpath.dir");
7599 if (!NT_STATUS_IS_OK(status)) {
7600 printf("mkdir1 failed : %s\n", nt_errstr(status));
7604 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7605 if (!NT_STATUS_IS_OK(status)) {
7606 printf("mkdir2 failed : %s\n", nt_errstr(status));
7610 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7612 if (!NT_STATUS_IS_OK(status)) {
7613 printf("open1 failed (%s)\n", nt_errstr(status));
7616 cli_close(cli, fnum);
7618 status = cli_chkpath(cli, "\\chkpath.dir");
7619 if (!NT_STATUS_IS_OK(status)) {
7620 printf("chkpath1 failed: %s\n", nt_errstr(status));
7624 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7625 if (!NT_STATUS_IS_OK(status)) {
7626 printf("chkpath2 failed: %s\n", nt_errstr(status));
7630 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7631 if (!NT_STATUS_IS_OK(status)) {
7632 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7633 NT_STATUS_NOT_A_DIRECTORY);
7635 printf("* chkpath on a file should fail\n");
7639 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7640 if (!NT_STATUS_IS_OK(status)) {
7641 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7642 NT_STATUS_OBJECT_NAME_NOT_FOUND);
7644 printf("* chkpath on a non existent file should fail\n");
7648 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7649 if (!NT_STATUS_IS_OK(status)) {
7650 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7651 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7653 printf("* chkpath on a non existent component should fail\n");
7657 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7658 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7659 cli_rmdir(cli, "\\chkpath.dir");
7661 if (!torture_close_connection(cli)) {
7668 static bool run_eatest(int dummy)
7670 static struct cli_state *cli;
7671 const char *fname = "\\eatest.txt";
7672 bool correct = True;
7676 struct ea_struct *ea_list = NULL;
7677 TALLOC_CTX *mem_ctx = talloc_init("eatest");
7680 printf("starting eatest\n");
7682 if (!torture_open_connection(&cli, 0)) {
7683 talloc_destroy(mem_ctx);
7687 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7689 status = cli_ntcreate(cli, fname, 0,
7690 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7691 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7692 0x4044, 0, &fnum, NULL);
7693 if (!NT_STATUS_IS_OK(status)) {
7694 printf("open failed - %s\n", nt_errstr(status));
7695 talloc_destroy(mem_ctx);
7699 for (i = 0; i < 10; i++) {
7700 fstring ea_name, ea_val;
7702 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7703 memset(ea_val, (char)i+1, i+1);
7704 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7705 if (!NT_STATUS_IS_OK(status)) {
7706 printf("ea_set of name %s failed - %s\n", ea_name,
7708 talloc_destroy(mem_ctx);
7713 cli_close(cli, fnum);
7714 for (i = 0; i < 10; i++) {
7715 fstring ea_name, ea_val;
7717 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7718 memset(ea_val, (char)i+1, i+1);
7719 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7720 if (!NT_STATUS_IS_OK(status)) {
7721 printf("ea_set of name %s failed - %s\n", ea_name,
7723 talloc_destroy(mem_ctx);
7728 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7729 if (!NT_STATUS_IS_OK(status)) {
7730 printf("ea_get list failed - %s\n", nt_errstr(status));
7734 printf("num_eas = %d\n", (int)num_eas);
7736 if (num_eas != 20) {
7737 printf("Should be 20 EA's stored... failing.\n");
7741 for (i = 0; i < num_eas; i++) {
7742 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7743 dump_data(0, ea_list[i].value.data,
7744 ea_list[i].value.length);
7747 /* Setting EA's to zero length deletes them. Test this */
7748 printf("Now deleting all EA's - case indepenent....\n");
7751 cli_set_ea_path(cli, fname, "", "", 0);
7753 for (i = 0; i < 20; i++) {
7755 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7756 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7757 if (!NT_STATUS_IS_OK(status)) {
7758 printf("ea_set of name %s failed - %s\n", ea_name,
7760 talloc_destroy(mem_ctx);
7766 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7767 if (!NT_STATUS_IS_OK(status)) {
7768 printf("ea_get list failed - %s\n", nt_errstr(status));
7772 printf("num_eas = %d\n", (int)num_eas);
7773 for (i = 0; i < num_eas; i++) {
7774 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7775 dump_data(0, ea_list[i].value.data,
7776 ea_list[i].value.length);
7780 printf("deleting EA's failed.\n");
7784 /* Try and delete a non existent EA. */
7785 status = cli_set_ea_path(cli, fname, "foo", "", 0);
7786 if (!NT_STATUS_IS_OK(status)) {
7787 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7792 talloc_destroy(mem_ctx);
7793 if (!torture_close_connection(cli)) {
7800 static bool run_dirtest1(int dummy)
7803 static struct cli_state *cli;
7806 bool correct = True;
7808 printf("starting directory test\n");
7810 if (!torture_open_connection(&cli, 0)) {
7814 smbXcli_conn_set_sockopt(cli->conn, sockops);
7816 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7817 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7818 cli_rmdir(cli, "\\LISTDIR");
7819 cli_mkdir(cli, "\\LISTDIR");
7821 /* Create 1000 files and 1000 directories. */
7822 for (i=0;i<1000;i++) {
7824 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7825 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7826 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7827 0, 0, &fnum, NULL))) {
7828 fprintf(stderr,"Failed to open %s\n", fname);
7831 cli_close(cli, fnum);
7833 for (i=0;i<1000;i++) {
7835 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7836 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7837 fprintf(stderr,"Failed to open %s\n", fname);
7842 /* Now ensure that doing an old list sees both files and directories. */
7844 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7845 printf("num_seen = %d\n", num_seen );
7846 /* We should see 100 files + 1000 directories + . and .. */
7847 if (num_seen != 2002)
7850 /* Ensure if we have the "must have" bits we only see the
7854 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7855 printf("num_seen = %d\n", num_seen );
7856 if (num_seen != 1002)
7860 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7861 printf("num_seen = %d\n", num_seen );
7862 if (num_seen != 1000)
7865 /* Delete everything. */
7866 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7867 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7868 cli_rmdir(cli, "\\LISTDIR");
7871 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7872 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7873 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7876 if (!torture_close_connection(cli)) {
7880 printf("finished dirtest1\n");
7885 static bool run_error_map_extract(int dummy) {
7887 static struct cli_state *c_dos;
7888 static struct cli_state *c_nt;
7900 /* NT-Error connection */
7902 disable_spnego = true;
7903 if (!(c_nt = open_nbt_connection())) {
7904 disable_spnego = false;
7907 disable_spnego = false;
7909 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7912 if (!NT_STATUS_IS_OK(status)) {
7913 printf("%s rejected the NT-error negprot (%s)\n", host,
7919 status = cli_session_setup_anon(c_nt);
7920 if (!NT_STATUS_IS_OK(status)) {
7921 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7925 /* DOS-Error connection */
7927 disable_spnego = true;
7928 force_dos_errors = true;
7929 if (!(c_dos = open_nbt_connection())) {
7930 disable_spnego = false;
7931 force_dos_errors = false;
7934 disable_spnego = false;
7935 force_dos_errors = false;
7937 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7939 if (!NT_STATUS_IS_OK(status)) {
7940 printf("%s rejected the DOS-error negprot (%s)\n", host,
7942 cli_shutdown(c_dos);
7946 status = cli_session_setup_anon(c_dos);
7947 if (!NT_STATUS_IS_OK(status)) {
7948 printf("%s rejected the DOS-error initial session setup (%s)\n",
7949 host, nt_errstr(status));
7953 c_nt->map_dos_errors = false;
7954 c_dos->map_dos_errors = false;
7956 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7957 struct cli_credentials *user_creds = NULL;
7959 fstr_sprintf(user, "%X", error);
7961 user_creds = cli_session_creds_init(talloc_tos(),
7966 false, /* use_kerberos */
7967 false, /* fallback_after_kerberos */
7968 false, /* use_ccache */
7969 false); /* password_is_nt_hash */
7970 if (user_creds == NULL) {
7971 printf("cli_session_creds_init(%s) failed\n", user);
7975 status = cli_session_setup_creds(c_nt, user_creds);
7976 if (NT_STATUS_IS_OK(status)) {
7977 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7980 /* Case #1: 32-bit NT errors */
7981 if (!NT_STATUS_IS_DOS(status)) {
7984 printf("/** Dos error on NT connection! (%s) */\n",
7986 nt_status = NT_STATUS(0xc0000000);
7989 status = cli_session_setup_creds(c_dos, user_creds);
7990 if (NT_STATUS_IS_OK(status)) {
7991 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7994 /* Case #1: 32-bit NT errors */
7995 if (NT_STATUS_IS_DOS(status)) {
7996 printf("/** NT error on DOS connection! (%s) */\n",
7998 errnum = errclass = 0;
8000 errclass = NT_STATUS_DOS_CLASS(status);
8001 errnum = NT_STATUS_DOS_CODE(status);
8004 if (NT_STATUS_V(nt_status) != error) {
8005 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
8006 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
8007 get_nt_error_c_code(talloc_tos(), nt_status));
8010 printf("\t{%s,\t%s,\t%s},\n",
8011 smb_dos_err_class(errclass),
8012 smb_dos_err_name(errclass, errnum),
8013 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
8015 TALLOC_FREE(user_creds);
8020 static bool run_sesssetup_bench(int dummy)
8022 static struct cli_state *c;
8023 const char *fname = "\\file.dat";
8028 if (!torture_open_connection(&c, 0)) {
8032 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8033 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8034 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
8035 if (!NT_STATUS_IS_OK(status)) {
8036 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8040 for (i=0; i<torture_numops; i++) {
8041 status = cli_session_setup_creds(c, torture_creds);
8042 if (!NT_STATUS_IS_OK(status)) {
8043 d_printf("(%s) cli_session_setup_creds failed: %s\n",
8044 __location__, nt_errstr(status));
8048 d_printf("\r%d ", (int)cli_state_get_uid(c));
8050 status = cli_ulogoff(c);
8051 if (!NT_STATUS_IS_OK(status)) {
8052 d_printf("(%s) cli_ulogoff failed: %s\n",
8053 __location__, nt_errstr(status));
8061 static bool subst_test(const char *str, const char *user, const char *domain,
8062 uid_t uid, gid_t gid, const char *expected)
8067 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
8069 if (strcmp(subst, expected) != 0) {
8070 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
8071 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
8080 static void chain1_open_completion(struct tevent_req *req)
8084 status = cli_openx_recv(req, &fnum);
8087 d_printf("cli_openx_recv returned %s: %d\n",
8089 NT_STATUS_IS_OK(status) ? fnum : -1);
8092 static void chain1_write_completion(struct tevent_req *req)
8096 status = cli_write_andx_recv(req, &written);
8099 d_printf("cli_write_andx_recv returned %s: %d\n",
8101 NT_STATUS_IS_OK(status) ? (int)written : -1);
8104 static void chain1_close_completion(struct tevent_req *req)
8107 bool *done = (bool *)tevent_req_callback_data_void(req);
8109 status = cli_close_recv(req);
8114 d_printf("cli_close returned %s\n", nt_errstr(status));
8117 static bool run_chain1(int dummy)
8119 struct cli_state *cli1;
8120 struct tevent_context *evt = samba_tevent_context_init(NULL);
8121 struct tevent_req *reqs[3], *smbreqs[3];
8123 const char *str = "foobar";
8126 printf("starting chain1 test\n");
8127 if (!torture_open_connection(&cli1, 0)) {
8131 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8133 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
8134 O_CREAT|O_RDWR, 0, &smbreqs[0]);
8135 if (reqs[0] == NULL) return false;
8136 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
8139 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
8140 (const uint8_t *)str, 0, strlen(str)+1,
8141 smbreqs, 1, &smbreqs[1]);
8142 if (reqs[1] == NULL) return false;
8143 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
8145 reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
8146 if (reqs[2] == NULL) return false;
8147 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
8149 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8150 if (!NT_STATUS_IS_OK(status)) {
8155 tevent_loop_once(evt);
8158 torture_close_connection(cli1);
8162 static void chain2_sesssetup_completion(struct tevent_req *req)
8165 status = cli_session_setup_guest_recv(req);
8166 d_printf("sesssetup returned %s\n", nt_errstr(status));
8169 static void chain2_tcon_completion(struct tevent_req *req)
8171 bool *done = (bool *)tevent_req_callback_data_void(req);
8173 status = cli_tcon_andx_recv(req);
8174 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
8178 static bool run_chain2(int dummy)
8180 struct cli_state *cli1;
8181 struct tevent_context *evt = samba_tevent_context_init(NULL);
8182 struct tevent_req *reqs[2], *smbreqs[2];
8185 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
8187 printf("starting chain2 test\n");
8188 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
8189 port_to_use, SMB_SIGNING_DEFAULT, flags);
8190 if (!NT_STATUS_IS_OK(status)) {
8194 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8196 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
8198 if (reqs[0] == NULL) return false;
8199 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
8201 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
8202 "?????", NULL, 0, &smbreqs[1]);
8203 if (reqs[1] == NULL) return false;
8204 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
8206 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8207 if (!NT_STATUS_IS_OK(status)) {
8212 tevent_loop_once(evt);
8215 torture_close_connection(cli1);
8220 struct torture_createdel_state {
8221 struct tevent_context *ev;
8222 struct cli_state *cli;
8225 static void torture_createdel_created(struct tevent_req *subreq);
8226 static void torture_createdel_closed(struct tevent_req *subreq);
8228 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8229 struct tevent_context *ev,
8230 struct cli_state *cli,
8233 struct tevent_req *req, *subreq;
8234 struct torture_createdel_state *state;
8236 req = tevent_req_create(mem_ctx, &state,
8237 struct torture_createdel_state);
8244 subreq = cli_ntcreate_send(
8245 state, ev, cli, name, 0,
8246 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8247 FILE_ATTRIBUTE_NORMAL,
8248 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8249 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
8251 if (tevent_req_nomem(subreq, req)) {
8252 return tevent_req_post(req, ev);
8254 tevent_req_set_callback(subreq, torture_createdel_created, req);
8258 static void torture_createdel_created(struct tevent_req *subreq)
8260 struct tevent_req *req = tevent_req_callback_data(
8261 subreq, struct tevent_req);
8262 struct torture_createdel_state *state = tevent_req_data(
8263 req, struct torture_createdel_state);
8267 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8268 TALLOC_FREE(subreq);
8269 if (tevent_req_nterror(req, status)) {
8270 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8271 nt_errstr(status)));
8275 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8276 if (tevent_req_nomem(subreq, req)) {
8279 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8282 static void torture_createdel_closed(struct tevent_req *subreq)
8284 struct tevent_req *req = tevent_req_callback_data(
8285 subreq, struct tevent_req);
8288 status = cli_close_recv(subreq);
8289 if (tevent_req_nterror(req, status)) {
8290 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8293 tevent_req_done(req);
8296 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8298 return tevent_req_simple_recv_ntstatus(req);
8301 struct torture_createdels_state {
8302 struct tevent_context *ev;
8303 struct cli_state *cli;
8304 const char *base_name;
8308 struct tevent_req **reqs;
8311 static void torture_createdels_done(struct tevent_req *subreq);
8313 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8314 struct tevent_context *ev,
8315 struct cli_state *cli,
8316 const char *base_name,
8320 struct tevent_req *req;
8321 struct torture_createdels_state *state;
8324 req = tevent_req_create(mem_ctx, &state,
8325 struct torture_createdels_state);
8331 state->base_name = talloc_strdup(state, base_name);
8332 if (tevent_req_nomem(state->base_name, req)) {
8333 return tevent_req_post(req, ev);
8335 state->num_files = MAX(num_parallel, num_files);
8337 state->received = 0;
8339 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8340 if (tevent_req_nomem(state->reqs, req)) {
8341 return tevent_req_post(req, ev);
8344 for (i=0; i<num_parallel; i++) {
8347 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8349 if (tevent_req_nomem(name, req)) {
8350 return tevent_req_post(req, ev);
8352 state->reqs[i] = torture_createdel_send(
8353 state->reqs, state->ev, state->cli, name);
8354 if (tevent_req_nomem(state->reqs[i], req)) {
8355 return tevent_req_post(req, ev);
8357 name = talloc_move(state->reqs[i], &name);
8358 tevent_req_set_callback(state->reqs[i],
8359 torture_createdels_done, req);
8365 static void torture_createdels_done(struct tevent_req *subreq)
8367 struct tevent_req *req = tevent_req_callback_data(
8368 subreq, struct tevent_req);
8369 struct torture_createdels_state *state = tevent_req_data(
8370 req, struct torture_createdels_state);
8371 size_t num_parallel = talloc_array_length(state->reqs);
8376 status = torture_createdel_recv(subreq);
8377 if (!NT_STATUS_IS_OK(status)){
8378 DEBUG(10, ("torture_createdel_recv returned %s\n",
8379 nt_errstr(status)));
8380 TALLOC_FREE(subreq);
8381 tevent_req_nterror(req, status);
8385 for (i=0; i<num_parallel; i++) {
8386 if (subreq == state->reqs[i]) {
8390 if (i == num_parallel) {
8391 DEBUG(10, ("received something we did not send\n"));
8392 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8395 TALLOC_FREE(state->reqs[i]);
8397 if (state->sent >= state->num_files) {
8398 tevent_req_done(req);
8402 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8404 if (tevent_req_nomem(name, req)) {
8407 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8409 if (tevent_req_nomem(state->reqs[i], req)) {
8412 name = talloc_move(state->reqs[i], &name);
8413 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8417 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8419 return tevent_req_simple_recv_ntstatus(req);
8422 struct swallow_notify_state {
8423 struct tevent_context *ev;
8424 struct cli_state *cli;
8426 uint32_t completion_filter;
8428 bool (*fn)(uint32_t action, const char *name, void *priv);
8432 static void swallow_notify_done(struct tevent_req *subreq);
8434 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8435 struct tevent_context *ev,
8436 struct cli_state *cli,
8438 uint32_t completion_filter,
8440 bool (*fn)(uint32_t action,
8445 struct tevent_req *req, *subreq;
8446 struct swallow_notify_state *state;
8448 req = tevent_req_create(mem_ctx, &state,
8449 struct swallow_notify_state);
8456 state->completion_filter = completion_filter;
8457 state->recursive = recursive;
8461 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8462 0xffff, state->completion_filter,
8464 if (tevent_req_nomem(subreq, req)) {
8465 return tevent_req_post(req, ev);
8467 tevent_req_set_callback(subreq, swallow_notify_done, req);
8471 static void swallow_notify_done(struct tevent_req *subreq)
8473 struct tevent_req *req = tevent_req_callback_data(
8474 subreq, struct tevent_req);
8475 struct swallow_notify_state *state = tevent_req_data(
8476 req, struct swallow_notify_state);
8478 uint32_t i, num_changes;
8479 struct notify_change *changes;
8481 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8482 TALLOC_FREE(subreq);
8483 if (!NT_STATUS_IS_OK(status)) {
8484 DEBUG(10, ("cli_notify_recv returned %s\n",
8485 nt_errstr(status)));
8486 tevent_req_nterror(req, status);
8490 for (i=0; i<num_changes; i++) {
8491 state->fn(changes[i].action, changes[i].name, state->priv);
8493 TALLOC_FREE(changes);
8495 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8496 0xffff, state->completion_filter,
8498 if (tevent_req_nomem(subreq, req)) {
8501 tevent_req_set_callback(subreq, swallow_notify_done, req);
8504 static bool print_notifies(uint32_t action, const char *name, void *priv)
8506 if (DEBUGLEVEL > 5) {
8507 d_printf("%d %s\n", (int)action, name);
8512 static void notify_bench_done(struct tevent_req *req)
8514 int *num_finished = (int *)tevent_req_callback_data_void(req);
8518 static bool run_notify_bench(int dummy)
8520 const char *dname = "\\notify-bench";
8521 struct tevent_context *ev;
8524 struct tevent_req *req1;
8525 struct tevent_req *req2 = NULL;
8526 int i, num_unc_names;
8527 int num_finished = 0;
8529 printf("starting notify-bench test\n");
8531 if (use_multishare_conn) {
8533 unc_list = file_lines_load(multishare_conn_fname,
8534 &num_unc_names, 0, NULL);
8535 if (!unc_list || num_unc_names <= 0) {
8536 d_printf("Failed to load unc names list from '%s'\n",
8537 multishare_conn_fname);
8540 TALLOC_FREE(unc_list);
8545 ev = samba_tevent_context_init(talloc_tos());
8547 d_printf("tevent_context_init failed\n");
8551 for (i=0; i<num_unc_names; i++) {
8552 struct cli_state *cli;
8555 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8557 if (base_fname == NULL) {
8561 if (!torture_open_connection(&cli, i)) {
8565 status = cli_ntcreate(cli, dname, 0,
8566 MAXIMUM_ALLOWED_ACCESS,
8567 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8569 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8572 if (!NT_STATUS_IS_OK(status)) {
8573 d_printf("Could not create %s: %s\n", dname,
8578 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8579 FILE_NOTIFY_CHANGE_FILE_NAME |
8580 FILE_NOTIFY_CHANGE_DIR_NAME |
8581 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8582 FILE_NOTIFY_CHANGE_LAST_WRITE,
8583 false, print_notifies, NULL);
8585 d_printf("Could not create notify request\n");
8589 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8590 base_fname, 10, torture_numops);
8592 d_printf("Could not create createdels request\n");
8595 TALLOC_FREE(base_fname);
8597 tevent_req_set_callback(req2, notify_bench_done,
8601 while (num_finished < num_unc_names) {
8603 ret = tevent_loop_once(ev);
8605 d_printf("tevent_loop_once failed\n");
8610 if (!tevent_req_poll(req2, ev)) {
8611 d_printf("tevent_req_poll failed\n");
8614 status = torture_createdels_recv(req2);
8615 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8620 static bool run_mangle1(int dummy)
8622 struct cli_state *cli;
8623 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8627 time_t change_time, access_time, write_time;
8631 printf("starting mangle1 test\n");
8632 if (!torture_open_connection(&cli, 0)) {
8636 smbXcli_conn_set_sockopt(cli->conn, sockops);
8638 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8639 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8641 if (!NT_STATUS_IS_OK(status)) {
8642 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8645 cli_close(cli, fnum);
8647 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8648 if (!NT_STATUS_IS_OK(status)) {
8649 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8653 d_printf("alt_name: %s\n", alt_name);
8655 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8656 if (!NT_STATUS_IS_OK(status)) {
8657 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8661 cli_close(cli, fnum);
8663 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8664 &write_time, &size, &mode);
8665 if (!NT_STATUS_IS_OK(status)) {
8666 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8674 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8675 struct file_info *f,
8679 if (f->short_name == NULL) {
8680 return NT_STATUS_OK;
8683 if (strlen(f->short_name) == 0) {
8684 return NT_STATUS_OK;
8687 printf("unexpected shortname: %s\n", f->short_name);
8689 return NT_STATUS_OBJECT_NAME_INVALID;
8692 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8693 struct file_info *f,
8699 printf("name: %s\n", f->name);
8700 fstrcpy(name, f->name);
8701 return NT_STATUS_OK;
8704 static bool run_mangle_illegal(int dummy)
8706 struct cli_state *cli = NULL;
8707 struct cli_state *cli_posix = NULL;
8708 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8709 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8710 char *mangled_path = NULL;
8716 printf("starting mangle-illegal test\n");
8718 if (!torture_open_connection(&cli, 0)) {
8722 smbXcli_conn_set_sockopt(cli->conn, sockops);
8724 if (!torture_open_connection(&cli_posix, 0)) {
8728 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8730 status = torture_setup_unix_extensions(cli_posix);
8731 if (!NT_STATUS_IS_OK(status)) {
8735 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8736 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8737 if (!NT_STATUS_IS_OK(status)) {
8738 printf("mkdir1 failed : %s\n", nt_errstr(status));
8743 * Create a file with illegal NTFS characters and test that we
8744 * get a usable mangled name
8747 cli_setatr(cli_posix, illegal_fname, 0, 0);
8748 cli_posix_unlink(cli_posix, illegal_fname);
8750 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8752 if (!NT_STATUS_IS_OK(status)) {
8753 printf("POSIX create of %s failed (%s)\n",
8754 illegal_fname, nt_errstr(status));
8758 status = cli_close(cli_posix, fnum);
8759 if (!NT_STATUS_IS_OK(status)) {
8760 printf("close failed (%s)\n", nt_errstr(status));
8764 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8765 if (!NT_STATUS_IS_OK(status)) {
8766 d_printf("cli_list failed: %s\n", nt_errstr(status));
8770 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8771 if (mangled_path == NULL) {
8775 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8776 if (!NT_STATUS_IS_OK(status)) {
8777 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8778 TALLOC_FREE(mangled_path);
8781 TALLOC_FREE(mangled_path);
8782 cli_close(cli, fnum);
8784 cli_setatr(cli_posix, illegal_fname, 0, 0);
8785 cli_posix_unlink(cli_posix, illegal_fname);
8788 * Create a file with a long name and check that we got *no* short name.
8791 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8792 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8794 if (!NT_STATUS_IS_OK(status)) {
8795 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8798 cli_close(cli, fnum);
8800 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8801 if (!NT_STATUS_IS_OK(status)) {
8802 d_printf("cli_list failed\n");
8806 cli_unlink(cli, fname, 0);
8807 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8809 if (!torture_close_connection(cli_posix)) {
8813 if (!torture_close_connection(cli)) {
8820 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8822 size_t *to_pull = (size_t *)priv;
8823 size_t thistime = *to_pull;
8825 thistime = MIN(thistime, n);
8826 if (thistime == 0) {
8830 memset(buf, 0, thistime);
8831 *to_pull -= thistime;
8835 static bool run_windows_write(int dummy)
8837 struct cli_state *cli1;
8841 const char *fname = "\\writetest.txt";
8842 struct timeval start_time;
8847 printf("starting windows_write test\n");
8848 if (!torture_open_connection(&cli1, 0)) {
8852 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8853 if (!NT_STATUS_IS_OK(status)) {
8854 printf("open failed (%s)\n", nt_errstr(status));
8858 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8860 start_time = timeval_current();
8862 for (i=0; i<torture_numops; i++) {
8864 off_t start = i * torture_blocksize;
8865 size_t to_pull = torture_blocksize - 1;
8867 status = cli_writeall(cli1, fnum, 0, &c,
8868 start + torture_blocksize - 1, 1, NULL);
8869 if (!NT_STATUS_IS_OK(status)) {
8870 printf("cli_write failed: %s\n", nt_errstr(status));
8874 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8875 null_source, &to_pull);
8876 if (!NT_STATUS_IS_OK(status)) {
8877 printf("cli_push returned: %s\n", nt_errstr(status));
8882 seconds = timeval_elapsed(&start_time);
8883 kbytes = (double)torture_blocksize * torture_numops;
8886 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8887 (double)seconds, (int)(kbytes/seconds));
8891 cli_close(cli1, fnum);
8892 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8893 torture_close_connection(cli1);
8897 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8899 size_t max_pdu = 0x1FFFF;
8901 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8905 if (smb1cli_conn_signing_is_active(cli->conn)) {
8909 if (smb1cli_conn_encryption_on(cli->conn)) {
8910 max_pdu = CLI_BUFFER_SIZE;
8913 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8914 len_requested &= 0xFFFF;
8917 return MIN(len_requested,
8918 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8921 static bool check_read_call(struct cli_state *cli,
8924 size_t len_requested)
8927 struct tevent_req *subreq = NULL;
8928 ssize_t len_read = 0;
8929 size_t len_expected = 0;
8930 struct tevent_context *ev = NULL;
8932 ev = samba_tevent_context_init(talloc_tos());
8937 subreq = cli_read_andx_send(talloc_tos(),
8944 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8948 status = cli_read_andx_recv(subreq, &len_read, &buf);
8949 if (!NT_STATUS_IS_OK(status)) {
8950 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8954 TALLOC_FREE(subreq);
8957 len_expected = calc_expected_return(cli, len_requested);
8959 if (len_expected > 0x10000 && len_read == 0x10000) {
8960 /* Windows servers only return a max of 0x10000,
8961 doesn't matter if you set CAP_LARGE_READX in
8962 the client sessionsetupX call or not. */
8963 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8964 (unsigned int)len_requested);
8965 } else if (len_read != len_expected) {
8966 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8967 (unsigned int)len_requested,
8968 (unsigned int)len_read,
8969 (unsigned int)len_expected);
8972 d_printf("Correct read reply.\n");
8978 /* Test large readX variants. */
8979 static bool large_readx_tests(struct cli_state *cli,
8983 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8984 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8987 /* A read of 0x10000 should return 0x10000 bytes. */
8988 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8991 /* A read of 0x10000 should return 0x10001 bytes. */
8992 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8995 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8996 the requested number of bytes. */
8997 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
9000 /* A read of 1MB should return 1MB bytes (on Samba). */
9001 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
9005 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
9008 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
9011 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
9017 static bool run_large_readx(int dummy)
9019 uint8_t *buf = NULL;
9020 struct cli_state *cli1 = NULL;
9021 struct cli_state *cli2 = NULL;
9022 bool correct = false;
9023 const char *fname = "\\large_readx.dat";
9025 uint16_t fnum1 = UINT16_MAX;
9026 uint32_t normal_caps = 0;
9027 size_t file_size = 20*1024*1024;
9028 TALLOC_CTX *frame = talloc_stackframe();
9032 enum smb_signing_setting signing_setting;
9033 enum protocol_types protocol;
9037 .signing_setting = SMB_SIGNING_IF_REQUIRED,
9038 .protocol = PROTOCOL_NT1,
9040 .name = "NT1 - SIGNING_REQUIRED",
9041 .signing_setting = SMB_SIGNING_REQUIRED,
9042 .protocol = PROTOCOL_NT1,
9046 printf("starting large_readx test\n");
9048 if (!torture_open_connection(&cli1, 0)) {
9052 normal_caps = smb1cli_conn_capabilities(cli1->conn);
9054 if (!(normal_caps & CAP_LARGE_READX)) {
9055 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9056 (unsigned int)normal_caps);
9060 /* Create a file of size 4MB. */
9061 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
9062 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9063 0, 0, &fnum1, NULL);
9065 if (!NT_STATUS_IS_OK(status)) {
9066 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
9070 /* Write file_size bytes. */
9071 buf = talloc_zero_array(frame, uint8_t, file_size);
9076 status = cli_writeall(cli1,
9083 if (!NT_STATUS_IS_OK(status)) {
9084 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9088 status = cli_close(cli1, fnum1);
9089 if (!NT_STATUS_IS_OK(status)) {
9090 d_printf("cli_close failed: %s\n", nt_errstr(status));
9096 for (i=0; i < ARRAY_SIZE(runs); i++) {
9097 enum smb_signing_setting saved_signing_setting = signing_state;
9098 uint16_t fnum2 = -1;
9101 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
9103 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
9107 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
9109 signing_state = runs[i].signing_setting;
9110 cli2 = open_nbt_connection();
9111 signing_state = saved_signing_setting;
9116 status = smbXcli_negprot(cli2->conn,
9120 if (!NT_STATUS_IS_OK(status)) {
9124 status = cli_session_setup_creds(cli2, torture_creds);
9125 if (!NT_STATUS_IS_OK(status)) {
9129 status = cli_tree_connect(cli2,
9133 if (!NT_STATUS_IS_OK(status)) {
9137 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
9139 normal_caps = smb1cli_conn_capabilities(cli2->conn);
9141 if (!(normal_caps & CAP_LARGE_READX)) {
9142 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9143 (unsigned int)normal_caps);
9148 if (force_cli_encryption(cli2, share) == false) {
9151 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
9152 uint16_t major, minor;
9153 uint32_t caplow, caphigh;
9155 status = cli_unix_extensions_version(cli2,
9158 if (!NT_STATUS_IS_OK(status)) {
9163 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
9164 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
9165 0, 0, &fnum2, NULL);
9166 if (!NT_STATUS_IS_OK(status)) {
9167 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
9171 /* All reads must return less than file_size bytes. */
9172 if (!large_readx_tests(cli2, fnum2, buf)) {
9176 status = cli_close(cli2, fnum2);
9177 if (!NT_STATUS_IS_OK(status)) {
9178 d_printf("cli_close failed: %s\n", nt_errstr(status));
9183 if (!torture_close_connection(cli2)) {
9190 printf("Success on large_readx test\n");
9195 if (!torture_close_connection(cli2)) {
9201 if (fnum1 != UINT16_MAX) {
9202 status = cli_close(cli1, fnum1);
9203 if (!NT_STATUS_IS_OK(status)) {
9204 d_printf("cli_close failed: %s\n", nt_errstr(status));
9209 status = cli_unlink(cli1, fname,
9210 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9211 if (!NT_STATUS_IS_OK(status)) {
9212 printf("unlink failed (%s)\n", nt_errstr(status));
9215 if (!torture_close_connection(cli1)) {
9222 printf("finished large_readx test\n");
9226 static bool run_cli_echo(int dummy)
9228 struct cli_state *cli;
9231 printf("starting cli_echo test\n");
9232 if (!torture_open_connection(&cli, 0)) {
9235 smbXcli_conn_set_sockopt(cli->conn, sockops);
9237 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9239 d_printf("cli_echo returned %s\n", nt_errstr(status));
9241 torture_close_connection(cli);
9242 return NT_STATUS_IS_OK(status);
9245 static int splice_status(off_t written, void *priv)
9250 static bool run_cli_splice(int dummy)
9252 uint8_t *buf = NULL;
9253 struct cli_state *cli1 = NULL;
9254 bool correct = false;
9255 const char *fname_src = "\\splice_src.dat";
9256 const char *fname_dst = "\\splice_dst.dat";
9258 uint16_t fnum1 = UINT16_MAX;
9259 uint16_t fnum2 = UINT16_MAX;
9260 size_t file_size = 2*1024*1024;
9261 size_t splice_size = 1*1024*1024 + 713;
9263 uint8_t digest1[16], digest2[16];
9266 TALLOC_CTX *frame = talloc_stackframe();
9268 printf("starting cli_splice test\n");
9270 if (!torture_open_connection(&cli1, 0)) {
9274 cli_unlink(cli1, fname_src,
9275 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9276 cli_unlink(cli1, fname_dst,
9277 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9280 status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
9281 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9282 0, 0, &fnum1, NULL);
9284 if (!NT_STATUS_IS_OK(status)) {
9285 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
9289 /* Write file_size bytes - must be bigger than splice_size. */
9290 buf = talloc_zero_array(frame, uint8_t, file_size);
9292 d_printf("talloc_fail\n");
9296 /* Fill it with random numbers. */
9297 generate_random_buffer(buf, file_size);
9299 /* MD5 the first 1MB + 713 bytes. */
9301 MD5Update(&md5_ctx, buf, splice_size);
9302 MD5Final(digest1, &md5_ctx);
9304 status = cli_writeall(cli1,
9311 if (!NT_STATUS_IS_OK(status)) {
9312 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9316 status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
9317 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9318 0, 0, &fnum2, NULL);
9320 if (!NT_STATUS_IS_OK(status)) {
9321 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
9325 /* Now splice 1MB + 713 bytes. */
9326 status = cli_splice(cli1,
9337 if (!NT_STATUS_IS_OK(status)) {
9338 d_printf("cli_splice failed: %s\n", nt_errstr(status));
9342 /* Clear the old buffer. */
9343 memset(buf, '\0', file_size);
9345 /* Read the new file. */
9346 status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
9347 if (!NT_STATUS_IS_OK(status)) {
9348 d_printf("cli_read failed: %s\n", nt_errstr(status));
9351 if (nread != splice_size) {
9352 d_printf("bad read of 0x%x, should be 0x%x\n",
9353 (unsigned int)nread,
9354 (unsigned int)splice_size);
9358 /* MD5 the first 1MB + 713 bytes. */
9360 MD5Update(&md5_ctx, buf, splice_size);
9361 MD5Final(digest2, &md5_ctx);
9363 /* Must be the same. */
9364 if (memcmp(digest1, digest2, 16) != 0) {
9365 d_printf("bad MD5 compare\n");
9370 printf("Success on cli_splice test\n");
9375 if (fnum1 != UINT16_MAX) {
9376 cli_close(cli1, fnum1);
9378 if (fnum2 != UINT16_MAX) {
9379 cli_close(cli1, fnum2);
9382 cli_unlink(cli1, fname_src,
9383 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9384 cli_unlink(cli1, fname_dst,
9385 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9387 if (!torture_close_connection(cli1)) {
9396 static bool run_uid_regression_test(int dummy)
9398 static struct cli_state *cli;
9401 bool correct = True;
9402 struct smbXcli_tcon *orig_tcon = NULL;
9405 printf("starting uid regression test\n");
9407 if (!torture_open_connection(&cli, 0)) {
9411 smbXcli_conn_set_sockopt(cli->conn, sockops);
9413 /* Ok - now save then logoff our current user. */
9414 old_vuid = cli_state_get_uid(cli);
9416 status = cli_ulogoff(cli);
9417 if (!NT_STATUS_IS_OK(status)) {
9418 d_printf("(%s) cli_ulogoff failed: %s\n",
9419 __location__, nt_errstr(status));
9424 cli_state_set_uid(cli, old_vuid);
9426 /* Try an operation. */
9427 status = cli_mkdir(cli, "\\uid_reg_test");
9428 if (NT_STATUS_IS_OK(status)) {
9429 d_printf("(%s) cli_mkdir succeeded\n",
9434 /* Should be bad uid. */
9435 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9436 NT_STATUS_USER_SESSION_DELETED)) {
9442 old_cnum = cli_state_get_tid(cli);
9443 orig_tcon = cli_state_save_tcon(cli);
9444 if (orig_tcon == NULL) {
9449 /* Now try a SMBtdis with the invald vuid set to zero. */
9450 cli_state_set_uid(cli, 0);
9452 /* This should succeed. */
9453 status = cli_tdis(cli);
9455 if (NT_STATUS_IS_OK(status)) {
9456 d_printf("First tdis with invalid vuid should succeed.\n");
9458 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9460 cli_state_restore_tcon(cli, orig_tcon);
9464 cli_state_restore_tcon(cli, orig_tcon);
9465 cli_state_set_uid(cli, old_vuid);
9466 cli_state_set_tid(cli, old_cnum);
9468 /* This should fail. */
9469 status = cli_tdis(cli);
9470 if (NT_STATUS_IS_OK(status)) {
9471 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9475 /* Should be bad tid. */
9476 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9477 NT_STATUS_NETWORK_NAME_DELETED)) {
9483 cli_rmdir(cli, "\\uid_reg_test");
9492 static const char *illegal_chars = "*\\/?<>|\":";
9493 static char force_shortname_chars[] = " +,.[];=\177";
9495 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9496 const char *mask, void *state)
9498 struct cli_state *pcli = (struct cli_state *)state;
9500 NTSTATUS status = NT_STATUS_OK;
9502 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9504 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9505 return NT_STATUS_OK;
9507 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9508 status = cli_rmdir(pcli, fname);
9509 if (!NT_STATUS_IS_OK(status)) {
9510 printf("del_fn: failed to rmdir %s\n,", fname );
9513 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9514 if (!NT_STATUS_IS_OK(status)) {
9515 printf("del_fn: failed to unlink %s\n,", fname );
9527 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9528 const char *name, void *state)
9530 struct sn_state *s = (struct sn_state *)state;
9534 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9535 i, finfo->name, finfo->short_name);
9538 if (strchr(force_shortname_chars, i)) {
9539 if (!finfo->short_name) {
9540 /* Shortname not created when it should be. */
9541 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9542 __location__, finfo->name, i);
9545 } else if (finfo->short_name){
9546 /* Shortname created when it should not be. */
9547 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9548 __location__, finfo->short_name, finfo->name);
9552 return NT_STATUS_OK;
9555 static bool run_shortname_test(int dummy)
9557 static struct cli_state *cli;
9558 bool correct = True;
9564 printf("starting shortname test\n");
9566 if (!torture_open_connection(&cli, 0)) {
9570 smbXcli_conn_set_sockopt(cli->conn, sockops);
9572 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9573 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9574 cli_rmdir(cli, "\\shortname");
9576 status = cli_mkdir(cli, "\\shortname");
9577 if (!NT_STATUS_IS_OK(status)) {
9578 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9579 __location__, nt_errstr(status));
9584 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9588 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9595 for (i = 32; i < 128; i++) {
9596 uint16_t fnum = (uint16_t)-1;
9600 if (strchr(illegal_chars, i)) {
9605 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9606 FILE_SHARE_READ|FILE_SHARE_WRITE,
9607 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9608 if (!NT_STATUS_IS_OK(status)) {
9609 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9610 __location__, fname, nt_errstr(status));
9614 cli_close(cli, fnum);
9617 status = cli_list(cli, "\\shortname\\test*.*", 0,
9618 shortname_list_fn, &s);
9619 if (s.matched != 1) {
9620 d_printf("(%s) failed to list %s: %s\n",
9621 __location__, fname, nt_errstr(status));
9626 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9627 if (!NT_STATUS_IS_OK(status)) {
9628 d_printf("(%s) failed to delete %s: %s\n",
9629 __location__, fname, nt_errstr(status));
9642 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9643 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9644 cli_rmdir(cli, "\\shortname");
9645 torture_close_connection(cli);
9649 static void pagedsearch_cb(struct tevent_req *req)
9652 struct tldap_message *msg;
9655 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9656 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9657 d_printf("tldap_search_paged_recv failed: %s\n",
9658 tldap_rc2string(rc));
9661 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9665 if (!tldap_entry_dn(msg, &dn)) {
9666 d_printf("tldap_entry_dn failed\n");
9669 d_printf("%s\n", dn);
9673 static bool run_tldap(int dummy)
9675 struct tldap_context *ld;
9679 struct sockaddr_storage addr;
9680 struct tevent_context *ev;
9681 struct tevent_req *req;
9685 if (!resolve_name(host, &addr, 0, false)) {
9686 d_printf("could not find host %s\n", host);
9689 status = open_socket_out(&addr, 389, 9999, &fd);
9690 if (!NT_STATUS_IS_OK(status)) {
9691 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9695 ld = tldap_context_create(talloc_tos(), fd);
9698 d_printf("tldap_context_create failed\n");
9702 rc = tldap_fetch_rootdse(ld);
9703 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9704 d_printf("tldap_fetch_rootdse failed: %s\n",
9705 tldap_errstr(talloc_tos(), ld, rc));
9709 basedn = tldap_talloc_single_attribute(
9710 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9711 if (basedn == NULL) {
9712 d_printf("no defaultNamingContext\n");
9715 d_printf("defaultNamingContext: %s\n", basedn);
9717 ev = samba_tevent_context_init(talloc_tos());
9719 d_printf("tevent_context_init failed\n");
9723 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9724 TLDAP_SCOPE_SUB, "(objectclass=*)",
9726 NULL, 0, NULL, 0, 0, 0, 0, 5);
9728 d_printf("tldap_search_paged_send failed\n");
9731 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9733 tevent_req_poll(req, ev);
9737 /* test search filters against rootDSE */
9738 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9739 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9741 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9742 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9743 talloc_tos(), NULL);
9744 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9745 d_printf("tldap_search with complex filter failed: %s\n",
9746 tldap_errstr(talloc_tos(), ld, rc));
9754 /* Torture test to ensure no regression of :
9755 https://bugzilla.samba.org/show_bug.cgi?id=7084
9758 static bool run_dir_createtime(int dummy)
9760 struct cli_state *cli;
9761 const char *dname = "\\testdir_createtime";
9762 const char *fname = "\\testdir_createtime\\testfile";
9764 struct timespec create_time;
9765 struct timespec create_time1;
9769 if (!torture_open_connection(&cli, 0)) {
9773 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9774 cli_rmdir(cli, dname);
9776 status = cli_mkdir(cli, dname);
9777 if (!NT_STATUS_IS_OK(status)) {
9778 printf("mkdir failed: %s\n", nt_errstr(status));
9782 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9784 if (!NT_STATUS_IS_OK(status)) {
9785 printf("cli_qpathinfo2 returned %s\n",
9790 /* Sleep 3 seconds, then create a file. */
9793 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9795 if (!NT_STATUS_IS_OK(status)) {
9796 printf("cli_openx failed: %s\n", nt_errstr(status));
9800 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9802 if (!NT_STATUS_IS_OK(status)) {
9803 printf("cli_qpathinfo2 (2) returned %s\n",
9808 if (timespec_compare(&create_time1, &create_time)) {
9809 printf("run_dir_createtime: create time was updated (error)\n");
9811 printf("run_dir_createtime: create time was not updated (correct)\n");
9817 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9818 cli_rmdir(cli, dname);
9819 if (!torture_close_connection(cli)) {
9826 static bool run_streamerror(int dummy)
9828 struct cli_state *cli;
9829 const char *dname = "\\testdir_streamerror";
9830 const char *streamname =
9831 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9833 time_t change_time, access_time, write_time;
9835 uint16_t mode, fnum;
9838 if (!torture_open_connection(&cli, 0)) {
9842 cli_unlink(cli, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9843 cli_rmdir(cli, dname);
9845 status = cli_mkdir(cli, dname);
9846 if (!NT_STATUS_IS_OK(status)) {
9847 printf("mkdir failed: %s\n", nt_errstr(status));
9851 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9852 &write_time, &size, &mode);
9853 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9854 printf("pathinfo returned %s, expected "
9855 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9860 status = cli_ntcreate(cli, streamname, 0x16,
9861 FILE_READ_DATA|FILE_READ_EA|
9862 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9863 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9864 FILE_OPEN, 0, 0, &fnum, NULL);
9866 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9867 printf("ntcreate returned %s, expected "
9868 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9874 cli_rmdir(cli, dname);
9878 struct pidtest_state {
9884 static void pid_echo_done(struct tevent_req *subreq);
9886 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9887 struct tevent_context *ev,
9888 struct cli_state *cli)
9890 struct tevent_req *req, *subreq;
9891 struct pidtest_state *state;
9893 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9898 SSVAL(state->vwv, 0, 1);
9899 state->data = data_blob_const("hello", 5);
9901 subreq = smb1cli_req_send(state,
9906 0, 0, /* *_flags2 */
9908 0xDEADBEEF, /* pid */
9911 ARRAY_SIZE(state->vwv), state->vwv,
9912 state->data.length, state->data.data);
9914 if (tevent_req_nomem(subreq, req)) {
9915 return tevent_req_post(req, ev);
9917 tevent_req_set_callback(subreq, pid_echo_done, req);
9921 static void pid_echo_done(struct tevent_req *subreq)
9923 struct tevent_req *req = tevent_req_callback_data(
9924 subreq, struct tevent_req);
9925 struct pidtest_state *state = tevent_req_data(
9926 req, struct pidtest_state);
9929 uint8_t *bytes = NULL;
9930 struct iovec *recv_iov = NULL;
9931 uint8_t *phdr = NULL;
9932 uint16_t pidlow = 0;
9933 uint16_t pidhigh = 0;
9934 struct smb1cli_req_expected_response expected[] = {
9936 .status = NT_STATUS_OK,
9941 status = smb1cli_req_recv(subreq, state,
9946 NULL, /* pvwv_offset */
9949 NULL, /* pbytes_offset */
9951 expected, ARRAY_SIZE(expected));
9953 TALLOC_FREE(subreq);
9955 if (!NT_STATUS_IS_OK(status)) {
9956 tevent_req_nterror(req, status);
9960 if (num_bytes != state->data.length) {
9961 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9965 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9966 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9970 /* Check pid low/high == DEADBEEF */
9971 pidlow = SVAL(phdr, HDR_PID);
9972 if (pidlow != 0xBEEF){
9973 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9974 (unsigned int)pidlow);
9975 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9978 pidhigh = SVAL(phdr, HDR_PIDHIGH);
9979 if (pidhigh != 0xDEAD){
9980 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9981 (unsigned int)pidhigh);
9982 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9986 tevent_req_done(req);
9989 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9991 return tevent_req_simple_recv_ntstatus(req);
9994 static bool run_pidhigh(int dummy)
9996 bool success = false;
9997 struct cli_state *cli = NULL;
9999 struct tevent_context *ev = NULL;
10000 struct tevent_req *req = NULL;
10001 TALLOC_CTX *frame = talloc_stackframe();
10003 printf("starting pid high test\n");
10004 if (!torture_open_connection(&cli, 0)) {
10007 smbXcli_conn_set_sockopt(cli->conn, sockops);
10009 ev = samba_tevent_context_init(frame);
10014 req = pid_echo_send(frame, ev, cli);
10019 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
10023 status = pid_echo_recv(req);
10024 if (NT_STATUS_IS_OK(status)) {
10025 printf("pid high test ok\n");
10031 TALLOC_FREE(frame);
10032 torture_close_connection(cli);
10037 Test Windows open on a bad POSIX symlink.
10039 static bool run_symlink_open_test(int dummy)
10041 static struct cli_state *cli;
10042 const char *fname = "non_existant_file";
10043 const char *sname = "dangling_symlink";
10044 uint16_t fnum = (uint16_t)-1;
10045 bool correct = false;
10047 TALLOC_CTX *frame = NULL;
10049 frame = talloc_stackframe();
10051 printf("Starting Windows bad symlink open test\n");
10053 if (!torture_open_connection(&cli, 0)) {
10054 TALLOC_FREE(frame);
10058 smbXcli_conn_set_sockopt(cli->conn, sockops);
10060 status = torture_setup_unix_extensions(cli);
10061 if (!NT_STATUS_IS_OK(status)) {
10062 TALLOC_FREE(frame);
10066 /* Ensure nothing exists. */
10067 cli_setatr(cli, fname, 0, 0);
10068 cli_posix_unlink(cli, fname);
10069 cli_setatr(cli, sname, 0, 0);
10070 cli_posix_unlink(cli, sname);
10072 /* Create a symlink pointing nowhere. */
10073 status = cli_posix_symlink(cli, fname, sname);
10074 if (!NT_STATUS_IS_OK(status)) {
10075 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
10078 nt_errstr(status));
10082 /* Now ensure that a Windows open doesn't hang. */
10083 status = cli_ntcreate(cli,
10086 FILE_READ_DATA|FILE_WRITE_DATA,
10088 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
10096 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
10097 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
10098 * we use O_NOFOLLOW on the server or not.
10100 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
10101 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
10105 printf("cli_ntcreate of %s returned %s - should return"
10106 " either (%s) or (%s)\n",
10109 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
10110 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
10118 if (fnum != (uint16_t)-1) {
10119 cli_close(cli, fnum);
10120 fnum = (uint16_t)-1;
10123 cli_setatr(cli, sname, 0, 0);
10124 cli_posix_unlink(cli, sname);
10125 cli_setatr(cli, fname, 0, 0);
10126 cli_posix_unlink(cli, fname);
10128 if (!torture_close_connection(cli)) {
10132 TALLOC_FREE(frame);
10137 * Only testing minimal time strings, as the others
10138 * need (locale-dependent) guessing at what strftime does and
10139 * even may differ in builds.
10141 static bool timesubst_test(void)
10143 TALLOC_CTX *ctx = NULL;
10144 /* Sa 23. Dez 04:33:20 CET 2017 */
10145 const struct timeval tv = { 1514000000, 123 };
10146 const char* expect_minimal = "20171223_033320";
10147 const char* expect_minus = "20171223_033320_000123";
10149 char *env_tz, *orig_tz = NULL;
10150 bool result = true;
10152 ctx = talloc_new(NULL);
10154 env_tz = getenv("TZ");
10156 orig_tz = talloc_strdup(ctx, env_tz);
10158 setenv("TZ", "UTC", 1);
10160 s = minimal_timeval_string(ctx, &tv, false);
10162 if(!s || strcmp(s, expect_minimal)) {
10163 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
10164 "[%s]\n", s ? s : "<nil>", expect_minimal);
10168 s = minimal_timeval_string(ctx, &tv, true);
10169 if(!s || strcmp(s, expect_minus)) {
10170 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
10171 "[%s]\n", s ? s : "<nil>", expect_minus);
10177 setenv("TZ", orig_tz, 1);
10184 static bool run_local_substitute(int dummy)
10188 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
10189 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
10190 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
10191 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
10192 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
10193 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
10194 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
10195 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
10196 ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
10197 /* Substitution depends on current time, so better test the underlying
10198 formatting function. At least covers %t. */
10199 ok &= timesubst_test();
10201 /* Different captialization rules in sub_basic... */
10203 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
10209 static bool run_local_base64(int dummy)
10214 for (i=1; i<2000; i++) {
10215 DATA_BLOB blob1, blob2;
10218 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
10220 generate_random_buffer(blob1.data, blob1.length);
10222 b64 = base64_encode_data_blob(talloc_tos(), blob1);
10224 d_fprintf(stderr, "base64_encode_data_blob failed "
10225 "for %d bytes\n", i);
10228 blob2 = base64_decode_data_blob(b64);
10231 if (data_blob_cmp(&blob1, &blob2)) {
10232 d_fprintf(stderr, "data_blob_cmp failed for %d "
10236 TALLOC_FREE(blob1.data);
10237 data_blob_free(&blob2);
10242 static void parse_fn(const struct gencache_timeout *t,
10244 void *private_data)
10249 static bool run_local_gencache(int dummy)
10255 struct memcache *mem;
10258 mem = memcache_init(NULL, 0);
10260 d_printf("%s: memcache_init failed\n", __location__);
10263 memcache_set_global(mem);
10265 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
10266 d_printf("%s: gencache_set() failed\n", __location__);
10270 if (!gencache_get("foo", NULL, NULL, NULL)) {
10271 d_printf("%s: gencache_get() failed\n", __location__);
10275 for (i=0; i<1000000; i++) {
10276 gencache_parse("foo", parse_fn, NULL);
10279 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10280 d_printf("%s: gencache_get() failed\n", __location__);
10285 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10286 d_printf("%s: gencache_get() failed\n", __location__);
10290 if (strcmp(val, "bar") != 0) {
10291 d_printf("%s: gencache_get() returned %s, expected %s\n",
10292 __location__, val, "bar");
10299 if (!gencache_del("foo")) {
10300 d_printf("%s: gencache_del() failed\n", __location__);
10303 if (gencache_del("foo")) {
10304 d_printf("%s: second gencache_del() succeeded\n",
10309 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
10310 d_printf("%s: gencache_get() on deleted entry "
10311 "succeeded\n", __location__);
10315 blob = data_blob_string_const_null("bar");
10316 tm = time(NULL) + 60;
10318 if (!gencache_set_data_blob("foo", blob, tm)) {
10319 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
10323 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10324 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
10328 if (strcmp((const char *)blob.data, "bar") != 0) {
10329 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10330 __location__, (const char *)blob.data, "bar");
10331 data_blob_free(&blob);
10335 data_blob_free(&blob);
10337 if (!gencache_del("foo")) {
10338 d_printf("%s: gencache_del() failed\n", __location__);
10341 if (gencache_del("foo")) {
10342 d_printf("%s: second gencache_del() succeeded\n",
10347 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10348 d_printf("%s: gencache_get_data_blob() on deleted entry "
10349 "succeeded\n", __location__);
10354 blob.data = (uint8_t *)&v;
10355 blob.length = sizeof(v);
10357 if (!gencache_set_data_blob("blob", blob, tm)) {
10358 d_printf("%s: gencache_set_data_blob() failed\n",
10362 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
10363 d_printf("%s: gencache_get succeeded\n", __location__);
10370 static bool rbt_testval(struct db_context *db, const char *key,
10373 struct db_record *rec;
10374 TDB_DATA data = string_tdb_data(value);
10379 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10381 d_fprintf(stderr, "fetch_locked failed\n");
10384 status = dbwrap_record_store(rec, data, 0);
10385 if (!NT_STATUS_IS_OK(status)) {
10386 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
10391 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10393 d_fprintf(stderr, "second fetch_locked failed\n");
10397 dbvalue = dbwrap_record_get_value(rec);
10398 if ((dbvalue.dsize != data.dsize)
10399 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
10400 d_fprintf(stderr, "Got wrong data back\n");
10410 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
10412 int *count2 = (int *)private_data;
10417 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
10419 int *count2 = (int *)private_data;
10421 dbwrap_record_delete(rec);
10425 static bool run_local_rbtree(int dummy)
10427 struct db_context *db;
10434 db = db_open_rbt(NULL);
10437 d_fprintf(stderr, "db_open_rbt failed\n");
10441 for (i=0; i<1000; i++) {
10444 if (asprintf(&key, "key%ld", random()) == -1) {
10447 if (asprintf(&value, "value%ld", random()) == -1) {
10452 if (!rbt_testval(db, key, value)) {
10459 if (asprintf(&value, "value%ld", random()) == -1) {
10464 if (!rbt_testval(db, key, value)) {
10475 count = 0; count2 = 0;
10476 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10478 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10479 if ((count != count2) || (count != 1000)) {
10482 count = 0; count2 = 0;
10483 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10485 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10486 if ((count != count2) || (count != 1000)) {
10489 count = 0; count2 = 0;
10490 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10492 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10493 if ((count != count2) || (count != 0)) {
10504 local test for character set functions
10506 This is a very simple test for the functionality in convert_string_error()
10508 static bool run_local_convert_string(int dummy)
10510 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10511 const char *test_strings[2] = { "March", "M\303\244rz" };
10515 for (i=0; i<2; i++) {
10516 const char *str = test_strings[i];
10517 int len = strlen(str);
10518 size_t converted_size;
10521 memset(dst, 'X', sizeof(dst));
10523 /* first try with real source length */
10524 ret = convert_string_error(CH_UNIX, CH_UTF8,
10529 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10533 if (converted_size != len) {
10534 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10535 str, len, (int)converted_size);
10539 if (strncmp(str, dst, converted_size) != 0) {
10540 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10544 if (strlen(str) != converted_size) {
10545 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10546 (int)strlen(str), (int)converted_size);
10550 if (dst[converted_size] != 'X') {
10551 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10555 /* now with srclen==-1, this causes the nul to be
10557 ret = convert_string_error(CH_UNIX, CH_UTF8,
10562 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10566 if (converted_size != len+1) {
10567 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10568 str, len, (int)converted_size);
10572 if (strncmp(str, dst, converted_size) != 0) {
10573 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10577 if (len+1 != converted_size) {
10578 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10579 len+1, (int)converted_size);
10583 if (dst[converted_size] != 'X') {
10584 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10591 TALLOC_FREE(tmp_ctx);
10594 TALLOC_FREE(tmp_ctx);
10598 static bool run_local_string_to_sid(int dummy) {
10599 struct dom_sid sid;
10601 if (string_to_sid(&sid, "S--1-5-32-545")) {
10602 printf("allowing S--1-5-32-545\n");
10605 if (string_to_sid(&sid, "S-1-5-32-+545")) {
10606 printf("allowing S-1-5-32-+545\n");
10609 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")) {
10610 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10613 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10614 printf("allowing S-1-5-32-545-abc\n");
10617 if (string_to_sid(&sid, "S-300-5-32-545")) {
10618 printf("allowing S-300-5-32-545\n");
10621 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10622 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10625 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10626 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10629 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10630 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10633 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10634 printf("could not parse S-1-5-32-545\n");
10637 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10638 printf("mis-parsed S-1-5-32-545 as %s\n",
10639 sid_string_tos(&sid));
10645 static bool sid_to_string_test(const char *expected) {
10648 struct dom_sid sid;
10650 if (!string_to_sid(&sid, expected)) {
10651 printf("could not parse %s\n", expected);
10655 str = dom_sid_string(NULL, &sid);
10656 if (strcmp(str, expected)) {
10657 printf("Comparison failed (%s != %s)\n", str, expected);
10664 static bool run_local_sid_to_string(int dummy) {
10665 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10667 if (!sid_to_string_test("S-1-545"))
10669 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10674 static bool run_local_binary_to_sid(int dummy) {
10675 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10676 static const uint8_t good_binary_sid[] = {
10677 0x1, /* revision number */
10678 15, /* num auths */
10679 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10680 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10681 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10682 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10683 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10684 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10685 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10686 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10687 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10688 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10689 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10690 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10691 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10692 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10693 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10694 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10697 static const uint8_t long_binary_sid[] = {
10698 0x1, /* revision number */
10699 15, /* num auths */
10700 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10701 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10702 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10703 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10704 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10705 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10706 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10707 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10708 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10709 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10710 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10711 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10712 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10713 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10714 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10715 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10716 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10717 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10718 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10721 static const uint8_t long_binary_sid2[] = {
10722 0x1, /* revision number */
10723 32, /* num auths */
10724 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10725 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10726 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10727 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10728 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10729 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10730 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10731 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10732 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10733 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10734 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10735 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10736 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10737 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10738 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10739 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10740 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10741 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10742 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10743 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10744 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10745 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10746 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10747 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10748 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10749 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10750 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10751 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10752 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10753 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10754 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10755 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10756 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10759 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10762 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10765 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10771 /* Split a path name into filename and stream name components. Canonicalise
10772 * such that an implicit $DATA token is always explicit.
10774 * The "specification" of this function can be found in the
10775 * run_local_stream_name() function in torture.c, I've tried those
10776 * combinations against a W2k3 server.
10779 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10780 char **pbase, char **pstream)
10783 char *stream = NULL;
10784 char *sname; /* stream name */
10785 const char *stype; /* stream type */
10787 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10789 sname = strchr_m(fname, ':');
10791 if (sname == NULL) {
10792 if (pbase != NULL) {
10793 base = talloc_strdup(mem_ctx, fname);
10794 NT_STATUS_HAVE_NO_MEMORY(base);
10799 if (pbase != NULL) {
10800 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10801 NT_STATUS_HAVE_NO_MEMORY(base);
10806 stype = strchr_m(sname, ':');
10808 if (stype == NULL) {
10809 sname = talloc_strdup(mem_ctx, sname);
10813 if (strcasecmp_m(stype, ":$DATA") != 0) {
10815 * If there is an explicit stream type, so far we only
10816 * allow $DATA. Is there anything else allowed? -- vl
10818 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10820 return NT_STATUS_OBJECT_NAME_INVALID;
10822 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10826 if (sname == NULL) {
10828 return NT_STATUS_NO_MEMORY;
10831 if (sname[0] == '\0') {
10833 * no stream name, so no stream
10838 if (pstream != NULL) {
10839 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10840 if (stream == NULL) {
10841 TALLOC_FREE(sname);
10843 return NT_STATUS_NO_MEMORY;
10846 * upper-case the type field
10848 (void)strupper_m(strchr_m(stream, ':')+1);
10852 if (pbase != NULL) {
10855 if (pstream != NULL) {
10858 return NT_STATUS_OK;
10861 static bool test_stream_name(const char *fname, const char *expected_base,
10862 const char *expected_stream,
10863 NTSTATUS expected_status)
10867 char *stream = NULL;
10869 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10870 if (!NT_STATUS_EQUAL(status, expected_status)) {
10874 if (!NT_STATUS_IS_OK(status)) {
10878 if (base == NULL) goto error;
10880 if (strcmp(expected_base, base) != 0) goto error;
10882 if ((expected_stream != NULL) && (stream == NULL)) goto error;
10883 if ((expected_stream == NULL) && (stream != NULL)) goto error;
10885 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10889 TALLOC_FREE(stream);
10893 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10894 fname, expected_base ? expected_base : "<NULL>",
10895 expected_stream ? expected_stream : "<NULL>",
10896 nt_errstr(expected_status));
10897 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10898 base ? base : "<NULL>", stream ? stream : "<NULL>",
10899 nt_errstr(status));
10901 TALLOC_FREE(stream);
10905 static bool run_local_stream_name(int dummy)
10909 ret &= test_stream_name(
10910 "bla", "bla", NULL, NT_STATUS_OK);
10911 ret &= test_stream_name(
10912 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10913 ret &= test_stream_name(
10914 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10915 ret &= test_stream_name(
10916 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10917 ret &= test_stream_name(
10918 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10919 ret &= test_stream_name(
10920 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10921 ret &= test_stream_name(
10922 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10923 ret &= test_stream_name(
10924 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10929 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10931 if (a.length != b.length) {
10932 printf("a.length=%d != b.length=%d\n",
10933 (int)a.length, (int)b.length);
10936 if (memcmp(a.data, b.data, a.length) != 0) {
10937 printf("a.data and b.data differ\n");
10943 static bool run_local_memcache(int dummy)
10945 struct memcache *cache;
10946 DATA_BLOB k1, k2, k3;
10950 TALLOC_CTX *mem_ctx;
10955 size_t size1, size2;
10958 mem_ctx = talloc_init("foo");
10959 if (mem_ctx == NULL) {
10963 /* STAT_CACHE TESTS */
10965 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10967 if (cache == NULL) {
10968 printf("memcache_init failed\n");
10972 d1 = data_blob_const("d1", 2);
10973 d3 = data_blob_const("d3", 2);
10975 k1 = data_blob_const("d1", 2);
10976 k2 = data_blob_const("d2", 2);
10977 k3 = data_blob_const("d3", 2);
10979 memcache_add(cache, STAT_CACHE, k1, d1);
10981 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10982 printf("could not find k1\n");
10985 if (!data_blob_equal(d1, v1)) {
10989 memcache_add(cache, STAT_CACHE, k1, d3);
10991 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10992 printf("could not find replaced k1\n");
10995 if (!data_blob_equal(d3, v3)) {
10999 TALLOC_FREE(cache);
11001 /* GETWD_CACHE TESTS */
11002 str1 = talloc_strdup(mem_ctx, "string1");
11003 if (str1 == NULL) {
11006 ptr2 = str1; /* Keep an alias for comparison. */
11008 str2 = talloc_strdup(mem_ctx, "string2");
11009 if (str2 == NULL) {
11013 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
11014 if (cache == NULL) {
11015 printf("memcache_init failed\n");
11019 memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
11020 /* str1 == NULL now. */
11021 ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
11022 if (ptr1 == NULL) {
11023 printf("could not find k2\n");
11026 if (ptr1 != ptr2) {
11027 printf("fetch of k2 got wrong string\n");
11031 /* Add a blob to ensure k2 gets purged. */
11032 d3 = data_blob_talloc_zero(mem_ctx, 180);
11033 memcache_add(cache, STAT_CACHE, k3, d3);
11035 ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
11036 if (ptr2 != NULL) {
11037 printf("Did find k2, should have been purged\n");
11041 TALLOC_FREE(cache);
11042 TALLOC_FREE(mem_ctx);
11044 mem_ctx = talloc_init("foo");
11045 if (mem_ctx == NULL) {
11049 cache = memcache_init(NULL, 0);
11050 if (cache == NULL) {
11054 str1 = talloc_strdup(mem_ctx, "string1");
11055 if (str1 == NULL) {
11058 str2 = talloc_strdup(mem_ctx, "string2");
11059 if (str2 == NULL) {
11062 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
11063 data_blob_string_const("torture"), &str1);
11064 size1 = talloc_total_size(cache);
11066 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
11067 data_blob_string_const("torture"), &str2);
11068 size2 = talloc_total_size(cache);
11070 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
11072 if (size2 > size1) {
11073 printf("memcache leaks memory!\n");
11079 TALLOC_FREE(cache);
11083 static void wbclient_done(struct tevent_req *req)
11086 struct winbindd_response *wb_resp;
11087 int *i = (int *)tevent_req_callback_data_void(req);
11089 wbc_err = wb_trans_recv(req, req, &wb_resp);
11092 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
11095 static bool run_wbclient_multi_ping(int dummy)
11097 struct tevent_context *ev;
11098 struct wb_context **wb_ctx;
11099 struct winbindd_request wb_req;
11100 bool result = false;
11103 BlockSignals(True, SIGPIPE);
11105 ev = tevent_context_init(talloc_tos());
11110 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
11111 if (wb_ctx == NULL) {
11115 ZERO_STRUCT(wb_req);
11116 wb_req.cmd = WINBINDD_PING;
11118 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
11120 for (i=0; i<torture_nprocs; i++) {
11121 wb_ctx[i] = wb_context_init(ev, NULL);
11122 if (wb_ctx[i] == NULL) {
11125 for (j=0; j<torture_numops; j++) {
11126 struct tevent_req *req;
11127 req = wb_trans_send(ev, ev, wb_ctx[i],
11128 (j % 2) == 0, &wb_req);
11132 tevent_req_set_callback(req, wbclient_done, &i);
11138 while (i < torture_nprocs * torture_numops) {
11139 tevent_loop_once(ev);
11148 static bool dbtrans_inc(struct db_context *db)
11150 struct db_record *rec;
11156 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11158 printf(__location__ "fetch_lock failed\n");
11162 value = dbwrap_record_get_value(rec);
11164 if (value.dsize != sizeof(uint32_t)) {
11165 printf(__location__ "value.dsize = %d\n",
11170 memcpy(&val, value.dptr, sizeof(val));
11173 status = dbwrap_record_store(
11174 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
11175 if (!NT_STATUS_IS_OK(status)) {
11176 printf(__location__ "store failed: %s\n",
11177 nt_errstr(status));
11187 static bool run_local_dbtrans(int dummy)
11189 struct db_context *db;
11190 struct db_record *rec;
11196 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
11197 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
11200 printf("Could not open transtest.db\n");
11204 res = dbwrap_transaction_start(db);
11206 printf(__location__ "transaction_start failed\n");
11210 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11212 printf(__location__ "fetch_lock failed\n");
11216 value = dbwrap_record_get_value(rec);
11218 if (value.dptr == NULL) {
11220 status = dbwrap_record_store(
11221 rec, make_tdb_data((uint8_t *)&initial,
11224 if (!NT_STATUS_IS_OK(status)) {
11225 printf(__location__ "store returned %s\n",
11226 nt_errstr(status));
11233 res = dbwrap_transaction_commit(db);
11235 printf(__location__ "transaction_commit failed\n");
11240 uint32_t val, val2;
11243 res = dbwrap_transaction_start(db);
11245 printf(__location__ "transaction_start failed\n");
11249 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
11250 if (!NT_STATUS_IS_OK(status)) {
11251 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11252 nt_errstr(status));
11256 for (i=0; i<10; i++) {
11257 if (!dbtrans_inc(db)) {
11262 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
11263 if (!NT_STATUS_IS_OK(status)) {
11264 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11265 nt_errstr(status));
11269 if (val2 != val + 10) {
11270 printf(__location__ "val=%d, val2=%d\n",
11271 (int)val, (int)val2);
11275 printf("val2=%d\r", val2);
11277 res = dbwrap_transaction_commit(db);
11279 printf(__location__ "transaction_commit failed\n");
11289 * Just a dummy test to be run under a debugger. There's no real way
11290 * to inspect the tevent_poll specific function from outside of
11294 static bool run_local_tevent_poll(int dummy)
11296 struct tevent_context *ev;
11297 struct tevent_fd *fd1, *fd2;
11298 bool result = false;
11300 ev = tevent_context_init_byname(NULL, "poll");
11302 d_fprintf(stderr, "tevent_context_init_byname failed\n");
11306 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
11308 d_fprintf(stderr, "tevent_add_fd failed\n");
11311 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
11313 d_fprintf(stderr, "tevent_add_fd failed\n");
11318 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
11320 d_fprintf(stderr, "tevent_add_fd failed\n");
11330 static bool run_local_hex_encode_buf(int dummy)
11336 for (i=0; i<sizeof(src); i++) {
11339 hex_encode_buf(buf, src, sizeof(src));
11340 if (strcmp(buf, "0001020304050607") != 0) {
11343 hex_encode_buf(buf, NULL, 0);
11344 if (buf[0] != '\0') {
11350 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11372 "1001:1111:1111:1000:0:1111:1111:1111",
11381 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11395 "1001:1111:1111:1000:0:1111:1111:1111"
11398 static bool run_local_remove_duplicate_addrs2(int dummy)
11400 struct ip_service test_vector[28];
11403 /* Construct the sockaddr_storage test vector. */
11404 for (i = 0; i < 28; i++) {
11405 struct addrinfo hints;
11406 struct addrinfo *res = NULL;
11409 memset(&hints, '\0', sizeof(hints));
11410 hints.ai_flags = AI_NUMERICHOST;
11411 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11416 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11417 remove_duplicate_addrs2_test_strings_vector[i]);
11420 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11421 memcpy(&test_vector[i].ss,
11427 count = remove_duplicate_addrs2(test_vector, i);
11430 fprintf(stderr, "count wrong (%d) should be 14\n",
11435 for (i = 0; i < count; i++) {
11436 char addr[INET6_ADDRSTRLEN];
11438 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11440 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11441 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11444 remove_duplicate_addrs2_test_strings_result[i]);
11449 printf("run_local_remove_duplicate_addrs2: success\n");
11453 static bool run_local_tdb_opener(int dummy)
11459 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11460 O_RDWR|O_CREAT, 0755);
11462 perror("tdb_open failed");
11473 static bool run_local_tdb_writer(int dummy)
11479 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11481 perror("tdb_open failed");
11485 val.dptr = (uint8_t *)&v;
11486 val.dsize = sizeof(v);
11492 ret = tdb_store(t, val, val, 0);
11494 printf("%s\n", tdb_errorstr(t));
11499 data = tdb_fetch(t, val);
11500 if (data.dptr != NULL) {
11501 SAFE_FREE(data.dptr);
11507 static bool run_local_canonicalize_path(int dummy)
11509 const char *src[] = {
11516 ".././././../../../boo",
11520 const char *dst[] = {
11533 for (i = 0; src[i] != NULL; i++) {
11534 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11536 perror("talloc fail\n");
11539 if (strcmp(d, dst[i]) != 0) {
11541 "canonicalize mismatch %s -> %s != %s",
11542 src[i], d, dst[i]);
11550 static bool run_ign_bad_negprot(int dummy)
11552 struct tevent_context *ev;
11553 struct tevent_req *req;
11554 struct smbXcli_conn *conn;
11555 struct sockaddr_storage ss;
11560 printf("starting ignore bad negprot\n");
11562 ok = resolve_name(host, &ss, 0x20, true);
11564 d_fprintf(stderr, "Could not resolve name %s\n", host);
11568 status = open_socket_out(&ss, 445, 10000, &fd);
11569 if (!NT_STATUS_IS_OK(status)) {
11570 d_fprintf(stderr, "open_socket_out failed: %s\n",
11571 nt_errstr(status));
11575 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11577 if (conn == NULL) {
11578 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11582 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11583 if (NT_STATUS_IS_OK(status)) {
11584 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11588 ev = samba_tevent_context_init(talloc_tos());
11590 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11594 req = smb1cli_session_setup_nt1_send(
11595 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11596 data_blob_null, data_blob_null, 0x40,
11597 "Windows 2000 2195", "Windows 2000 5.0");
11599 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11603 ok = tevent_req_poll_ntstatus(req, ev, &status);
11605 d_fprintf(stderr, "tevent_req_poll failed\n");
11609 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11611 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11612 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11613 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11614 nt_errstr(status));
11620 printf("starting ignore bad negprot\n");
11625 static double create_procs(bool (*fn)(int), bool *result)
11628 volatile pid_t *child_status;
11629 volatile bool *child_status_out;
11632 struct timeval start;
11636 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11637 if (!child_status) {
11638 printf("Failed to setup shared memory\n");
11642 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11643 if (!child_status_out) {
11644 printf("Failed to setup result status shared memory\n");
11648 for (i = 0; i < torture_nprocs; i++) {
11649 child_status[i] = 0;
11650 child_status_out[i] = True;
11653 start = timeval_current();
11655 for (i=0;i<torture_nprocs;i++) {
11658 pid_t mypid = getpid();
11659 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11661 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11664 if (torture_open_connection(¤t_cli, i)) break;
11665 if (tries-- == 0) {
11666 printf("pid %d failed to start\n", (int)getpid());
11672 child_status[i] = getpid();
11674 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11676 child_status_out[i] = fn(i);
11683 for (i=0;i<torture_nprocs;i++) {
11684 if (child_status[i]) synccount++;
11686 if (synccount == torture_nprocs) break;
11688 } while (timeval_elapsed(&start) < 30);
11690 if (synccount != torture_nprocs) {
11691 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11693 return timeval_elapsed(&start);
11696 /* start the client load */
11697 start = timeval_current();
11699 for (i=0;i<torture_nprocs;i++) {
11700 child_status[i] = 0;
11703 printf("%d clients started\n", torture_nprocs);
11705 for (i=0;i<torture_nprocs;i++) {
11706 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11711 for (i=0;i<torture_nprocs;i++) {
11712 if (!child_status_out[i]) {
11716 return timeval_elapsed(&start);
11719 #define FLAG_MULTIPROC 1
11725 } torture_ops[] = {
11726 {"FDPASS", run_fdpasstest, 0},
11727 {"LOCK1", run_locktest1, 0},
11728 {"LOCK2", run_locktest2, 0},
11729 {"LOCK3", run_locktest3, 0},
11730 {"LOCK4", run_locktest4, 0},
11731 {"LOCK5", run_locktest5, 0},
11732 {"LOCK6", run_locktest6, 0},
11733 {"LOCK7", run_locktest7, 0},
11734 {"LOCK8", run_locktest8, 0},
11735 {"LOCK9", run_locktest9, 0},
11736 {"UNLINK", run_unlinktest, 0},
11737 {"BROWSE", run_browsetest, 0},
11738 {"ATTR", run_attrtest, 0},
11739 {"TRANS2", run_trans2test, 0},
11740 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
11741 {"TORTURE",run_torture, FLAG_MULTIPROC},
11742 {"RANDOMIPC", run_randomipc, 0},
11743 {"NEGNOWAIT", run_negprot_nowait, 0},
11744 {"NBENCH", run_nbench, 0},
11745 {"NBENCH2", run_nbench2, 0},
11746 {"OPLOCK1", run_oplock1, 0},
11747 {"OPLOCK2", run_oplock2, 0},
11748 {"OPLOCK4", run_oplock4, 0},
11749 {"DIR", run_dirtest, 0},
11750 {"DIR1", run_dirtest1, 0},
11751 {"DIR-CREATETIME", run_dir_createtime, 0},
11752 {"DENY1", torture_denytest1, 0},
11753 {"DENY2", torture_denytest2, 0},
11754 {"TCON", run_tcon_test, 0},
11755 {"TCONDEV", run_tcon_devtype_test, 0},
11756 {"RW1", run_readwritetest, 0},
11757 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
11758 {"RW3", run_readwritelarge, 0},
11759 {"RW-SIGNING", run_readwritelarge_signtest, 0},
11760 {"OPEN", run_opentest, 0},
11761 {"POSIX", run_simple_posix_open_test, 0},
11762 {"POSIX-APPEND", run_posix_append, 0},
11763 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
11764 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
11765 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
11766 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
11767 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
11768 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
11769 {"ASYNC-ECHO", run_async_echo, 0},
11770 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
11771 { "SHORTNAME-TEST", run_shortname_test, 0},
11772 { "ADDRCHANGE", run_addrchange, 0},
11774 {"OPENATTR", run_openattrtest, 0},
11776 {"XCOPY", run_xcopy, 0},
11777 {"RENAME", run_rename, 0},
11778 {"RENAME-ACCESS", run_rename_access, 0},
11779 {"OWNER-RIGHTS", run_owner_rights, 0},
11780 {"DELETE", run_deletetest, 0},
11781 {"DELETE-PRINT", run_delete_print_test, 0},
11782 {"WILDDELETE", run_wild_deletetest, 0},
11783 {"DELETE-LN", run_deletetest_ln, 0},
11784 {"PROPERTIES", run_properties, 0},
11785 {"MANGLE", torture_mangle, 0},
11786 {"MANGLE1", run_mangle1, 0},
11787 {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
11788 {"W2K", run_w2ktest, 0},
11789 {"TRANS2SCAN", torture_trans2_scan, 0},
11790 {"NTTRANSSCAN", torture_nttrans_scan, 0},
11791 {"UTABLE", torture_utable, 0},
11792 {"CASETABLE", torture_casetable, 0},
11793 {"ERRMAPEXTRACT", run_error_map_extract, 0},
11794 {"PIPE_NUMBER", run_pipe_number, 0},
11795 {"TCON2", run_tcon2_test, 0},
11796 {"IOCTL", torture_ioctl_test, 0},
11797 {"CHKPATH", torture_chkpath_test, 0},
11798 {"FDSESS", run_fdsesstest, 0},
11799 { "EATEST", run_eatest, 0},
11800 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
11801 { "CHAIN1", run_chain1, 0},
11802 { "CHAIN2", run_chain2, 0},
11803 { "CHAIN3", run_chain3, 0},
11804 { "WINDOWS-WRITE", run_windows_write, 0},
11805 { "LARGE_READX", run_large_readx, 0},
11806 { "NTTRANS-CREATE", run_nttrans_create, 0},
11807 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
11808 { "CLI_ECHO", run_cli_echo, 0},
11809 { "CLI_SPLICE", run_cli_splice, 0},
11810 { "TLDAP", run_tldap },
11811 { "STREAMERROR", run_streamerror },
11812 { "NOTIFY-BENCH", run_notify_bench },
11813 { "NOTIFY-BENCH2", run_notify_bench2 },
11814 { "NOTIFY-BENCH3", run_notify_bench3 },
11815 { "BAD-NBT-SESSION", run_bad_nbt_session },
11816 { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
11817 { "SMB-ANY-CONNECT", run_smb_any_connect },
11818 { "NOTIFY-ONLINE", run_notify_online },
11819 { "SMB2-BASIC", run_smb2_basic },
11820 { "SMB2-NEGPROT", run_smb2_negprot },
11821 { "SMB2-ANONYMOUS", run_smb2_anonymous },
11822 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
11823 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
11824 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
11825 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
11826 { "SMB2-FTRUNCATE", run_smb2_ftruncate },
11827 { "SMB2-DIR-FSYNC", run_smb2_dir_fsync },
11828 { "CLEANUP1", run_cleanup1 },
11829 { "CLEANUP2", run_cleanup2 },
11830 { "CLEANUP3", run_cleanup3 },
11831 { "CLEANUP4", run_cleanup4 },
11832 { "OPLOCK-CANCEL", run_oplock_cancel },
11833 { "PIDHIGH", run_pidhigh },
11834 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
11835 { "LOCAL-GENCACHE", run_local_gencache, 0},
11836 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
11837 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2, 0 },
11838 { "LOCAL-DBWRAP-DO-LOCKED1", run_dbwrap_do_locked1, 0 },
11839 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
11840 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
11841 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
11842 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
11843 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
11844 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
11845 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
11846 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
11847 { "LOCAL-MESSAGING-SEND-ALL", run_messaging_send_all, 0 },
11848 { "LOCAL-BASE64", run_local_base64, 0},
11849 { "LOCAL-RBTREE", run_local_rbtree, 0},
11850 { "LOCAL-MEMCACHE", run_local_memcache, 0},
11851 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
11852 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
11853 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
11854 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
11855 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
11856 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
11857 { "LOCAL-TEVENT-POLL", run_local_tevent_poll, 0},
11858 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
11859 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
11860 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
11861 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
11862 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
11863 { "local-tdb-opener", run_local_tdb_opener, 0 },
11864 { "local-tdb-writer", run_local_tdb_writer, 0 },
11865 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
11866 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
11867 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
11868 { "LOCAL-G-LOCK1", run_g_lock1, 0 },
11869 { "LOCAL-G-LOCK2", run_g_lock2, 0 },
11870 { "LOCAL-G-LOCK3", run_g_lock3, 0 },
11871 { "LOCAL-G-LOCK4", run_g_lock4, 0 },
11872 { "LOCAL-G-LOCK5", run_g_lock5, 0 },
11873 { "LOCAL-G-LOCK6", run_g_lock6, 0 },
11874 { "LOCAL-G-LOCK-PING-PONG", run_g_lock_ping_pong, 0 },
11875 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
11876 { "LOCAL-NAMEMAP-CACHE1", run_local_namemap_cache1, 0 },
11877 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
11880 /****************************************************************************
11881 run a specified test or "ALL"
11882 ****************************************************************************/
11883 static bool run_test(const char *name)
11886 bool result = True;
11887 bool found = False;
11890 if (strequal(name,"ALL")) {
11891 for (i=0;torture_ops[i].name;i++) {
11892 run_test(torture_ops[i].name);
11897 for (i=0;torture_ops[i].name;i++) {
11898 fstr_sprintf(randomfname, "\\XX%x",
11899 (unsigned)random());
11901 if (strequal(name, torture_ops[i].name)) {
11903 printf("Running %s\n", name);
11904 if (torture_ops[i].flags & FLAG_MULTIPROC) {
11905 t = create_procs(torture_ops[i].fn, &result);
11908 printf("TEST %s FAILED!\n", name);
11911 struct timeval start;
11912 start = timeval_current();
11913 if (!torture_ops[i].fn(0)) {
11915 printf("TEST %s FAILED!\n", name);
11917 t = timeval_elapsed(&start);
11919 printf("%s took %g secs\n\n", name, t);
11924 printf("Did not find a test named %s\n", name);
11932 static void usage(void)
11936 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11937 printf("Please use samba4 torture.\n\n");
11939 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11941 printf("\t-d debuglevel\n");
11942 printf("\t-U user%%pass\n");
11943 printf("\t-k use kerberos\n");
11944 printf("\t-N numprocs\n");
11945 printf("\t-n my_netbios_name\n");
11946 printf("\t-W workgroup\n");
11947 printf("\t-o num_operations\n");
11948 printf("\t-O socket_options\n");
11949 printf("\t-m maximum protocol\n");
11950 printf("\t-L use oplocks\n");
11951 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11952 printf("\t-A showall\n");
11953 printf("\t-p port\n");
11954 printf("\t-s seed\n");
11955 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11956 printf("\t-f filename filename to test\n");
11957 printf("\t-e encrypt\n");
11960 printf("tests are:");
11961 for (i=0;torture_ops[i].name;i++) {
11962 printf(" %s", torture_ops[i].name);
11966 printf("default test is ALL\n");
11971 /****************************************************************************
11973 ****************************************************************************/
11974 int main(int argc,char *argv[])
11980 bool correct = True;
11981 TALLOC_CTX *frame = talloc_stackframe();
11982 int seed = time(NULL);
11984 #ifdef HAVE_SETBUFFER
11985 setbuffer(stdout, NULL, 0);
11988 setup_logging("smbtorture", DEBUG_STDOUT);
11993 if (is_default_dyn_CONFIGFILE()) {
11994 if(getenv("SMB_CONF_PATH")) {
11995 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11998 lp_load_global(get_dyn_CONFIGFILE());
12005 for(p = argv[1]; *p; p++)
12009 if (strncmp(argv[1], "//", 2)) {
12013 fstrcpy(host, &argv[1][2]);
12014 p = strchr_m(&host[2],'/');
12019 fstrcpy(share, p+1);
12021 fstrcpy(myname, get_myname(talloc_tos()));
12023 fprintf(stderr, "Failed to get my hostname.\n");
12027 if (*username == 0 && getenv("LOGNAME")) {
12028 fstrcpy(username,getenv("LOGNAME"));
12034 fstrcpy(workgroup, lp_workgroup());
12036 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
12040 port_to_use = atoi(optarg);
12043 seed = atoi(optarg);
12046 fstrcpy(workgroup,optarg);
12049 lp_set_cmdline("client max protocol", optarg);
12052 torture_nprocs = atoi(optarg);
12055 torture_numops = atoi(optarg);
12058 lp_set_cmdline("log level", optarg);
12064 use_oplocks = True;
12067 local_path = optarg;
12070 torture_showall = True;
12073 fstrcpy(myname, optarg);
12076 client_txt = optarg;
12083 use_kerberos = True;
12085 d_printf("No kerberos support compiled in\n");
12091 fstrcpy(username,optarg);
12092 p = strchr_m(username,'%');
12095 fstrcpy(password, p+1);
12100 fstrcpy(multishare_conn_fname, optarg);
12101 use_multishare_conn = True;
12104 torture_blocksize = atoi(optarg);
12107 test_filename = SMB_STRDUP(optarg);
12110 printf("Unknown option %c (%d)\n", (char)opt, opt);
12115 d_printf("using seed %d\n", seed);
12119 if(use_kerberos && !gotuser) gotpass = True;
12122 char pwd[256] = {0};
12125 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
12127 fstrcpy(password, pwd);
12132 printf("host=%s share=%s user=%s myname=%s\n",
12133 host, share, username, myname);
12135 torture_creds = cli_session_creds_init(frame,
12141 false, /* fallback_after_kerberos */
12142 false, /* use_ccache */
12143 false); /* password_is_nt_hash */
12144 if (torture_creds == NULL) {
12145 d_printf("cli_session_creds_init() failed.\n");
12149 if (argc == optind) {
12150 correct = run_test("ALL");
12152 for (i=optind;i<argc;i++) {
12153 if (!run_test(argv[i])) {
12159 TALLOC_FREE(frame);