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)) {
7260 Test POSIX mkdir is case-sensitive.
7262 static bool run_posix_mkdir_test(int dummy)
7264 static struct cli_state *cli;
7265 const char *fname_foo = "POSIX_foo";
7266 const char *fname_foo_Foo = "POSIX_foo/Foo";
7267 const char *fname_foo_foo = "POSIX_foo/foo";
7268 const char *fname_Foo = "POSIX_Foo";
7269 const char *fname_Foo_Foo = "POSIX_Foo/Foo";
7270 const char *fname_Foo_foo = "POSIX_Foo/foo";
7271 bool correct = false;
7273 TALLOC_CTX *frame = NULL;
7274 uint16_t fnum = (uint16_t)-1;
7276 frame = talloc_stackframe();
7278 printf("Starting POSIX mkdir test\n");
7280 if (!torture_open_connection(&cli, 0)) {
7285 smbXcli_conn_set_sockopt(cli->conn, sockops);
7287 status = torture_setup_unix_extensions(cli);
7288 if (!NT_STATUS_IS_OK(status)) {
7293 cli_posix_rmdir(cli, fname_foo_foo);
7294 cli_posix_rmdir(cli, fname_foo_Foo);
7295 cli_posix_rmdir(cli, fname_foo);
7297 cli_posix_rmdir(cli, fname_Foo_foo);
7298 cli_posix_rmdir(cli, fname_Foo_Foo);
7299 cli_posix_rmdir(cli, fname_Foo);
7302 * Create a file POSIX_foo then try
7303 * and use it in a directory path by
7304 * doing mkdir POSIX_foo/bar.
7305 * The mkdir should fail with
7306 * NT_STATUS_OBJECT_PATH_NOT_FOUND
7309 status = cli_posix_open(cli,
7314 if (!NT_STATUS_IS_OK(status)) {
7315 printf("cli_posix_open of %s failed error %s\n",
7321 status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
7322 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
7323 printf("cli_posix_mkdir of %s should fail with "
7324 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
7331 status = cli_close(cli, fnum);
7332 if (!NT_STATUS_IS_OK(status)) {
7333 printf("cli_close failed %s\n", nt_errstr(status));
7336 fnum = (uint16_t)-1;
7338 status = cli_posix_unlink(cli, fname_foo);
7339 if (!NT_STATUS_IS_OK(status)) {
7340 printf("cli_posix_unlink of %s failed error %s\n",
7347 * Now we've deleted everything, posix_mkdir, posix_rmdir,
7348 * posix_open, posix_unlink, on
7349 * POSIX_foo/foo should return NT_STATUS_OBJECT_PATH_NOT_FOUND
7350 * not silently create POSIX_foo/foo.
7353 status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
7354 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
7355 printf("cli_posix_mkdir of %s should fail with "
7356 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
7363 status = cli_posix_rmdir(cli, fname_foo_foo);
7364 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
7365 printf("cli_posix_rmdir of %s should fail with "
7366 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
7373 status = cli_posix_open(cli,
7378 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
7379 printf("cli_posix_open of %s should fail with "
7380 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
7387 status = cli_posix_unlink(cli, fname_foo_foo);
7388 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
7389 printf("cli_posix_unlink of %s should fail with "
7390 "NT_STATUS_OBJECT_PATH_NOT_FOUND got "
7397 status = cli_posix_mkdir(cli, fname_foo, 0777);
7398 if (!NT_STATUS_IS_OK(status)) {
7399 printf("cli_posix_mkdir of %s failed\n", fname_foo);
7403 status = cli_posix_mkdir(cli, fname_Foo, 0777);
7404 if (!NT_STATUS_IS_OK(status)) {
7405 printf("cli_posix_mkdir of %s failed\n", fname_Foo);
7409 status = cli_posix_mkdir(cli, fname_foo_foo, 0777);
7410 if (!NT_STATUS_IS_OK(status)) {
7411 printf("cli_posix_mkdir of %s failed\n", fname_foo_foo);
7415 status = cli_posix_mkdir(cli, fname_foo_Foo, 0777);
7416 if (!NT_STATUS_IS_OK(status)) {
7417 printf("cli_posix_mkdir of %s failed\n", fname_foo_Foo);
7421 status = cli_posix_mkdir(cli, fname_Foo_foo, 0777);
7422 if (!NT_STATUS_IS_OK(status)) {
7423 printf("cli_posix_mkdir of %s failed\n", fname_Foo_foo);
7427 status = cli_posix_mkdir(cli, fname_Foo_Foo, 0777);
7428 if (!NT_STATUS_IS_OK(status)) {
7429 printf("cli_posix_mkdir of %s failed\n", fname_Foo_Foo);
7433 printf("POSIX mkdir test passed\n");
7438 if (fnum != (uint16_t)-1) {
7439 cli_close(cli, fnum);
7440 fnum = (uint16_t)-1;
7443 cli_posix_rmdir(cli, fname_foo_foo);
7444 cli_posix_rmdir(cli, fname_foo_Foo);
7445 cli_posix_rmdir(cli, fname_foo);
7447 cli_posix_rmdir(cli, fname_Foo_foo);
7448 cli_posix_rmdir(cli, fname_Foo_Foo);
7449 cli_posix_rmdir(cli, fname_Foo);
7451 if (!torture_close_connection(cli)) {
7460 static uint32_t open_attrs_table[] = {
7461 FILE_ATTRIBUTE_NORMAL,
7462 FILE_ATTRIBUTE_ARCHIVE,
7463 FILE_ATTRIBUTE_READONLY,
7464 FILE_ATTRIBUTE_HIDDEN,
7465 FILE_ATTRIBUTE_SYSTEM,
7467 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7468 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7469 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7470 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7471 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7472 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7474 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7475 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7476 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7477 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7480 struct trunc_open_results {
7483 uint32_t trunc_attr;
7484 uint32_t result_attr;
7487 static struct trunc_open_results attr_results[] = {
7488 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7489 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7490 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7491 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7492 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7493 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7494 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7495 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7496 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7497 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7498 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7499 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7500 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7501 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7502 { 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 },
7503 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7504 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7505 { 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 },
7506 { 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 },
7507 { 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 },
7508 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7509 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7510 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7511 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7512 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7513 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7516 static bool run_openattrtest(int dummy)
7518 static struct cli_state *cli1;
7519 const char *fname = "\\openattr.file";
7521 bool correct = True;
7523 unsigned int i, j, k, l;
7526 printf("starting open attr test\n");
7528 if (!torture_open_connection(&cli1, 0)) {
7532 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7534 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7535 cli_setatr(cli1, fname, 0, 0);
7536 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7538 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7539 open_attrs_table[i], FILE_SHARE_NONE,
7540 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7541 if (!NT_STATUS_IS_OK(status)) {
7542 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7546 status = cli_close(cli1, fnum1);
7547 if (!NT_STATUS_IS_OK(status)) {
7548 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7552 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7553 status = cli_ntcreate(cli1, fname, 0,
7554 FILE_READ_DATA|FILE_WRITE_DATA,
7555 open_attrs_table[j],
7556 FILE_SHARE_NONE, FILE_OVERWRITE,
7557 0, 0, &fnum1, NULL);
7558 if (!NT_STATUS_IS_OK(status)) {
7559 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7560 if (attr_results[l].num == k) {
7561 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7562 k, open_attrs_table[i],
7563 open_attrs_table[j],
7564 fname, NT_STATUS_V(status), nt_errstr(status));
7569 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7570 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7571 k, open_attrs_table[i], open_attrs_table[j],
7576 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7582 status = cli_close(cli1, fnum1);
7583 if (!NT_STATUS_IS_OK(status)) {
7584 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7588 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7589 if (!NT_STATUS_IS_OK(status)) {
7590 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7595 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7596 k, open_attrs_table[i], open_attrs_table[j], attr );
7599 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7600 if (attr_results[l].num == k) {
7601 if (attr != attr_results[l].result_attr ||
7602 open_attrs_table[i] != attr_results[l].init_attr ||
7603 open_attrs_table[j] != attr_results[l].trunc_attr) {
7604 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7605 open_attrs_table[i],
7606 open_attrs_table[j],
7608 attr_results[l].result_attr);
7618 cli_setatr(cli1, fname, 0, 0);
7619 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7621 printf("open attr test %s.\n", correct ? "passed" : "failed");
7623 if (!torture_close_connection(cli1)) {
7629 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7630 const char *name, void *state)
7632 int *matched = (int *)state;
7633 if (matched != NULL) {
7636 return NT_STATUS_OK;
7640 test directory listing speed
7642 static bool run_dirtest(int dummy)
7645 static struct cli_state *cli;
7647 struct timeval core_start;
7648 bool correct = True;
7651 printf("starting directory test\n");
7653 if (!torture_open_connection(&cli, 0)) {
7657 smbXcli_conn_set_sockopt(cli->conn, sockops);
7660 for (i=0;i<torture_numops;i++) {
7662 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7663 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7664 fprintf(stderr,"Failed to open %s\n", fname);
7667 cli_close(cli, fnum);
7670 core_start = timeval_current();
7673 cli_list(cli, "a*.*", 0, list_fn, &matched);
7674 printf("Matched %d\n", matched);
7677 cli_list(cli, "b*.*", 0, list_fn, &matched);
7678 printf("Matched %d\n", matched);
7681 cli_list(cli, "xyzabc", 0, list_fn, &matched);
7682 printf("Matched %d\n", matched);
7684 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7687 for (i=0;i<torture_numops;i++) {
7689 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7690 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7693 if (!torture_close_connection(cli)) {
7697 printf("finished dirtest\n");
7702 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7705 struct cli_state *pcli = (struct cli_state *)state;
7707 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7709 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7710 return NT_STATUS_OK;
7712 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7713 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7714 printf("del_fn: failed to rmdir %s\n,", fname );
7716 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7717 printf("del_fn: failed to unlink %s\n,", fname );
7719 return NT_STATUS_OK;
7724 sees what IOCTLs are supported
7726 bool torture_ioctl_test(int dummy)
7728 static struct cli_state *cli;
7729 uint16_t device, function;
7731 const char *fname = "\\ioctl.dat";
7735 if (!torture_open_connection(&cli, 0)) {
7739 printf("starting ioctl test\n");
7741 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7743 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7744 if (!NT_STATUS_IS_OK(status)) {
7745 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7749 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7750 printf("ioctl device info: %s\n", nt_errstr(status));
7752 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7753 printf("ioctl job info: %s\n", nt_errstr(status));
7755 for (device=0;device<0x100;device++) {
7756 printf("ioctl test with device = 0x%x\n", device);
7757 for (function=0;function<0x100;function++) {
7758 uint32_t code = (device<<16) | function;
7760 status = cli_raw_ioctl(cli, fnum, code, &blob);
7762 if (NT_STATUS_IS_OK(status)) {
7763 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7765 data_blob_free(&blob);
7770 if (!torture_close_connection(cli)) {
7779 tries varients of chkpath
7781 bool torture_chkpath_test(int dummy)
7783 static struct cli_state *cli;
7788 if (!torture_open_connection(&cli, 0)) {
7792 printf("starting chkpath test\n");
7794 /* cleanup from an old run */
7795 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7796 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7797 cli_rmdir(cli, "\\chkpath.dir");
7799 status = cli_mkdir(cli, "\\chkpath.dir");
7800 if (!NT_STATUS_IS_OK(status)) {
7801 printf("mkdir1 failed : %s\n", nt_errstr(status));
7805 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7806 if (!NT_STATUS_IS_OK(status)) {
7807 printf("mkdir2 failed : %s\n", nt_errstr(status));
7811 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7813 if (!NT_STATUS_IS_OK(status)) {
7814 printf("open1 failed (%s)\n", nt_errstr(status));
7817 cli_close(cli, fnum);
7819 status = cli_chkpath(cli, "\\chkpath.dir");
7820 if (!NT_STATUS_IS_OK(status)) {
7821 printf("chkpath1 failed: %s\n", nt_errstr(status));
7825 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7826 if (!NT_STATUS_IS_OK(status)) {
7827 printf("chkpath2 failed: %s\n", nt_errstr(status));
7831 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7832 if (!NT_STATUS_IS_OK(status)) {
7833 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7834 NT_STATUS_NOT_A_DIRECTORY);
7836 printf("* chkpath on a file should fail\n");
7840 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7841 if (!NT_STATUS_IS_OK(status)) {
7842 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7843 NT_STATUS_OBJECT_NAME_NOT_FOUND);
7845 printf("* chkpath on a non existent file should fail\n");
7849 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7850 if (!NT_STATUS_IS_OK(status)) {
7851 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7852 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7854 printf("* chkpath on a non existent component should fail\n");
7858 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7859 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7860 cli_rmdir(cli, "\\chkpath.dir");
7862 if (!torture_close_connection(cli)) {
7869 static bool run_eatest(int dummy)
7871 static struct cli_state *cli;
7872 const char *fname = "\\eatest.txt";
7873 bool correct = True;
7877 struct ea_struct *ea_list = NULL;
7878 TALLOC_CTX *mem_ctx = talloc_init("eatest");
7881 printf("starting eatest\n");
7883 if (!torture_open_connection(&cli, 0)) {
7884 talloc_destroy(mem_ctx);
7888 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7890 status = cli_ntcreate(cli, fname, 0,
7891 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7892 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7893 0x4044, 0, &fnum, NULL);
7894 if (!NT_STATUS_IS_OK(status)) {
7895 printf("open failed - %s\n", nt_errstr(status));
7896 talloc_destroy(mem_ctx);
7900 for (i = 0; i < 10; i++) {
7901 fstring ea_name, ea_val;
7903 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7904 memset(ea_val, (char)i+1, i+1);
7905 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7906 if (!NT_STATUS_IS_OK(status)) {
7907 printf("ea_set of name %s failed - %s\n", ea_name,
7909 talloc_destroy(mem_ctx);
7914 cli_close(cli, fnum);
7915 for (i = 0; i < 10; i++) {
7916 fstring ea_name, ea_val;
7918 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7919 memset(ea_val, (char)i+1, i+1);
7920 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7921 if (!NT_STATUS_IS_OK(status)) {
7922 printf("ea_set of name %s failed - %s\n", ea_name,
7924 talloc_destroy(mem_ctx);
7929 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7930 if (!NT_STATUS_IS_OK(status)) {
7931 printf("ea_get list failed - %s\n", nt_errstr(status));
7935 printf("num_eas = %d\n", (int)num_eas);
7937 if (num_eas != 20) {
7938 printf("Should be 20 EA's stored... failing.\n");
7942 for (i = 0; i < num_eas; i++) {
7943 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7944 dump_data(0, ea_list[i].value.data,
7945 ea_list[i].value.length);
7948 /* Setting EA's to zero length deletes them. Test this */
7949 printf("Now deleting all EA's - case indepenent....\n");
7952 cli_set_ea_path(cli, fname, "", "", 0);
7954 for (i = 0; i < 20; i++) {
7956 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7957 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7958 if (!NT_STATUS_IS_OK(status)) {
7959 printf("ea_set of name %s failed - %s\n", ea_name,
7961 talloc_destroy(mem_ctx);
7967 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7968 if (!NT_STATUS_IS_OK(status)) {
7969 printf("ea_get list failed - %s\n", nt_errstr(status));
7973 printf("num_eas = %d\n", (int)num_eas);
7974 for (i = 0; i < num_eas; i++) {
7975 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7976 dump_data(0, ea_list[i].value.data,
7977 ea_list[i].value.length);
7981 printf("deleting EA's failed.\n");
7985 /* Try and delete a non existent EA. */
7986 status = cli_set_ea_path(cli, fname, "foo", "", 0);
7987 if (!NT_STATUS_IS_OK(status)) {
7988 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7993 talloc_destroy(mem_ctx);
7994 if (!torture_close_connection(cli)) {
8001 static bool run_dirtest1(int dummy)
8004 static struct cli_state *cli;
8007 bool correct = True;
8009 printf("starting directory test\n");
8011 if (!torture_open_connection(&cli, 0)) {
8015 smbXcli_conn_set_sockopt(cli->conn, sockops);
8017 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
8018 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
8019 cli_rmdir(cli, "\\LISTDIR");
8020 cli_mkdir(cli, "\\LISTDIR");
8022 /* Create 1000 files and 1000 directories. */
8023 for (i=0;i<1000;i++) {
8025 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
8026 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
8027 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
8028 0, 0, &fnum, NULL))) {
8029 fprintf(stderr,"Failed to open %s\n", fname);
8032 cli_close(cli, fnum);
8034 for (i=0;i<1000;i++) {
8036 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
8037 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
8038 fprintf(stderr,"Failed to open %s\n", fname);
8043 /* Now ensure that doing an old list sees both files and directories. */
8045 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
8046 printf("num_seen = %d\n", num_seen );
8047 /* We should see 100 files + 1000 directories + . and .. */
8048 if (num_seen != 2002)
8051 /* Ensure if we have the "must have" bits we only see the
8055 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
8056 printf("num_seen = %d\n", num_seen );
8057 if (num_seen != 1002)
8061 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
8062 printf("num_seen = %d\n", num_seen );
8063 if (num_seen != 1000)
8066 /* Delete everything. */
8067 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
8068 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
8069 cli_rmdir(cli, "\\LISTDIR");
8072 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
8073 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
8074 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
8077 if (!torture_close_connection(cli)) {
8081 printf("finished dirtest1\n");
8086 static bool run_error_map_extract(int dummy) {
8088 static struct cli_state *c_dos;
8089 static struct cli_state *c_nt;
8101 /* NT-Error connection */
8103 disable_spnego = true;
8104 if (!(c_nt = open_nbt_connection())) {
8105 disable_spnego = false;
8108 disable_spnego = false;
8110 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
8113 if (!NT_STATUS_IS_OK(status)) {
8114 printf("%s rejected the NT-error negprot (%s)\n", host,
8120 status = cli_session_setup_anon(c_nt);
8121 if (!NT_STATUS_IS_OK(status)) {
8122 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
8126 /* DOS-Error connection */
8128 disable_spnego = true;
8129 force_dos_errors = true;
8130 if (!(c_dos = open_nbt_connection())) {
8131 disable_spnego = false;
8132 force_dos_errors = false;
8135 disable_spnego = false;
8136 force_dos_errors = false;
8138 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
8140 if (!NT_STATUS_IS_OK(status)) {
8141 printf("%s rejected the DOS-error negprot (%s)\n", host,
8143 cli_shutdown(c_dos);
8147 status = cli_session_setup_anon(c_dos);
8148 if (!NT_STATUS_IS_OK(status)) {
8149 printf("%s rejected the DOS-error initial session setup (%s)\n",
8150 host, nt_errstr(status));
8154 c_nt->map_dos_errors = false;
8155 c_dos->map_dos_errors = false;
8157 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
8158 struct cli_credentials *user_creds = NULL;
8160 fstr_sprintf(user, "%X", error);
8162 user_creds = cli_session_creds_init(talloc_tos(),
8167 false, /* use_kerberos */
8168 false, /* fallback_after_kerberos */
8169 false, /* use_ccache */
8170 false); /* password_is_nt_hash */
8171 if (user_creds == NULL) {
8172 printf("cli_session_creds_init(%s) failed\n", user);
8176 status = cli_session_setup_creds(c_nt, user_creds);
8177 if (NT_STATUS_IS_OK(status)) {
8178 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
8181 /* Case #1: 32-bit NT errors */
8182 if (!NT_STATUS_IS_DOS(status)) {
8185 printf("/** Dos error on NT connection! (%s) */\n",
8187 nt_status = NT_STATUS(0xc0000000);
8190 status = cli_session_setup_creds(c_dos, user_creds);
8191 if (NT_STATUS_IS_OK(status)) {
8192 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
8195 /* Case #1: 32-bit NT errors */
8196 if (NT_STATUS_IS_DOS(status)) {
8197 printf("/** NT error on DOS connection! (%s) */\n",
8199 errnum = errclass = 0;
8201 errclass = NT_STATUS_DOS_CLASS(status);
8202 errnum = NT_STATUS_DOS_CODE(status);
8205 if (NT_STATUS_V(nt_status) != error) {
8206 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
8207 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
8208 get_nt_error_c_code(talloc_tos(), nt_status));
8211 printf("\t{%s,\t%s,\t%s},\n",
8212 smb_dos_err_class(errclass),
8213 smb_dos_err_name(errclass, errnum),
8214 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
8216 TALLOC_FREE(user_creds);
8221 static bool run_sesssetup_bench(int dummy)
8223 static struct cli_state *c;
8224 const char *fname = "\\file.dat";
8229 if (!torture_open_connection(&c, 0)) {
8233 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8234 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8235 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
8236 if (!NT_STATUS_IS_OK(status)) {
8237 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8241 for (i=0; i<torture_numops; i++) {
8242 status = cli_session_setup_creds(c, torture_creds);
8243 if (!NT_STATUS_IS_OK(status)) {
8244 d_printf("(%s) cli_session_setup_creds failed: %s\n",
8245 __location__, nt_errstr(status));
8249 d_printf("\r%d ", (int)cli_state_get_uid(c));
8251 status = cli_ulogoff(c);
8252 if (!NT_STATUS_IS_OK(status)) {
8253 d_printf("(%s) cli_ulogoff failed: %s\n",
8254 __location__, nt_errstr(status));
8262 static bool subst_test(const char *str, const char *user, const char *domain,
8263 uid_t uid, gid_t gid, const char *expected)
8268 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
8270 if (strcmp(subst, expected) != 0) {
8271 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
8272 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
8281 static void chain1_open_completion(struct tevent_req *req)
8285 status = cli_openx_recv(req, &fnum);
8288 d_printf("cli_openx_recv returned %s: %d\n",
8290 NT_STATUS_IS_OK(status) ? fnum : -1);
8293 static void chain1_write_completion(struct tevent_req *req)
8297 status = cli_write_andx_recv(req, &written);
8300 d_printf("cli_write_andx_recv returned %s: %d\n",
8302 NT_STATUS_IS_OK(status) ? (int)written : -1);
8305 static void chain1_close_completion(struct tevent_req *req)
8308 bool *done = (bool *)tevent_req_callback_data_void(req);
8310 status = cli_close_recv(req);
8315 d_printf("cli_close returned %s\n", nt_errstr(status));
8318 static bool run_chain1(int dummy)
8320 struct cli_state *cli1;
8321 struct tevent_context *evt = samba_tevent_context_init(NULL);
8322 struct tevent_req *reqs[3], *smbreqs[3];
8324 const char *str = "foobar";
8325 const char *fname = "\\test_chain";
8328 printf("starting chain1 test\n");
8329 if (!torture_open_connection(&cli1, 0)) {
8333 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8335 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8337 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, fname,
8338 O_CREAT|O_RDWR, 0, &smbreqs[0]);
8339 if (reqs[0] == NULL) return false;
8340 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
8343 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
8344 (const uint8_t *)str, 0, strlen(str)+1,
8345 smbreqs, 1, &smbreqs[1]);
8346 if (reqs[1] == NULL) return false;
8347 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
8349 reqs[2] = cli_smb1_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
8350 if (reqs[2] == NULL) return false;
8351 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
8353 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8354 if (!NT_STATUS_IS_OK(status)) {
8359 tevent_loop_once(evt);
8362 torture_close_connection(cli1);
8366 static void chain2_sesssetup_completion(struct tevent_req *req)
8369 status = cli_session_setup_guest_recv(req);
8370 d_printf("sesssetup returned %s\n", nt_errstr(status));
8373 static void chain2_tcon_completion(struct tevent_req *req)
8375 bool *done = (bool *)tevent_req_callback_data_void(req);
8377 status = cli_tcon_andx_recv(req);
8378 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
8382 static bool run_chain2(int dummy)
8384 struct cli_state *cli1;
8385 struct tevent_context *evt = samba_tevent_context_init(NULL);
8386 struct tevent_req *reqs[2], *smbreqs[2];
8389 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
8391 printf("starting chain2 test\n");
8392 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
8393 port_to_use, SMB_SIGNING_DEFAULT, flags);
8394 if (!NT_STATUS_IS_OK(status)) {
8398 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8400 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
8402 if (reqs[0] == NULL) return false;
8403 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
8405 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
8406 "?????", NULL, 0, &smbreqs[1]);
8407 if (reqs[1] == NULL) return false;
8408 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
8410 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8411 if (!NT_STATUS_IS_OK(status)) {
8416 tevent_loop_once(evt);
8419 torture_close_connection(cli1);
8424 struct torture_createdel_state {
8425 struct tevent_context *ev;
8426 struct cli_state *cli;
8429 static void torture_createdel_created(struct tevent_req *subreq);
8430 static void torture_createdel_closed(struct tevent_req *subreq);
8432 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8433 struct tevent_context *ev,
8434 struct cli_state *cli,
8437 struct tevent_req *req, *subreq;
8438 struct torture_createdel_state *state;
8440 req = tevent_req_create(mem_ctx, &state,
8441 struct torture_createdel_state);
8448 subreq = cli_ntcreate_send(
8449 state, ev, cli, name, 0,
8450 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8451 FILE_ATTRIBUTE_NORMAL,
8452 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8453 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE,
8454 SMB2_IMPERSONATION_IMPERSONATION, 0);
8456 if (tevent_req_nomem(subreq, req)) {
8457 return tevent_req_post(req, ev);
8459 tevent_req_set_callback(subreq, torture_createdel_created, req);
8463 static void torture_createdel_created(struct tevent_req *subreq)
8465 struct tevent_req *req = tevent_req_callback_data(
8466 subreq, struct tevent_req);
8467 struct torture_createdel_state *state = tevent_req_data(
8468 req, struct torture_createdel_state);
8472 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8473 TALLOC_FREE(subreq);
8474 if (tevent_req_nterror(req, status)) {
8475 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8476 nt_errstr(status)));
8480 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8481 if (tevent_req_nomem(subreq, req)) {
8484 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8487 static void torture_createdel_closed(struct tevent_req *subreq)
8489 struct tevent_req *req = tevent_req_callback_data(
8490 subreq, struct tevent_req);
8493 status = cli_close_recv(subreq);
8494 if (tevent_req_nterror(req, status)) {
8495 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8498 tevent_req_done(req);
8501 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8503 return tevent_req_simple_recv_ntstatus(req);
8506 struct torture_createdels_state {
8507 struct tevent_context *ev;
8508 struct cli_state *cli;
8509 const char *base_name;
8513 struct tevent_req **reqs;
8516 static void torture_createdels_done(struct tevent_req *subreq);
8518 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8519 struct tevent_context *ev,
8520 struct cli_state *cli,
8521 const char *base_name,
8525 struct tevent_req *req;
8526 struct torture_createdels_state *state;
8529 req = tevent_req_create(mem_ctx, &state,
8530 struct torture_createdels_state);
8536 state->base_name = talloc_strdup(state, base_name);
8537 if (tevent_req_nomem(state->base_name, req)) {
8538 return tevent_req_post(req, ev);
8540 state->num_files = MAX(num_parallel, num_files);
8542 state->received = 0;
8544 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8545 if (tevent_req_nomem(state->reqs, req)) {
8546 return tevent_req_post(req, ev);
8549 for (i=0; i<num_parallel; i++) {
8552 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8554 if (tevent_req_nomem(name, req)) {
8555 return tevent_req_post(req, ev);
8557 state->reqs[i] = torture_createdel_send(
8558 state->reqs, state->ev, state->cli, name);
8559 if (tevent_req_nomem(state->reqs[i], req)) {
8560 return tevent_req_post(req, ev);
8562 name = talloc_move(state->reqs[i], &name);
8563 tevent_req_set_callback(state->reqs[i],
8564 torture_createdels_done, req);
8570 static void torture_createdels_done(struct tevent_req *subreq)
8572 struct tevent_req *req = tevent_req_callback_data(
8573 subreq, struct tevent_req);
8574 struct torture_createdels_state *state = tevent_req_data(
8575 req, struct torture_createdels_state);
8576 size_t num_parallel = talloc_array_length(state->reqs);
8581 status = torture_createdel_recv(subreq);
8582 if (!NT_STATUS_IS_OK(status)){
8583 DEBUG(10, ("torture_createdel_recv returned %s\n",
8584 nt_errstr(status)));
8585 TALLOC_FREE(subreq);
8586 tevent_req_nterror(req, status);
8590 for (i=0; i<num_parallel; i++) {
8591 if (subreq == state->reqs[i]) {
8595 if (i == num_parallel) {
8596 DEBUG(10, ("received something we did not send\n"));
8597 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8600 TALLOC_FREE(state->reqs[i]);
8602 if (state->sent >= state->num_files) {
8603 tevent_req_done(req);
8607 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8609 if (tevent_req_nomem(name, req)) {
8612 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8614 if (tevent_req_nomem(state->reqs[i], req)) {
8617 name = talloc_move(state->reqs[i], &name);
8618 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8622 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8624 return tevent_req_simple_recv_ntstatus(req);
8627 struct swallow_notify_state {
8628 struct tevent_context *ev;
8629 struct cli_state *cli;
8631 uint32_t completion_filter;
8633 bool (*fn)(uint32_t action, const char *name, void *priv);
8637 static void swallow_notify_done(struct tevent_req *subreq);
8639 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8640 struct tevent_context *ev,
8641 struct cli_state *cli,
8643 uint32_t completion_filter,
8645 bool (*fn)(uint32_t action,
8650 struct tevent_req *req, *subreq;
8651 struct swallow_notify_state *state;
8653 req = tevent_req_create(mem_ctx, &state,
8654 struct swallow_notify_state);
8661 state->completion_filter = completion_filter;
8662 state->recursive = recursive;
8666 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8667 0xffff, state->completion_filter,
8669 if (tevent_req_nomem(subreq, req)) {
8670 return tevent_req_post(req, ev);
8672 tevent_req_set_callback(subreq, swallow_notify_done, req);
8676 static void swallow_notify_done(struct tevent_req *subreq)
8678 struct tevent_req *req = tevent_req_callback_data(
8679 subreq, struct tevent_req);
8680 struct swallow_notify_state *state = tevent_req_data(
8681 req, struct swallow_notify_state);
8683 uint32_t i, num_changes;
8684 struct notify_change *changes;
8686 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8687 TALLOC_FREE(subreq);
8688 if (!NT_STATUS_IS_OK(status)) {
8689 DEBUG(10, ("cli_notify_recv returned %s\n",
8690 nt_errstr(status)));
8691 tevent_req_nterror(req, status);
8695 for (i=0; i<num_changes; i++) {
8696 state->fn(changes[i].action, changes[i].name, state->priv);
8698 TALLOC_FREE(changes);
8700 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8701 0xffff, state->completion_filter,
8703 if (tevent_req_nomem(subreq, req)) {
8706 tevent_req_set_callback(subreq, swallow_notify_done, req);
8709 static bool print_notifies(uint32_t action, const char *name, void *priv)
8711 if (DEBUGLEVEL > 5) {
8712 d_printf("%d %s\n", (int)action, name);
8717 static void notify_bench_done(struct tevent_req *req)
8719 int *num_finished = (int *)tevent_req_callback_data_void(req);
8723 static bool run_notify_bench(int dummy)
8725 const char *dname = "\\notify-bench";
8726 struct tevent_context *ev;
8729 struct tevent_req *req1;
8730 struct tevent_req *req2 = NULL;
8731 int i, num_unc_names;
8732 int num_finished = 0;
8734 printf("starting notify-bench test\n");
8736 if (use_multishare_conn) {
8738 unc_list = file_lines_load(multishare_conn_fname,
8739 &num_unc_names, 0, NULL);
8740 if (!unc_list || num_unc_names <= 0) {
8741 d_printf("Failed to load unc names list from '%s'\n",
8742 multishare_conn_fname);
8745 TALLOC_FREE(unc_list);
8750 ev = samba_tevent_context_init(talloc_tos());
8752 d_printf("tevent_context_init failed\n");
8756 for (i=0; i<num_unc_names; i++) {
8757 struct cli_state *cli;
8760 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8762 if (base_fname == NULL) {
8766 if (!torture_open_connection(&cli, i)) {
8770 status = cli_ntcreate(cli, dname, 0,
8771 MAXIMUM_ALLOWED_ACCESS,
8772 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8774 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8777 if (!NT_STATUS_IS_OK(status)) {
8778 d_printf("Could not create %s: %s\n", dname,
8783 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8784 FILE_NOTIFY_CHANGE_FILE_NAME |
8785 FILE_NOTIFY_CHANGE_DIR_NAME |
8786 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8787 FILE_NOTIFY_CHANGE_LAST_WRITE,
8788 false, print_notifies, NULL);
8790 d_printf("Could not create notify request\n");
8794 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8795 base_fname, 10, torture_numops);
8797 d_printf("Could not create createdels request\n");
8800 TALLOC_FREE(base_fname);
8802 tevent_req_set_callback(req2, notify_bench_done,
8806 while (num_finished < num_unc_names) {
8808 ret = tevent_loop_once(ev);
8810 d_printf("tevent_loop_once failed\n");
8815 if (!tevent_req_poll(req2, ev)) {
8816 d_printf("tevent_req_poll failed\n");
8819 status = torture_createdels_recv(req2);
8820 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8825 static bool run_mangle1(int dummy)
8827 struct cli_state *cli;
8828 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8832 time_t change_time, access_time, write_time;
8836 printf("starting mangle1 test\n");
8837 if (!torture_open_connection(&cli, 0)) {
8841 smbXcli_conn_set_sockopt(cli->conn, sockops);
8843 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8844 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8846 if (!NT_STATUS_IS_OK(status)) {
8847 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8850 cli_close(cli, fnum);
8852 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8853 if (!NT_STATUS_IS_OK(status)) {
8854 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8858 d_printf("alt_name: %s\n", alt_name);
8860 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8861 if (!NT_STATUS_IS_OK(status)) {
8862 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8866 cli_close(cli, fnum);
8868 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8869 &write_time, &size, &mode);
8870 if (!NT_STATUS_IS_OK(status)) {
8871 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8879 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8880 struct file_info *f,
8884 if (f->short_name == NULL) {
8885 return NT_STATUS_OK;
8888 if (strlen(f->short_name) == 0) {
8889 return NT_STATUS_OK;
8892 printf("unexpected shortname: %s\n", f->short_name);
8894 return NT_STATUS_OBJECT_NAME_INVALID;
8897 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8898 struct file_info *f,
8904 printf("name: %s\n", f->name);
8905 fstrcpy(name, f->name);
8906 return NT_STATUS_OK;
8909 static bool run_mangle_illegal(int dummy)
8911 struct cli_state *cli = NULL;
8912 struct cli_state *cli_posix = NULL;
8913 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8914 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8915 char *mangled_path = NULL;
8921 printf("starting mangle-illegal test\n");
8923 if (!torture_open_connection(&cli, 0)) {
8927 smbXcli_conn_set_sockopt(cli->conn, sockops);
8929 if (!torture_open_connection(&cli_posix, 0)) {
8933 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8935 status = torture_setup_unix_extensions(cli_posix);
8936 if (!NT_STATUS_IS_OK(status)) {
8940 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8941 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8942 if (!NT_STATUS_IS_OK(status)) {
8943 printf("mkdir1 failed : %s\n", nt_errstr(status));
8948 * Create a file with illegal NTFS characters and test that we
8949 * get a usable mangled name
8952 cli_setatr(cli_posix, illegal_fname, 0, 0);
8953 cli_posix_unlink(cli_posix, illegal_fname);
8955 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8957 if (!NT_STATUS_IS_OK(status)) {
8958 printf("POSIX create of %s failed (%s)\n",
8959 illegal_fname, nt_errstr(status));
8963 status = cli_close(cli_posix, fnum);
8964 if (!NT_STATUS_IS_OK(status)) {
8965 printf("close failed (%s)\n", nt_errstr(status));
8969 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8970 if (!NT_STATUS_IS_OK(status)) {
8971 d_printf("cli_list failed: %s\n", nt_errstr(status));
8975 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8976 if (mangled_path == NULL) {
8980 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8981 if (!NT_STATUS_IS_OK(status)) {
8982 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8983 TALLOC_FREE(mangled_path);
8986 TALLOC_FREE(mangled_path);
8987 cli_close(cli, fnum);
8989 cli_setatr(cli_posix, illegal_fname, 0, 0);
8990 cli_posix_unlink(cli_posix, illegal_fname);
8993 * Create a file with a long name and check that we got *no* short name.
8996 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8997 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8999 if (!NT_STATUS_IS_OK(status)) {
9000 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
9003 cli_close(cli, fnum);
9005 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
9006 if (!NT_STATUS_IS_OK(status)) {
9007 d_printf("cli_list failed\n");
9011 cli_unlink(cli, fname, 0);
9012 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
9014 if (!torture_close_connection(cli_posix)) {
9018 if (!torture_close_connection(cli)) {
9025 static size_t null_source(uint8_t *buf, size_t n, void *priv)
9027 size_t *to_pull = (size_t *)priv;
9028 size_t thistime = *to_pull;
9030 thistime = MIN(thistime, n);
9031 if (thistime == 0) {
9035 memset(buf, 0, thistime);
9036 *to_pull -= thistime;
9040 static bool run_windows_write(int dummy)
9042 struct cli_state *cli1;
9046 const char *fname = "\\writetest.txt";
9047 struct timeval start_time;
9052 printf("starting windows_write test\n");
9053 if (!torture_open_connection(&cli1, 0)) {
9057 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
9058 if (!NT_STATUS_IS_OK(status)) {
9059 printf("open failed (%s)\n", nt_errstr(status));
9063 smbXcli_conn_set_sockopt(cli1->conn, sockops);
9065 start_time = timeval_current();
9067 for (i=0; i<torture_numops; i++) {
9069 off_t start = i * torture_blocksize;
9070 size_t to_pull = torture_blocksize - 1;
9072 status = cli_writeall(cli1, fnum, 0, &c,
9073 start + torture_blocksize - 1, 1, NULL);
9074 if (!NT_STATUS_IS_OK(status)) {
9075 printf("cli_write failed: %s\n", nt_errstr(status));
9079 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
9080 null_source, &to_pull);
9081 if (!NT_STATUS_IS_OK(status)) {
9082 printf("cli_push returned: %s\n", nt_errstr(status));
9087 seconds = timeval_elapsed(&start_time);
9088 kbytes = (double)torture_blocksize * torture_numops;
9091 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
9092 (double)seconds, (int)(kbytes/seconds));
9096 cli_close(cli1, fnum);
9097 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9098 torture_close_connection(cli1);
9102 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
9104 size_t max_pdu = 0x1FFFF;
9106 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
9110 if (smb1cli_conn_signing_is_active(cli->conn)) {
9114 if (smb1cli_conn_encryption_on(cli->conn)) {
9115 max_pdu = CLI_BUFFER_SIZE;
9118 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
9119 len_requested &= 0xFFFF;
9122 return MIN(len_requested,
9123 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
9126 static bool check_read_call(struct cli_state *cli,
9129 size_t len_requested)
9132 struct tevent_req *subreq = NULL;
9133 ssize_t len_read = 0;
9134 size_t len_expected = 0;
9135 struct tevent_context *ev = NULL;
9137 ev = samba_tevent_context_init(talloc_tos());
9142 subreq = cli_read_andx_send(talloc_tos(),
9149 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
9153 status = cli_read_andx_recv(subreq, &len_read, &buf);
9154 if (!NT_STATUS_IS_OK(status)) {
9155 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
9159 TALLOC_FREE(subreq);
9162 len_expected = calc_expected_return(cli, len_requested);
9164 if (len_expected > 0x10000 && len_read == 0x10000) {
9165 /* Windows servers only return a max of 0x10000,
9166 doesn't matter if you set CAP_LARGE_READX in
9167 the client sessionsetupX call or not. */
9168 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
9169 (unsigned int)len_requested);
9170 } else if (len_read != len_expected) {
9171 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
9172 (unsigned int)len_requested,
9173 (unsigned int)len_read,
9174 (unsigned int)len_expected);
9177 d_printf("Correct read reply.\n");
9183 /* Test large readX variants. */
9184 static bool large_readx_tests(struct cli_state *cli,
9188 /* A read of 0xFFFF0001 should *always* return 1 byte. */
9189 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
9192 /* A read of 0x10000 should return 0x10000 bytes. */
9193 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
9196 /* A read of 0x10000 should return 0x10001 bytes. */
9197 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
9200 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
9201 the requested number of bytes. */
9202 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
9205 /* A read of 1MB should return 1MB bytes (on Samba). */
9206 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
9210 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
9213 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
9216 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
9222 static bool run_large_readx(int dummy)
9224 uint8_t *buf = NULL;
9225 struct cli_state *cli1 = NULL;
9226 struct cli_state *cli2 = NULL;
9227 bool correct = false;
9228 const char *fname = "\\large_readx.dat";
9230 uint16_t fnum1 = UINT16_MAX;
9231 uint32_t normal_caps = 0;
9232 size_t file_size = 20*1024*1024;
9233 TALLOC_CTX *frame = talloc_stackframe();
9237 enum smb_signing_setting signing_setting;
9238 enum protocol_types protocol;
9242 .signing_setting = SMB_SIGNING_IF_REQUIRED,
9243 .protocol = PROTOCOL_NT1,
9245 .name = "NT1 - SIGNING_REQUIRED",
9246 .signing_setting = SMB_SIGNING_REQUIRED,
9247 .protocol = PROTOCOL_NT1,
9251 printf("starting large_readx test\n");
9253 if (!torture_open_connection(&cli1, 0)) {
9257 normal_caps = smb1cli_conn_capabilities(cli1->conn);
9259 if (!(normal_caps & CAP_LARGE_READX)) {
9260 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9261 (unsigned int)normal_caps);
9265 /* Create a file of size 4MB. */
9266 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
9267 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9268 0, 0, &fnum1, NULL);
9270 if (!NT_STATUS_IS_OK(status)) {
9271 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
9275 /* Write file_size bytes. */
9276 buf = talloc_zero_array(frame, uint8_t, file_size);
9281 status = cli_writeall(cli1,
9288 if (!NT_STATUS_IS_OK(status)) {
9289 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9293 status = cli_close(cli1, fnum1);
9294 if (!NT_STATUS_IS_OK(status)) {
9295 d_printf("cli_close failed: %s\n", nt_errstr(status));
9301 for (i=0; i < ARRAY_SIZE(runs); i++) {
9302 enum smb_signing_setting saved_signing_setting = signing_state;
9303 uint16_t fnum2 = -1;
9306 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
9308 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
9312 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
9314 signing_state = runs[i].signing_setting;
9315 cli2 = open_nbt_connection();
9316 signing_state = saved_signing_setting;
9321 status = smbXcli_negprot(cli2->conn,
9325 if (!NT_STATUS_IS_OK(status)) {
9329 status = cli_session_setup_creds(cli2, torture_creds);
9330 if (!NT_STATUS_IS_OK(status)) {
9334 status = cli_tree_connect(cli2,
9338 if (!NT_STATUS_IS_OK(status)) {
9342 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
9344 normal_caps = smb1cli_conn_capabilities(cli2->conn);
9346 if (!(normal_caps & CAP_LARGE_READX)) {
9347 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9348 (unsigned int)normal_caps);
9353 if (force_cli_encryption(cli2, share) == false) {
9356 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
9357 uint16_t major, minor;
9358 uint32_t caplow, caphigh;
9360 status = cli_unix_extensions_version(cli2,
9363 if (!NT_STATUS_IS_OK(status)) {
9368 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
9369 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
9370 0, 0, &fnum2, NULL);
9371 if (!NT_STATUS_IS_OK(status)) {
9372 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
9376 /* All reads must return less than file_size bytes. */
9377 if (!large_readx_tests(cli2, fnum2, buf)) {
9381 status = cli_close(cli2, fnum2);
9382 if (!NT_STATUS_IS_OK(status)) {
9383 d_printf("cli_close failed: %s\n", nt_errstr(status));
9388 if (!torture_close_connection(cli2)) {
9395 printf("Success on large_readx test\n");
9400 if (!torture_close_connection(cli2)) {
9406 if (fnum1 != UINT16_MAX) {
9407 status = cli_close(cli1, fnum1);
9408 if (!NT_STATUS_IS_OK(status)) {
9409 d_printf("cli_close failed: %s\n", nt_errstr(status));
9414 status = cli_unlink(cli1, fname,
9415 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9416 if (!NT_STATUS_IS_OK(status)) {
9417 printf("unlink failed (%s)\n", nt_errstr(status));
9420 if (!torture_close_connection(cli1)) {
9427 printf("finished large_readx test\n");
9431 static bool run_cli_echo(int dummy)
9433 struct cli_state *cli;
9436 printf("starting cli_echo test\n");
9437 if (!torture_open_connection(&cli, 0)) {
9440 smbXcli_conn_set_sockopt(cli->conn, sockops);
9442 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9444 d_printf("cli_echo returned %s\n", nt_errstr(status));
9446 torture_close_connection(cli);
9447 return NT_STATUS_IS_OK(status);
9450 static int splice_status(off_t written, void *priv)
9455 static bool run_cli_splice(int dummy)
9457 uint8_t *buf = NULL;
9458 struct cli_state *cli1 = NULL;
9459 bool correct = false;
9460 const char *fname_src = "\\splice_src.dat";
9461 const char *fname_dst = "\\splice_dst.dat";
9463 uint16_t fnum1 = UINT16_MAX;
9464 uint16_t fnum2 = UINT16_MAX;
9465 size_t file_size = 2*1024*1024;
9466 size_t splice_size = 1*1024*1024 + 713;
9468 uint8_t digest1[16], digest2[16];
9471 TALLOC_CTX *frame = talloc_stackframe();
9473 printf("starting cli_splice test\n");
9475 if (!torture_open_connection(&cli1, 0)) {
9479 cli_unlink(cli1, fname_src,
9480 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9481 cli_unlink(cli1, fname_dst,
9482 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9485 status = cli_ntcreate(cli1, fname_src, 0, GENERIC_ALL_ACCESS,
9486 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9487 0, 0, &fnum1, NULL);
9489 if (!NT_STATUS_IS_OK(status)) {
9490 d_printf("open %s failed: %s\n", fname_src, nt_errstr(status));
9494 /* Write file_size bytes - must be bigger than splice_size. */
9495 buf = talloc_zero_array(frame, uint8_t, file_size);
9497 d_printf("talloc_fail\n");
9501 /* Fill it with random numbers. */
9502 generate_random_buffer(buf, file_size);
9504 /* MD5 the first 1MB + 713 bytes. */
9506 MD5Update(&md5_ctx, buf, splice_size);
9507 MD5Final(digest1, &md5_ctx);
9509 status = cli_writeall(cli1,
9516 if (!NT_STATUS_IS_OK(status)) {
9517 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9521 status = cli_ntcreate(cli1, fname_dst, 0, GENERIC_ALL_ACCESS,
9522 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
9523 0, 0, &fnum2, NULL);
9525 if (!NT_STATUS_IS_OK(status)) {
9526 d_printf("open %s failed: %s\n", fname_dst, nt_errstr(status));
9530 /* Now splice 1MB + 713 bytes. */
9531 status = cli_splice(cli1,
9542 if (!NT_STATUS_IS_OK(status)) {
9543 d_printf("cli_splice failed: %s\n", nt_errstr(status));
9547 /* Clear the old buffer. */
9548 memset(buf, '\0', file_size);
9550 /* Read the new file. */
9551 status = cli_read(cli1, fnum2, (char *)buf, 0, splice_size, &nread);
9552 if (!NT_STATUS_IS_OK(status)) {
9553 d_printf("cli_read failed: %s\n", nt_errstr(status));
9556 if (nread != splice_size) {
9557 d_printf("bad read of 0x%x, should be 0x%x\n",
9558 (unsigned int)nread,
9559 (unsigned int)splice_size);
9563 /* MD5 the first 1MB + 713 bytes. */
9565 MD5Update(&md5_ctx, buf, splice_size);
9566 MD5Final(digest2, &md5_ctx);
9568 /* Must be the same. */
9569 if (memcmp(digest1, digest2, 16) != 0) {
9570 d_printf("bad MD5 compare\n");
9575 printf("Success on cli_splice test\n");
9580 if (fnum1 != UINT16_MAX) {
9581 cli_close(cli1, fnum1);
9583 if (fnum2 != UINT16_MAX) {
9584 cli_close(cli1, fnum2);
9587 cli_unlink(cli1, fname_src,
9588 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9589 cli_unlink(cli1, fname_dst,
9590 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9592 if (!torture_close_connection(cli1)) {
9601 static bool run_uid_regression_test(int dummy)
9603 static struct cli_state *cli;
9606 bool correct = True;
9607 struct smbXcli_tcon *orig_tcon = NULL;
9610 printf("starting uid regression test\n");
9612 if (!torture_open_connection(&cli, 0)) {
9616 smbXcli_conn_set_sockopt(cli->conn, sockops);
9618 /* Ok - now save then logoff our current user. */
9619 old_vuid = cli_state_get_uid(cli);
9621 status = cli_ulogoff(cli);
9622 if (!NT_STATUS_IS_OK(status)) {
9623 d_printf("(%s) cli_ulogoff failed: %s\n",
9624 __location__, nt_errstr(status));
9629 cli_state_set_uid(cli, old_vuid);
9631 /* Try an operation. */
9632 status = cli_mkdir(cli, "\\uid_reg_test");
9633 if (NT_STATUS_IS_OK(status)) {
9634 d_printf("(%s) cli_mkdir succeeded\n",
9639 /* Should be bad uid. */
9640 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9641 NT_STATUS_USER_SESSION_DELETED)) {
9647 old_cnum = cli_state_get_tid(cli);
9648 orig_tcon = cli_state_save_tcon(cli);
9649 if (orig_tcon == NULL) {
9654 /* Now try a SMBtdis with the invald vuid set to zero. */
9655 cli_state_set_uid(cli, 0);
9657 /* This should succeed. */
9658 status = cli_tdis(cli);
9660 if (NT_STATUS_IS_OK(status)) {
9661 d_printf("First tdis with invalid vuid should succeed.\n");
9663 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9665 cli_state_restore_tcon(cli, orig_tcon);
9669 cli_state_restore_tcon(cli, orig_tcon);
9670 cli_state_set_uid(cli, old_vuid);
9671 cli_state_set_tid(cli, old_cnum);
9673 /* This should fail. */
9674 status = cli_tdis(cli);
9675 if (NT_STATUS_IS_OK(status)) {
9676 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9680 /* Should be bad tid. */
9681 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9682 NT_STATUS_NETWORK_NAME_DELETED)) {
9688 cli_rmdir(cli, "\\uid_reg_test");
9697 static const char *illegal_chars = "*\\/?<>|\":";
9698 static char force_shortname_chars[] = " +,.[];=\177";
9700 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9701 const char *mask, void *state)
9703 struct cli_state *pcli = (struct cli_state *)state;
9705 NTSTATUS status = NT_STATUS_OK;
9707 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9709 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9710 return NT_STATUS_OK;
9712 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9713 status = cli_rmdir(pcli, fname);
9714 if (!NT_STATUS_IS_OK(status)) {
9715 printf("del_fn: failed to rmdir %s\n,", fname );
9718 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9719 if (!NT_STATUS_IS_OK(status)) {
9720 printf("del_fn: failed to unlink %s\n,", fname );
9732 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9733 const char *name, void *state)
9735 struct sn_state *s = (struct sn_state *)state;
9739 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9740 i, finfo->name, finfo->short_name);
9743 if (strchr(force_shortname_chars, i)) {
9744 if (!finfo->short_name) {
9745 /* Shortname not created when it should be. */
9746 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9747 __location__, finfo->name, i);
9750 } else if (finfo->short_name){
9751 /* Shortname created when it should not be. */
9752 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9753 __location__, finfo->short_name, finfo->name);
9757 return NT_STATUS_OK;
9760 static bool run_shortname_test(int dummy)
9762 static struct cli_state *cli;
9763 bool correct = True;
9769 printf("starting shortname test\n");
9771 if (!torture_open_connection(&cli, 0)) {
9775 smbXcli_conn_set_sockopt(cli->conn, sockops);
9777 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9778 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9779 cli_rmdir(cli, "\\shortname");
9781 status = cli_mkdir(cli, "\\shortname");
9782 if (!NT_STATUS_IS_OK(status)) {
9783 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9784 __location__, nt_errstr(status));
9789 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9793 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9800 for (i = 32; i < 128; i++) {
9801 uint16_t fnum = (uint16_t)-1;
9805 if (strchr(illegal_chars, i)) {
9810 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9811 FILE_SHARE_READ|FILE_SHARE_WRITE,
9812 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9813 if (!NT_STATUS_IS_OK(status)) {
9814 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9815 __location__, fname, nt_errstr(status));
9819 cli_close(cli, fnum);
9822 status = cli_list(cli, "\\shortname\\test*.*", 0,
9823 shortname_list_fn, &s);
9824 if (s.matched != 1) {
9825 d_printf("(%s) failed to list %s: %s\n",
9826 __location__, fname, nt_errstr(status));
9831 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9832 if (!NT_STATUS_IS_OK(status)) {
9833 d_printf("(%s) failed to delete %s: %s\n",
9834 __location__, fname, nt_errstr(status));
9847 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9848 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9849 cli_rmdir(cli, "\\shortname");
9850 torture_close_connection(cli);
9854 static void pagedsearch_cb(struct tevent_req *req)
9857 struct tldap_message *msg;
9860 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9861 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9862 d_printf("tldap_search_paged_recv failed: %s\n",
9863 tldap_rc2string(rc));
9866 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9870 if (!tldap_entry_dn(msg, &dn)) {
9871 d_printf("tldap_entry_dn failed\n");
9874 d_printf("%s\n", dn);
9878 static bool run_tldap(int dummy)
9880 struct tldap_context *ld;
9884 struct sockaddr_storage addr;
9885 struct tevent_context *ev;
9886 struct tevent_req *req;
9890 if (!resolve_name(host, &addr, 0, false)) {
9891 d_printf("could not find host %s\n", host);
9894 status = open_socket_out(&addr, 389, 9999, &fd);
9895 if (!NT_STATUS_IS_OK(status)) {
9896 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9900 ld = tldap_context_create(talloc_tos(), fd);
9903 d_printf("tldap_context_create failed\n");
9907 rc = tldap_fetch_rootdse(ld);
9908 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9909 d_printf("tldap_fetch_rootdse failed: %s\n",
9910 tldap_errstr(talloc_tos(), ld, rc));
9914 basedn = tldap_talloc_single_attribute(
9915 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9916 if (basedn == NULL) {
9917 d_printf("no defaultNamingContext\n");
9920 d_printf("defaultNamingContext: %s\n", basedn);
9922 ev = samba_tevent_context_init(talloc_tos());
9924 d_printf("tevent_context_init failed\n");
9928 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9929 TLDAP_SCOPE_SUB, "(objectclass=*)",
9931 NULL, 0, NULL, 0, 0, 0, 0, 5);
9933 d_printf("tldap_search_paged_send failed\n");
9936 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9938 tevent_req_poll(req, ev);
9942 /* test search filters against rootDSE */
9943 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9944 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9946 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9947 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9948 talloc_tos(), NULL);
9949 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9950 d_printf("tldap_search with complex filter failed: %s\n",
9951 tldap_errstr(talloc_tos(), ld, rc));
9959 /* Torture test to ensure no regression of :
9960 https://bugzilla.samba.org/show_bug.cgi?id=7084
9963 static bool run_dir_createtime(int dummy)
9965 struct cli_state *cli;
9966 const char *dname = "\\testdir_createtime";
9967 const char *fname = "\\testdir_createtime\\testfile";
9969 struct timespec create_time;
9970 struct timespec create_time1;
9974 if (!torture_open_connection(&cli, 0)) {
9978 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9979 cli_rmdir(cli, dname);
9981 status = cli_mkdir(cli, dname);
9982 if (!NT_STATUS_IS_OK(status)) {
9983 printf("mkdir failed: %s\n", nt_errstr(status));
9987 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9989 if (!NT_STATUS_IS_OK(status)) {
9990 printf("cli_qpathinfo2 returned %s\n",
9995 /* Sleep 3 seconds, then create a file. */
9998 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
10000 if (!NT_STATUS_IS_OK(status)) {
10001 printf("cli_openx failed: %s\n", nt_errstr(status));
10005 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
10007 if (!NT_STATUS_IS_OK(status)) {
10008 printf("cli_qpathinfo2 (2) returned %s\n",
10009 nt_errstr(status));
10013 if (timespec_compare(&create_time1, &create_time)) {
10014 printf("run_dir_createtime: create time was updated (error)\n");
10016 printf("run_dir_createtime: create time was not updated (correct)\n");
10022 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
10023 cli_rmdir(cli, dname);
10024 if (!torture_close_connection(cli)) {
10031 static bool run_streamerror(int dummy)
10033 struct cli_state *cli;
10034 const char *dname = "\\testdir_streamerror";
10035 const char *streamname =
10036 "testdir_streamerror:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
10038 time_t change_time, access_time, write_time;
10040 uint16_t mode, fnum;
10043 if (!torture_open_connection(&cli, 0)) {
10047 cli_unlink(cli, "\\testdir_streamerror\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
10048 cli_rmdir(cli, dname);
10050 status = cli_mkdir(cli, dname);
10051 if (!NT_STATUS_IS_OK(status)) {
10052 printf("mkdir failed: %s\n", nt_errstr(status));
10056 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
10057 &write_time, &size, &mode);
10058 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
10059 printf("pathinfo returned %s, expected "
10060 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
10061 nt_errstr(status));
10065 status = cli_ntcreate(cli, streamname, 0x16,
10066 FILE_READ_DATA|FILE_READ_EA|
10067 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
10068 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
10069 FILE_OPEN, 0, 0, &fnum, NULL);
10071 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
10072 printf("ntcreate returned %s, expected "
10073 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
10074 nt_errstr(status));
10079 cli_rmdir(cli, dname);
10083 struct pidtest_state {
10089 static void pid_echo_done(struct tevent_req *subreq);
10091 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
10092 struct tevent_context *ev,
10093 struct cli_state *cli)
10095 struct tevent_req *req, *subreq;
10096 struct pidtest_state *state;
10098 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
10103 SSVAL(state->vwv, 0, 1);
10104 state->data = data_blob_const("hello", 5);
10106 subreq = smb1cli_req_send(state,
10110 0, 0, /* *_flags */
10111 0, 0, /* *_flags2 */
10113 0xDEADBEEF, /* pid */
10115 NULL, /* session */
10116 ARRAY_SIZE(state->vwv), state->vwv,
10117 state->data.length, state->data.data);
10119 if (tevent_req_nomem(subreq, req)) {
10120 return tevent_req_post(req, ev);
10122 tevent_req_set_callback(subreq, pid_echo_done, req);
10126 static void pid_echo_done(struct tevent_req *subreq)
10128 struct tevent_req *req = tevent_req_callback_data(
10129 subreq, struct tevent_req);
10130 struct pidtest_state *state = tevent_req_data(
10131 req, struct pidtest_state);
10133 uint32_t num_bytes;
10134 uint8_t *bytes = NULL;
10135 struct iovec *recv_iov = NULL;
10136 uint8_t *phdr = NULL;
10137 uint16_t pidlow = 0;
10138 uint16_t pidhigh = 0;
10139 struct smb1cli_req_expected_response expected[] = {
10141 .status = NT_STATUS_OK,
10146 status = smb1cli_req_recv(subreq, state,
10151 NULL, /* pvwv_offset */
10154 NULL, /* pbytes_offset */
10156 expected, ARRAY_SIZE(expected));
10158 TALLOC_FREE(subreq);
10160 if (!NT_STATUS_IS_OK(status)) {
10161 tevent_req_nterror(req, status);
10165 if (num_bytes != state->data.length) {
10166 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
10170 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
10171 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
10175 /* Check pid low/high == DEADBEEF */
10176 pidlow = SVAL(phdr, HDR_PID);
10177 if (pidlow != 0xBEEF){
10178 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
10179 (unsigned int)pidlow);
10180 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
10183 pidhigh = SVAL(phdr, HDR_PIDHIGH);
10184 if (pidhigh != 0xDEAD){
10185 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
10186 (unsigned int)pidhigh);
10187 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
10191 tevent_req_done(req);
10194 static NTSTATUS pid_echo_recv(struct tevent_req *req)
10196 return tevent_req_simple_recv_ntstatus(req);
10199 static bool run_pidhigh(int dummy)
10201 bool success = false;
10202 struct cli_state *cli = NULL;
10204 struct tevent_context *ev = NULL;
10205 struct tevent_req *req = NULL;
10206 TALLOC_CTX *frame = talloc_stackframe();
10208 printf("starting pid high test\n");
10209 if (!torture_open_connection(&cli, 0)) {
10212 smbXcli_conn_set_sockopt(cli->conn, sockops);
10214 ev = samba_tevent_context_init(frame);
10219 req = pid_echo_send(frame, ev, cli);
10224 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
10228 status = pid_echo_recv(req);
10229 if (NT_STATUS_IS_OK(status)) {
10230 printf("pid high test ok\n");
10236 TALLOC_FREE(frame);
10237 torture_close_connection(cli);
10242 Test Windows open on a bad POSIX symlink.
10244 static bool run_symlink_open_test(int dummy)
10246 static struct cli_state *cli;
10247 const char *fname = "non_existant_file";
10248 const char *sname = "dangling_symlink";
10249 uint16_t fnum = (uint16_t)-1;
10250 bool correct = false;
10252 TALLOC_CTX *frame = NULL;
10254 frame = talloc_stackframe();
10256 printf("Starting Windows bad symlink open test\n");
10258 if (!torture_open_connection(&cli, 0)) {
10259 TALLOC_FREE(frame);
10263 smbXcli_conn_set_sockopt(cli->conn, sockops);
10265 status = torture_setup_unix_extensions(cli);
10266 if (!NT_STATUS_IS_OK(status)) {
10267 TALLOC_FREE(frame);
10271 /* Ensure nothing exists. */
10272 cli_setatr(cli, fname, 0, 0);
10273 cli_posix_unlink(cli, fname);
10274 cli_setatr(cli, sname, 0, 0);
10275 cli_posix_unlink(cli, sname);
10277 /* Create a symlink pointing nowhere. */
10278 status = cli_posix_symlink(cli, fname, sname);
10279 if (!NT_STATUS_IS_OK(status)) {
10280 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
10283 nt_errstr(status));
10287 /* Now ensure that a Windows open doesn't hang. */
10288 status = cli_ntcreate(cli,
10291 FILE_READ_DATA|FILE_WRITE_DATA,
10293 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
10301 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
10302 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
10303 * we use O_NOFOLLOW on the server or not.
10305 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
10306 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
10310 printf("cli_ntcreate of %s returned %s - should return"
10311 " either (%s) or (%s)\n",
10314 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
10315 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
10323 if (fnum != (uint16_t)-1) {
10324 cli_close(cli, fnum);
10325 fnum = (uint16_t)-1;
10328 cli_setatr(cli, sname, 0, 0);
10329 cli_posix_unlink(cli, sname);
10330 cli_setatr(cli, fname, 0, 0);
10331 cli_posix_unlink(cli, fname);
10333 if (!torture_close_connection(cli)) {
10337 TALLOC_FREE(frame);
10342 * Only testing minimal time strings, as the others
10343 * need (locale-dependent) guessing at what strftime does and
10344 * even may differ in builds.
10346 static bool timesubst_test(void)
10348 TALLOC_CTX *ctx = NULL;
10349 /* Sa 23. Dez 04:33:20 CET 2017 */
10350 const struct timeval tv = { 1514000000, 123 };
10351 const char* expect_minimal = "20171223_033320";
10352 const char* expect_minus = "20171223_033320_000123";
10354 char *env_tz, *orig_tz = NULL;
10355 bool result = true;
10357 ctx = talloc_new(NULL);
10359 env_tz = getenv("TZ");
10361 orig_tz = talloc_strdup(ctx, env_tz);
10363 setenv("TZ", "UTC", 1);
10365 s = minimal_timeval_string(ctx, &tv, false);
10367 if(!s || strcmp(s, expect_minimal)) {
10368 printf("minimal_timeval_string(ctx, tv, false) returned [%s], expected "
10369 "[%s]\n", s ? s : "<nil>", expect_minimal);
10373 s = minimal_timeval_string(ctx, &tv, true);
10374 if(!s || strcmp(s, expect_minus)) {
10375 printf("minimal_timeval_string(ctx, tv, true) returned [%s], expected "
10376 "[%s]\n", s ? s : "<nil>", expect_minus);
10382 setenv("TZ", orig_tz, 1);
10389 static bool run_local_substitute(int dummy)
10393 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
10394 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
10395 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
10396 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
10397 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
10398 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
10399 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
10400 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
10401 ok &= subst_test("%j %J", "", "", -1, -1, "0_0_0_0 0_0_0_0");
10402 /* Substitution depends on current time, so better test the underlying
10403 formatting function. At least covers %t. */
10404 ok &= timesubst_test();
10406 /* Different captialization rules in sub_basic... */
10408 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
10414 static bool run_local_base64(int dummy)
10419 for (i=1; i<2000; i++) {
10420 DATA_BLOB blob1, blob2;
10423 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
10425 generate_random_buffer(blob1.data, blob1.length);
10427 b64 = base64_encode_data_blob(talloc_tos(), blob1);
10429 d_fprintf(stderr, "base64_encode_data_blob failed "
10430 "for %d bytes\n", i);
10433 blob2 = base64_decode_data_blob(b64);
10436 if (data_blob_cmp(&blob1, &blob2)) {
10437 d_fprintf(stderr, "data_blob_cmp failed for %d "
10441 TALLOC_FREE(blob1.data);
10442 data_blob_free(&blob2);
10447 static void parse_fn(const struct gencache_timeout *t,
10449 void *private_data)
10454 static bool run_local_gencache(int dummy)
10460 struct memcache *mem;
10463 mem = memcache_init(NULL, 0);
10465 d_printf("%s: memcache_init failed\n", __location__);
10468 memcache_set_global(mem);
10470 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
10471 d_printf("%s: gencache_set() failed\n", __location__);
10475 if (!gencache_get("foo", NULL, NULL, NULL)) {
10476 d_printf("%s: gencache_get() failed\n", __location__);
10480 for (i=0; i<1000000; i++) {
10481 gencache_parse("foo", parse_fn, NULL);
10484 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10485 d_printf("%s: gencache_get() failed\n", __location__);
10490 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10491 d_printf("%s: gencache_get() failed\n", __location__);
10495 if (strcmp(val, "bar") != 0) {
10496 d_printf("%s: gencache_get() returned %s, expected %s\n",
10497 __location__, val, "bar");
10504 if (!gencache_del("foo")) {
10505 d_printf("%s: gencache_del() failed\n", __location__);
10508 if (gencache_del("foo")) {
10509 d_printf("%s: second gencache_del() succeeded\n",
10514 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
10515 d_printf("%s: gencache_get() on deleted entry "
10516 "succeeded\n", __location__);
10520 blob = data_blob_string_const_null("bar");
10521 tm = time(NULL) + 60;
10523 if (!gencache_set_data_blob("foo", blob, tm)) {
10524 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
10528 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10529 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
10533 if (strcmp((const char *)blob.data, "bar") != 0) {
10534 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10535 __location__, (const char *)blob.data, "bar");
10536 data_blob_free(&blob);
10540 data_blob_free(&blob);
10542 if (!gencache_del("foo")) {
10543 d_printf("%s: gencache_del() failed\n", __location__);
10546 if (gencache_del("foo")) {
10547 d_printf("%s: second gencache_del() succeeded\n",
10552 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10553 d_printf("%s: gencache_get_data_blob() on deleted entry "
10554 "succeeded\n", __location__);
10559 blob.data = (uint8_t *)&v;
10560 blob.length = sizeof(v);
10562 if (!gencache_set_data_blob("blob", blob, tm)) {
10563 d_printf("%s: gencache_set_data_blob() failed\n",
10567 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
10568 d_printf("%s: gencache_get succeeded\n", __location__);
10575 static bool rbt_testval(struct db_context *db, const char *key,
10578 struct db_record *rec;
10579 TDB_DATA data = string_tdb_data(value);
10584 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10586 d_fprintf(stderr, "fetch_locked failed\n");
10589 status = dbwrap_record_store(rec, data, 0);
10590 if (!NT_STATUS_IS_OK(status)) {
10591 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
10596 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10598 d_fprintf(stderr, "second fetch_locked failed\n");
10602 dbvalue = dbwrap_record_get_value(rec);
10603 if ((dbvalue.dsize != data.dsize)
10604 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
10605 d_fprintf(stderr, "Got wrong data back\n");
10615 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
10617 int *count2 = (int *)private_data;
10622 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
10624 int *count2 = (int *)private_data;
10626 dbwrap_record_delete(rec);
10630 static bool run_local_rbtree(int dummy)
10632 struct db_context *db;
10639 db = db_open_rbt(NULL);
10642 d_fprintf(stderr, "db_open_rbt failed\n");
10646 for (i=0; i<1000; i++) {
10649 if (asprintf(&key, "key%ld", random()) == -1) {
10652 if (asprintf(&value, "value%ld", random()) == -1) {
10657 if (!rbt_testval(db, key, value)) {
10664 if (asprintf(&value, "value%ld", random()) == -1) {
10669 if (!rbt_testval(db, key, value)) {
10680 count = 0; count2 = 0;
10681 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10683 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10684 if ((count != count2) || (count != 1000)) {
10687 count = 0; count2 = 0;
10688 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10690 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10691 if ((count != count2) || (count != 1000)) {
10694 count = 0; count2 = 0;
10695 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10697 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10698 if ((count != count2) || (count != 0)) {
10709 local test for character set functions
10711 This is a very simple test for the functionality in convert_string_error()
10713 static bool run_local_convert_string(int dummy)
10715 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10716 const char *test_strings[2] = { "March", "M\303\244rz" };
10720 for (i=0; i<2; i++) {
10721 const char *str = test_strings[i];
10722 int len = strlen(str);
10723 size_t converted_size;
10726 memset(dst, 'X', sizeof(dst));
10728 /* first try with real source length */
10729 ret = convert_string_error(CH_UNIX, CH_UTF8,
10734 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10738 if (converted_size != len) {
10739 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10740 str, len, (int)converted_size);
10744 if (strncmp(str, dst, converted_size) != 0) {
10745 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10749 if (strlen(str) != converted_size) {
10750 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10751 (int)strlen(str), (int)converted_size);
10755 if (dst[converted_size] != 'X') {
10756 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10760 /* now with srclen==-1, this causes the nul to be
10762 ret = convert_string_error(CH_UNIX, CH_UTF8,
10767 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10771 if (converted_size != len+1) {
10772 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10773 str, len, (int)converted_size);
10777 if (strncmp(str, dst, converted_size) != 0) {
10778 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10782 if (len+1 != converted_size) {
10783 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10784 len+1, (int)converted_size);
10788 if (dst[converted_size] != 'X') {
10789 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10796 TALLOC_FREE(tmp_ctx);
10799 TALLOC_FREE(tmp_ctx);
10803 static bool run_local_string_to_sid(int dummy) {
10804 struct dom_sid sid;
10806 if (string_to_sid(&sid, "S--1-5-32-545")) {
10807 printf("allowing S--1-5-32-545\n");
10810 if (string_to_sid(&sid, "S-1-5-32-+545")) {
10811 printf("allowing S-1-5-32-+545\n");
10814 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")) {
10815 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10818 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10819 printf("allowing S-1-5-32-545-abc\n");
10822 if (string_to_sid(&sid, "S-300-5-32-545")) {
10823 printf("allowing S-300-5-32-545\n");
10826 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10827 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10830 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10831 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10834 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10835 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10838 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10839 printf("could not parse S-1-5-32-545\n");
10842 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10843 struct dom_sid_buf buf;
10844 printf("mis-parsed S-1-5-32-545 as %s\n",
10845 dom_sid_str_buf(&sid, &buf));
10851 static bool sid_to_string_test(const char *expected) {
10854 struct dom_sid sid;
10856 if (!string_to_sid(&sid, expected)) {
10857 printf("could not parse %s\n", expected);
10861 str = dom_sid_string(NULL, &sid);
10862 if (strcmp(str, expected)) {
10863 printf("Comparison failed (%s != %s)\n", str, expected);
10870 static bool run_local_sid_to_string(int dummy) {
10871 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10873 if (!sid_to_string_test("S-1-545"))
10875 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10880 static bool run_local_binary_to_sid(int dummy) {
10881 struct sid_parse_ret ret;
10882 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10883 static const uint8_t good_binary_sid[] = {
10884 0x1, /* revision number */
10885 15, /* num auths */
10886 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10887 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10888 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10889 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10890 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10891 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10892 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10893 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10894 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10895 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10896 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10897 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10898 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10899 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10900 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10901 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10904 static const uint8_t long_binary_sid[] = {
10905 0x1, /* revision number */
10906 15, /* num auths */
10907 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10908 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10909 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10910 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10911 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10912 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10913 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10914 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10915 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10916 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10917 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10918 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10919 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10920 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10921 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10922 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10923 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10924 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10925 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10928 static const uint8_t long_binary_sid2[] = {
10929 0x1, /* revision number */
10930 32, /* num auths */
10931 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10932 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10933 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10934 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10935 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10936 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10937 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10938 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10939 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10940 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10941 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10942 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10943 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10944 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10945 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10946 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10947 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10948 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10949 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10950 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10951 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10952 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10953 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10954 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10955 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10956 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10957 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10958 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10959 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10960 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10961 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10962 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10963 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10966 ret = sid_parse(good_binary_sid, sizeof(good_binary_sid), sid);
10967 if (ret.len == -1) {
10970 ret = sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid);
10971 if (ret.len != -1) {
10974 ret = sid_parse(long_binary_sid, sizeof(long_binary_sid), sid);
10975 if (ret.len != -1) {
10981 /* Split a path name into filename and stream name components. Canonicalise
10982 * such that an implicit $DATA token is always explicit.
10984 * The "specification" of this function can be found in the
10985 * run_local_stream_name() function in torture.c, I've tried those
10986 * combinations against a W2k3 server.
10989 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10990 char **pbase, char **pstream)
10993 char *stream = NULL;
10994 char *sname; /* stream name */
10995 const char *stype; /* stream type */
10997 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10999 sname = strchr_m(fname, ':');
11001 if (sname == NULL) {
11002 if (pbase != NULL) {
11003 base = talloc_strdup(mem_ctx, fname);
11004 NT_STATUS_HAVE_NO_MEMORY(base);
11009 if (pbase != NULL) {
11010 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
11011 NT_STATUS_HAVE_NO_MEMORY(base);
11016 stype = strchr_m(sname, ':');
11018 if (stype == NULL) {
11019 sname = talloc_strdup(mem_ctx, sname);
11023 if (strcasecmp_m(stype, ":$DATA") != 0) {
11025 * If there is an explicit stream type, so far we only
11026 * allow $DATA. Is there anything else allowed? -- vl
11028 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
11030 return NT_STATUS_OBJECT_NAME_INVALID;
11032 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
11036 if (sname == NULL) {
11038 return NT_STATUS_NO_MEMORY;
11041 if (sname[0] == '\0') {
11043 * no stream name, so no stream
11048 if (pstream != NULL) {
11049 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
11050 if (stream == NULL) {
11051 TALLOC_FREE(sname);
11053 return NT_STATUS_NO_MEMORY;
11056 * upper-case the type field
11058 (void)strupper_m(strchr_m(stream, ':')+1);
11062 if (pbase != NULL) {
11065 if (pstream != NULL) {
11068 return NT_STATUS_OK;
11071 static bool test_stream_name(const char *fname, const char *expected_base,
11072 const char *expected_stream,
11073 NTSTATUS expected_status)
11077 char *stream = NULL;
11079 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
11080 if (!NT_STATUS_EQUAL(status, expected_status)) {
11084 if (!NT_STATUS_IS_OK(status)) {
11088 if (base == NULL) goto error;
11090 if (strcmp(expected_base, base) != 0) goto error;
11092 if ((expected_stream != NULL) && (stream == NULL)) goto error;
11093 if ((expected_stream == NULL) && (stream != NULL)) goto error;
11095 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
11099 TALLOC_FREE(stream);
11103 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
11104 fname, expected_base ? expected_base : "<NULL>",
11105 expected_stream ? expected_stream : "<NULL>",
11106 nt_errstr(expected_status));
11107 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
11108 base ? base : "<NULL>", stream ? stream : "<NULL>",
11109 nt_errstr(status));
11111 TALLOC_FREE(stream);
11115 static bool run_local_stream_name(int dummy)
11119 ret &= test_stream_name(
11120 "bla", "bla", NULL, NT_STATUS_OK);
11121 ret &= test_stream_name(
11122 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
11123 ret &= test_stream_name(
11124 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
11125 ret &= test_stream_name(
11126 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
11127 ret &= test_stream_name(
11128 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
11129 ret &= test_stream_name(
11130 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
11131 ret &= test_stream_name(
11132 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
11133 ret &= test_stream_name(
11134 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
11139 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
11141 if (a.length != b.length) {
11142 printf("a.length=%d != b.length=%d\n",
11143 (int)a.length, (int)b.length);
11146 if (memcmp(a.data, b.data, a.length) != 0) {
11147 printf("a.data and b.data differ\n");
11153 static bool run_local_memcache(int dummy)
11155 struct memcache *cache;
11156 DATA_BLOB k1, k2, k3;
11160 TALLOC_CTX *mem_ctx;
11165 size_t size1, size2;
11168 mem_ctx = talloc_init("foo");
11169 if (mem_ctx == NULL) {
11173 /* STAT_CACHE TESTS */
11175 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
11177 if (cache == NULL) {
11178 printf("memcache_init failed\n");
11182 d1 = data_blob_const("d1", 2);
11183 d3 = data_blob_const("d3", 2);
11185 k1 = data_blob_const("d1", 2);
11186 k2 = data_blob_const("d2", 2);
11187 k3 = data_blob_const("d3", 2);
11189 memcache_add(cache, STAT_CACHE, k1, d1);
11191 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
11192 printf("could not find k1\n");
11195 if (!data_blob_equal(d1, v1)) {
11199 memcache_add(cache, STAT_CACHE, k1, d3);
11201 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
11202 printf("could not find replaced k1\n");
11205 if (!data_blob_equal(d3, v3)) {
11209 TALLOC_FREE(cache);
11211 /* GETWD_CACHE TESTS */
11212 str1 = talloc_strdup(mem_ctx, "string1");
11213 if (str1 == NULL) {
11216 ptr2 = str1; /* Keep an alias for comparison. */
11218 str2 = talloc_strdup(mem_ctx, "string2");
11219 if (str2 == NULL) {
11223 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
11224 if (cache == NULL) {
11225 printf("memcache_init failed\n");
11229 memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
11230 /* str1 == NULL now. */
11231 ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
11232 if (ptr1 == NULL) {
11233 printf("could not find k2\n");
11236 if (ptr1 != ptr2) {
11237 printf("fetch of k2 got wrong string\n");
11241 /* Add a blob to ensure k2 gets purged. */
11242 d3 = data_blob_talloc_zero(mem_ctx, 180);
11243 memcache_add(cache, STAT_CACHE, k3, d3);
11245 ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
11246 if (ptr2 != NULL) {
11247 printf("Did find k2, should have been purged\n");
11251 TALLOC_FREE(cache);
11252 TALLOC_FREE(mem_ctx);
11254 mem_ctx = talloc_init("foo");
11255 if (mem_ctx == NULL) {
11259 cache = memcache_init(NULL, 0);
11260 if (cache == NULL) {
11264 str1 = talloc_strdup(mem_ctx, "string1");
11265 if (str1 == NULL) {
11268 str2 = talloc_strdup(mem_ctx, "string2");
11269 if (str2 == NULL) {
11272 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
11273 data_blob_string_const("torture"), &str1);
11274 size1 = talloc_total_size(cache);
11276 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
11277 data_blob_string_const("torture"), &str2);
11278 size2 = talloc_total_size(cache);
11280 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
11282 if (size2 > size1) {
11283 printf("memcache leaks memory!\n");
11289 TALLOC_FREE(cache);
11293 static void wbclient_done(struct tevent_req *req)
11296 struct winbindd_response *wb_resp;
11297 int *i = (int *)tevent_req_callback_data_void(req);
11299 wbc_err = wb_trans_recv(req, req, &wb_resp);
11302 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
11305 static bool run_wbclient_multi_ping(int dummy)
11307 struct tevent_context *ev;
11308 struct wb_context **wb_ctx;
11309 struct winbindd_request wb_req;
11310 bool result = false;
11313 BlockSignals(True, SIGPIPE);
11315 ev = tevent_context_init(talloc_tos());
11320 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
11321 if (wb_ctx == NULL) {
11325 ZERO_STRUCT(wb_req);
11326 wb_req.cmd = WINBINDD_PING;
11328 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
11330 for (i=0; i<torture_nprocs; i++) {
11331 wb_ctx[i] = wb_context_init(ev, NULL);
11332 if (wb_ctx[i] == NULL) {
11335 for (j=0; j<torture_numops; j++) {
11336 struct tevent_req *req;
11337 req = wb_trans_send(ev, ev, wb_ctx[i],
11338 (j % 2) == 0, &wb_req);
11342 tevent_req_set_callback(req, wbclient_done, &i);
11348 while (i < torture_nprocs * torture_numops) {
11349 tevent_loop_once(ev);
11358 static bool dbtrans_inc(struct db_context *db)
11360 struct db_record *rec;
11366 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11368 printf(__location__ "fetch_lock failed\n");
11372 value = dbwrap_record_get_value(rec);
11374 if (value.dsize != sizeof(uint32_t)) {
11375 printf(__location__ "value.dsize = %d\n",
11380 memcpy(&val, value.dptr, sizeof(val));
11383 status = dbwrap_record_store(
11384 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
11385 if (!NT_STATUS_IS_OK(status)) {
11386 printf(__location__ "store failed: %s\n",
11387 nt_errstr(status));
11397 static bool run_local_dbtrans(int dummy)
11399 struct db_context *db;
11400 struct db_record *rec;
11406 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
11407 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
11410 printf("Could not open transtest.db\n");
11414 res = dbwrap_transaction_start(db);
11416 printf(__location__ "transaction_start failed\n");
11420 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
11422 printf(__location__ "fetch_lock failed\n");
11426 value = dbwrap_record_get_value(rec);
11428 if (value.dptr == NULL) {
11430 status = dbwrap_record_store(
11431 rec, make_tdb_data((uint8_t *)&initial,
11434 if (!NT_STATUS_IS_OK(status)) {
11435 printf(__location__ "store returned %s\n",
11436 nt_errstr(status));
11443 res = dbwrap_transaction_commit(db);
11445 printf(__location__ "transaction_commit failed\n");
11450 uint32_t val, val2;
11453 res = dbwrap_transaction_start(db);
11455 printf(__location__ "transaction_start failed\n");
11459 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
11460 if (!NT_STATUS_IS_OK(status)) {
11461 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11462 nt_errstr(status));
11466 for (i=0; i<10; i++) {
11467 if (!dbtrans_inc(db)) {
11472 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
11473 if (!NT_STATUS_IS_OK(status)) {
11474 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
11475 nt_errstr(status));
11479 if (val2 != val + 10) {
11480 printf(__location__ "val=%d, val2=%d\n",
11481 (int)val, (int)val2);
11485 printf("val2=%d\r", val2);
11487 res = dbwrap_transaction_commit(db);
11489 printf(__location__ "transaction_commit failed\n");
11499 * Just a dummy test to be run under a debugger. There's no real way
11500 * to inspect the tevent_poll specific function from outside of
11504 static bool run_local_tevent_poll(int dummy)
11506 struct tevent_context *ev;
11507 struct tevent_fd *fd1, *fd2;
11508 bool result = false;
11510 ev = tevent_context_init_byname(NULL, "poll");
11512 d_fprintf(stderr, "tevent_context_init_byname failed\n");
11516 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
11518 d_fprintf(stderr, "tevent_add_fd failed\n");
11521 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
11523 d_fprintf(stderr, "tevent_add_fd failed\n");
11528 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
11530 d_fprintf(stderr, "tevent_add_fd failed\n");
11540 static bool run_local_hex_encode_buf(int dummy)
11546 for (i=0; i<sizeof(src); i++) {
11549 hex_encode_buf(buf, src, sizeof(src));
11550 if (strcmp(buf, "0001020304050607") != 0) {
11553 hex_encode_buf(buf, NULL, 0);
11554 if (buf[0] != '\0') {
11560 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11582 "1001:1111:1111:1000:0:1111:1111:1111",
11591 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11605 "1001:1111:1111:1000:0:1111:1111:1111"
11608 static bool run_local_remove_duplicate_addrs2(int dummy)
11610 struct ip_service test_vector[28];
11613 /* Construct the sockaddr_storage test vector. */
11614 for (i = 0; i < 28; i++) {
11615 struct addrinfo hints;
11616 struct addrinfo *res = NULL;
11619 memset(&hints, '\0', sizeof(hints));
11620 hints.ai_flags = AI_NUMERICHOST;
11621 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11626 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11627 remove_duplicate_addrs2_test_strings_vector[i]);
11630 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11631 memcpy(&test_vector[i].ss,
11637 count = remove_duplicate_addrs2(test_vector, i);
11640 fprintf(stderr, "count wrong (%d) should be 14\n",
11645 for (i = 0; i < count; i++) {
11646 char addr[INET6_ADDRSTRLEN];
11648 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11650 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11651 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11654 remove_duplicate_addrs2_test_strings_result[i]);
11659 printf("run_local_remove_duplicate_addrs2: success\n");
11663 static bool run_local_tdb_opener(int dummy)
11669 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11670 O_RDWR|O_CREAT, 0755);
11672 perror("tdb_open failed");
11683 static bool run_local_tdb_writer(int dummy)
11689 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11691 perror("tdb_open failed");
11695 val.dptr = (uint8_t *)&v;
11696 val.dsize = sizeof(v);
11702 ret = tdb_store(t, val, val, 0);
11704 printf("%s\n", tdb_errorstr(t));
11709 data = tdb_fetch(t, val);
11710 if (data.dptr != NULL) {
11711 SAFE_FREE(data.dptr);
11717 static bool run_local_canonicalize_path(int dummy)
11719 const char *src[] = {
11726 ".././././../../../boo",
11730 const char *dst[] = {
11743 for (i = 0; src[i] != NULL; i++) {
11744 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11746 perror("talloc fail\n");
11749 if (strcmp(d, dst[i]) != 0) {
11751 "canonicalize mismatch %s -> %s != %s",
11752 src[i], d, dst[i]);
11760 static bool run_ign_bad_negprot(int dummy)
11762 struct tevent_context *ev;
11763 struct tevent_req *req;
11764 struct smbXcli_conn *conn;
11765 struct sockaddr_storage ss;
11770 printf("starting ignore bad negprot\n");
11772 ok = resolve_name(host, &ss, 0x20, true);
11774 d_fprintf(stderr, "Could not resolve name %s\n", host);
11778 status = open_socket_out(&ss, 445, 10000, &fd);
11779 if (!NT_STATUS_IS_OK(status)) {
11780 d_fprintf(stderr, "open_socket_out failed: %s\n",
11781 nt_errstr(status));
11785 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11787 if (conn == NULL) {
11788 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11792 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11793 if (NT_STATUS_IS_OK(status)) {
11794 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11798 ev = samba_tevent_context_init(talloc_tos());
11800 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11804 req = smb1cli_session_setup_nt1_send(
11805 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11806 data_blob_null, data_blob_null, 0x40,
11807 "Windows 2000 2195", "Windows 2000 5.0");
11809 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11813 ok = tevent_req_poll_ntstatus(req, ev, &status);
11815 d_fprintf(stderr, "tevent_req_poll failed\n");
11819 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11821 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11822 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11823 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11824 nt_errstr(status));
11830 printf("starting ignore bad negprot\n");
11835 static double create_procs(bool (*fn)(int), bool *result)
11838 volatile pid_t *child_status;
11839 volatile bool *child_status_out;
11842 struct timeval start;
11846 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11847 if (!child_status) {
11848 printf("Failed to setup shared memory\n");
11852 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11853 if (!child_status_out) {
11854 printf("Failed to setup result status shared memory\n");
11858 for (i = 0; i < torture_nprocs; i++) {
11859 child_status[i] = 0;
11860 child_status_out[i] = True;
11863 start = timeval_current();
11865 for (i=0;i<torture_nprocs;i++) {
11868 pid_t mypid = getpid();
11869 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11871 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11874 if (torture_open_connection(¤t_cli, i)) break;
11875 if (tries-- == 0) {
11876 printf("pid %d failed to start\n", (int)getpid());
11882 child_status[i] = getpid();
11884 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11886 child_status_out[i] = fn(i);
11893 for (i=0;i<torture_nprocs;i++) {
11894 if (child_status[i]) synccount++;
11896 if (synccount == torture_nprocs) break;
11898 } while (timeval_elapsed(&start) < 30);
11900 if (synccount != torture_nprocs) {
11901 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11903 return timeval_elapsed(&start);
11906 /* start the client load */
11907 start = timeval_current();
11909 for (i=0;i<torture_nprocs;i++) {
11910 child_status[i] = 0;
11913 printf("%d clients started\n", torture_nprocs);
11915 for (i=0;i<torture_nprocs;i++) {
11916 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11921 for (i=0;i<torture_nprocs;i++) {
11922 if (!child_status_out[i]) {
11926 return timeval_elapsed(&start);
11929 #define FLAG_MULTIPROC 1
11935 } torture_ops[] = {
11938 .fn = run_fdpasstest,
11942 .fn = run_locktest1,
11946 .fn = run_locktest2,
11950 .fn = run_locktest3,
11954 .fn = run_locktest4,
11958 .fn = run_locktest5,
11962 .fn = run_locktest6,
11966 .fn = run_locktest7,
11970 .fn = run_locktest8,
11974 .fn = run_locktest9,
11978 .fn = run_unlinktest,
11982 .fn = run_browsetest,
11986 .fn = run_attrtest,
11990 .fn = run_trans2test,
11994 .fn = run_maxfidtest,
11995 .flags = FLAG_MULTIPROC,
12000 .flags = FLAG_MULTIPROC,
12003 .name = "RANDOMIPC",
12004 .fn = run_randomipc,
12007 .name = "NEGNOWAIT",
12008 .fn = run_negprot_nowait,
12036 .fn = run_dirtest1,
12039 .name = "DIR-CREATETIME",
12040 .fn = run_dir_createtime,
12044 .fn = torture_denytest1,
12048 .fn = torture_denytest2,
12052 .fn = run_tcon_test,
12056 .fn = run_tcon_devtype_test,
12060 .fn = run_readwritetest,
12064 .fn = run_readwritemulti,
12065 .flags = FLAG_MULTIPROC
12069 .fn = run_readwritelarge,
12072 .name = "RW-SIGNING",
12073 .fn = run_readwritelarge_signtest,
12077 .fn = run_opentest,
12081 .fn = run_simple_posix_open_test,
12084 .name = "POSIX-APPEND",
12085 .fn = run_posix_append,
12088 .name = "POSIX-SYMLINK-ACL",
12089 .fn = run_acl_symlink_test,
12092 .name = "POSIX-SYMLINK-EA",
12093 .fn = run_ea_symlink_test,
12096 .name = "POSIX-STREAM-DELETE",
12097 .fn = run_posix_stream_delete,
12100 .name = "POSIX-OFD-LOCK",
12101 .fn = run_posix_ofd_lock_test,
12104 .name = "POSIX-MKDIR",
12105 .fn = run_posix_mkdir_test,
12108 .name = "WINDOWS-BAD-SYMLINK",
12109 .fn = run_symlink_open_test,
12112 .name = "CASE-INSENSITIVE-CREATE",
12113 .fn = run_case_insensitive_create,
12116 .name = "ASYNC-ECHO",
12117 .fn = run_async_echo,
12120 .name = "UID-REGRESSION-TEST",
12121 .fn = run_uid_regression_test,
12124 .name = "SHORTNAME-TEST",
12125 .fn = run_shortname_test,
12128 .name = "ADDRCHANGE",
12129 .fn = run_addrchange,
12133 .name = "OPENATTR",
12134 .fn = run_openattrtest,
12146 .name = "RENAME-ACCESS",
12147 .fn = run_rename_access,
12150 .name = "OWNER-RIGHTS",
12151 .fn = run_owner_rights,
12155 .fn = run_deletetest,
12158 .name = "DELETE-PRINT",
12159 .fn = run_delete_print_test,
12162 .name = "WILDDELETE",
12163 .fn = run_wild_deletetest,
12166 .name = "DELETE-LN",
12167 .fn = run_deletetest_ln,
12170 .name = "PROPERTIES",
12171 .fn = run_properties,
12175 .fn = torture_mangle,
12182 .name = "MANGLE-ILLEGAL",
12183 .fn = run_mangle_illegal,
12190 .name = "TRANS2SCAN",
12191 .fn = torture_trans2_scan,
12194 .name = "NTTRANSSCAN",
12195 .fn = torture_nttrans_scan,
12199 .fn = torture_utable,
12202 .name = "CASETABLE",
12203 .fn = torture_casetable,
12206 .name = "ERRMAPEXTRACT",
12207 .fn = run_error_map_extract,
12210 .name = "PIPE_NUMBER",
12211 .fn = run_pipe_number,
12215 .fn = run_tcon2_test,
12219 .fn = torture_ioctl_test,
12223 .fn = torture_chkpath_test,
12227 .fn = run_fdsesstest,
12234 .name = "SESSSETUP_BENCH",
12235 .fn = run_sesssetup_bench,
12250 .name = "WINDOWS-WRITE",
12251 .fn = run_windows_write,
12254 .name = "LARGE_READX",
12255 .fn = run_large_readx,
12258 .name = "NTTRANS-CREATE",
12259 .fn = run_nttrans_create,
12262 .name = "NTTRANS-FSCTL",
12263 .fn = run_nttrans_fsctl,
12266 .name = "CLI_ECHO",
12267 .fn = run_cli_echo,
12270 .name = "CLI_SPLICE",
12271 .fn = run_cli_splice,
12278 .name = "STREAMERROR",
12279 .fn = run_streamerror,
12282 .name = "NOTIFY-BENCH",
12283 .fn = run_notify_bench,
12286 .name = "NOTIFY-BENCH2",
12287 .fn = run_notify_bench2,
12290 .name = "NOTIFY-BENCH3",
12291 .fn = run_notify_bench3,
12294 .name = "BAD-NBT-SESSION",
12295 .fn = run_bad_nbt_session,
12298 .name = "IGN-BAD-NEGPROT",
12299 .fn = run_ign_bad_negprot,
12302 .name = "SMB-ANY-CONNECT",
12303 .fn = run_smb_any_connect,
12306 .name = "NOTIFY-ONLINE",
12307 .fn = run_notify_online,
12310 .name = "SMB2-BASIC",
12311 .fn = run_smb2_basic,
12314 .name = "SMB2-NEGPROT",
12315 .fn = run_smb2_negprot,
12318 .name = "SMB2-ANONYMOUS",
12319 .fn = run_smb2_anonymous,
12322 .name = "SMB2-SESSION-RECONNECT",
12323 .fn = run_smb2_session_reconnect,
12326 .name = "SMB2-TCON-DEPENDENCE",
12327 .fn = run_smb2_tcon_dependence,
12330 .name = "SMB2-MULTI-CHANNEL",
12331 .fn = run_smb2_multi_channel,
12334 .name = "SMB2-SESSION-REAUTH",
12335 .fn = run_smb2_session_reauth,
12338 .name = "SMB2-FTRUNCATE",
12339 .fn = run_smb2_ftruncate,
12342 .name = "SMB2-DIR-FSYNC",
12343 .fn = run_smb2_dir_fsync,
12346 .name = "CLEANUP1",
12347 .fn = run_cleanup1,
12350 .name = "CLEANUP2",
12351 .fn = run_cleanup2,
12354 .name = "CLEANUP3",
12355 .fn = run_cleanup3,
12358 .name = "CLEANUP4",
12359 .fn = run_cleanup4,
12362 .name = "OPLOCK-CANCEL",
12363 .fn = run_oplock_cancel,
12370 .name = "LOCAL-SUBSTITUTE",
12371 .fn = run_local_substitute,
12374 .name = "LOCAL-GENCACHE",
12375 .fn = run_local_gencache,
12378 .name = "LOCAL-DBWRAP-WATCH1",
12379 .fn = run_dbwrap_watch1,
12382 .name = "LOCAL-DBWRAP-WATCH2",
12383 .fn = run_dbwrap_watch2,
12386 .name = "LOCAL-DBWRAP-DO-LOCKED1",
12387 .fn = run_dbwrap_do_locked1,
12390 .name = "LOCAL-MESSAGING-READ1",
12391 .fn = run_messaging_read1,
12394 .name = "LOCAL-MESSAGING-READ2",
12395 .fn = run_messaging_read2,
12398 .name = "LOCAL-MESSAGING-READ3",
12399 .fn = run_messaging_read3,
12402 .name = "LOCAL-MESSAGING-READ4",
12403 .fn = run_messaging_read4,
12406 .name = "LOCAL-MESSAGING-FDPASS1",
12407 .fn = run_messaging_fdpass1,
12410 .name = "LOCAL-MESSAGING-FDPASS2",
12411 .fn = run_messaging_fdpass2,
12414 .name = "LOCAL-MESSAGING-FDPASS2a",
12415 .fn = run_messaging_fdpass2a,
12418 .name = "LOCAL-MESSAGING-FDPASS2b",
12419 .fn = run_messaging_fdpass2b,
12422 .name = "LOCAL-MESSAGING-SEND-ALL",
12423 .fn = run_messaging_send_all,
12426 .name = "LOCAL-BASE64",
12427 .fn = run_local_base64,
12430 .name = "LOCAL-RBTREE",
12431 .fn = run_local_rbtree,
12434 .name = "LOCAL-MEMCACHE",
12435 .fn = run_local_memcache,
12438 .name = "LOCAL-STREAM-NAME",
12439 .fn = run_local_stream_name,
12442 .name = "WBCLIENT-MULTI-PING",
12443 .fn = run_wbclient_multi_ping,
12446 .name = "LOCAL-string_to_sid",
12447 .fn = run_local_string_to_sid,
12450 .name = "LOCAL-sid_to_string",
12451 .fn = run_local_sid_to_string,
12454 .name = "LOCAL-binary_to_sid",
12455 .fn = run_local_binary_to_sid,
12458 .name = "LOCAL-DBTRANS",
12459 .fn = run_local_dbtrans,
12462 .name = "LOCAL-TEVENT-POLL",
12463 .fn = run_local_tevent_poll,
12466 .name = "LOCAL-CONVERT-STRING",
12467 .fn = run_local_convert_string,
12470 .name = "LOCAL-CONV-AUTH-INFO",
12471 .fn = run_local_conv_auth_info,
12474 .name = "LOCAL-hex_encode_buf",
12475 .fn = run_local_hex_encode_buf,
12478 .name = "LOCAL-IDMAP-TDB-COMMON",
12479 .fn = run_idmap_tdb_common_test,
12482 .name = "LOCAL-remove_duplicate_addrs2",
12483 .fn = run_local_remove_duplicate_addrs2,
12486 .name = "local-tdb-opener",
12487 .fn = run_local_tdb_opener,
12490 .name = "local-tdb-writer",
12491 .fn = run_local_tdb_writer,
12494 .name = "LOCAL-DBWRAP-CTDB",
12495 .fn = run_local_dbwrap_ctdb,
12498 .name = "LOCAL-BENCH-PTHREADPOOL",
12499 .fn = run_bench_pthreadpool,
12502 .name = "LOCAL-PTHREADPOOL-TEVENT",
12503 .fn = run_pthreadpool_tevent,
12506 .name = "LOCAL-G-LOCK1",
12510 .name = "LOCAL-G-LOCK2",
12514 .name = "LOCAL-G-LOCK3",
12518 .name = "LOCAL-G-LOCK4",
12522 .name = "LOCAL-G-LOCK5",
12526 .name = "LOCAL-G-LOCK6",
12530 .name = "LOCAL-G-LOCK-PING-PONG",
12531 .fn = run_g_lock_ping_pong,
12534 .name = "LOCAL-CANONICALIZE-PATH",
12535 .fn = run_local_canonicalize_path,
12538 .name = "LOCAL-NAMEMAP-CACHE1",
12539 .fn = run_local_namemap_cache1,
12542 .name = "LOCAL-IDMAP-CACHE1",
12543 .fn = run_local_idmap_cache1,
12546 .name = "qpathinfo-bufsize",
12547 .fn = run_qpathinfo_bufsize,
12550 .name = "hide-new-files-timeout",
12551 .fn = run_hidenewfiles,
12558 /****************************************************************************
12559 run a specified test or "ALL"
12560 ****************************************************************************/
12561 static bool run_test(const char *name)
12564 bool result = True;
12565 bool found = False;
12568 if (strequal(name,"ALL")) {
12569 for (i=0;torture_ops[i].name;i++) {
12570 run_test(torture_ops[i].name);
12575 for (i=0;torture_ops[i].name;i++) {
12576 fstr_sprintf(randomfname, "\\XX%x",
12577 (unsigned)random());
12579 if (strequal(name, torture_ops[i].name)) {
12581 printf("Running %s\n", name);
12582 if (torture_ops[i].flags & FLAG_MULTIPROC) {
12583 t = create_procs(torture_ops[i].fn, &result);
12586 printf("TEST %s FAILED!\n", name);
12589 struct timeval start;
12590 start = timeval_current();
12591 if (!torture_ops[i].fn(0)) {
12593 printf("TEST %s FAILED!\n", name);
12595 t = timeval_elapsed(&start);
12597 printf("%s took %g secs\n\n", name, t);
12602 printf("Did not find a test named %s\n", name);
12610 static void usage(void)
12614 printf("WARNING samba4 test suite is much more complete nowadays.\n");
12615 printf("Please use samba4 torture.\n\n");
12617 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
12619 printf("\t-d debuglevel\n");
12620 printf("\t-U user%%pass\n");
12621 printf("\t-k use kerberos\n");
12622 printf("\t-N numprocs\n");
12623 printf("\t-n my_netbios_name\n");
12624 printf("\t-W workgroup\n");
12625 printf("\t-o num_operations\n");
12626 printf("\t-O socket_options\n");
12627 printf("\t-m maximum protocol\n");
12628 printf("\t-L use oplocks\n");
12629 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
12630 printf("\t-A showall\n");
12631 printf("\t-p port\n");
12632 printf("\t-s seed\n");
12633 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
12634 printf("\t-f filename filename to test\n");
12635 printf("\t-e encrypt\n");
12638 printf("tests are:");
12639 for (i=0;torture_ops[i].name;i++) {
12640 printf(" %s", torture_ops[i].name);
12644 printf("default test is ALL\n");
12649 /****************************************************************************
12651 ****************************************************************************/
12652 int main(int argc,char *argv[])
12658 bool correct = True;
12659 TALLOC_CTX *frame = talloc_stackframe();
12660 int seed = time(NULL);
12662 #ifdef HAVE_SETBUFFER
12663 setbuffer(stdout, NULL, 0);
12666 setup_logging("smbtorture", DEBUG_STDOUT);
12671 if (is_default_dyn_CONFIGFILE()) {
12672 if(getenv("SMB_CONF_PATH")) {
12673 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
12676 lp_load_global(get_dyn_CONFIGFILE());
12683 for(p = argv[1]; *p; p++)
12687 if (strncmp(argv[1], "//", 2)) {
12691 fstrcpy(host, &argv[1][2]);
12692 p = strchr_m(&host[2],'/');
12697 fstrcpy(share, p+1);
12699 fstrcpy(myname, get_myname(talloc_tos()));
12701 fprintf(stderr, "Failed to get my hostname.\n");
12705 if (*username == 0 && getenv("LOGNAME")) {
12706 fstrcpy(username,getenv("LOGNAME"));
12712 fstrcpy(workgroup, lp_workgroup());
12714 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
12718 port_to_use = atoi(optarg);
12721 seed = atoi(optarg);
12724 fstrcpy(workgroup,optarg);
12727 lp_set_cmdline("client max protocol", optarg);
12730 torture_nprocs = atoi(optarg);
12733 torture_numops = atoi(optarg);
12736 lp_set_cmdline("log level", optarg);
12742 use_oplocks = True;
12745 local_path = optarg;
12748 torture_showall = True;
12751 fstrcpy(myname, optarg);
12754 client_txt = optarg;
12761 use_kerberos = True;
12763 d_printf("No kerberos support compiled in\n");
12769 fstrcpy(username,optarg);
12770 p = strchr_m(username,'%');
12773 fstrcpy(password, p+1);
12778 fstrcpy(multishare_conn_fname, optarg);
12779 use_multishare_conn = True;
12782 torture_blocksize = atoi(optarg);
12785 test_filename = SMB_STRDUP(optarg);
12788 printf("Unknown option %c (%d)\n", (char)opt, opt);
12793 d_printf("using seed %d\n", seed);
12797 if(use_kerberos && !gotuser) gotpass = True;
12800 char pwd[256] = {0};
12803 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
12805 fstrcpy(password, pwd);
12810 printf("host=%s share=%s user=%s myname=%s\n",
12811 host, share, username, myname);
12813 torture_creds = cli_session_creds_init(frame,
12819 false, /* fallback_after_kerberos */
12820 false, /* use_ccache */
12821 false); /* password_is_nt_hash */
12822 if (torture_creds == NULL) {
12823 d_printf("cli_session_creds_init() failed.\n");
12827 if (argc == optind) {
12828 correct = run_test("ALL");
12830 for (i=optind;i<argc;i++) {
12831 if (!run_test(argv[i])) {
12837 TALLOC_FREE(frame);