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";
8124 const char *fname = "\\test_chain";
8127 printf("starting chain1 test\n");
8128 if (!torture_open_connection(&cli1, 0)) {
8132 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8134 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8136 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname,
8137 O_CREAT|O_RDWR, 0, &smbreqs[0]);
8138 if (reqs[0] == NULL) return false;
8139 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
8142 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
8143 (const uint8_t *)str, 0, strlen(str)+1,
8144 smbreqs, 1, &smbreqs[1]);
8145 if (reqs[1] == NULL) return false;
8146 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
8148 reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
8149 if (reqs[2] == NULL) return false;
8150 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
8152 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8153 if (!NT_STATUS_IS_OK(status)) {
8158 tevent_loop_once(evt);
8161 torture_close_connection(cli1);
8165 static void chain2_sesssetup_completion(struct tevent_req *req)
8168 status = cli_session_setup_guest_recv(req);
8169 d_printf("sesssetup returned %s\n", nt_errstr(status));
8172 static void chain2_tcon_completion(struct tevent_req *req)
8174 bool *done = (bool *)tevent_req_callback_data_void(req);
8176 status = cli_tcon_andx_recv(req);
8177 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
8181 static bool run_chain2(int dummy)
8183 struct cli_state *cli1;
8184 struct tevent_context *evt = samba_tevent_context_init(NULL);
8185 struct tevent_req *reqs[2], *smbreqs[2];
8188 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
8190 printf("starting chain2 test\n");
8191 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
8192 port_to_use, SMB_SIGNING_DEFAULT, flags);
8193 if (!NT_STATUS_IS_OK(status)) {
8197 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8199 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
8201 if (reqs[0] == NULL) return false;
8202 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
8204 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
8205 "?????", NULL, 0, &smbreqs[1]);
8206 if (reqs[1] == NULL) return false;
8207 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
8209 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8210 if (!NT_STATUS_IS_OK(status)) {
8215 tevent_loop_once(evt);
8218 torture_close_connection(cli1);
8223 struct torture_createdel_state {
8224 struct tevent_context *ev;
8225 struct cli_state *cli;
8228 static void torture_createdel_created(struct tevent_req *subreq);
8229 static void torture_createdel_closed(struct tevent_req *subreq);
8231 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8232 struct tevent_context *ev,
8233 struct cli_state *cli,
8236 struct tevent_req *req, *subreq;
8237 struct torture_createdel_state *state;
8239 req = tevent_req_create(mem_ctx, &state,
8240 struct torture_createdel_state);
8247 subreq = cli_ntcreate_send(
8248 state, ev, cli, name, 0,
8249 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8250 FILE_ATTRIBUTE_NORMAL,
8251 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8252 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE,
8253 SMB2_IMPERSONATION_IMPERSONATION, 0);
8255 if (tevent_req_nomem(subreq, req)) {
8256 return tevent_req_post(req, ev);
8258 tevent_req_set_callback(subreq, torture_createdel_created, req);
8262 static void torture_createdel_created(struct tevent_req *subreq)
8264 struct tevent_req *req = tevent_req_callback_data(
8265 subreq, struct tevent_req);
8266 struct torture_createdel_state *state = tevent_req_data(
8267 req, struct torture_createdel_state);
8271 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8272 TALLOC_FREE(subreq);
8273 if (tevent_req_nterror(req, status)) {
8274 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8275 nt_errstr(status)));
8279 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8280 if (tevent_req_nomem(subreq, req)) {
8283 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8286 static void torture_createdel_closed(struct tevent_req *subreq)
8288 struct tevent_req *req = tevent_req_callback_data(
8289 subreq, struct tevent_req);
8292 status = cli_close_recv(subreq);
8293 if (tevent_req_nterror(req, status)) {
8294 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8297 tevent_req_done(req);
8300 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8302 return tevent_req_simple_recv_ntstatus(req);
8305 struct torture_createdels_state {
8306 struct tevent_context *ev;
8307 struct cli_state *cli;
8308 const char *base_name;
8312 struct tevent_req **reqs;
8315 static void torture_createdels_done(struct tevent_req *subreq);
8317 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8318 struct tevent_context *ev,
8319 struct cli_state *cli,
8320 const char *base_name,
8324 struct tevent_req *req;
8325 struct torture_createdels_state *state;
8328 req = tevent_req_create(mem_ctx, &state,
8329 struct torture_createdels_state);
8335 state->base_name = talloc_strdup(state, base_name);
8336 if (tevent_req_nomem(state->base_name, req)) {
8337 return tevent_req_post(req, ev);
8339 state->num_files = MAX(num_parallel, num_files);
8341 state->received = 0;
8343 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8344 if (tevent_req_nomem(state->reqs, req)) {
8345 return tevent_req_post(req, ev);
8348 for (i=0; i<num_parallel; i++) {
8351 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8353 if (tevent_req_nomem(name, req)) {
8354 return tevent_req_post(req, ev);
8356 state->reqs[i] = torture_createdel_send(
8357 state->reqs, state->ev, state->cli, name);
8358 if (tevent_req_nomem(state->reqs[i], req)) {
8359 return tevent_req_post(req, ev);
8361 name = talloc_move(state->reqs[i], &name);
8362 tevent_req_set_callback(state->reqs[i],
8363 torture_createdels_done, req);
8369 static void torture_createdels_done(struct tevent_req *subreq)
8371 struct tevent_req *req = tevent_req_callback_data(
8372 subreq, struct tevent_req);
8373 struct torture_createdels_state *state = tevent_req_data(
8374 req, struct torture_createdels_state);
8375 size_t num_parallel = talloc_array_length(state->reqs);
8380 status = torture_createdel_recv(subreq);
8381 if (!NT_STATUS_IS_OK(status)){
8382 DEBUG(10, ("torture_createdel_recv returned %s\n",
8383 nt_errstr(status)));
8384 TALLOC_FREE(subreq);
8385 tevent_req_nterror(req, status);
8389 for (i=0; i<num_parallel; i++) {
8390 if (subreq == state->reqs[i]) {
8394 if (i == num_parallel) {
8395 DEBUG(10, ("received something we did not send\n"));
8396 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8399 TALLOC_FREE(state->reqs[i]);
8401 if (state->sent >= state->num_files) {
8402 tevent_req_done(req);
8406 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8408 if (tevent_req_nomem(name, req)) {
8411 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8413 if (tevent_req_nomem(state->reqs[i], req)) {
8416 name = talloc_move(state->reqs[i], &name);
8417 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8421 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8423 return tevent_req_simple_recv_ntstatus(req);
8426 struct swallow_notify_state {
8427 struct tevent_context *ev;
8428 struct cli_state *cli;
8430 uint32_t completion_filter;
8432 bool (*fn)(uint32_t action, const char *name, void *priv);
8436 static void swallow_notify_done(struct tevent_req *subreq);
8438 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8439 struct tevent_context *ev,
8440 struct cli_state *cli,
8442 uint32_t completion_filter,
8444 bool (*fn)(uint32_t action,
8449 struct tevent_req *req, *subreq;
8450 struct swallow_notify_state *state;
8452 req = tevent_req_create(mem_ctx, &state,
8453 struct swallow_notify_state);
8460 state->completion_filter = completion_filter;
8461 state->recursive = recursive;
8465 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8466 0xffff, state->completion_filter,
8468 if (tevent_req_nomem(subreq, req)) {
8469 return tevent_req_post(req, ev);
8471 tevent_req_set_callback(subreq, swallow_notify_done, req);
8475 static void swallow_notify_done(struct tevent_req *subreq)
8477 struct tevent_req *req = tevent_req_callback_data(
8478 subreq, struct tevent_req);
8479 struct swallow_notify_state *state = tevent_req_data(
8480 req, struct swallow_notify_state);
8482 uint32_t i, num_changes;
8483 struct notify_change *changes;
8485 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8486 TALLOC_FREE(subreq);
8487 if (!NT_STATUS_IS_OK(status)) {
8488 DEBUG(10, ("cli_notify_recv returned %s\n",
8489 nt_errstr(status)));
8490 tevent_req_nterror(req, status);
8494 for (i=0; i<num_changes; i++) {
8495 state->fn(changes[i].action, changes[i].name, state->priv);
8497 TALLOC_FREE(changes);
8499 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8500 0xffff, state->completion_filter,
8502 if (tevent_req_nomem(subreq, req)) {
8505 tevent_req_set_callback(subreq, swallow_notify_done, req);
8508 static bool print_notifies(uint32_t action, const char *name, void *priv)
8510 if (DEBUGLEVEL > 5) {
8511 d_printf("%d %s\n", (int)action, name);
8516 static void notify_bench_done(struct tevent_req *req)
8518 int *num_finished = (int *)tevent_req_callback_data_void(req);
8522 static bool run_notify_bench(int dummy)
8524 const char *dname = "\\notify-bench";
8525 struct tevent_context *ev;
8528 struct tevent_req *req1;
8529 struct tevent_req *req2 = NULL;
8530 int i, num_unc_names;
8531 int num_finished = 0;
8533 printf("starting notify-bench test\n");
8535 if (use_multishare_conn) {
8537 unc_list = file_lines_load(multishare_conn_fname,
8538 &num_unc_names, 0, NULL);
8539 if (!unc_list || num_unc_names <= 0) {
8540 d_printf("Failed to load unc names list from '%s'\n",
8541 multishare_conn_fname);
8544 TALLOC_FREE(unc_list);
8549 ev = samba_tevent_context_init(talloc_tos());
8551 d_printf("tevent_context_init failed\n");
8555 for (i=0; i<num_unc_names; i++) {
8556 struct cli_state *cli;
8559 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8561 if (base_fname == NULL) {
8565 if (!torture_open_connection(&cli, i)) {
8569 status = cli_ntcreate(cli, dname, 0,
8570 MAXIMUM_ALLOWED_ACCESS,
8571 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8573 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8576 if (!NT_STATUS_IS_OK(status)) {
8577 d_printf("Could not create %s: %s\n", dname,
8582 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8583 FILE_NOTIFY_CHANGE_FILE_NAME |
8584 FILE_NOTIFY_CHANGE_DIR_NAME |
8585 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8586 FILE_NOTIFY_CHANGE_LAST_WRITE,
8587 false, print_notifies, NULL);
8589 d_printf("Could not create notify request\n");
8593 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8594 base_fname, 10, torture_numops);
8596 d_printf("Could not create createdels request\n");
8599 TALLOC_FREE(base_fname);
8601 tevent_req_set_callback(req2, notify_bench_done,
8605 while (num_finished < num_unc_names) {
8607 ret = tevent_loop_once(ev);
8609 d_printf("tevent_loop_once failed\n");
8614 if (!tevent_req_poll(req2, ev)) {
8615 d_printf("tevent_req_poll failed\n");
8618 status = torture_createdels_recv(req2);
8619 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8624 static bool run_mangle1(int dummy)
8626 struct cli_state *cli;
8627 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8631 time_t change_time, access_time, write_time;
8635 printf("starting mangle1 test\n");
8636 if (!torture_open_connection(&cli, 0)) {
8640 smbXcli_conn_set_sockopt(cli->conn, sockops);
8642 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8643 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8645 if (!NT_STATUS_IS_OK(status)) {
8646 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8649 cli_close(cli, fnum);
8651 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8652 if (!NT_STATUS_IS_OK(status)) {
8653 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8657 d_printf("alt_name: %s\n", alt_name);
8659 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8660 if (!NT_STATUS_IS_OK(status)) {
8661 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8665 cli_close(cli, fnum);
8667 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8668 &write_time, &size, &mode);
8669 if (!NT_STATUS_IS_OK(status)) {
8670 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8678 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8679 struct file_info *f,
8683 if (f->short_name == NULL) {
8684 return NT_STATUS_OK;
8687 if (strlen(f->short_name) == 0) {
8688 return NT_STATUS_OK;
8691 printf("unexpected shortname: %s\n", f->short_name);
8693 return NT_STATUS_OBJECT_NAME_INVALID;
8696 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8697 struct file_info *f,
8703 printf("name: %s\n", f->name);
8704 fstrcpy(name, f->name);
8705 return NT_STATUS_OK;
8708 static bool run_mangle_illegal(int dummy)
8710 struct cli_state *cli = NULL;
8711 struct cli_state *cli_posix = NULL;
8712 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8713 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8714 char *mangled_path = NULL;
8720 printf("starting mangle-illegal test\n");
8722 if (!torture_open_connection(&cli, 0)) {
8726 smbXcli_conn_set_sockopt(cli->conn, sockops);
8728 if (!torture_open_connection(&cli_posix, 0)) {
8732 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8734 status = torture_setup_unix_extensions(cli_posix);
8735 if (!NT_STATUS_IS_OK(status)) {
8739 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8740 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8741 if (!NT_STATUS_IS_OK(status)) {
8742 printf("mkdir1 failed : %s\n", nt_errstr(status));
8747 * Create a file with illegal NTFS characters and test that we
8748 * get a usable mangled name
8751 cli_setatr(cli_posix, illegal_fname, 0, 0);
8752 cli_posix_unlink(cli_posix, illegal_fname);
8754 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8756 if (!NT_STATUS_IS_OK(status)) {
8757 printf("POSIX create of %s failed (%s)\n",
8758 illegal_fname, nt_errstr(status));
8762 status = cli_close(cli_posix, fnum);
8763 if (!NT_STATUS_IS_OK(status)) {
8764 printf("close failed (%s)\n", nt_errstr(status));
8768 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8769 if (!NT_STATUS_IS_OK(status)) {
8770 d_printf("cli_list failed: %s\n", nt_errstr(status));
8774 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8775 if (mangled_path == NULL) {
8779 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8780 if (!NT_STATUS_IS_OK(status)) {
8781 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8782 TALLOC_FREE(mangled_path);
8785 TALLOC_FREE(mangled_path);
8786 cli_close(cli, fnum);
8788 cli_setatr(cli_posix, illegal_fname, 0, 0);
8789 cli_posix_unlink(cli_posix, illegal_fname);
8792 * Create a file with a long name and check that we got *no* short name.
8795 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8796 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8798 if (!NT_STATUS_IS_OK(status)) {
8799 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8802 cli_close(cli, fnum);
8804 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8805 if (!NT_STATUS_IS_OK(status)) {
8806 d_printf("cli_list failed\n");
8810 cli_unlink(cli, fname, 0);
8811 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8813 if (!torture_close_connection(cli_posix)) {
8817 if (!torture_close_connection(cli)) {
8824 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8826 size_t *to_pull = (size_t *)priv;
8827 size_t thistime = *to_pull;
8829 thistime = MIN(thistime, n);
8830 if (thistime == 0) {
8834 memset(buf, 0, thistime);
8835 *to_pull -= thistime;
8839 static bool run_windows_write(int dummy)
8841 struct cli_state *cli1;
8845 const char *fname = "\\writetest.txt";
8846 struct timeval start_time;
8851 printf("starting windows_write test\n");
8852 if (!torture_open_connection(&cli1, 0)) {
8856 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8857 if (!NT_STATUS_IS_OK(status)) {
8858 printf("open failed (%s)\n", nt_errstr(status));
8862 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8864 start_time = timeval_current();
8866 for (i=0; i<torture_numops; i++) {
8868 off_t start = i * torture_blocksize;
8869 size_t to_pull = torture_blocksize - 1;
8871 status = cli_writeall(cli1, fnum, 0, &c,
8872 start + torture_blocksize - 1, 1, NULL);
8873 if (!NT_STATUS_IS_OK(status)) {
8874 printf("cli_write failed: %s\n", nt_errstr(status));
8878 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8879 null_source, &to_pull);
8880 if (!NT_STATUS_IS_OK(status)) {
8881 printf("cli_push returned: %s\n", nt_errstr(status));
8886 seconds = timeval_elapsed(&start_time);
8887 kbytes = (double)torture_blocksize * torture_numops;
8890 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8891 (double)seconds, (int)(kbytes/seconds));
8895 cli_close(cli1, fnum);
8896 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8897 torture_close_connection(cli1);
8901 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8903 size_t max_pdu = 0x1FFFF;
8905 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8909 if (smb1cli_conn_signing_is_active(cli->conn)) {
8913 if (smb1cli_conn_encryption_on(cli->conn)) {
8914 max_pdu = CLI_BUFFER_SIZE;
8917 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8918 len_requested &= 0xFFFF;
8921 return MIN(len_requested,
8922 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8925 static bool check_read_call(struct cli_state *cli,
8928 size_t len_requested)
8931 struct tevent_req *subreq = NULL;
8932 ssize_t len_read = 0;
8933 size_t len_expected = 0;
8934 struct tevent_context *ev = NULL;
8936 ev = samba_tevent_context_init(talloc_tos());
8941 subreq = cli_read_andx_send(talloc_tos(),
8948 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8952 status = cli_read_andx_recv(subreq, &len_read, &buf);
8953 if (!NT_STATUS_IS_OK(status)) {
8954 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8958 TALLOC_FREE(subreq);
8961 len_expected = calc_expected_return(cli, len_requested);
8963 if (len_expected > 0x10000 && len_read == 0x10000) {
8964 /* Windows servers only return a max of 0x10000,
8965 doesn't matter if you set CAP_LARGE_READX in
8966 the client sessionsetupX call or not. */
8967 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8968 (unsigned int)len_requested);
8969 } else if (len_read != len_expected) {
8970 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8971 (unsigned int)len_requested,
8972 (unsigned int)len_read,
8973 (unsigned int)len_expected);
8976 d_printf("Correct read reply.\n");
8982 /* Test large readX variants. */
8983 static bool large_readx_tests(struct cli_state *cli,
8987 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8988 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8991 /* A read of 0x10000 should return 0x10000 bytes. */
8992 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8995 /* A read of 0x10000 should return 0x10001 bytes. */
8996 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8999 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
9000 the requested number of bytes. */
9001 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
9004 /* A read of 1MB should return 1MB bytes (on Samba). */
9005 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
9009 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
9012 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
9015 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
9021 static bool run_large_readx(int dummy)
9023 uint8_t *buf = NULL;
9024 struct cli_state *cli1 = NULL;
9025 struct cli_state *cli2 = NULL;
9026 bool correct = false;
9027 const char *fname = "\\large_readx.dat";
9029 uint16_t fnum1 = UINT16_MAX;
9030 uint32_t normal_caps = 0;
9031 size_t file_size = 20*1024*1024;
9032 TALLOC_CTX *frame = talloc_stackframe();
9036 enum smb_signing_setting signing_setting;
9037 enum protocol_types protocol;
9041 .signing_setting = SMB_SIGNING_IF_REQUIRED,
9042 .protocol = PROTOCOL_NT1,
9044 .name = "NT1 - SIGNING_REQUIRED",
9045 .signing_setting = SMB_SIGNING_REQUIRED,
9046 .protocol = PROTOCOL_NT1,
9050 printf("starting large_readx test\n");
9052 if (!torture_open_connection(&cli1, 0)) {
9056 normal_caps = smb1cli_conn_capabilities(cli1->conn);
9058 if (!(normal_caps & CAP_LARGE_READX)) {
9059 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9060 (unsigned int)normal_caps);
9064 /* Create a file of size 4MB. */
9065 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
9066 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9067 0, 0, &fnum1, NULL);
9069 if (!NT_STATUS_IS_OK(status)) {
9070 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
9074 /* Write file_size bytes. */
9075 buf = talloc_zero_array(frame, uint8_t, file_size);
9080 status = cli_writeall(cli1,
9087 if (!NT_STATUS_IS_OK(status)) {
9088 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9092 status = cli_close(cli1, fnum1);
9093 if (!NT_STATUS_IS_OK(status)) {
9094 d_printf("cli_close failed: %s\n", nt_errstr(status));
9100 for (i=0; i < ARRAY_SIZE(runs); i++) {
9101 enum smb_signing_setting saved_signing_setting = signing_state;
9102 uint16_t fnum2 = -1;
9105 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
9107 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
9111 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
9113 signing_state = runs[i].signing_setting;
9114 cli2 = open_nbt_connection();
9115 signing_state = saved_signing_setting;
9120 status = smbXcli_negprot(cli2->conn,
9124 if (!NT_STATUS_IS_OK(status)) {
9128 status = cli_session_setup_creds(cli2, torture_creds);
9129 if (!NT_STATUS_IS_OK(status)) {
9133 status = cli_tree_connect(cli2,
9137 if (!NT_STATUS_IS_OK(status)) {
9141 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
9143 normal_caps = smb1cli_conn_capabilities(cli2->conn);
9145 if (!(normal_caps & CAP_LARGE_READX)) {
9146 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9147 (unsigned int)normal_caps);
9152 if (force_cli_encryption(cli2, share) == false) {
9155 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
9156 uint16_t major, minor;
9157 uint32_t caplow, caphigh;
9159 status = cli_unix_extensions_version(cli2,
9162 if (!NT_STATUS_IS_OK(status)) {
9167 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
9168 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
9169 0, 0, &fnum2, NULL);
9170 if (!NT_STATUS_IS_OK(status)) {
9171 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
9175 /* All reads must return less than file_size bytes. */
9176 if (!large_readx_tests(cli2, fnum2, buf)) {
9180 status = cli_close(cli2, fnum2);
9181 if (!NT_STATUS_IS_OK(status)) {
9182 d_printf("cli_close failed: %s\n", nt_errstr(status));
9187 if (!torture_close_connection(cli2)) {
9194 printf("Success on large_readx test\n");
9199 if (!torture_close_connection(cli2)) {
9205 if (fnum1 != UINT16_MAX) {
9206 status = cli_close(cli1, fnum1);
9207 if (!NT_STATUS_IS_OK(status)) {
9208 d_printf("cli_close failed: %s\n", nt_errstr(status));
9213 status = cli_unlink(cli1, fname,
9214 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9215 if (!NT_STATUS_IS_OK(status)) {
9216 printf("unlink failed (%s)\n", nt_errstr(status));
9219 if (!torture_close_connection(cli1)) {
9226 printf("finished large_readx test\n");
9230 static bool run_cli_echo(int dummy)
9232 struct cli_state *cli;
9235 printf("starting cli_echo test\n");
9236 if (!torture_open_connection(&cli, 0)) {
9239 smbXcli_conn_set_sockopt(cli->conn, sockops);
9241 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9243 d_printf("cli_echo returned %s\n", nt_errstr(status));
9245 torture_close_connection(cli);
9246 return NT_STATUS_IS_OK(status);
9249 static int splice_status(off_t written, void *priv)
9254 static bool run_cli_splice(int dummy)
9256 uint8_t *buf = NULL;
9257 struct cli_state *cli1 = NULL;
9258 bool correct = false;
9259 const char *fname_src = "\\splice_src.dat";
9260 const char *fname_dst = "\\splice_dst.dat";
9262 uint16_t fnum1 = UINT16_MAX;
9263 uint16_t fnum2 = UINT16_MAX;
9264 size_t file_size = 2*1024*1024;
9265 size_t splice_size = 1*1024*1024 + 713;
9267 uint8_t digest1[16], digest2[16];
9270 TALLOC_CTX *frame = talloc_stackframe();
9272 printf("starting cli_splice test\n");
9274 if (!torture_open_connection(&cli1, 0)) {
9278 cli_unlink(cli1, fname_src,
9279 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9280 cli_unlink(cli1, fname_dst,
9281 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9284 status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
9285 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9286 0, 0, &fnum1, NULL);
9288 if (!NT_STATUS_IS_OK(status)) {
9289 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
9293 /* Write file_size bytes - must be bigger than splice_size. */
9294 buf = talloc_zero_array(frame, uint8_t, file_size);
9296 d_printf("talloc_fail\n");
9300 /* Fill it with random numbers. */
9301 generate_random_buffer(buf, file_size);
9303 /* MD5 the first 1MB + 713 bytes. */
9305 MD5Update(&md5_ctx, buf, splice_size);
9306 MD5Final(digest1, &md5_ctx);
9308 status = cli_writeall(cli1,
9315 if (!NT_STATUS_IS_OK(status)) {
9316 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9320 status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
9321 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9322 0, 0, &fnum2, NULL);
9324 if (!NT_STATUS_IS_OK(status)) {
9325 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
9329 /* Now splice 1MB + 713 bytes. */
9330 status = cli_splice(cli1,
9341 if (!NT_STATUS_IS_OK(status)) {
9342 d_printf("cli_splice failed: %s\n", nt_errstr(status));
9346 /* Clear the old buffer. */
9347 memset(buf, '\0', file_size);
9349 /* Read the new file. */
9350 status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
9351 if (!NT_STATUS_IS_OK(status)) {
9352 d_printf("cli_read failed: %s\n", nt_errstr(status));
9355 if (nread != splice_size) {
9356 d_printf("bad read of 0x%x, should be 0x%x\n",
9357 (unsigned int)nread,
9358 (unsigned int)splice_size);
9362 /* MD5 the first 1MB + 713 bytes. */
9364 MD5Update(&md5_ctx, buf, splice_size);
9365 MD5Final(digest2, &md5_ctx);
9367 /* Must be the same. */
9368 if (memcmp(digest1, digest2, 16) != 0) {
9369 d_printf("bad MD5 compare\n");
9374 printf("Success on cli_splice test\n");
9379 if (fnum1 != UINT16_MAX) {
9380 cli_close(cli1, fnum1);
9382 if (fnum2 != UINT16_MAX) {
9383 cli_close(cli1, fnum2);
9386 cli_unlink(cli1, fname_src,
9387 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9388 cli_unlink(cli1, fname_dst,
9389 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9391 if (!torture_close_connection(cli1)) {
9400 static bool run_uid_regression_test(int dummy)
9402 static struct cli_state *cli;
9405 bool correct = True;
9406 struct smbXcli_tcon *orig_tcon = NULL;
9409 printf("starting uid regression test\n");
9411 if (!torture_open_connection(&cli, 0)) {
9415 smbXcli_conn_set_sockopt(cli->conn, sockops);
9417 /* Ok - now save then logoff our current user. */
9418 old_vuid = cli_state_get_uid(cli);
9420 status = cli_ulogoff(cli);
9421 if (!NT_STATUS_IS_OK(status)) {
9422 d_printf("(%s) cli_ulogoff failed: %s\n",
9423 __location__, nt_errstr(status));
9428 cli_state_set_uid(cli, old_vuid);
9430 /* Try an operation. */
9431 status = cli_mkdir(cli, "\\uid_reg_test");
9432 if (NT_STATUS_IS_OK(status)) {
9433 d_printf("(%s) cli_mkdir succeeded\n",
9438 /* Should be bad uid. */
9439 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9440 NT_STATUS_USER_SESSION_DELETED)) {
9446 old_cnum = cli_state_get_tid(cli);
9447 orig_tcon = cli_state_save_tcon(cli);
9448 if (orig_tcon == NULL) {
9453 /* Now try a SMBtdis with the invald vuid set to zero. */
9454 cli_state_set_uid(cli, 0);
9456 /* This should succeed. */
9457 status = cli_tdis(cli);
9459 if (NT_STATUS_IS_OK(status)) {
9460 d_printf("First tdis with invalid vuid should succeed.\n");
9462 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9464 cli_state_restore_tcon(cli, orig_tcon);
9468 cli_state_restore_tcon(cli, orig_tcon);
9469 cli_state_set_uid(cli, old_vuid);
9470 cli_state_set_tid(cli, old_cnum);
9472 /* This should fail. */
9473 status = cli_tdis(cli);
9474 if (NT_STATUS_IS_OK(status)) {
9475 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9479 /* Should be bad tid. */
9480 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9481 NT_STATUS_NETWORK_NAME_DELETED)) {
9487 cli_rmdir(cli, "\\uid_reg_test");
9496 static const char *illegal_chars = "*\\/?<>|\":";
9497 static char force_shortname_chars[] = " +,.[];=\177";
9499 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9500 const char *mask, void *state)
9502 struct cli_state *pcli = (struct cli_state *)state;
9504 NTSTATUS status = NT_STATUS_OK;
9506 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9508 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9509 return NT_STATUS_OK;
9511 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9512 status = cli_rmdir(pcli, fname);
9513 if (!NT_STATUS_IS_OK(status)) {
9514 printf("del_fn: failed to rmdir %s\n,", fname );
9517 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9518 if (!NT_STATUS_IS_OK(status)) {
9519 printf("del_fn: failed to unlink %s\n,", fname );
9531 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9532 const char *name, void *state)
9534 struct sn_state *s = (struct sn_state *)state;
9538 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9539 i, finfo->name, finfo->short_name);
9542 if (strchr(force_shortname_chars, i)) {
9543 if (!finfo->short_name) {
9544 /* Shortname not created when it should be. */
9545 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9546 __location__, finfo->name, i);
9549 } else if (finfo->short_name){
9550 /* Shortname created when it should not be. */
9551 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9552 __location__, finfo->short_name, finfo->name);
9556 return NT_STATUS_OK;
9559 static bool run_shortname_test(int dummy)
9561 static struct cli_state *cli;
9562 bool correct = True;
9568 printf("starting shortname test\n");
9570 if (!torture_open_connection(&cli, 0)) {
9574 smbXcli_conn_set_sockopt(cli->conn, sockops);
9576 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9577 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9578 cli_rmdir(cli, "\\shortname");
9580 status = cli_mkdir(cli, "\\shortname");
9581 if (!NT_STATUS_IS_OK(status)) {
9582 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9583 __location__, nt_errstr(status));
9588 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9592 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9599 for (i = 32; i < 128; i++) {
9600 uint16_t fnum = (uint16_t)-1;
9604 if (strchr(illegal_chars, i)) {
9609 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9610 FILE_SHARE_READ|FILE_SHARE_WRITE,
9611 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9612 if (!NT_STATUS_IS_OK(status)) {
9613 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9614 __location__, fname, nt_errstr(status));
9618 cli_close(cli, fnum);
9621 status = cli_list(cli, "\\shortname\\test*.*", 0,
9622 shortname_list_fn, &s);
9623 if (s.matched != 1) {
9624 d_printf("(%s) failed to list %s: %s\n",
9625 __location__, fname, nt_errstr(status));
9630 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9631 if (!NT_STATUS_IS_OK(status)) {
9632 d_printf("(%s) failed to delete %s: %s\n",
9633 __location__, fname, nt_errstr(status));
9646 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9647 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9648 cli_rmdir(cli, "\\shortname");
9649 torture_close_connection(cli);
9653 static void pagedsearch_cb(struct tevent_req *req)
9656 struct tldap_message *msg;
9659 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9660 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9661 d_printf("tldap_search_paged_recv failed: %s\n",
9662 tldap_rc2string(rc));
9665 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9669 if (!tldap_entry_dn(msg, &dn)) {
9670 d_printf("tldap_entry_dn failed\n");
9673 d_printf("%s\n", dn);
9677 static bool run_tldap(int dummy)
9679 struct tldap_context *ld;
9683 struct sockaddr_storage addr;
9684 struct tevent_context *ev;
9685 struct tevent_req *req;
9689 if (!resolve_name(host, &addr, 0, false)) {
9690 d_printf("could not find host %s\n", host);
9693 status = open_socket_out(&addr, 389, 9999, &fd);
9694 if (!NT_STATUS_IS_OK(status)) {
9695 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9699 ld = tldap_context_create(talloc_tos(), fd);
9702 d_printf("tldap_context_create failed\n");
9706 rc = tldap_fetch_rootdse(ld);
9707 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9708 d_printf("tldap_fetch_rootdse failed: %s\n",
9709 tldap_errstr(talloc_tos(), ld, rc));
9713 basedn = tldap_talloc_single_attribute(
9714 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9715 if (basedn == NULL) {
9716 d_printf("no defaultNamingContext\n");
9719 d_printf("defaultNamingContext: %s\n", basedn);
9721 ev = samba_tevent_context_init(talloc_tos());
9723 d_printf("tevent_context_init failed\n");
9727 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9728 TLDAP_SCOPE_SUB, "(objectclass=*)",
9730 NULL, 0, NULL, 0, 0, 0, 0, 5);
9732 d_printf("tldap_search_paged_send failed\n");
9735 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9737 tevent_req_poll(req, ev);
9741 /* test search filters against rootDSE */
9742 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9743 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9745 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9746 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9747 talloc_tos(), NULL);
9748 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9749 d_printf("tldap_search with complex filter failed: %s\n",
9750 tldap_errstr(talloc_tos(), ld, rc));
9758 /* Torture test to ensure no regression of :
9759 https://bugzilla.samba.org/show_bug.cgi?id=7084
9762 static bool run_dir_createtime(int dummy)
9764 struct cli_state *cli;
9765 const char *dname = "\\testdir_createtime";
9766 const char *fname = "\\testdir_createtime\\testfile";
9768 struct timespec create_time;
9769 struct timespec create_time1;
9773 if (!torture_open_connection(&cli, 0)) {
9777 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9778 cli_rmdir(cli, dname);
9780 status = cli_mkdir(cli, dname);
9781 if (!NT_STATUS_IS_OK(status)) {
9782 printf("mkdir failed: %s\n", nt_errstr(status));
9786 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9788 if (!NT_STATUS_IS_OK(status)) {
9789 printf("cli_qpathinfo2 returned %s\n",
9794 /* Sleep 3 seconds, then create a file. */
9797 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9799 if (!NT_STATUS_IS_OK(status)) {
9800 printf("cli_openx failed: %s\n", nt_errstr(status));
9804 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9806 if (!NT_STATUS_IS_OK(status)) {
9807 printf("cli_qpathinfo2 (2) returned %s\n",
9812 if (timespec_compare(&create_time1, &create_time)) {
9813 printf("run_dir_createtime: create time was updated (error)\n");
9815 printf("run_dir_createtime: create time was not updated (correct)\n");
9821 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9822 cli_rmdir(cli, dname);
9823 if (!torture_close_connection(cli)) {
9830 static bool run_streamerror(int dummy)
9832 struct cli_state *cli;
9833 const char *dname = "\\testdir_streamerror";
9834 const char *streamname =
9835 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9837 time_t change_time, access_time, write_time;
9839 uint16_t mode, fnum;
9842 if (!torture_open_connection(&cli, 0)) {
9846 cli_unlink(cli, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9847 cli_rmdir(cli, dname);
9849 status = cli_mkdir(cli, dname);
9850 if (!NT_STATUS_IS_OK(status)) {
9851 printf("mkdir failed: %s\n", nt_errstr(status));
9855 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9856 &write_time, &size, &mode);
9857 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9858 printf("pathinfo returned %s, expected "
9859 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9864 status = cli_ntcreate(cli, streamname, 0x16,
9865 FILE_READ_DATA|FILE_READ_EA|
9866 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9867 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9868 FILE_OPEN, 0, 0, &fnum, NULL);
9870 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9871 printf("ntcreate returned %s, expected "
9872 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9878 cli_rmdir(cli, dname);
9882 struct pidtest_state {
9888 static void pid_echo_done(struct tevent_req *subreq);
9890 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9891 struct tevent_context *ev,
9892 struct cli_state *cli)
9894 struct tevent_req *req, *subreq;
9895 struct pidtest_state *state;
9897 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9902 SSVAL(state->vwv, 0, 1);
9903 state->data = data_blob_const("hello", 5);
9905 subreq = smb1cli_req_send(state,
9910 0, 0, /* *_flags2 */
9912 0xDEADBEEF, /* pid */
9915 ARRAY_SIZE(state->vwv), state->vwv,
9916 state->data.length, state->data.data);
9918 if (tevent_req_nomem(subreq, req)) {
9919 return tevent_req_post(req, ev);
9921 tevent_req_set_callback(subreq, pid_echo_done, req);
9925 static void pid_echo_done(struct tevent_req *subreq)
9927 struct tevent_req *req = tevent_req_callback_data(
9928 subreq, struct tevent_req);
9929 struct pidtest_state *state = tevent_req_data(
9930 req, struct pidtest_state);
9933 uint8_t *bytes = NULL;
9934 struct iovec *recv_iov = NULL;
9935 uint8_t *phdr = NULL;
9936 uint16_t pidlow = 0;
9937 uint16_t pidhigh = 0;
9938 struct smb1cli_req_expected_response expected[] = {
9940 .status = NT_STATUS_OK,
9945 status = smb1cli_req_recv(subreq, state,
9950 NULL, /* pvwv_offset */
9953 NULL, /* pbytes_offset */
9955 expected, ARRAY_SIZE(expected));
9957 TALLOC_FREE(subreq);
9959 if (!NT_STATUS_IS_OK(status)) {
9960 tevent_req_nterror(req, status);
9964 if (num_bytes != state->data.length) {
9965 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9969 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9970 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9974 /* Check pid low/high == DEADBEEF */
9975 pidlow = SVAL(phdr, HDR_PID);
9976 if (pidlow != 0xBEEF){
9977 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9978 (unsigned int)pidlow);
9979 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9982 pidhigh = SVAL(phdr, HDR_PIDHIGH);
9983 if (pidhigh != 0xDEAD){
9984 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9985 (unsigned int)pidhigh);
9986 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9990 tevent_req_done(req);
9993 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9995 return tevent_req_simple_recv_ntstatus(req);
9998 static bool run_pidhigh(int dummy)
10000 bool success = false;
10001 struct cli_state *cli = NULL;
10003 struct tevent_context *ev = NULL;
10004 struct tevent_req *req = NULL;
10005 TALLOC_CTX *frame = talloc_stackframe();
10007 printf("starting pid high test\n");
10008 if (!torture_open_connection(&cli, 0)) {
10011 smbXcli_conn_set_sockopt(cli->conn, sockops);
10013 ev = samba_tevent_context_init(frame);
10018 req = pid_echo_send(frame, ev, cli);
10023 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
10027 status = pid_echo_recv(req);
10028 if (NT_STATUS_IS_OK(status)) {
10029 printf("pid high test ok\n");
10035 TALLOC_FREE(frame);
10036 torture_close_connection(cli);
10041 Test Windows open on a bad POSIX symlink.
10043 static bool run_symlink_open_test(int dummy)
10045 static struct cli_state *cli;
10046 const char *fname = "non_existant_file";
10047 const char *sname = "dangling_symlink";
10048 uint16_t fnum = (uint16_t)-1;
10049 bool correct = false;
10051 TALLOC_CTX *frame = NULL;
10053 frame = talloc_stackframe();
10055 printf("Starting Windows bad symlink open test\n");
10057 if (!torture_open_connection(&cli, 0)) {
10058 TALLOC_FREE(frame);
10062 smbXcli_conn_set_sockopt(cli->conn, sockops);
10064 status = torture_setup_unix_extensions(cli);
10065 if (!NT_STATUS_IS_OK(status)) {
10066 TALLOC_FREE(frame);
10070 /* Ensure nothing exists. */
10071 cli_setatr(cli, fname, 0, 0);
10072 cli_posix_unlink(cli, fname);
10073 cli_setatr(cli, sname, 0, 0);
10074 cli_posix_unlink(cli, sname);
10076 /* Create a symlink pointing nowhere. */
10077 status = cli_posix_symlink(cli, fname, sname);
10078 if (!NT_STATUS_IS_OK(status)) {
10079 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
10082 nt_errstr(status));
10086 /* Now ensure that a Windows open doesn't hang. */
10087 status = cli_ntcreate(cli,
10090 FILE_READ_DATA|FILE_WRITE_DATA,
10092 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
10100 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
10101 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
10102 * we use O_NOFOLLOW on the server or not.
10104 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
10105 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
10109 printf("cli_ntcreate of %s returned %s - should return"
10110 " either (%s) or (%s)\n",
10113 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
10114 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
10122 if (fnum != (uint16_t)-1) {
10123 cli_close(cli, fnum);
10124 fnum = (uint16_t)-1;
10127 cli_setatr(cli, sname, 0, 0);
10128 cli_posix_unlink(cli, sname);
10129 cli_setatr(cli, fname, 0, 0);
10130 cli_posix_unlink(cli, fname);
10132 if (!torture_close_connection(cli)) {
10136 TALLOC_FREE(frame);
10141 * Only testing minimal time strings, as the others
10142 * need (locale-dependent) guessing at what strftime does and
10143 * even may differ in builds.
10145 static bool timesubst_test(void)
10147 TALLOC_CTX *ctx = NULL;
10148 /* Sa 23. Dez 04:33:20 CET 2017 */
10149 const struct timeval tv = { 1514000000, 123 };
10150 const char* expect_minimal = "20171223_033320";
10151 const char* expect_minus = "20171223_033320_000123";
10153 char *env_tz, *orig_tz = NULL;
10154 bool result = true;
10156 ctx = talloc_new(NULL);
10158 env_tz = getenv("TZ");
10160 orig_tz = talloc_strdup(ctx, env_tz);
10162 setenv("TZ", "UTC", 1);
10164 s = minimal_timeval_string(ctx, &tv, false);
10166 if(!s || strcmp(s, expect_minimal)) {
10167 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
10168 "[%s]\n", s ? s : "<nil>", expect_minimal);
10172 s = minimal_timeval_string(ctx, &tv, true);
10173 if(!s || strcmp(s, expect_minus)) {
10174 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
10175 "[%s]\n", s ? s : "<nil>", expect_minus);
10181 setenv("TZ", orig_tz, 1);
10188 static bool run_local_substitute(int dummy)
10192 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
10193 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
10194 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
10195 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
10196 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
10197 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
10198 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
10199 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
10200 ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
10201 /* Substitution depends on current time, so better test the underlying
10202 formatting function. At least covers %t. */
10203 ok &= timesubst_test();
10205 /* Different captialization rules in sub_basic... */
10207 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
10213 static bool run_local_base64(int dummy)
10218 for (i=1; i<2000; i++) {
10219 DATA_BLOB blob1, blob2;
10222 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
10224 generate_random_buffer(blob1.data, blob1.length);
10226 b64 = base64_encode_data_blob(talloc_tos(), blob1);
10228 d_fprintf(stderr, "base64_encode_data_blob failed "
10229 "for %d bytes\n", i);
10232 blob2 = base64_decode_data_blob(b64);
10235 if (data_blob_cmp(&blob1, &blob2)) {
10236 d_fprintf(stderr, "data_blob_cmp failed for %d "
10240 TALLOC_FREE(blob1.data);
10241 data_blob_free(&blob2);
10246 static void parse_fn(const struct gencache_timeout *t,
10248 void *private_data)
10253 static bool run_local_gencache(int dummy)
10259 struct memcache *mem;
10262 mem = memcache_init(NULL, 0);
10264 d_printf("%s: memcache_init failed\n", __location__);
10267 memcache_set_global(mem);
10269 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
10270 d_printf("%s: gencache_set() failed\n", __location__);
10274 if (!gencache_get("foo", NULL, NULL, NULL)) {
10275 d_printf("%s: gencache_get() failed\n", __location__);
10279 for (i=0; i<1000000; i++) {
10280 gencache_parse("foo", parse_fn, NULL);
10283 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10284 d_printf("%s: gencache_get() failed\n", __location__);
10289 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10290 d_printf("%s: gencache_get() failed\n", __location__);
10294 if (strcmp(val, "bar") != 0) {
10295 d_printf("%s: gencache_get() returned %s, expected %s\n",
10296 __location__, val, "bar");
10303 if (!gencache_del("foo")) {
10304 d_printf("%s: gencache_del() failed\n", __location__);
10307 if (gencache_del("foo")) {
10308 d_printf("%s: second gencache_del() succeeded\n",
10313 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
10314 d_printf("%s: gencache_get() on deleted entry "
10315 "succeeded\n", __location__);
10319 blob = data_blob_string_const_null("bar");
10320 tm = time(NULL) + 60;
10322 if (!gencache_set_data_blob("foo", blob, tm)) {
10323 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
10327 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10328 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
10332 if (strcmp((const char *)blob.data, "bar") != 0) {
10333 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10334 __location__, (const char *)blob.data, "bar");
10335 data_blob_free(&blob);
10339 data_blob_free(&blob);
10341 if (!gencache_del("foo")) {
10342 d_printf("%s: gencache_del() failed\n", __location__);
10345 if (gencache_del("foo")) {
10346 d_printf("%s: second gencache_del() succeeded\n",
10351 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10352 d_printf("%s: gencache_get_data_blob() on deleted entry "
10353 "succeeded\n", __location__);
10358 blob.data = (uint8_t *)&v;
10359 blob.length = sizeof(v);
10361 if (!gencache_set_data_blob("blob", blob, tm)) {
10362 d_printf("%s: gencache_set_data_blob() failed\n",
10366 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
10367 d_printf("%s: gencache_get succeeded\n", __location__);
10374 static bool rbt_testval(struct db_context *db, const char *key,
10377 struct db_record *rec;
10378 TDB_DATA data = string_tdb_data(value);
10383 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10385 d_fprintf(stderr, "fetch_locked failed\n");
10388 status = dbwrap_record_store(rec, data, 0);
10389 if (!NT_STATUS_IS_OK(status)) {
10390 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
10395 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10397 d_fprintf(stderr, "second fetch_locked failed\n");
10401 dbvalue = dbwrap_record_get_value(rec);
10402 if ((dbvalue.dsize != data.dsize)
10403 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
10404 d_fprintf(stderr, "Got wrong data back\n");
10414 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
10416 int *count2 = (int *)private_data;
10421 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
10423 int *count2 = (int *)private_data;
10425 dbwrap_record_delete(rec);
10429 static bool run_local_rbtree(int dummy)
10431 struct db_context *db;
10438 db = db_open_rbt(NULL);
10441 d_fprintf(stderr, "db_open_rbt failed\n");
10445 for (i=0; i<1000; i++) {
10448 if (asprintf(&key, "key%ld", random()) == -1) {
10451 if (asprintf(&value, "value%ld", random()) == -1) {
10456 if (!rbt_testval(db, key, value)) {
10463 if (asprintf(&value, "value%ld", random()) == -1) {
10468 if (!rbt_testval(db, key, value)) {
10479 count = 0; count2 = 0;
10480 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10482 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10483 if ((count != count2) || (count != 1000)) {
10486 count = 0; count2 = 0;
10487 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10489 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10490 if ((count != count2) || (count != 1000)) {
10493 count = 0; count2 = 0;
10494 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10496 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10497 if ((count != count2) || (count != 0)) {
10508 local test for character set functions
10510 This is a very simple test for the functionality in convert_string_error()
10512 static bool run_local_convert_string(int dummy)
10514 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10515 const char *test_strings[2] = { "March", "M\303\244rz" };
10519 for (i=0; i<2; i++) {
10520 const char *str = test_strings[i];
10521 int len = strlen(str);
10522 size_t converted_size;
10525 memset(dst, 'X', sizeof(dst));
10527 /* first try with real source length */
10528 ret = convert_string_error(CH_UNIX, CH_UTF8,
10533 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10537 if (converted_size != len) {
10538 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10539 str, len, (int)converted_size);
10543 if (strncmp(str, dst, converted_size) != 0) {
10544 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10548 if (strlen(str) != converted_size) {
10549 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10550 (int)strlen(str), (int)converted_size);
10554 if (dst[converted_size] != 'X') {
10555 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10559 /* now with srclen==-1, this causes the nul to be
10561 ret = convert_string_error(CH_UNIX, CH_UTF8,
10566 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10570 if (converted_size != len+1) {
10571 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10572 str, len, (int)converted_size);
10576 if (strncmp(str, dst, converted_size) != 0) {
10577 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10581 if (len+1 != converted_size) {
10582 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10583 len+1, (int)converted_size);
10587 if (dst[converted_size] != 'X') {
10588 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10595 TALLOC_FREE(tmp_ctx);
10598 TALLOC_FREE(tmp_ctx);
10602 static bool run_local_string_to_sid(int dummy) {
10603 struct dom_sid sid;
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-5-32-+545")) {
10610 printf("allowing S-1-5-32-+545\n");
10613 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")) {
10614 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10617 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10618 printf("allowing S-1-5-32-545-abc\n");
10621 if (string_to_sid(&sid, "S-300-5-32-545")) {
10622 printf("allowing S-300-5-32-545\n");
10625 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10626 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10629 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10630 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10633 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10634 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10637 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10638 printf("could not parse S-1-5-32-545\n");
10641 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10642 struct dom_sid_buf buf;
10643 printf("mis-parsed S-1-5-32-545 as %s\n",
10644 dom_sid_str_buf(&sid, &buf));
10650 static bool sid_to_string_test(const char *expected) {
10653 struct dom_sid sid;
10655 if (!string_to_sid(&sid, expected)) {
10656 printf("could not parse %s\n", expected);
10660 str = dom_sid_string(NULL, &sid);
10661 if (strcmp(str, expected)) {
10662 printf("Comparison failed (%s != %s)\n", str, expected);
10669 static bool run_local_sid_to_string(int dummy) {
10670 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10672 if (!sid_to_string_test("S-1-545"))
10674 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10679 static bool run_local_binary_to_sid(int dummy) {
10680 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10681 static const uint8_t good_binary_sid[] = {
10682 0x1, /* revision number */
10683 15, /* num auths */
10684 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10685 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10686 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10687 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10688 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10689 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10690 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10691 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10692 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10693 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10694 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10695 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10696 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10697 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10698 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10699 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10702 static const uint8_t long_binary_sid[] = {
10703 0x1, /* revision number */
10704 15, /* num auths */
10705 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10706 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10707 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10708 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10709 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10710 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10711 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10712 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10713 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10714 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10715 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10716 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10717 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10718 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10719 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10720 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10721 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10722 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10723 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10726 static const uint8_t long_binary_sid2[] = {
10727 0x1, /* revision number */
10728 32, /* num auths */
10729 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10730 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10731 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10732 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10733 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10734 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10735 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10736 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10737 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10738 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10739 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10740 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10741 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10742 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10743 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10744 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10745 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10746 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10747 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10748 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10749 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10750 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10751 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10752 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10753 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10754 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10755 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10756 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10757 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10758 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10759 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10760 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10761 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10764 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10767 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10770 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10776 /* Split a path name into filename and stream name components. Canonicalise
10777 * such that an implicit $DATA token is always explicit.
10779 * The "specification" of this function can be found in the
10780 * run_local_stream_name() function in torture.c, I've tried those
10781 * combinations against a W2k3 server.
10784 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10785 char **pbase, char **pstream)
10788 char *stream = NULL;
10789 char *sname; /* stream name */
10790 const char *stype; /* stream type */
10792 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10794 sname = strchr_m(fname, ':');
10796 if (sname == NULL) {
10797 if (pbase != NULL) {
10798 base = talloc_strdup(mem_ctx, fname);
10799 NT_STATUS_HAVE_NO_MEMORY(base);
10804 if (pbase != NULL) {
10805 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10806 NT_STATUS_HAVE_NO_MEMORY(base);
10811 stype = strchr_m(sname, ':');
10813 if (stype == NULL) {
10814 sname = talloc_strdup(mem_ctx, sname);
10818 if (strcasecmp_m(stype, ":$DATA") != 0) {
10820 * If there is an explicit stream type, so far we only
10821 * allow $DATA. Is there anything else allowed? -- vl
10823 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10825 return NT_STATUS_OBJECT_NAME_INVALID;
10827 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10831 if (sname == NULL) {
10833 return NT_STATUS_NO_MEMORY;
10836 if (sname[0] == '\0') {
10838 * no stream name, so no stream
10843 if (pstream != NULL) {
10844 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10845 if (stream == NULL) {
10846 TALLOC_FREE(sname);
10848 return NT_STATUS_NO_MEMORY;
10851 * upper-case the type field
10853 (void)strupper_m(strchr_m(stream, ':')+1);
10857 if (pbase != NULL) {
10860 if (pstream != NULL) {
10863 return NT_STATUS_OK;
10866 static bool test_stream_name(const char *fname, const char *expected_base,
10867 const char *expected_stream,
10868 NTSTATUS expected_status)
10872 char *stream = NULL;
10874 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10875 if (!NT_STATUS_EQUAL(status, expected_status)) {
10879 if (!NT_STATUS_IS_OK(status)) {
10883 if (base == NULL) goto error;
10885 if (strcmp(expected_base, base) != 0) goto error;
10887 if ((expected_stream != NULL) && (stream == NULL)) goto error;
10888 if ((expected_stream == NULL) && (stream != NULL)) goto error;
10890 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10894 TALLOC_FREE(stream);
10898 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10899 fname, expected_base ? expected_base : "<NULL>",
10900 expected_stream ? expected_stream : "<NULL>",
10901 nt_errstr(expected_status));
10902 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10903 base ? base : "<NULL>", stream ? stream : "<NULL>",
10904 nt_errstr(status));
10906 TALLOC_FREE(stream);
10910 static bool run_local_stream_name(int dummy)
10914 ret &= test_stream_name(
10915 "bla", "bla", NULL, NT_STATUS_OK);
10916 ret &= test_stream_name(
10917 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10918 ret &= test_stream_name(
10919 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10920 ret &= test_stream_name(
10921 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10922 ret &= test_stream_name(
10923 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10924 ret &= test_stream_name(
10925 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10926 ret &= test_stream_name(
10927 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10928 ret &= test_stream_name(
10929 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10934 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10936 if (a.length != b.length) {
10937 printf("a.length=%d != b.length=%d\n",
10938 (int)a.length, (int)b.length);
10941 if (memcmp(a.data, b.data, a.length) != 0) {
10942 printf("a.data and b.data differ\n");
10948 static bool run_local_memcache(int dummy)
10950 struct memcache *cache;
10951 DATA_BLOB k1, k2, k3;
10955 TALLOC_CTX *mem_ctx;
10960 size_t size1, size2;
10963 mem_ctx = talloc_init("foo");
10964 if (mem_ctx == NULL) {
10968 /* STAT_CACHE TESTS */
10970 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10972 if (cache == NULL) {
10973 printf("memcache_init failed\n");
10977 d1 = data_blob_const("d1", 2);
10978 d3 = data_blob_const("d3", 2);
10980 k1 = data_blob_const("d1", 2);
10981 k2 = data_blob_const("d2", 2);
10982 k3 = data_blob_const("d3", 2);
10984 memcache_add(cache, STAT_CACHE, k1, d1);
10986 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10987 printf("could not find k1\n");
10990 if (!data_blob_equal(d1, v1)) {
10994 memcache_add(cache, STAT_CACHE, k1, d3);
10996 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10997 printf("could not find replaced k1\n");
11000 if (!data_blob_equal(d3, v3)) {
11004 TALLOC_FREE(cache);
11006 /* GETWD_CACHE TESTS */
11007 str1 = talloc_strdup(mem_ctx, "string1");
11008 if (str1 == NULL) {
11011 ptr2 = str1; /* Keep an alias for comparison. */
11013 str2 = talloc_strdup(mem_ctx, "string2");
11014 if (str2 == NULL) {
11018 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
11019 if (cache == NULL) {
11020 printf("memcache_init failed\n");
11024 memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
11025 /* str1 == NULL now. */
11026 ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
11027 if (ptr1 == NULL) {
11028 printf("could not find k2\n");
11031 if (ptr1 != ptr2) {
11032 printf("fetch of k2 got wrong string\n");
11036 /* Add a blob to ensure k2 gets purged. */
11037 d3 = data_blob_talloc_zero(mem_ctx, 180);
11038 memcache_add(cache, STAT_CACHE, k3, d3);
11040 ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
11041 if (ptr2 != NULL) {
11042 printf("Did find k2, should have been purged\n");
11046 TALLOC_FREE(cache);
11047 TALLOC_FREE(mem_ctx);
11049 mem_ctx = talloc_init("foo");
11050 if (mem_ctx == NULL) {
11054 cache = memcache_init(NULL, 0);
11055 if (cache == NULL) {
11059 str1 = talloc_strdup(mem_ctx, "string1");
11060 if (str1 == NULL) {
11063 str2 = talloc_strdup(mem_ctx, "string2");
11064 if (str2 == NULL) {
11067 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
11068 data_blob_string_const("torture"), &str1);
11069 size1 = talloc_total_size(cache);
11071 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
11072 data_blob_string_const("torture"), &str2);
11073 size2 = talloc_total_size(cache);
11075 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
11077 if (size2 > size1) {
11078 printf("memcache leaks memory!\n");
11084 TALLOC_FREE(cache);
11088 static void wbclient_done(struct tevent_req *req)
11091 struct winbindd_response *wb_resp;
11092 int *i = (int *)tevent_req_callback_data_void(req);
11094 wbc_err = wb_trans_recv(req, req, &wb_resp);
11097 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
11100 static bool run_wbclient_multi_ping(int dummy)
11102 struct tevent_context *ev;
11103 struct wb_context **wb_ctx;
11104 struct winbindd_request wb_req;
11105 bool result = false;
11108 BlockSignals(True, SIGPIPE);
11110 ev = tevent_context_init(talloc_tos());
11115 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
11116 if (wb_ctx == NULL) {
11120 ZERO_STRUCT(wb_req);
11121 wb_req.cmd = WINBINDD_PING;
11123 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
11125 for (i=0; i<torture_nprocs; i++) {
11126 wb_ctx[i] = wb_context_init(ev, NULL);
11127 if (wb_ctx[i] == NULL) {
11130 for (j=0; j<torture_numops; j++) {
11131 struct tevent_req *req;
11132 req = wb_trans_send(ev, ev, wb_ctx[i],
11133 (j % 2) == 0, &wb_req);
11137 tevent_req_set_callback(req, wbclient_done, &i);
11143 while (i < torture_nprocs * torture_numops) {
11144 tevent_loop_once(ev);
11153 static bool dbtrans_inc(struct db_context *db)
11155 struct db_record *rec;
11161 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11163 printf(__location__ "fetch_lock failed\n");
11167 value = dbwrap_record_get_value(rec);
11169 if (value.dsize != sizeof(uint32_t)) {
11170 printf(__location__ "value.dsize = %d\n",
11175 memcpy(&val, value.dptr, sizeof(val));
11178 status = dbwrap_record_store(
11179 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
11180 if (!NT_STATUS_IS_OK(status)) {
11181 printf(__location__ "store failed: %s\n",
11182 nt_errstr(status));
11192 static bool run_local_dbtrans(int dummy)
11194 struct db_context *db;
11195 struct db_record *rec;
11201 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
11202 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
11205 printf("Could not open transtest.db\n");
11209 res = dbwrap_transaction_start(db);
11211 printf(__location__ "transaction_start failed\n");
11215 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11217 printf(__location__ "fetch_lock failed\n");
11221 value = dbwrap_record_get_value(rec);
11223 if (value.dptr == NULL) {
11225 status = dbwrap_record_store(
11226 rec, make_tdb_data((uint8_t *)&initial,
11229 if (!NT_STATUS_IS_OK(status)) {
11230 printf(__location__ "store returned %s\n",
11231 nt_errstr(status));
11238 res = dbwrap_transaction_commit(db);
11240 printf(__location__ "transaction_commit failed\n");
11245 uint32_t val, val2;
11248 res = dbwrap_transaction_start(db);
11250 printf(__location__ "transaction_start failed\n");
11254 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
11255 if (!NT_STATUS_IS_OK(status)) {
11256 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11257 nt_errstr(status));
11261 for (i=0; i<10; i++) {
11262 if (!dbtrans_inc(db)) {
11267 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
11268 if (!NT_STATUS_IS_OK(status)) {
11269 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11270 nt_errstr(status));
11274 if (val2 != val + 10) {
11275 printf(__location__ "val=%d, val2=%d\n",
11276 (int)val, (int)val2);
11280 printf("val2=%d\r", val2);
11282 res = dbwrap_transaction_commit(db);
11284 printf(__location__ "transaction_commit failed\n");
11294 * Just a dummy test to be run under a debugger. There's no real way
11295 * to inspect the tevent_poll specific function from outside of
11299 static bool run_local_tevent_poll(int dummy)
11301 struct tevent_context *ev;
11302 struct tevent_fd *fd1, *fd2;
11303 bool result = false;
11305 ev = tevent_context_init_byname(NULL, "poll");
11307 d_fprintf(stderr, "tevent_context_init_byname failed\n");
11311 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
11313 d_fprintf(stderr, "tevent_add_fd failed\n");
11316 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
11318 d_fprintf(stderr, "tevent_add_fd failed\n");
11323 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
11325 d_fprintf(stderr, "tevent_add_fd failed\n");
11335 static bool run_local_hex_encode_buf(int dummy)
11341 for (i=0; i<sizeof(src); i++) {
11344 hex_encode_buf(buf, src, sizeof(src));
11345 if (strcmp(buf, "0001020304050607") != 0) {
11348 hex_encode_buf(buf, NULL, 0);
11349 if (buf[0] != '\0') {
11355 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11377 "1001:1111:1111:1000:0:1111:1111:1111",
11386 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11400 "1001:1111:1111:1000:0:1111:1111:1111"
11403 static bool run_local_remove_duplicate_addrs2(int dummy)
11405 struct ip_service test_vector[28];
11408 /* Construct the sockaddr_storage test vector. */
11409 for (i = 0; i < 28; i++) {
11410 struct addrinfo hints;
11411 struct addrinfo *res = NULL;
11414 memset(&hints, '\0', sizeof(hints));
11415 hints.ai_flags = AI_NUMERICHOST;
11416 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11421 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11422 remove_duplicate_addrs2_test_strings_vector[i]);
11425 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11426 memcpy(&test_vector[i].ss,
11432 count = remove_duplicate_addrs2(test_vector, i);
11435 fprintf(stderr, "count wrong (%d) should be 14\n",
11440 for (i = 0; i < count; i++) {
11441 char addr[INET6_ADDRSTRLEN];
11443 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11445 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11446 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11449 remove_duplicate_addrs2_test_strings_result[i]);
11454 printf("run_local_remove_duplicate_addrs2: success\n");
11458 static bool run_local_tdb_opener(int dummy)
11464 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11465 O_RDWR|O_CREAT, 0755);
11467 perror("tdb_open failed");
11478 static bool run_local_tdb_writer(int dummy)
11484 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11486 perror("tdb_open failed");
11490 val.dptr = (uint8_t *)&v;
11491 val.dsize = sizeof(v);
11497 ret = tdb_store(t, val, val, 0);
11499 printf("%s\n", tdb_errorstr(t));
11504 data = tdb_fetch(t, val);
11505 if (data.dptr != NULL) {
11506 SAFE_FREE(data.dptr);
11512 static bool run_local_canonicalize_path(int dummy)
11514 const char *src[] = {
11521 ".././././../../../boo",
11525 const char *dst[] = {
11538 for (i = 0; src[i] != NULL; i++) {
11539 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11541 perror("talloc fail\n");
11544 if (strcmp(d, dst[i]) != 0) {
11546 "canonicalize mismatch %s -> %s != %s",
11547 src[i], d, dst[i]);
11555 static bool run_ign_bad_negprot(int dummy)
11557 struct tevent_context *ev;
11558 struct tevent_req *req;
11559 struct smbXcli_conn *conn;
11560 struct sockaddr_storage ss;
11565 printf("starting ignore bad negprot\n");
11567 ok = resolve_name(host, &ss, 0x20, true);
11569 d_fprintf(stderr, "Could not resolve name %s\n", host);
11573 status = open_socket_out(&ss, 445, 10000, &fd);
11574 if (!NT_STATUS_IS_OK(status)) {
11575 d_fprintf(stderr, "open_socket_out failed: %s\n",
11576 nt_errstr(status));
11580 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11582 if (conn == NULL) {
11583 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11587 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11588 if (NT_STATUS_IS_OK(status)) {
11589 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11593 ev = samba_tevent_context_init(talloc_tos());
11595 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11599 req = smb1cli_session_setup_nt1_send(
11600 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11601 data_blob_null, data_blob_null, 0x40,
11602 "Windows 2000 2195", "Windows 2000 5.0");
11604 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11608 ok = tevent_req_poll_ntstatus(req, ev, &status);
11610 d_fprintf(stderr, "tevent_req_poll failed\n");
11614 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11616 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11617 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11618 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11619 nt_errstr(status));
11625 printf("starting ignore bad negprot\n");
11630 static double create_procs(bool (*fn)(int), bool *result)
11633 volatile pid_t *child_status;
11634 volatile bool *child_status_out;
11637 struct timeval start;
11641 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11642 if (!child_status) {
11643 printf("Failed to setup shared memory\n");
11647 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11648 if (!child_status_out) {
11649 printf("Failed to setup result status shared memory\n");
11653 for (i = 0; i < torture_nprocs; i++) {
11654 child_status[i] = 0;
11655 child_status_out[i] = True;
11658 start = timeval_current();
11660 for (i=0;i<torture_nprocs;i++) {
11663 pid_t mypid = getpid();
11664 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11666 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11669 if (torture_open_connection(¤t_cli, i)) break;
11670 if (tries-- == 0) {
11671 printf("pid %d failed to start\n", (int)getpid());
11677 child_status[i] = getpid();
11679 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11681 child_status_out[i] = fn(i);
11688 for (i=0;i<torture_nprocs;i++) {
11689 if (child_status[i]) synccount++;
11691 if (synccount == torture_nprocs) break;
11693 } while (timeval_elapsed(&start) < 30);
11695 if (synccount != torture_nprocs) {
11696 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11698 return timeval_elapsed(&start);
11701 /* start the client load */
11702 start = timeval_current();
11704 for (i=0;i<torture_nprocs;i++) {
11705 child_status[i] = 0;
11708 printf("%d clients started\n", torture_nprocs);
11710 for (i=0;i<torture_nprocs;i++) {
11711 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11716 for (i=0;i<torture_nprocs;i++) {
11717 if (!child_status_out[i]) {
11721 return timeval_elapsed(&start);
11724 #define FLAG_MULTIPROC 1
11730 } torture_ops[] = {
11733 .fn = run_fdpasstest,
11737 .fn = run_locktest1,
11741 .fn = run_locktest2,
11745 .fn = run_locktest3,
11749 .fn = run_locktest4,
11753 .fn = run_locktest5,
11757 .fn = run_locktest6,
11761 .fn = run_locktest7,
11765 .fn = run_locktest8,
11769 .fn = run_locktest9,
11773 .fn = run_unlinktest,
11777 .fn = run_browsetest,
11781 .fn = run_attrtest,
11785 .fn = run_trans2test,
11789 .fn = run_maxfidtest,
11790 .flags = FLAG_MULTIPROC,
11795 .flags = FLAG_MULTIPROC,
11798 .name = "RANDOMIPC",
11799 .fn = run_randomipc,
11802 .name = "NEGNOWAIT",
11803 .fn = run_negprot_nowait,
11831 .fn = run_dirtest1,
11834 .name = "DIR-CREATETIME",
11835 .fn = run_dir_createtime,
11839 .fn = torture_denytest1,
11843 .fn = torture_denytest2,
11847 .fn = run_tcon_test,
11851 .fn = run_tcon_devtype_test,
11855 .fn = run_readwritetest,
11859 .fn = run_readwritemulti,
11860 .flags = FLAG_MULTIPROC
11864 .fn = run_readwritelarge,
11867 .name = "RW-SIGNING",
11868 .fn = run_readwritelarge_signtest,
11872 .fn = run_opentest,
11876 .fn = run_simple_posix_open_test,
11879 .name = "POSIX-APPEND",
11880 .fn = run_posix_append,
11883 .name = "POSIX-SYMLINK-ACL",
11884 .fn = run_acl_symlink_test,
11887 .name = "POSIX-SYMLINK-EA",
11888 .fn = run_ea_symlink_test,
11891 .name = "POSIX-STREAM-DELETE",
11892 .fn = run_posix_stream_delete,
11895 .name = "POSIX-OFD-LOCK",
11896 .fn = run_posix_ofd_lock_test,
11899 .name = "WINDOWS-BAD-SYMLINK",
11900 .fn = run_symlink_open_test,
11903 .name = "CASE-INSENSITIVE-CREATE",
11904 .fn = run_case_insensitive_create,
11907 .name = "ASYNC-ECHO",
11908 .fn = run_async_echo,
11911 .name = "UID-REGRESSION-TEST",
11912 .fn = run_uid_regression_test,
11915 .name = "SHORTNAME-TEST",
11916 .fn = run_shortname_test,
11919 .name = "ADDRCHANGE",
11920 .fn = run_addrchange,
11924 .name = "OPENATTR",
11925 .fn = run_openattrtest,
11937 .name = "RENAME-ACCESS",
11938 .fn = run_rename_access,
11941 .name = "OWNER-RIGHTS",
11942 .fn = run_owner_rights,
11946 .fn = run_deletetest,
11949 .name = "DELETE-PRINT",
11950 .fn = run_delete_print_test,
11953 .name = "WILDDELETE",
11954 .fn = run_wild_deletetest,
11957 .name = "DELETE-LN",
11958 .fn = run_deletetest_ln,
11961 .name = "PROPERTIES",
11962 .fn = run_properties,
11966 .fn = torture_mangle,
11973 .name = "MANGLE-ILLEGAL",
11974 .fn = run_mangle_illegal,
11981 .name = "TRANS2SCAN",
11982 .fn = torture_trans2_scan,
11985 .name = "NTTRANSSCAN",
11986 .fn = torture_nttrans_scan,
11990 .fn = torture_utable,
11993 .name = "CASETABLE",
11994 .fn = torture_casetable,
11997 .name = "ERRMAPEXTRACT",
11998 .fn = run_error_map_extract,
12001 .name = "PIPE_NUMBER",
12002 .fn = run_pipe_number,
12006 .fn = run_tcon2_test,
12010 .fn = torture_ioctl_test,
12014 .fn = torture_chkpath_test,
12018 .fn = run_fdsesstest,
12025 .name = "SESSSETUP_BENCH",
12026 .fn = run_sesssetup_bench,
12041 .name = "WINDOWS-WRITE",
12042 .fn = run_windows_write,
12045 .name = "LARGE_READX",
12046 .fn = run_large_readx,
12049 .name = "NTTRANS-CREATE",
12050 .fn = run_nttrans_create,
12053 .name = "NTTRANS-FSCTL",
12054 .fn = run_nttrans_fsctl,
12057 .name = "CLI_ECHO",
12058 .fn = run_cli_echo,
12061 .name = "CLI_SPLICE",
12062 .fn = run_cli_splice,
12069 .name = "STREAMERROR",
12070 .fn = run_streamerror,
12073 .name = "NOTIFY-BENCH",
12074 .fn = run_notify_bench,
12077 .name = "NOTIFY-BENCH2",
12078 .fn = run_notify_bench2,
12081 .name = "NOTIFY-BENCH3",
12082 .fn = run_notify_bench3,
12085 .name = "BAD-NBT-SESSION",
12086 .fn = run_bad_nbt_session,
12089 .name = "IGN-BAD-NEGPROT",
12090 .fn = run_ign_bad_negprot,
12093 .name = "SMB-ANY-CONNECT",
12094 .fn = run_smb_any_connect,
12097 .name = "NOTIFY-ONLINE",
12098 .fn = run_notify_online,
12101 .name = "SMB2-BASIC",
12102 .fn = run_smb2_basic,
12105 .name = "SMB2-NEGPROT",
12106 .fn = run_smb2_negprot,
12109 .name = "SMB2-ANONYMOUS",
12110 .fn = run_smb2_anonymous,
12113 .name = "SMB2-SESSION-RECONNECT",
12114 .fn = run_smb2_session_reconnect,
12117 .name = "SMB2-TCON-DEPENDENCE",
12118 .fn = run_smb2_tcon_dependence,
12121 .name = "SMB2-MULTI-CHANNEL",
12122 .fn = run_smb2_multi_channel,
12125 .name = "SMB2-SESSION-REAUTH",
12126 .fn = run_smb2_session_reauth,
12129 .name = "SMB2-FTRUNCATE",
12130 .fn = run_smb2_ftruncate,
12133 .name = "SMB2-DIR-FSYNC",
12134 .fn = run_smb2_dir_fsync,
12137 .name = "CLEANUP1",
12138 .fn = run_cleanup1,
12141 .name = "CLEANUP2",
12142 .fn = run_cleanup2,
12145 .name = "CLEANUP3",
12146 .fn = run_cleanup3,
12149 .name = "CLEANUP4",
12150 .fn = run_cleanup4,
12153 .name = "OPLOCK-CANCEL",
12154 .fn = run_oplock_cancel,
12161 .name = "LOCAL-SUBSTITUTE",
12162 .fn = run_local_substitute,
12165 .name = "LOCAL-GENCACHE",
12166 .fn = run_local_gencache,
12169 .name = "LOCAL-DBWRAP-WATCH1",
12170 .fn = run_dbwrap_watch1,
12173 .name = "LOCAL-DBWRAP-WATCH2",
12174 .fn = run_dbwrap_watch2,
12177 .name = "LOCAL-DBWRAP-DO-LOCKED1",
12178 .fn = run_dbwrap_do_locked1,
12181 .name = "LOCAL-MESSAGING-READ1",
12182 .fn = run_messaging_read1,
12185 .name = "LOCAL-MESSAGING-READ2",
12186 .fn = run_messaging_read2,
12189 .name = "LOCAL-MESSAGING-READ3",
12190 .fn = run_messaging_read3,
12193 .name = "LOCAL-MESSAGING-READ4",
12194 .fn = run_messaging_read4,
12197 .name = "LOCAL-MESSAGING-FDPASS1",
12198 .fn = run_messaging_fdpass1,
12201 .name = "LOCAL-MESSAGING-FDPASS2",
12202 .fn = run_messaging_fdpass2,
12205 .name = "LOCAL-MESSAGING-FDPASS2a",
12206 .fn = run_messaging_fdpass2a,
12209 .name = "LOCAL-MESSAGING-FDPASS2b",
12210 .fn = run_messaging_fdpass2b,
12213 .name = "LOCAL-MESSAGING-SEND-ALL",
12214 .fn = run_messaging_send_all,
12217 .name = "LOCAL-BASE64",
12218 .fn = run_local_base64,
12221 .name = "LOCAL-RBTREE",
12222 .fn = run_local_rbtree,
12225 .name = "LOCAL-MEMCACHE",
12226 .fn = run_local_memcache,
12229 .name = "LOCAL-STREAM-NAME",
12230 .fn = run_local_stream_name,
12233 .name = "WBCLIENT-MULTI-PING",
12234 .fn = run_wbclient_multi_ping,
12237 .name = "LOCAL-string_to_sid",
12238 .fn = run_local_string_to_sid,
12241 .name = "LOCAL-sid_to_string",
12242 .fn = run_local_sid_to_string,
12245 .name = "LOCAL-binary_to_sid",
12246 .fn = run_local_binary_to_sid,
12249 .name = "LOCAL-DBTRANS",
12250 .fn = run_local_dbtrans,
12253 .name = "LOCAL-TEVENT-POLL",
12254 .fn = run_local_tevent_poll,
12257 .name = "LOCAL-CONVERT-STRING",
12258 .fn = run_local_convert_string,
12261 .name = "LOCAL-CONV-AUTH-INFO",
12262 .fn = run_local_conv_auth_info,
12265 .name = "LOCAL-hex_encode_buf",
12266 .fn = run_local_hex_encode_buf,
12269 .name = "LOCAL-IDMAP-TDB-COMMON",
12270 .fn = run_idmap_tdb_common_test,
12273 .name = "LOCAL-remove_duplicate_addrs2",
12274 .fn = run_local_remove_duplicate_addrs2,
12277 .name = "local-tdb-opener",
12278 .fn = run_local_tdb_opener,
12281 .name = "local-tdb-writer",
12282 .fn = run_local_tdb_writer,
12285 .name = "LOCAL-DBWRAP-CTDB",
12286 .fn = run_local_dbwrap_ctdb,
12289 .name = "LOCAL-BENCH-PTHREADPOOL",
12290 .fn = run_bench_pthreadpool,
12293 .name = "LOCAL-PTHREADPOOL-TEVENT",
12294 .fn = run_pthreadpool_tevent,
12297 .name = "LOCAL-G-LOCK1",
12301 .name = "LOCAL-G-LOCK2",
12305 .name = "LOCAL-G-LOCK3",
12309 .name = "LOCAL-G-LOCK4",
12313 .name = "LOCAL-G-LOCK5",
12317 .name = "LOCAL-G-LOCK6",
12321 .name = "LOCAL-G-LOCK-PING-PONG",
12322 .fn = run_g_lock_ping_pong,
12325 .name = "LOCAL-CANONICALIZE-PATH",
12326 .fn = run_local_canonicalize_path,
12329 .name = "LOCAL-NAMEMAP-CACHE1",
12330 .fn = run_local_namemap_cache1,
12333 .name = "qpathinfo-bufsize",
12334 .fn = run_qpathinfo_bufsize,
12337 .name = "hide-new-files-timeout",
12338 .fn = run_hidenewfiles,
12345 /****************************************************************************
12346 run a specified test or "ALL"
12347 ****************************************************************************/
12348 static bool run_test(const char *name)
12351 bool result = True;
12352 bool found = False;
12355 if (strequal(name,"ALL")) {
12356 for (i=0;torture_ops[i].name;i++) {
12357 run_test(torture_ops[i].name);
12362 for (i=0;torture_ops[i].name;i++) {
12363 fstr_sprintf(randomfname, "\\XX%x",
12364 (unsigned)random());
12366 if (strequal(name, torture_ops[i].name)) {
12368 printf("Running %s\n", name);
12369 if (torture_ops[i].flags & FLAG_MULTIPROC) {
12370 t = create_procs(torture_ops[i].fn, &result);
12373 printf("TEST %s FAILED!\n", name);
12376 struct timeval start;
12377 start = timeval_current();
12378 if (!torture_ops[i].fn(0)) {
12380 printf("TEST %s FAILED!\n", name);
12382 t = timeval_elapsed(&start);
12384 printf("%s took %g secs\n\n", name, t);
12389 printf("Did not find a test named %s\n", name);
12397 static void usage(void)
12401 printf("WARNING samba4 test suite is much more complete nowadays.\n");
12402 printf("Please use samba4 torture.\n\n");
12404 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
12406 printf("\t-d debuglevel\n");
12407 printf("\t-U user%%pass\n");
12408 printf("\t-k use kerberos\n");
12409 printf("\t-N numprocs\n");
12410 printf("\t-n my_netbios_name\n");
12411 printf("\t-W workgroup\n");
12412 printf("\t-o num_operations\n");
12413 printf("\t-O socket_options\n");
12414 printf("\t-m maximum protocol\n");
12415 printf("\t-L use oplocks\n");
12416 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
12417 printf("\t-A showall\n");
12418 printf("\t-p port\n");
12419 printf("\t-s seed\n");
12420 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
12421 printf("\t-f filename filename to test\n");
12422 printf("\t-e encrypt\n");
12425 printf("tests are:");
12426 for (i=0;torture_ops[i].name;i++) {
12427 printf(" %s", torture_ops[i].name);
12431 printf("default test is ALL\n");
12436 /****************************************************************************
12438 ****************************************************************************/
12439 int main(int argc,char *argv[])
12445 bool correct = True;
12446 TALLOC_CTX *frame = talloc_stackframe();
12447 int seed = time(NULL);
12449 #ifdef HAVE_SETBUFFER
12450 setbuffer(stdout, NULL, 0);
12453 setup_logging("smbtorture", DEBUG_STDOUT);
12458 if (is_default_dyn_CONFIGFILE()) {
12459 if(getenv("SMB_CONF_PATH")) {
12460 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
12463 lp_load_global(get_dyn_CONFIGFILE());
12470 for(p = argv[1]; *p; p++)
12474 if (strncmp(argv[1], "//", 2)) {
12478 fstrcpy(host, &argv[1][2]);
12479 p = strchr_m(&host[2],'/');
12484 fstrcpy(share, p+1);
12486 fstrcpy(myname, get_myname(talloc_tos()));
12488 fprintf(stderr, "Failed to get my hostname.\n");
12492 if (*username == 0 && getenv("LOGNAME")) {
12493 fstrcpy(username,getenv("LOGNAME"));
12499 fstrcpy(workgroup, lp_workgroup());
12501 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
12505 port_to_use = atoi(optarg);
12508 seed = atoi(optarg);
12511 fstrcpy(workgroup,optarg);
12514 lp_set_cmdline("client max protocol", optarg);
12517 torture_nprocs = atoi(optarg);
12520 torture_numops = atoi(optarg);
12523 lp_set_cmdline("log level", optarg);
12529 use_oplocks = True;
12532 local_path = optarg;
12535 torture_showall = True;
12538 fstrcpy(myname, optarg);
12541 client_txt = optarg;
12548 use_kerberos = True;
12550 d_printf("No kerberos support compiled in\n");
12556 fstrcpy(username,optarg);
12557 p = strchr_m(username,'%');
12560 fstrcpy(password, p+1);
12565 fstrcpy(multishare_conn_fname, optarg);
12566 use_multishare_conn = True;
12569 torture_blocksize = atoi(optarg);
12572 test_filename = SMB_STRDUP(optarg);
12575 printf("Unknown option %c (%d)\n", (char)opt, opt);
12580 d_printf("using seed %d\n", seed);
12584 if(use_kerberos && !gotuser) gotpass = True;
12587 char pwd[256] = {0};
12590 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
12592 fstrcpy(password, pwd);
12597 printf("host=%s share=%s user=%s myname=%s\n",
12598 host, share, username, myname);
12600 torture_creds = cli_session_creds_init(frame,
12606 false, /* fallback_after_kerberos */
12607 false, /* use_ccache */
12608 false); /* password_is_nt_hash */
12609 if (torture_creds == NULL) {
12610 d_printf("cli_session_creds_init() failed.\n");
12614 if (argc == optind) {
12615 correct = run_test("ALL");
12617 for (i=optind;i<argc;i++) {
12618 if (!run_test(argv[i])) {
12624 TALLOC_FREE(frame);