2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
29 #include "../lib/util/memcache.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap/dbwrap.h"
32 #include "dbwrap/dbwrap_open.h"
33 #include "dbwrap/dbwrap_rbt.h"
34 #include "talloc_dict.h"
35 #include "async_smb.h"
36 #include "libsmb/libsmb.h"
37 #include "libsmb/clirap.h"
39 #include "libsmb/nmblib.h"
40 #include "../lib/util/tevent_ntstatus.h"
42 #include "../libcli/smb/read_smb.h"
43 #include "../libcli/smb/smbXcli_base.h"
44 #include "lib/util/sys_rw_data.h"
45 #include "lib/util/base64.h"
50 fstring host, workgroup, share, password, username, myname;
51 static const char *sockops="TCP_NODELAY";
53 static int port_to_use=0;
54 int torture_numops=100;
55 int torture_blocksize=1024*1024;
56 static int procnum; /* records process count number when forking */
57 static struct cli_state *current_cli;
58 static fstring randomfname;
59 static bool use_oplocks;
60 static bool use_level_II_oplocks;
61 static const char *client_txt = "client_oplocks.txt";
62 static bool disable_spnego;
63 static bool use_kerberos;
64 static bool force_dos_errors;
65 static fstring multishare_conn_fname;
66 static bool use_multishare_conn = False;
67 static bool do_encrypt;
68 static const char *local_path = NULL;
69 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
72 bool torture_showall = False;
74 static double create_procs(bool (*fn)(int), bool *result);
76 /********************************************************************
77 Ensure a connection is encrypted.
78 ********************************************************************/
80 static bool force_cli_encryption(struct cli_state *c,
81 const char *sharename)
83 uint16_t major, minor;
84 uint32_t caplow, caphigh;
87 if (!SERVER_HAS_UNIX_CIFS(c)) {
88 d_printf("Encryption required and "
89 "server that doesn't support "
90 "UNIX extensions - failing connect\n");
94 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
96 if (!NT_STATUS_IS_OK(status)) {
97 d_printf("Encryption required and "
98 "can't get UNIX CIFS extensions "
99 "version from server: %s\n", nt_errstr(status));
103 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
104 d_printf("Encryption required and "
105 "share %s doesn't support "
106 "encryption.\n", sharename);
110 if (c->use_kerberos) {
111 status = cli_gss_smb_encryption_start(c);
113 status = cli_raw_ntlm_smb_encryption_start(c,
119 if (!NT_STATUS_IS_OK(status)) {
120 d_printf("Encryption required and "
121 "setup failed with error %s.\n",
130 static struct cli_state *open_nbt_connection(void)
136 if (disable_spnego) {
137 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
141 flags |= CLI_FULL_CONNECTION_OPLOCKS;
144 if (use_level_II_oplocks) {
145 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
149 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
152 if (force_dos_errors) {
153 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
156 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
157 signing_state, flags, &c);
158 if (!NT_STATUS_IS_OK(status)) {
159 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
163 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
168 /****************************************************************************
169 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
170 ****************************************************************************/
172 static bool cli_bad_session_request(int fd,
173 struct nmb_name *calling, struct nmb_name *called)
182 uint8_t message_type;
184 struct tevent_context *ev;
185 struct tevent_req *req;
187 frame = talloc_stackframe();
189 iov[0].iov_base = len_buf;
190 iov[0].iov_len = sizeof(len_buf);
192 /* put in the destination name */
194 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
196 if (iov[1].iov_base == NULL) {
199 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
200 talloc_get_size(iov[1].iov_base));
204 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
206 if (iov[2].iov_base == NULL) {
209 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
210 talloc_get_size(iov[2].iov_base));
212 /* Deliberately corrupt the name len (first byte) */
213 *((uint8_t *)iov[2].iov_base) = 100;
215 /* send a session request (RFC 1002) */
216 /* setup the packet length
217 * Remove four bytes from the length count, since the length
218 * field in the NBT Session Service header counts the number
219 * of bytes which follow. The cli_send_smb() function knows
220 * about this and accounts for those four bytes.
224 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
225 SCVAL(len_buf,0,0x81);
227 len = write_data_iov(fd, iov, 3);
232 ev = samba_tevent_context_init(frame);
236 req = read_smb_send(frame, ev, fd);
240 if (!tevent_req_poll(req, ev)) {
243 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
250 message_type = CVAL(inbuf, 0);
251 if (message_type != 0x83) {
252 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
257 if (smb_len(inbuf) != 1) {
258 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
259 (int)smb_len(inbuf));
263 error = CVAL(inbuf, 4);
265 d_fprintf(stderr, "Expected error 0x82, got %d\n",
276 /* Insert a NULL at the first separator of the given path and return a pointer
277 * to the remainder of the string.
280 terminate_path_at_separator(char * path)
288 if ((p = strchr_m(path, '/'))) {
293 if ((p = strchr_m(path, '\\'))) {
303 parse a //server/share type UNC name
305 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
306 char **hostname, char **sharename)
310 *hostname = *sharename = NULL;
312 if (strncmp(unc_name, "\\\\", 2) &&
313 strncmp(unc_name, "//", 2)) {
317 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
318 p = terminate_path_at_separator(*hostname);
321 *sharename = talloc_strdup(mem_ctx, p);
322 terminate_path_at_separator(*sharename);
325 if (*hostname && *sharename) {
329 TALLOC_FREE(*hostname);
330 TALLOC_FREE(*sharename);
334 static bool torture_open_connection_share(struct cli_state **c,
335 const char *hostname,
336 const char *sharename)
342 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
344 flags |= CLI_FULL_CONNECTION_OPLOCKS;
345 if (use_level_II_oplocks)
346 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
348 status = cli_full_connection(c, myname,
349 hostname, NULL, port_to_use,
352 password, flags, signing_state);
353 if (!NT_STATUS_IS_OK(status)) {
354 printf("failed to open share connection: //%s/%s port:%d - %s\n",
355 hostname, sharename, port_to_use, nt_errstr(status));
359 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
362 return force_cli_encryption(*c,
368 bool torture_open_connection(struct cli_state **c, int conn_index)
370 char **unc_list = NULL;
371 int num_unc_names = 0;
374 if (use_multishare_conn==True) {
376 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
377 if (!unc_list || num_unc_names <= 0) {
378 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
382 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
384 printf("Failed to parse UNC name %s\n",
385 unc_list[conn_index % num_unc_names]);
386 TALLOC_FREE(unc_list);
390 result = torture_open_connection_share(c, h, s);
392 /* h, s were copied earlier */
393 TALLOC_FREE(unc_list);
397 return torture_open_connection_share(c, host, share);
400 bool torture_init_connection(struct cli_state **pcli)
402 struct cli_state *cli;
404 cli = open_nbt_connection();
413 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
415 uint16_t old_vuid = cli_state_get_uid(cli);
416 size_t passlen = strlen(password);
420 cli_state_set_uid(cli, 0);
421 status = cli_session_setup(cli, username,
425 ret = NT_STATUS_IS_OK(status);
426 *new_vuid = cli_state_get_uid(cli);
427 cli_state_set_uid(cli, old_vuid);
432 bool torture_close_connection(struct cli_state *c)
437 status = cli_tdis(c);
438 if (!NT_STATUS_IS_OK(status)) {
439 printf("tdis failed (%s)\n", nt_errstr(status));
449 /* check if the server produced the expected dos or nt error code */
450 static bool check_both_error(int line, NTSTATUS status,
451 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
453 if (NT_STATUS_IS_DOS(status)) {
457 /* Check DOS error */
458 cclass = NT_STATUS_DOS_CLASS(status);
459 num = NT_STATUS_DOS_CODE(status);
461 if (eclass != cclass || ecode != num) {
462 printf("unexpected error code class=%d code=%d\n",
463 (int)cclass, (int)num);
464 printf(" expected %d/%d %s (line=%d)\n",
465 (int)eclass, (int)ecode, nt_errstr(nterr), line);
470 if (!NT_STATUS_EQUAL(nterr, status)) {
471 printf("unexpected error code %s\n",
473 printf(" expected %s (line=%d)\n",
474 nt_errstr(nterr), line);
483 /* check if the server produced the expected error code */
484 static bool check_error(int line, NTSTATUS status,
485 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
487 if (NT_STATUS_IS_DOS(status)) {
491 /* Check DOS error */
493 cclass = NT_STATUS_DOS_CLASS(status);
494 num = NT_STATUS_DOS_CODE(status);
496 if (eclass != cclass || ecode != num) {
497 printf("unexpected error code class=%d code=%d\n",
498 (int)cclass, (int)num);
499 printf(" expected %d/%d %s (line=%d)\n",
500 (int)eclass, (int)ecode, nt_errstr(nterr),
508 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
509 printf("unexpected error code %s\n",
511 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
521 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
525 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
527 while (!NT_STATUS_IS_OK(status)) {
528 if (!check_both_error(__LINE__, status, ERRDOS,
529 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
533 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
540 static bool rw_torture(struct cli_state *c)
542 const char *lockfname = "\\torture.lck";
546 pid_t pid2, pid = getpid();
553 memset(buf, '\0', sizeof(buf));
555 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
557 if (!NT_STATUS_IS_OK(status)) {
558 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
560 if (!NT_STATUS_IS_OK(status)) {
561 printf("open of %s failed (%s)\n",
562 lockfname, nt_errstr(status));
566 for (i=0;i<torture_numops;i++) {
567 unsigned n = (unsigned)sys_random()%10;
570 printf("%d\r", i); fflush(stdout);
572 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
574 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
578 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
580 if (!NT_STATUS_IS_OK(status)) {
581 printf("open failed (%s)\n", nt_errstr(status));
586 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
588 if (!NT_STATUS_IS_OK(status)) {
589 printf("write failed (%s)\n", nt_errstr(status));
594 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
595 sizeof(pid)+(j*sizeof(buf)),
597 if (!NT_STATUS_IS_OK(status)) {
598 printf("write failed (%s)\n",
606 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
608 if (!NT_STATUS_IS_OK(status)) {
609 printf("read failed (%s)\n", nt_errstr(status));
611 } else if (nread != sizeof(pid)) {
612 printf("read/write compare failed: "
613 "recv %ld req %ld\n", (unsigned long)nread,
614 (unsigned long)sizeof(pid));
619 printf("data corruption!\n");
623 status = cli_close(c, fnum);
624 if (!NT_STATUS_IS_OK(status)) {
625 printf("close failed (%s)\n", nt_errstr(status));
629 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
630 if (!NT_STATUS_IS_OK(status)) {
631 printf("unlink failed (%s)\n", nt_errstr(status));
635 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
636 if (!NT_STATUS_IS_OK(status)) {
637 printf("unlock failed (%s)\n", nt_errstr(status));
643 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
650 static bool run_torture(int dummy)
652 struct cli_state *cli;
657 smbXcli_conn_set_sockopt(cli->conn, sockops);
659 ret = rw_torture(cli);
661 if (!torture_close_connection(cli)) {
668 static bool rw_torture3(struct cli_state *c, char *lockfname)
670 uint16_t fnum = (uint16_t)-1;
675 unsigned countprev = 0;
678 NTSTATUS status = NT_STATUS_OK;
681 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
683 SIVAL(buf, i, sys_random());
690 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
691 if (!NT_STATUS_IS_OK(status)) {
692 printf("unlink failed (%s) (normal, this file should "
693 "not exist)\n", nt_errstr(status));
696 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
698 if (!NT_STATUS_IS_OK(status)) {
699 printf("first open read/write of %s failed (%s)\n",
700 lockfname, nt_errstr(status));
706 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
708 status = cli_openx(c, lockfname, O_RDONLY,
710 if (NT_STATUS_IS_OK(status)) {
715 if (!NT_STATUS_IS_OK(status)) {
716 printf("second open read-only of %s failed (%s)\n",
717 lockfname, nt_errstr(status));
723 for (count = 0; count < sizeof(buf); count += sent)
725 if (count >= countprev) {
726 printf("%d %8d\r", i, count);
729 countprev += (sizeof(buf) / 20);
734 sent = ((unsigned)sys_random()%(20))+ 1;
735 if (sent > sizeof(buf) - count)
737 sent = sizeof(buf) - count;
740 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
742 if (!NT_STATUS_IS_OK(status)) {
743 printf("write failed (%s)\n",
750 status = cli_read(c, fnum, buf_rd+count, count,
751 sizeof(buf)-count, &sent);
752 if(!NT_STATUS_IS_OK(status)) {
753 printf("read failed offset:%d size:%ld (%s)\n",
754 count, (unsigned long)sizeof(buf)-count,
758 } else if (sent > 0) {
759 if (memcmp(buf_rd+count, buf+count, sent) != 0)
761 printf("read/write compare failed\n");
762 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
771 status = cli_close(c, fnum);
772 if (!NT_STATUS_IS_OK(status)) {
773 printf("close failed (%s)\n", nt_errstr(status));
780 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
782 const char *lockfname = "\\torture2.lck";
792 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
793 if (!NT_STATUS_IS_OK(status)) {
794 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
797 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
799 if (!NT_STATUS_IS_OK(status)) {
800 printf("first open read/write of %s failed (%s)\n",
801 lockfname, nt_errstr(status));
805 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
806 if (!NT_STATUS_IS_OK(status)) {
807 printf("second open read-only of %s failed (%s)\n",
808 lockfname, nt_errstr(status));
809 cli_close(c1, fnum1);
813 for (i = 0; i < torture_numops; i++)
815 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
817 printf("%d\r", i); fflush(stdout);
820 generate_random_buffer((unsigned char *)buf, buf_size);
822 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
824 if (!NT_STATUS_IS_OK(status)) {
825 printf("write failed (%s)\n", nt_errstr(status));
830 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
831 if(!NT_STATUS_IS_OK(status)) {
832 printf("read failed (%s)\n", nt_errstr(status));
835 } else if (bytes_read != buf_size) {
836 printf("read failed\n");
837 printf("read %ld, expected %ld\n",
838 (unsigned long)bytes_read,
839 (unsigned long)buf_size);
844 if (memcmp(buf_rd, buf, buf_size) != 0)
846 printf("read/write compare failed\n");
852 status = cli_close(c2, fnum2);
853 if (!NT_STATUS_IS_OK(status)) {
854 printf("close failed (%s)\n", nt_errstr(status));
858 status = cli_close(c1, fnum1);
859 if (!NT_STATUS_IS_OK(status)) {
860 printf("close failed (%s)\n", nt_errstr(status));
864 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
865 if (!NT_STATUS_IS_OK(status)) {
866 printf("unlink failed (%s)\n", nt_errstr(status));
873 static bool run_readwritetest(int dummy)
875 struct cli_state *cli1, *cli2;
876 bool test1, test2 = False;
878 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
881 smbXcli_conn_set_sockopt(cli1->conn, sockops);
882 smbXcli_conn_set_sockopt(cli2->conn, sockops);
884 printf("starting readwritetest\n");
886 test1 = rw_torture2(cli1, cli2);
887 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
890 test2 = rw_torture2(cli1, cli1);
891 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
894 if (!torture_close_connection(cli1)) {
898 if (!torture_close_connection(cli2)) {
902 return (test1 && test2);
905 static bool run_readwritemulti(int dummy)
907 struct cli_state *cli;
912 smbXcli_conn_set_sockopt(cli->conn, sockops);
914 printf("run_readwritemulti: fname %s\n", randomfname);
915 test = rw_torture3(cli, randomfname);
917 if (!torture_close_connection(cli)) {
924 static bool run_readwritelarge_internal(void)
926 static struct cli_state *cli1;
928 const char *lockfname = "\\large.dat";
934 if (!torture_open_connection(&cli1, 0)) {
937 smbXcli_conn_set_sockopt(cli1->conn, sockops);
938 memset(buf,'\0',sizeof(buf));
940 printf("starting readwritelarge_internal\n");
942 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
944 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
946 if (!NT_STATUS_IS_OK(status)) {
947 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
951 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
953 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
955 if (!NT_STATUS_IS_OK(status)) {
956 printf("qfileinfo failed (%s)\n", nt_errstr(status));
960 if (fsize == sizeof(buf))
961 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
962 (unsigned long)fsize);
964 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
965 (unsigned long)fsize);
969 status = cli_close(cli1, fnum1);
970 if (!NT_STATUS_IS_OK(status)) {
971 printf("close failed (%s)\n", nt_errstr(status));
975 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
976 if (!NT_STATUS_IS_OK(status)) {
977 printf("unlink failed (%s)\n", nt_errstr(status));
981 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
983 if (!NT_STATUS_IS_OK(status)) {
984 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
988 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
990 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
992 if (!NT_STATUS_IS_OK(status)) {
993 printf("qfileinfo failed (%s)\n", nt_errstr(status));
997 if (fsize == sizeof(buf))
998 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
999 (unsigned long)fsize);
1001 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1002 (unsigned long)fsize);
1007 /* ToDo - set allocation. JRA */
1008 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1009 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1012 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1014 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1018 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1021 status = cli_close(cli1, fnum1);
1022 if (!NT_STATUS_IS_OK(status)) {
1023 printf("close failed (%s)\n", nt_errstr(status));
1027 if (!torture_close_connection(cli1)) {
1033 static bool run_readwritelarge(int dummy)
1035 return run_readwritelarge_internal();
1038 static bool run_readwritelarge_signtest(int dummy)
1041 signing_state = SMB_SIGNING_REQUIRED;
1042 ret = run_readwritelarge_internal();
1043 signing_state = SMB_SIGNING_DEFAULT;
1050 #define ival(s) strtol(s, NULL, 0)
1052 /* run a test that simulates an approximate netbench client load */
1053 static bool run_netbench(int client)
1055 struct cli_state *cli;
1060 const char *params[20];
1061 bool correct = True;
1067 smbXcli_conn_set_sockopt(cli->conn, sockops);
1071 slprintf(cname,sizeof(cname)-1, "client%d", client);
1073 f = fopen(client_txt, "r");
1080 while (fgets(line, sizeof(line)-1, f)) {
1084 line[strlen(line)-1] = 0;
1086 /* printf("[%d] %s\n", line_count, line); */
1088 all_string_sub(line,"client1", cname, sizeof(line));
1090 /* parse the command parameters */
1091 params[0] = strtok_r(line, " ", &saveptr);
1093 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1097 if (i < 2) continue;
1099 if (!strncmp(params[0],"SMB", 3)) {
1100 printf("ERROR: You are using a dbench 1 load file\n");
1104 if (!strcmp(params[0],"NTCreateX")) {
1105 nb_createx(params[1], ival(params[2]), ival(params[3]),
1107 } else if (!strcmp(params[0],"Close")) {
1108 nb_close(ival(params[1]));
1109 } else if (!strcmp(params[0],"Rename")) {
1110 nb_rename(params[1], params[2]);
1111 } else if (!strcmp(params[0],"Unlink")) {
1112 nb_unlink(params[1]);
1113 } else if (!strcmp(params[0],"Deltree")) {
1114 nb_deltree(params[1]);
1115 } else if (!strcmp(params[0],"Rmdir")) {
1116 nb_rmdir(params[1]);
1117 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1118 nb_qpathinfo(params[1]);
1119 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1120 nb_qfileinfo(ival(params[1]));
1121 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1122 nb_qfsinfo(ival(params[1]));
1123 } else if (!strcmp(params[0],"FIND_FIRST")) {
1124 nb_findfirst(params[1]);
1125 } else if (!strcmp(params[0],"WriteX")) {
1126 nb_writex(ival(params[1]),
1127 ival(params[2]), ival(params[3]), ival(params[4]));
1128 } else if (!strcmp(params[0],"ReadX")) {
1129 nb_readx(ival(params[1]),
1130 ival(params[2]), ival(params[3]), ival(params[4]));
1131 } else if (!strcmp(params[0],"Flush")) {
1132 nb_flush(ival(params[1]));
1134 printf("Unknown operation %s\n", params[0]);
1142 if (!torture_close_connection(cli)) {
1150 /* run a test that simulates an approximate netbench client load */
1151 static bool run_nbench(int dummy)
1154 bool correct = True;
1156 nbio_shmem(torture_nprocs);
1160 signal(SIGALRM, nb_alarm);
1162 t = create_procs(run_netbench, &correct);
1165 printf("\nThroughput %g MB/sec\n",
1166 1.0e-6 * nbio_total() / t);
1172 This test checks for two things:
1174 1) correct support for retaining locks over a close (ie. the server
1175 must not use posix semantics)
1176 2) support for lock timeouts
1178 static bool run_locktest1(int dummy)
1180 struct cli_state *cli1, *cli2;
1181 const char *fname = "\\lockt1.lck";
1182 uint16_t fnum1, fnum2, fnum3;
1184 unsigned lock_timeout;
1187 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1190 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1191 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1193 printf("starting locktest1\n");
1195 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1197 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1199 if (!NT_STATUS_IS_OK(status)) {
1200 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1204 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1205 if (!NT_STATUS_IS_OK(status)) {
1206 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1210 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1211 if (!NT_STATUS_IS_OK(status)) {
1212 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1216 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1217 if (!NT_STATUS_IS_OK(status)) {
1218 printf("lock1 failed (%s)\n", nt_errstr(status));
1222 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1223 if (NT_STATUS_IS_OK(status)) {
1224 printf("lock2 succeeded! This is a locking bug\n");
1227 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1228 NT_STATUS_LOCK_NOT_GRANTED)) {
1233 lock_timeout = (1 + (random() % 20));
1234 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1236 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1237 if (NT_STATUS_IS_OK(status)) {
1238 printf("lock3 succeeded! This is a locking bug\n");
1241 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1242 NT_STATUS_FILE_LOCK_CONFLICT)) {
1248 if (ABS(t2 - t1) < lock_timeout-1) {
1249 printf("error: This server appears not to support timed lock requests\n");
1252 printf("server slept for %u seconds for a %u second timeout\n",
1253 (unsigned int)(t2-t1), lock_timeout);
1255 status = cli_close(cli1, fnum2);
1256 if (!NT_STATUS_IS_OK(status)) {
1257 printf("close1 failed (%s)\n", nt_errstr(status));
1261 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1262 if (NT_STATUS_IS_OK(status)) {
1263 printf("lock4 succeeded! This is a locking bug\n");
1266 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1267 NT_STATUS_FILE_LOCK_CONFLICT)) {
1272 status = cli_close(cli1, fnum1);
1273 if (!NT_STATUS_IS_OK(status)) {
1274 printf("close2 failed (%s)\n", nt_errstr(status));
1278 status = cli_close(cli2, fnum3);
1279 if (!NT_STATUS_IS_OK(status)) {
1280 printf("close3 failed (%s)\n", nt_errstr(status));
1284 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1285 if (!NT_STATUS_IS_OK(status)) {
1286 printf("unlink failed (%s)\n", nt_errstr(status));
1291 if (!torture_close_connection(cli1)) {
1295 if (!torture_close_connection(cli2)) {
1299 printf("Passed locktest1\n");
1304 this checks to see if a secondary tconx can use open files from an
1307 static bool run_tcon_test(int dummy)
1309 static struct cli_state *cli;
1310 const char *fname = "\\tcontest.tmp";
1312 uint16_t cnum1, cnum2, cnum3;
1313 uint16_t vuid1, vuid2;
1318 memset(buf, '\0', sizeof(buf));
1320 if (!torture_open_connection(&cli, 0)) {
1323 smbXcli_conn_set_sockopt(cli->conn, sockops);
1325 printf("starting tcontest\n");
1327 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1329 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1330 if (!NT_STATUS_IS_OK(status)) {
1331 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1335 cnum1 = cli_state_get_tid(cli);
1336 vuid1 = cli_state_get_uid(cli);
1338 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 printf("initial write failed (%s)", nt_errstr(status));
1344 status = cli_tree_connect(cli, share, "?????",
1345 password, strlen(password)+1);
1346 if (!NT_STATUS_IS_OK(status)) {
1347 printf("%s refused 2nd tree connect (%s)\n", host,
1353 cnum2 = cli_state_get_tid(cli);
1354 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1355 vuid2 = cli_state_get_uid(cli) + 1;
1357 /* try a write with the wrong tid */
1358 cli_state_set_tid(cli, cnum2);
1360 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1361 if (NT_STATUS_IS_OK(status)) {
1362 printf("* server allows write with wrong TID\n");
1365 printf("server fails write with wrong TID : %s\n",
1370 /* try a write with an invalid tid */
1371 cli_state_set_tid(cli, cnum3);
1373 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1374 if (NT_STATUS_IS_OK(status)) {
1375 printf("* server allows write with invalid TID\n");
1378 printf("server fails write with invalid TID : %s\n",
1382 /* try a write with an invalid vuid */
1383 cli_state_set_uid(cli, vuid2);
1384 cli_state_set_tid(cli, cnum1);
1386 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1387 if (NT_STATUS_IS_OK(status)) {
1388 printf("* server allows write with invalid VUID\n");
1391 printf("server fails write with invalid VUID : %s\n",
1395 cli_state_set_tid(cli, cnum1);
1396 cli_state_set_uid(cli, vuid1);
1398 status = cli_close(cli, fnum1);
1399 if (!NT_STATUS_IS_OK(status)) {
1400 printf("close failed (%s)\n", nt_errstr(status));
1404 cli_state_set_tid(cli, cnum2);
1406 status = cli_tdis(cli);
1407 if (!NT_STATUS_IS_OK(status)) {
1408 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1412 cli_state_set_tid(cli, cnum1);
1414 if (!torture_close_connection(cli)) {
1423 checks for old style tcon support
1425 static bool run_tcon2_test(int dummy)
1427 static struct cli_state *cli;
1428 uint16_t cnum, max_xmit;
1432 if (!torture_open_connection(&cli, 0)) {
1435 smbXcli_conn_set_sockopt(cli->conn, sockops);
1437 printf("starting tcon2 test\n");
1439 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1443 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1447 if (!NT_STATUS_IS_OK(status)) {
1448 printf("tcon2 failed : %s\n", nt_errstr(status));
1450 printf("tcon OK : max_xmit=%d cnum=%d\n",
1451 (int)max_xmit, (int)cnum);
1454 if (!torture_close_connection(cli)) {
1458 printf("Passed tcon2 test\n");
1462 static bool tcon_devtest(struct cli_state *cli,
1463 const char *myshare, const char *devtype,
1464 const char *return_devtype,
1465 NTSTATUS expected_error)
1470 status = cli_tree_connect(cli, myshare, devtype,
1471 password, strlen(password)+1);
1473 if (NT_STATUS_IS_OK(expected_error)) {
1474 if (NT_STATUS_IS_OK(status)) {
1475 if (strcmp(cli->dev, return_devtype) == 0) {
1478 printf("tconX to share %s with type %s "
1479 "succeeded but returned the wrong "
1480 "device type (got [%s] but should have got [%s])\n",
1481 myshare, devtype, cli->dev, return_devtype);
1485 printf("tconX to share %s with type %s "
1486 "should have succeeded but failed\n",
1492 if (NT_STATUS_IS_OK(status)) {
1493 printf("tconx to share %s with type %s "
1494 "should have failed but succeeded\n",
1498 if (NT_STATUS_EQUAL(status, expected_error)) {
1501 printf("Returned unexpected error\n");
1510 checks for correct tconX support
1512 static bool run_tcon_devtype_test(int dummy)
1514 static struct cli_state *cli1 = NULL;
1519 status = cli_full_connection(&cli1, myname,
1520 host, NULL, port_to_use,
1522 username, workgroup,
1523 password, flags, signing_state);
1525 if (!NT_STATUS_IS_OK(status)) {
1526 printf("could not open connection\n");
1530 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1533 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1536 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1539 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1542 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1545 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1548 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1551 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1554 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1557 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1563 printf("Passed tcondevtest\n");
1570 This test checks that
1572 1) the server supports multiple locking contexts on the one SMB
1573 connection, distinguished by PID.
1575 2) the server correctly fails overlapping locks made by the same PID (this
1576 goes against POSIX behaviour, which is why it is tricky to implement)
1578 3) the server denies unlock requests by an incorrect client PID
1580 static bool run_locktest2(int dummy)
1582 static struct cli_state *cli;
1583 const char *fname = "\\lockt2.lck";
1584 uint16_t fnum1, fnum2, fnum3;
1585 bool correct = True;
1588 if (!torture_open_connection(&cli, 0)) {
1592 smbXcli_conn_set_sockopt(cli->conn, sockops);
1594 printf("starting locktest2\n");
1596 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1600 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1601 if (!NT_STATUS_IS_OK(status)) {
1602 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1606 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1607 if (!NT_STATUS_IS_OK(status)) {
1608 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1614 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1615 if (!NT_STATUS_IS_OK(status)) {
1616 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1622 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1623 if (!NT_STATUS_IS_OK(status)) {
1624 printf("lock1 failed (%s)\n", nt_errstr(status));
1628 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1629 if (NT_STATUS_IS_OK(status)) {
1630 printf("WRITE lock1 succeeded! This is a locking bug\n");
1633 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1634 NT_STATUS_LOCK_NOT_GRANTED)) {
1639 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1640 if (NT_STATUS_IS_OK(status)) {
1641 printf("WRITE lock2 succeeded! This is a locking bug\n");
1644 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1645 NT_STATUS_LOCK_NOT_GRANTED)) {
1650 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1651 if (NT_STATUS_IS_OK(status)) {
1652 printf("READ lock2 succeeded! This is a locking bug\n");
1655 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1656 NT_STATUS_FILE_LOCK_CONFLICT)) {
1661 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1662 if (!NT_STATUS_IS_OK(status)) {
1663 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1666 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1667 printf("unlock at 100 succeeded! This is a locking bug\n");
1671 status = cli_unlock(cli, fnum1, 0, 4);
1672 if (NT_STATUS_IS_OK(status)) {
1673 printf("unlock1 succeeded! This is a locking bug\n");
1676 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1677 NT_STATUS_RANGE_NOT_LOCKED)) {
1682 status = cli_unlock(cli, fnum1, 0, 8);
1683 if (NT_STATUS_IS_OK(status)) {
1684 printf("unlock2 succeeded! This is a locking bug\n");
1687 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1688 NT_STATUS_RANGE_NOT_LOCKED)) {
1693 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1694 if (NT_STATUS_IS_OK(status)) {
1695 printf("lock3 succeeded! This is a locking bug\n");
1698 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1699 NT_STATUS_LOCK_NOT_GRANTED)) {
1706 status = cli_close(cli, fnum1);
1707 if (!NT_STATUS_IS_OK(status)) {
1708 printf("close1 failed (%s)\n", nt_errstr(status));
1712 status = cli_close(cli, fnum2);
1713 if (!NT_STATUS_IS_OK(status)) {
1714 printf("close2 failed (%s)\n", nt_errstr(status));
1718 status = cli_close(cli, fnum3);
1719 if (!NT_STATUS_IS_OK(status)) {
1720 printf("close3 failed (%s)\n", nt_errstr(status));
1724 if (!torture_close_connection(cli)) {
1728 printf("locktest2 finished\n");
1735 This test checks that
1737 1) the server supports the full offset range in lock requests
1739 static bool run_locktest3(int dummy)
1741 static struct cli_state *cli1, *cli2;
1742 const char *fname = "\\lockt3.lck";
1743 uint16_t fnum1, fnum2;
1746 bool correct = True;
1749 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1751 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1754 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1755 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1757 printf("starting locktest3\n");
1759 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1761 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1763 if (!NT_STATUS_IS_OK(status)) {
1764 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1768 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1769 if (!NT_STATUS_IS_OK(status)) {
1770 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1774 for (offset=i=0;i<torture_numops;i++) {
1777 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1778 if (!NT_STATUS_IS_OK(status)) {
1779 printf("lock1 %d failed (%s)\n",
1785 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1786 if (!NT_STATUS_IS_OK(status)) {
1787 printf("lock2 %d failed (%s)\n",
1794 for (offset=i=0;i<torture_numops;i++) {
1797 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1798 if (NT_STATUS_IS_OK(status)) {
1799 printf("error: lock1 %d succeeded!\n", i);
1803 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1804 if (NT_STATUS_IS_OK(status)) {
1805 printf("error: lock2 %d succeeded!\n", i);
1809 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1810 if (NT_STATUS_IS_OK(status)) {
1811 printf("error: lock3 %d succeeded!\n", i);
1815 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1816 if (NT_STATUS_IS_OK(status)) {
1817 printf("error: lock4 %d succeeded!\n", i);
1822 for (offset=i=0;i<torture_numops;i++) {
1825 status = cli_unlock(cli1, fnum1, offset-1, 1);
1826 if (!NT_STATUS_IS_OK(status)) {
1827 printf("unlock1 %d failed (%s)\n",
1833 status = cli_unlock(cli2, fnum2, offset-2, 1);
1834 if (!NT_STATUS_IS_OK(status)) {
1835 printf("unlock2 %d failed (%s)\n",
1842 status = cli_close(cli1, fnum1);
1843 if (!NT_STATUS_IS_OK(status)) {
1844 printf("close1 failed (%s)\n", nt_errstr(status));
1848 status = cli_close(cli2, fnum2);
1849 if (!NT_STATUS_IS_OK(status)) {
1850 printf("close2 failed (%s)\n", nt_errstr(status));
1854 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1855 if (!NT_STATUS_IS_OK(status)) {
1856 printf("unlink failed (%s)\n", nt_errstr(status));
1860 if (!torture_close_connection(cli1)) {
1864 if (!torture_close_connection(cli2)) {
1868 printf("finished locktest3\n");
1873 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1874 char *buf, off_t offset, size_t size,
1875 size_t *nread, size_t expect)
1880 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1882 if(!NT_STATUS_IS_OK(status)) {
1884 } else if (l_nread != expect) {
1895 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1896 printf("** "); correct = False; \
1900 looks at overlapping locks
1902 static bool run_locktest4(int dummy)
1904 static struct cli_state *cli1, *cli2;
1905 const char *fname = "\\lockt4.lck";
1906 uint16_t fnum1, fnum2, f;
1909 bool correct = True;
1912 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1916 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1917 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1919 printf("starting locktest4\n");
1921 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1923 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1924 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1926 memset(buf, 0, sizeof(buf));
1928 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1930 if (!NT_STATUS_IS_OK(status)) {
1931 printf("Failed to create file: %s\n", nt_errstr(status));
1936 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1937 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1938 EXPECTED(ret, False);
1939 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1941 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1942 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1943 EXPECTED(ret, True);
1944 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1946 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1947 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1948 EXPECTED(ret, False);
1949 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1951 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1952 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1953 EXPECTED(ret, True);
1954 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1956 ret = (cli_setpid(cli1, 1),
1957 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1958 (cli_setpid(cli1, 2),
1959 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1960 EXPECTED(ret, False);
1961 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1963 ret = (cli_setpid(cli1, 1),
1964 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1965 (cli_setpid(cli1, 2),
1966 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1967 EXPECTED(ret, True);
1968 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1970 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1971 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1972 EXPECTED(ret, True);
1973 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1975 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1976 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1977 EXPECTED(ret, False);
1978 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1980 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1981 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1982 EXPECTED(ret, False);
1983 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1985 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1986 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
1987 EXPECTED(ret, True);
1988 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1990 ret = (cli_setpid(cli1, 1),
1991 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1992 (cli_setpid(cli1, 2),
1993 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
1994 EXPECTED(ret, False);
1995 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1997 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
1998 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
1999 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2000 EXPECTED(ret, False);
2001 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2004 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2005 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2006 EXPECTED(ret, False);
2007 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2009 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2010 ret = NT_STATUS_IS_OK(status);
2012 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2014 ret = NT_STATUS_IS_OK(status);
2016 EXPECTED(ret, False);
2017 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2020 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2021 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2022 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2023 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2024 EXPECTED(ret, True);
2025 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2028 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2029 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2030 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2031 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2032 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2034 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2035 EXPECTED(ret, True);
2036 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2038 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2039 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2040 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2042 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2043 EXPECTED(ret, True);
2044 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2046 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2047 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2048 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2050 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2051 EXPECTED(ret, True);
2052 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2054 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2055 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2056 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2057 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2059 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2060 EXPECTED(ret, True);
2061 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2063 cli_close(cli1, fnum1);
2064 cli_close(cli2, fnum2);
2065 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2066 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2067 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2068 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2069 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2070 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2071 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2073 cli_close(cli1, fnum1);
2074 EXPECTED(ret, True);
2075 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2078 cli_close(cli1, fnum1);
2079 cli_close(cli2, fnum2);
2080 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2081 torture_close_connection(cli1);
2082 torture_close_connection(cli2);
2084 printf("finished locktest4\n");
2089 looks at lock upgrade/downgrade.
2091 static bool run_locktest5(int dummy)
2093 static struct cli_state *cli1, *cli2;
2094 const char *fname = "\\lockt5.lck";
2095 uint16_t fnum1, fnum2, fnum3;
2098 bool correct = True;
2101 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2105 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2106 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2108 printf("starting locktest5\n");
2110 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2112 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2113 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2114 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2116 memset(buf, 0, sizeof(buf));
2118 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2120 if (!NT_STATUS_IS_OK(status)) {
2121 printf("Failed to create file: %s\n", nt_errstr(status));
2126 /* Check for NT bug... */
2127 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2128 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2129 cli_close(cli1, fnum1);
2130 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2131 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2132 ret = NT_STATUS_IS_OK(status);
2133 EXPECTED(ret, True);
2134 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2135 cli_close(cli1, fnum1);
2136 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2137 cli_unlock(cli1, fnum3, 0, 1);
2139 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2140 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2141 EXPECTED(ret, True);
2142 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2144 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2145 ret = NT_STATUS_IS_OK(status);
2146 EXPECTED(ret, False);
2148 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2150 /* Unlock the process 2 lock. */
2151 cli_unlock(cli2, fnum2, 0, 4);
2153 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2154 ret = NT_STATUS_IS_OK(status);
2155 EXPECTED(ret, False);
2157 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2159 /* Unlock the process 1 fnum3 lock. */
2160 cli_unlock(cli1, fnum3, 0, 4);
2162 /* Stack 2 more locks here. */
2163 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2164 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2166 EXPECTED(ret, True);
2167 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2169 /* Unlock the first process lock, then check this was the WRITE lock that was
2172 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2173 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2175 EXPECTED(ret, True);
2176 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2178 /* Unlock the process 2 lock. */
2179 cli_unlock(cli2, fnum2, 0, 4);
2181 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2183 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2184 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2185 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2187 EXPECTED(ret, True);
2188 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2190 /* Ensure the next unlock fails. */
2191 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2192 EXPECTED(ret, False);
2193 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2195 /* Ensure connection 2 can get a write lock. */
2196 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2197 ret = NT_STATUS_IS_OK(status);
2198 EXPECTED(ret, True);
2200 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2204 cli_close(cli1, fnum1);
2205 cli_close(cli2, fnum2);
2206 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2207 if (!torture_close_connection(cli1)) {
2210 if (!torture_close_connection(cli2)) {
2214 printf("finished locktest5\n");
2220 tries the unusual lockingX locktype bits
2222 static bool run_locktest6(int dummy)
2224 static struct cli_state *cli;
2225 const char *fname[1] = { "\\lock6.txt" };
2230 if (!torture_open_connection(&cli, 0)) {
2234 smbXcli_conn_set_sockopt(cli->conn, sockops);
2236 printf("starting locktest6\n");
2239 printf("Testing %s\n", fname[i]);
2241 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2243 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2244 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2245 cli_close(cli, fnum);
2246 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2248 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2249 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2250 cli_close(cli, fnum);
2251 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2253 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2256 torture_close_connection(cli);
2258 printf("finished locktest6\n");
2262 static bool run_locktest7(int dummy)
2264 struct cli_state *cli1;
2265 const char *fname = "\\lockt7.lck";
2268 bool correct = False;
2272 if (!torture_open_connection(&cli1, 0)) {
2276 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2278 printf("starting locktest7\n");
2280 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2282 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2284 memset(buf, 0, sizeof(buf));
2286 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2288 if (!NT_STATUS_IS_OK(status)) {
2289 printf("Failed to create file: %s\n", nt_errstr(status));
2293 cli_setpid(cli1, 1);
2295 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2296 if (!NT_STATUS_IS_OK(status)) {
2297 printf("Unable to apply read lock on range 130:4, "
2298 "error was %s\n", nt_errstr(status));
2301 printf("pid1 successfully locked range 130:4 for READ\n");
2304 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2305 if (!NT_STATUS_IS_OK(status)) {
2306 printf("pid1 unable to read the range 130:4, error was %s\n",
2309 } else if (nread != 4) {
2310 printf("pid1 unable to read the range 130:4, "
2311 "recv %ld req %d\n", (unsigned long)nread, 4);
2314 printf("pid1 successfully read the range 130:4\n");
2317 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2318 if (!NT_STATUS_IS_OK(status)) {
2319 printf("pid1 unable to write to the range 130:4, error was "
2320 "%s\n", nt_errstr(status));
2321 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2322 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2326 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2330 cli_setpid(cli1, 2);
2332 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2333 if (!NT_STATUS_IS_OK(status)) {
2334 printf("pid2 unable to read the range 130:4, error was %s\n",
2337 } else if (nread != 4) {
2338 printf("pid2 unable to read the range 130:4, "
2339 "recv %ld req %d\n", (unsigned long)nread, 4);
2342 printf("pid2 successfully read the range 130:4\n");
2345 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2346 if (!NT_STATUS_IS_OK(status)) {
2347 printf("pid2 unable to write to the range 130:4, error was "
2348 "%s\n", nt_errstr(status));
2349 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2350 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2354 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2358 cli_setpid(cli1, 1);
2359 cli_unlock(cli1, fnum1, 130, 4);
2361 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2366 printf("pid1 successfully locked range 130:4 for WRITE\n");
2369 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2370 if (!NT_STATUS_IS_OK(status)) {
2371 printf("pid1 unable to read the range 130:4, error was %s\n",
2374 } else if (nread != 4) {
2375 printf("pid1 unable to read the range 130:4, "
2376 "recv %ld req %d\n", (unsigned long)nread, 4);
2379 printf("pid1 successfully read the range 130:4\n");
2382 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2383 if (!NT_STATUS_IS_OK(status)) {
2384 printf("pid1 unable to write to the range 130:4, error was "
2385 "%s\n", nt_errstr(status));
2388 printf("pid1 successfully wrote to the range 130:4\n");
2391 cli_setpid(cli1, 2);
2393 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2394 if (!NT_STATUS_IS_OK(status)) {
2395 printf("pid2 unable to read the range 130:4, error was "
2396 "%s\n", nt_errstr(status));
2397 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2398 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2402 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2403 (unsigned long)nread);
2407 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2408 if (!NT_STATUS_IS_OK(status)) {
2409 printf("pid2 unable to write to the range 130:4, error was "
2410 "%s\n", nt_errstr(status));
2411 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2412 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2416 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2420 cli_unlock(cli1, fnum1, 130, 0);
2424 cli_close(cli1, fnum1);
2425 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2426 torture_close_connection(cli1);
2428 printf("finished locktest7\n");
2433 * This demonstrates a problem with our use of GPFS share modes: A file
2434 * descriptor sitting in the pending close queue holding a GPFS share mode
2435 * blocks opening a file another time. Happens with Word 2007 temp files.
2436 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2437 * open is denied with NT_STATUS_SHARING_VIOLATION.
2440 static bool run_locktest8(int dummy)
2442 struct cli_state *cli1;
2443 const char *fname = "\\lockt8.lck";
2444 uint16_t fnum1, fnum2;
2446 bool correct = False;
2449 if (!torture_open_connection(&cli1, 0)) {
2453 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2455 printf("starting locktest8\n");
2457 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2459 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2461 if (!NT_STATUS_IS_OK(status)) {
2462 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2466 memset(buf, 0, sizeof(buf));
2468 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2469 if (!NT_STATUS_IS_OK(status)) {
2470 d_fprintf(stderr, "cli_openx second time returned %s\n",
2475 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2476 if (!NT_STATUS_IS_OK(status)) {
2477 printf("Unable to apply read lock on range 1:1, error was "
2478 "%s\n", nt_errstr(status));
2482 status = cli_close(cli1, fnum1);
2483 if (!NT_STATUS_IS_OK(status)) {
2484 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2488 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2489 if (!NT_STATUS_IS_OK(status)) {
2490 d_fprintf(stderr, "cli_openx third time returned %s\n",
2498 cli_close(cli1, fnum1);
2499 cli_close(cli1, fnum2);
2500 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2501 torture_close_connection(cli1);
2503 printf("finished locktest8\n");
2508 * This test is designed to be run in conjunction with
2509 * external NFS or POSIX locks taken in the filesystem.
2510 * It checks that the smbd server will block until the
2511 * lock is released and then acquire it. JRA.
2514 static bool got_alarm;
2515 static struct cli_state *alarm_cli;
2517 static void alarm_handler(int dummy)
2522 static void alarm_handler_parent(int dummy)
2524 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2527 static void do_local_lock(int read_fd, int write_fd)
2532 const char *local_pathname = NULL;
2535 local_pathname = talloc_asprintf(talloc_tos(),
2536 "%s/lockt9.lck", local_path);
2537 if (!local_pathname) {
2538 printf("child: alloc fail\n");
2542 unlink(local_pathname);
2543 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2545 printf("child: open of %s failed %s.\n",
2546 local_pathname, strerror(errno));
2550 /* Now take a fcntl lock. */
2551 lock.l_type = F_WRLCK;
2552 lock.l_whence = SEEK_SET;
2555 lock.l_pid = getpid();
2557 ret = fcntl(fd,F_SETLK,&lock);
2559 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2560 local_pathname, strerror(errno));
2563 printf("child: got lock 0:4 on file %s.\n",
2568 CatchSignal(SIGALRM, alarm_handler);
2570 /* Signal the parent. */
2571 if (write(write_fd, &c, 1) != 1) {
2572 printf("child: start signal fail %s.\n",
2579 /* Wait for the parent to be ready. */
2580 if (read(read_fd, &c, 1) != 1) {
2581 printf("child: reply signal fail %s.\n",
2589 printf("child: released lock 0:4 on file %s.\n",
2595 static bool run_locktest9(int dummy)
2597 struct cli_state *cli1;
2598 const char *fname = "\\lockt9.lck";
2600 bool correct = False;
2601 int pipe_in[2], pipe_out[2];
2605 struct timeval start;
2609 printf("starting locktest9\n");
2611 if (local_path == NULL) {
2612 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2616 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2621 if (child_pid == -1) {
2625 if (child_pid == 0) {
2627 do_local_lock(pipe_out[0], pipe_in[1]);
2637 ret = read(pipe_in[0], &c, 1);
2639 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2644 if (!torture_open_connection(&cli1, 0)) {
2648 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2650 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2652 if (!NT_STATUS_IS_OK(status)) {
2653 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2657 /* Ensure the child has the lock. */
2658 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2659 if (NT_STATUS_IS_OK(status)) {
2660 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2663 d_printf("Child has the lock.\n");
2666 /* Tell the child to wait 5 seconds then exit. */
2667 ret = write(pipe_out[1], &c, 1);
2669 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2674 /* Wait 20 seconds for the lock. */
2676 CatchSignal(SIGALRM, alarm_handler_parent);
2679 start = timeval_current();
2681 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2682 if (!NT_STATUS_IS_OK(status)) {
2683 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2684 "%s\n", nt_errstr(status));
2689 seconds = timeval_elapsed(&start);
2691 printf("Parent got the lock after %.2f seconds.\n",
2694 status = cli_close(cli1, fnum);
2695 if (!NT_STATUS_IS_OK(status)) {
2696 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2703 cli_close(cli1, fnum);
2704 torture_close_connection(cli1);
2708 printf("finished locktest9\n");
2713 test whether fnums and tids open on one VC are available on another (a major
2716 static bool run_fdpasstest(int dummy)
2718 struct cli_state *cli1, *cli2;
2719 const char *fname = "\\fdpass.tst";
2724 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2727 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2728 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2730 printf("starting fdpasstest\n");
2732 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2734 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2736 if (!NT_STATUS_IS_OK(status)) {
2737 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2741 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2743 if (!NT_STATUS_IS_OK(status)) {
2744 printf("write failed (%s)\n", nt_errstr(status));
2748 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2749 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2750 cli_setpid(cli2, cli_getpid(cli1));
2752 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2753 printf("read succeeded! nasty security hole [%s]\n", buf);
2757 cli_close(cli1, fnum1);
2758 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2760 torture_close_connection(cli1);
2761 torture_close_connection(cli2);
2763 printf("finished fdpasstest\n");
2767 static bool run_fdsesstest(int dummy)
2769 struct cli_state *cli;
2771 uint16_t saved_vuid;
2773 uint16_t saved_cnum;
2774 const char *fname = "\\fdsess.tst";
2775 const char *fname1 = "\\fdsess1.tst";
2782 if (!torture_open_connection(&cli, 0))
2784 smbXcli_conn_set_sockopt(cli->conn, sockops);
2786 if (!torture_cli_session_setup2(cli, &new_vuid))
2789 saved_cnum = cli_state_get_tid(cli);
2790 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", "", 1)))
2792 new_cnum = cli_state_get_tid(cli);
2793 cli_state_set_tid(cli, saved_cnum);
2795 printf("starting fdsesstest\n");
2797 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2798 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2800 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2801 if (!NT_STATUS_IS_OK(status)) {
2802 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2806 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2808 if (!NT_STATUS_IS_OK(status)) {
2809 printf("write failed (%s)\n", nt_errstr(status));
2813 saved_vuid = cli_state_get_uid(cli);
2814 cli_state_set_uid(cli, new_vuid);
2816 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2817 printf("read succeeded with different vuid! "
2818 "nasty security hole [%s]\n", buf);
2821 /* Try to open a file with different vuid, samba cnum. */
2822 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2823 printf("create with different vuid, same cnum succeeded.\n");
2824 cli_close(cli, fnum2);
2825 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2827 printf("create with different vuid, same cnum failed.\n");
2828 printf("This will cause problems with service clients.\n");
2832 cli_state_set_uid(cli, saved_vuid);
2834 /* Try with same vuid, different cnum. */
2835 cli_state_set_tid(cli, new_cnum);
2837 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2838 printf("read succeeded with different cnum![%s]\n", buf);
2842 cli_state_set_tid(cli, saved_cnum);
2843 cli_close(cli, fnum1);
2844 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2846 torture_close_connection(cli);
2848 printf("finished fdsesstest\n");
2853 This test checks that
2855 1) the server does not allow an unlink on a file that is open
2857 static bool run_unlinktest(int dummy)
2859 struct cli_state *cli;
2860 const char *fname = "\\unlink.tst";
2862 bool correct = True;
2865 if (!torture_open_connection(&cli, 0)) {
2869 smbXcli_conn_set_sockopt(cli->conn, sockops);
2871 printf("starting unlink test\n");
2873 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2877 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2878 if (!NT_STATUS_IS_OK(status)) {
2879 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2883 status = cli_unlink(cli, fname,
2884 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2885 if (NT_STATUS_IS_OK(status)) {
2886 printf("error: server allowed unlink on an open file\n");
2889 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2890 NT_STATUS_SHARING_VIOLATION);
2893 cli_close(cli, fnum);
2894 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2896 if (!torture_close_connection(cli)) {
2900 printf("unlink test finished\n");
2907 test how many open files this server supports on the one socket
2909 static bool run_maxfidtest(int dummy)
2911 struct cli_state *cli;
2913 uint16_t fnums[0x11000];
2916 bool correct = True;
2922 printf("failed to connect\n");
2926 smbXcli_conn_set_sockopt(cli->conn, sockops);
2928 for (i=0; i<0x11000; i++) {
2929 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2930 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2932 if (!NT_STATUS_IS_OK(status)) {
2933 printf("open of %s failed (%s)\n",
2934 fname, nt_errstr(status));
2935 printf("maximum fnum is %d\n", i);
2943 printf("cleaning up\n");
2945 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2946 cli_close(cli, fnums[i]);
2948 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2949 if (!NT_STATUS_IS_OK(status)) {
2950 printf("unlink of %s failed (%s)\n",
2951 fname, nt_errstr(status));
2958 printf("maxfid test finished\n");
2959 if (!torture_close_connection(cli)) {
2965 /* generate a random buffer */
2966 static void rand_buf(char *buf, int len)
2969 *buf = (char)sys_random();
2974 /* send smb negprot commands, not reading the response */
2975 static bool run_negprot_nowait(int dummy)
2977 struct tevent_context *ev;
2979 struct cli_state *cli;
2980 bool correct = True;
2982 printf("starting negprot nowait test\n");
2984 ev = samba_tevent_context_init(talloc_tos());
2989 if (!(cli = open_nbt_connection())) {
2994 for (i=0;i<50000;i++) {
2995 struct tevent_req *req;
2997 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
2998 PROTOCOL_CORE, PROTOCOL_NT1);
3003 if (!tevent_req_poll(req, ev)) {
3004 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3012 if (torture_close_connection(cli)) {
3016 printf("finished negprot nowait test\n");
3021 /* send smb negprot commands, not reading the response */
3022 static bool run_bad_nbt_session(int dummy)
3024 struct nmb_name called, calling;
3025 struct sockaddr_storage ss;
3030 printf("starting bad nbt session test\n");
3032 make_nmb_name(&calling, myname, 0x0);
3033 make_nmb_name(&called , host, 0x20);
3035 if (!resolve_name(host, &ss, 0x20, true)) {
3036 d_fprintf(stderr, "Could not resolve name %s\n", host);
3040 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3041 if (!NT_STATUS_IS_OK(status)) {
3042 d_fprintf(stderr, "open_socket_out failed: %s\n",
3047 ret = cli_bad_session_request(fd, &calling, &called);
3050 d_fprintf(stderr, "open_socket_out failed: %s\n",
3055 printf("finished bad nbt session test\n");
3059 /* send random IPC commands */
3060 static bool run_randomipc(int dummy)
3062 char *rparam = NULL;
3064 unsigned int rdrcnt,rprcnt;
3066 int api, param_len, i;
3067 struct cli_state *cli;
3068 bool correct = True;
3071 printf("starting random ipc test\n");
3073 if (!torture_open_connection(&cli, 0)) {
3077 for (i=0;i<count;i++) {
3078 api = sys_random() % 500;
3079 param_len = (sys_random() % 64);
3081 rand_buf(param, param_len);
3086 param, param_len, 8,
3087 NULL, 0, CLI_BUFFER_SIZE,
3091 printf("%d/%d\r", i,count);
3094 printf("%d/%d\n", i, count);
3096 if (!torture_close_connection(cli)) {
3103 printf("finished random ipc test\n");
3110 static void browse_callback(const char *sname, uint32_t stype,
3111 const char *comment, void *state)
3113 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3119 This test checks the browse list code
3122 static bool run_browsetest(int dummy)
3124 static struct cli_state *cli;
3125 bool correct = True;
3127 printf("starting browse test\n");
3129 if (!torture_open_connection(&cli, 0)) {
3133 printf("domain list:\n");
3134 cli_NetServerEnum(cli, cli->server_domain,
3135 SV_TYPE_DOMAIN_ENUM,
3136 browse_callback, NULL);
3138 printf("machine list:\n");
3139 cli_NetServerEnum(cli, cli->server_domain,
3141 browse_callback, NULL);
3143 if (!torture_close_connection(cli)) {
3147 printf("browse test finished\n");
3155 This checks how the getatr calls works
3157 static bool run_attrtest(int dummy)
3159 struct cli_state *cli;
3162 const char *fname = "\\attrib123456789.tst";
3163 bool correct = True;
3166 printf("starting attrib test\n");
3168 if (!torture_open_connection(&cli, 0)) {
3172 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3173 cli_openx(cli, fname,
3174 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3175 cli_close(cli, fnum);
3177 status = cli_getatr(cli, fname, NULL, NULL, &t);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("getatr failed (%s)\n", nt_errstr(status));
3183 if (abs(t - time(NULL)) > 60*60*24*10) {
3184 printf("ERROR: SMBgetatr bug. time is %s",
3190 t2 = t-60*60*24; /* 1 day ago */
3192 status = cli_setatr(cli, fname, 0, t2);
3193 if (!NT_STATUS_IS_OK(status)) {
3194 printf("setatr failed (%s)\n", nt_errstr(status));
3198 status = cli_getatr(cli, fname, NULL, NULL, &t);
3199 if (!NT_STATUS_IS_OK(status)) {
3200 printf("getatr failed (%s)\n", nt_errstr(status));
3205 printf("ERROR: getatr/setatr bug. times are\n%s",
3207 printf("%s", ctime(&t2));
3211 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3213 if (!torture_close_connection(cli)) {
3217 printf("attrib test finished\n");
3224 This checks a couple of trans2 calls
3226 static bool run_trans2test(int dummy)
3228 struct cli_state *cli;
3231 time_t c_time, a_time, m_time;
3232 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3233 const char *fname = "\\trans2.tst";
3234 const char *dname = "\\trans2";
3235 const char *fname2 = "\\trans2\\trans2.tst";
3237 bool correct = True;
3241 printf("starting trans2 test\n");
3243 if (!torture_open_connection(&cli, 0)) {
3247 status = cli_get_fs_attr_info(cli, &fs_attr);
3248 if (!NT_STATUS_IS_OK(status)) {
3249 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3254 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3255 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3256 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3257 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3258 if (!NT_STATUS_IS_OK(status)) {
3259 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3263 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3264 if (!NT_STATUS_IS_OK(status)) {
3265 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3268 else if (strcmp(pname, fname)) {
3269 printf("qfilename gave different name? [%s] [%s]\n",
3274 cli_close(cli, fnum);
3278 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3279 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3281 if (!NT_STATUS_IS_OK(status)) {
3282 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3285 cli_close(cli, fnum);
3287 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3289 if (!NT_STATUS_IS_OK(status)) {
3290 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3293 time_t t = time(NULL);
3295 if (c_time != m_time) {
3296 printf("create time=%s", ctime(&c_time));
3297 printf("modify time=%s", ctime(&m_time));
3298 printf("This system appears to have sticky create times\n");
3300 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3301 printf("access time=%s", ctime(&a_time));
3302 printf("This system appears to set a midnight access time\n");
3306 if (abs(m_time - t) > 60*60*24*7) {
3307 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3313 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3314 cli_openx(cli, fname,
3315 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3316 cli_close(cli, fnum);
3317 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3318 &m_time_ts, &size, NULL, NULL);
3319 if (!NT_STATUS_IS_OK(status)) {
3320 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3323 if (w_time_ts.tv_sec < 60*60*24*2) {
3324 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3325 printf("This system appears to set a initial 0 write time\n");
3330 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3333 /* check if the server updates the directory modification time
3334 when creating a new file */
3335 status = cli_mkdir(cli, dname);
3336 if (!NT_STATUS_IS_OK(status)) {
3337 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3341 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3342 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3343 if (!NT_STATUS_IS_OK(status)) {
3344 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3348 cli_openx(cli, fname2,
3349 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3350 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3351 cli_close(cli, fnum);
3352 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3353 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3354 if (!NT_STATUS_IS_OK(status)) {
3355 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3358 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3360 printf("This system does not update directory modification times\n");
3364 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3365 cli_rmdir(cli, dname);
3367 if (!torture_close_connection(cli)) {
3371 printf("trans2 test finished\n");
3377 This checks new W2K calls.
3380 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3382 uint8_t *buf = NULL;
3386 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3387 CLI_BUFFER_SIZE, NULL, &buf, &len);
3388 if (!NT_STATUS_IS_OK(status)) {
3389 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3392 printf("qfileinfo: level %d, len = %u\n", level, len);
3393 dump_data(0, (uint8_t *)buf, len);
3400 static bool run_w2ktest(int dummy)
3402 struct cli_state *cli;
3404 const char *fname = "\\w2ktest\\w2k.tst";
3406 bool correct = True;
3408 printf("starting w2k test\n");
3410 if (!torture_open_connection(&cli, 0)) {
3414 cli_openx(cli, fname,
3415 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3417 for (level = 1004; level < 1040; level++) {
3418 new_trans(cli, fnum, level);
3421 cli_close(cli, fnum);
3423 if (!torture_close_connection(cli)) {
3427 printf("w2k test finished\n");
3434 this is a harness for some oplock tests
3436 static bool run_oplock1(int dummy)
3438 struct cli_state *cli1;
3439 const char *fname = "\\lockt1.lck";
3441 bool correct = True;
3444 printf("starting oplock test 1\n");
3446 if (!torture_open_connection(&cli1, 0)) {
3450 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3452 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3454 cli1->use_oplocks = True;
3456 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3458 if (!NT_STATUS_IS_OK(status)) {
3459 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3463 cli1->use_oplocks = False;
3465 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3466 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3468 status = cli_close(cli1, fnum1);
3469 if (!NT_STATUS_IS_OK(status)) {
3470 printf("close2 failed (%s)\n", nt_errstr(status));
3474 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3475 if (!NT_STATUS_IS_OK(status)) {
3476 printf("unlink failed (%s)\n", nt_errstr(status));
3480 if (!torture_close_connection(cli1)) {
3484 printf("finished oplock test 1\n");
3489 static bool run_oplock2(int dummy)
3491 struct cli_state *cli1, *cli2;
3492 const char *fname = "\\lockt2.lck";
3493 uint16_t fnum1, fnum2;
3494 int saved_use_oplocks = use_oplocks;
3496 bool correct = True;
3497 volatile bool *shared_correct;
3501 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3502 *shared_correct = True;
3504 use_level_II_oplocks = True;
3507 printf("starting oplock test 2\n");
3509 if (!torture_open_connection(&cli1, 0)) {
3510 use_level_II_oplocks = False;
3511 use_oplocks = saved_use_oplocks;
3515 if (!torture_open_connection(&cli2, 1)) {
3516 use_level_II_oplocks = False;
3517 use_oplocks = saved_use_oplocks;
3521 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3523 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3524 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3526 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3528 if (!NT_STATUS_IS_OK(status)) {
3529 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3533 /* Don't need the globals any more. */
3534 use_level_II_oplocks = False;
3535 use_oplocks = saved_use_oplocks;
3539 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3540 if (!NT_STATUS_IS_OK(status)) {
3541 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3542 *shared_correct = False;
3548 status = cli_close(cli2, fnum2);
3549 if (!NT_STATUS_IS_OK(status)) {
3550 printf("close2 failed (%s)\n", nt_errstr(status));
3551 *shared_correct = False;
3559 /* Ensure cli1 processes the break. Empty file should always return 0
3561 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3562 if (!NT_STATUS_IS_OK(status)) {
3563 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3565 } else if (nread != 0) {
3566 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3567 (unsigned long)nread, 0);
3571 /* Should now be at level II. */
3572 /* Test if sending a write locks causes a break to none. */
3573 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3574 if (!NT_STATUS_IS_OK(status)) {
3575 printf("lock failed (%s)\n", nt_errstr(status));
3579 cli_unlock(cli1, fnum1, 0, 4);
3583 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3584 if (!NT_STATUS_IS_OK(status)) {
3585 printf("lock failed (%s)\n", nt_errstr(status));
3589 cli_unlock(cli1, fnum1, 0, 4);
3593 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3595 status = cli_close(cli1, fnum1);
3596 if (!NT_STATUS_IS_OK(status)) {
3597 printf("close1 failed (%s)\n", nt_errstr(status));
3603 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3604 if (!NT_STATUS_IS_OK(status)) {
3605 printf("unlink failed (%s)\n", nt_errstr(status));
3609 if (!torture_close_connection(cli1)) {
3613 if (!*shared_correct) {
3617 printf("finished oplock test 2\n");
3622 struct oplock4_state {
3623 struct tevent_context *ev;
3624 struct cli_state *cli;
3629 static void oplock4_got_break(struct tevent_req *req);
3630 static void oplock4_got_open(struct tevent_req *req);
3632 static bool run_oplock4(int dummy)
3634 struct tevent_context *ev;
3635 struct cli_state *cli1, *cli2;
3636 struct tevent_req *oplock_req, *open_req;
3637 const char *fname = "\\lockt4.lck";
3638 const char *fname_ln = "\\lockt4_ln.lck";
3639 uint16_t fnum1, fnum2;
3640 int saved_use_oplocks = use_oplocks;
3642 bool correct = true;
3646 struct oplock4_state *state;
3648 printf("starting oplock test 4\n");
3650 if (!torture_open_connection(&cli1, 0)) {
3651 use_level_II_oplocks = false;
3652 use_oplocks = saved_use_oplocks;
3656 if (!torture_open_connection(&cli2, 1)) {
3657 use_level_II_oplocks = false;
3658 use_oplocks = saved_use_oplocks;
3662 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3663 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3665 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3666 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3668 /* Create the file. */
3669 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3671 if (!NT_STATUS_IS_OK(status)) {
3672 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3676 status = cli_close(cli1, fnum1);
3677 if (!NT_STATUS_IS_OK(status)) {
3678 printf("close1 failed (%s)\n", nt_errstr(status));
3682 /* Now create a hardlink. */
3683 status = cli_nt_hardlink(cli1, fname, fname_ln);
3684 if (!NT_STATUS_IS_OK(status)) {
3685 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3689 /* Prove that opening hardlinks cause deny modes to conflict. */
3690 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3691 if (!NT_STATUS_IS_OK(status)) {
3692 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3696 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3697 if (NT_STATUS_IS_OK(status)) {
3698 printf("open of %s succeeded - should fail with sharing violation.\n",
3703 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3704 printf("open of %s should fail with sharing violation. Got %s\n",
3705 fname_ln, nt_errstr(status));
3709 status = cli_close(cli1, fnum1);
3710 if (!NT_STATUS_IS_OK(status)) {
3711 printf("close1 failed (%s)\n", nt_errstr(status));
3715 cli1->use_oplocks = true;
3716 cli2->use_oplocks = true;
3718 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3719 if (!NT_STATUS_IS_OK(status)) {
3720 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3724 ev = samba_tevent_context_init(talloc_tos());
3726 printf("tevent_context_init failed\n");
3730 state = talloc(ev, struct oplock4_state);
3731 if (state == NULL) {
3732 printf("talloc failed\n");
3737 state->got_break = &got_break;
3738 state->fnum2 = &fnum2;
3740 oplock_req = cli_smb_oplock_break_waiter_send(
3741 talloc_tos(), ev, cli1);
3742 if (oplock_req == NULL) {
3743 printf("cli_smb_oplock_break_waiter_send failed\n");
3746 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3748 open_req = cli_openx_send(
3749 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3750 if (open_req == NULL) {
3751 printf("cli_openx_send failed\n");
3754 tevent_req_set_callback(open_req, oplock4_got_open, state);
3759 while (!got_break || fnum2 == 0xffff) {
3761 ret = tevent_loop_once(ev);
3763 printf("tevent_loop_once failed: %s\n",
3769 status = cli_close(cli2, fnum2);
3770 if (!NT_STATUS_IS_OK(status)) {
3771 printf("close2 failed (%s)\n", nt_errstr(status));
3775 status = cli_close(cli1, fnum1);
3776 if (!NT_STATUS_IS_OK(status)) {
3777 printf("close1 failed (%s)\n", nt_errstr(status));
3781 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3782 if (!NT_STATUS_IS_OK(status)) {
3783 printf("unlink failed (%s)\n", nt_errstr(status));
3787 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3788 if (!NT_STATUS_IS_OK(status)) {
3789 printf("unlink failed (%s)\n", nt_errstr(status));
3793 if (!torture_close_connection(cli1)) {
3801 printf("finished oplock test 4\n");
3806 static void oplock4_got_break(struct tevent_req *req)
3808 struct oplock4_state *state = tevent_req_callback_data(
3809 req, struct oplock4_state);
3814 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3816 if (!NT_STATUS_IS_OK(status)) {
3817 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3821 *state->got_break = true;
3823 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3826 printf("cli_oplock_ack_send failed\n");
3831 static void oplock4_got_open(struct tevent_req *req)
3833 struct oplock4_state *state = tevent_req_callback_data(
3834 req, struct oplock4_state);
3837 status = cli_openx_recv(req, state->fnum2);
3838 if (!NT_STATUS_IS_OK(status)) {
3839 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3840 *state->fnum2 = 0xffff;
3845 Test delete on close semantics.
3847 static bool run_deletetest(int dummy)
3849 struct cli_state *cli1 = NULL;
3850 struct cli_state *cli2 = NULL;
3851 const char *fname = "\\delete.file";
3852 uint16_t fnum1 = (uint16_t)-1;
3853 uint16_t fnum2 = (uint16_t)-1;
3854 bool correct = false;
3857 printf("starting delete test\n");
3859 if (!torture_open_connection(&cli1, 0)) {
3863 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3865 /* Test 1 - this should delete the file on close. */
3867 cli_setatr(cli1, fname, 0, 0);
3868 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3870 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3871 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3872 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
3873 if (!NT_STATUS_IS_OK(status)) {
3874 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3878 status = cli_close(cli1, fnum1);
3879 if (!NT_STATUS_IS_OK(status)) {
3880 printf("[1] close failed (%s)\n", nt_errstr(status));
3884 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3885 if (NT_STATUS_IS_OK(status)) {
3886 printf("[1] open of %s succeeded (should fail)\n", fname);
3890 printf("first delete on close test succeeded.\n");
3892 /* Test 2 - this should delete the file on close. */
3894 cli_setatr(cli1, fname, 0, 0);
3895 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3897 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3898 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3899 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3900 if (!NT_STATUS_IS_OK(status)) {
3901 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3905 status = cli_nt_delete_on_close(cli1, fnum1, true);
3906 if (!NT_STATUS_IS_OK(status)) {
3907 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3911 status = cli_close(cli1, fnum1);
3912 if (!NT_STATUS_IS_OK(status)) {
3913 printf("[2] close failed (%s)\n", nt_errstr(status));
3917 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3918 if (NT_STATUS_IS_OK(status)) {
3919 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3920 status = cli_close(cli1, fnum1);
3921 if (!NT_STATUS_IS_OK(status)) {
3922 printf("[2] close failed (%s)\n", nt_errstr(status));
3924 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3928 printf("second delete on close test succeeded.\n");
3931 cli_setatr(cli1, fname, 0, 0);
3932 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3934 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3935 FILE_ATTRIBUTE_NORMAL,
3936 FILE_SHARE_READ|FILE_SHARE_WRITE,
3937 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3938 if (!NT_STATUS_IS_OK(status)) {
3939 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3943 /* This should fail with a sharing violation - open for delete is only compatible
3944 with SHARE_DELETE. */
3946 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3947 FILE_ATTRIBUTE_NORMAL,
3948 FILE_SHARE_READ|FILE_SHARE_WRITE,
3949 FILE_OPEN, 0, 0, &fnum2, NULL);
3950 if (NT_STATUS_IS_OK(status)) {
3951 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3955 /* This should succeed. */
3956 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3957 FILE_ATTRIBUTE_NORMAL,
3958 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3959 FILE_OPEN, 0, 0, &fnum2, NULL);
3960 if (!NT_STATUS_IS_OK(status)) {
3961 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
3965 status = cli_nt_delete_on_close(cli1, fnum1, true);
3966 if (!NT_STATUS_IS_OK(status)) {
3967 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3971 status = cli_close(cli1, fnum1);
3972 if (!NT_STATUS_IS_OK(status)) {
3973 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3977 status = cli_close(cli1, fnum2);
3978 if (!NT_STATUS_IS_OK(status)) {
3979 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3983 /* This should fail - file should no longer be there. */
3985 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3986 if (NT_STATUS_IS_OK(status)) {
3987 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3988 status = cli_close(cli1, fnum1);
3989 if (!NT_STATUS_IS_OK(status)) {
3990 printf("[3] close failed (%s)\n", nt_errstr(status));
3992 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3996 printf("third delete on close test succeeded.\n");
3999 cli_setatr(cli1, fname, 0, 0);
4000 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4002 status = cli_ntcreate(cli1, fname, 0,
4003 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4004 FILE_ATTRIBUTE_NORMAL,
4005 FILE_SHARE_READ|FILE_SHARE_WRITE,
4006 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4007 if (!NT_STATUS_IS_OK(status)) {
4008 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4012 /* This should succeed. */
4013 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4014 FILE_ATTRIBUTE_NORMAL,
4015 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4016 FILE_OPEN, 0, 0, &fnum2, NULL);
4017 if (!NT_STATUS_IS_OK(status)) {
4018 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4022 status = cli_close(cli1, fnum2);
4023 if (!NT_STATUS_IS_OK(status)) {
4024 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4028 status = cli_nt_delete_on_close(cli1, fnum1, true);
4029 if (!NT_STATUS_IS_OK(status)) {
4030 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4034 /* This should fail - no more opens once delete on close set. */
4035 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4036 FILE_ATTRIBUTE_NORMAL,
4037 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4038 FILE_OPEN, 0, 0, &fnum2, NULL);
4039 if (NT_STATUS_IS_OK(status)) {
4040 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4044 status = cli_close(cli1, fnum1);
4045 if (!NT_STATUS_IS_OK(status)) {
4046 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4050 printf("fourth delete on close test succeeded.\n");
4053 cli_setatr(cli1, fname, 0, 0);
4054 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4056 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4057 if (!NT_STATUS_IS_OK(status)) {
4058 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4062 /* This should fail - only allowed on NT opens with DELETE access. */
4064 status = cli_nt_delete_on_close(cli1, fnum1, true);
4065 if (NT_STATUS_IS_OK(status)) {
4066 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4070 status = cli_close(cli1, fnum1);
4071 if (!NT_STATUS_IS_OK(status)) {
4072 printf("[5] close failed (%s)\n", nt_errstr(status));
4076 printf("fifth delete on close test succeeded.\n");
4079 cli_setatr(cli1, fname, 0, 0);
4080 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4082 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4083 FILE_ATTRIBUTE_NORMAL,
4084 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4085 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4086 if (!NT_STATUS_IS_OK(status)) {
4087 printf("[6] open of %s failed (%s)\n", fname,
4092 /* This should fail - only allowed on NT opens with DELETE access. */
4094 status = cli_nt_delete_on_close(cli1, fnum1, true);
4095 if (NT_STATUS_IS_OK(status)) {
4096 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4100 status = cli_close(cli1, fnum1);
4101 if (!NT_STATUS_IS_OK(status)) {
4102 printf("[6] close failed (%s)\n", nt_errstr(status));
4106 printf("sixth delete on close test succeeded.\n");
4109 cli_setatr(cli1, fname, 0, 0);
4110 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4112 status = cli_ntcreate(cli1, fname, 0,
4113 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4114 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4115 0, 0, &fnum1, NULL);
4116 if (!NT_STATUS_IS_OK(status)) {
4117 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4121 status = cli_nt_delete_on_close(cli1, fnum1, true);
4122 if (!NT_STATUS_IS_OK(status)) {
4123 printf("[7] setting delete_on_close on file failed !\n");
4127 status = cli_nt_delete_on_close(cli1, fnum1, false);
4128 if (!NT_STATUS_IS_OK(status)) {
4129 printf("[7] unsetting delete_on_close on file failed !\n");
4133 status = cli_close(cli1, fnum1);
4134 if (!NT_STATUS_IS_OK(status)) {
4135 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4139 /* This next open should succeed - we reset the flag. */
4140 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4141 if (!NT_STATUS_IS_OK(status)) {
4142 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4146 status = cli_close(cli1, fnum1);
4147 if (!NT_STATUS_IS_OK(status)) {
4148 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4152 printf("seventh delete on close test succeeded.\n");
4155 cli_setatr(cli1, fname, 0, 0);
4156 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4158 if (!torture_open_connection(&cli2, 1)) {
4159 printf("[8] failed to open second connection.\n");
4163 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4165 status = cli_ntcreate(cli1, fname, 0,
4166 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4167 FILE_ATTRIBUTE_NORMAL,
4168 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4169 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4170 if (!NT_STATUS_IS_OK(status)) {
4171 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4175 status = cli_ntcreate(cli2, fname, 0,
4176 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4177 FILE_ATTRIBUTE_NORMAL,
4178 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4179 FILE_OPEN, 0, 0, &fnum2, NULL);
4180 if (!NT_STATUS_IS_OK(status)) {
4181 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4185 status = cli_nt_delete_on_close(cli1, fnum1, true);
4186 if (!NT_STATUS_IS_OK(status)) {
4187 printf("[8] setting delete_on_close on file failed !\n");
4191 status = cli_close(cli1, fnum1);
4192 if (!NT_STATUS_IS_OK(status)) {
4193 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4197 status = cli_close(cli2, fnum2);
4198 if (!NT_STATUS_IS_OK(status)) {
4199 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4203 /* This should fail.. */
4204 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4205 if (NT_STATUS_IS_OK(status)) {
4206 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4210 printf("eighth delete on close test succeeded.\n");
4214 /* This should fail - we need to set DELETE_ACCESS. */
4215 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4216 FILE_ATTRIBUTE_NORMAL,
4219 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4220 if (NT_STATUS_IS_OK(status)) {
4221 printf("[9] open of %s succeeded should have failed!\n", fname);
4225 printf("ninth delete on close test succeeded.\n");
4229 status = cli_ntcreate(cli1, fname, 0,
4230 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4231 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4232 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4234 if (!NT_STATUS_IS_OK(status)) {
4235 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4239 /* This should delete the file. */
4240 status = cli_close(cli1, fnum1);
4241 if (!NT_STATUS_IS_OK(status)) {
4242 printf("[10] close failed (%s)\n", nt_errstr(status));
4246 /* This should fail.. */
4247 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4248 if (NT_STATUS_IS_OK(status)) {
4249 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4253 printf("tenth delete on close test succeeded.\n");
4257 cli_setatr(cli1, fname, 0, 0);
4258 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4260 /* Can we open a read-only file with delete access? */
4262 /* Create a readonly file. */
4263 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4264 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4265 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4266 if (!NT_STATUS_IS_OK(status)) {
4267 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4271 status = cli_close(cli1, fnum1);
4272 if (!NT_STATUS_IS_OK(status)) {
4273 printf("[11] close failed (%s)\n", nt_errstr(status));
4277 /* Now try open for delete access. */
4278 status = cli_ntcreate(cli1, fname, 0,
4279 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4281 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4282 FILE_OPEN, 0, 0, &fnum1, NULL);
4283 if (!NT_STATUS_IS_OK(status)) {
4284 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4288 cli_close(cli1, fnum1);
4290 printf("eleventh delete on close test succeeded.\n");
4294 * like test 4 but with initial delete on close
4297 cli_setatr(cli1, fname, 0, 0);
4298 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4300 status = cli_ntcreate(cli1, fname, 0,
4301 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4302 FILE_ATTRIBUTE_NORMAL,
4303 FILE_SHARE_READ|FILE_SHARE_WRITE,
4305 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4306 if (!NT_STATUS_IS_OK(status)) {
4307 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4311 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4312 FILE_ATTRIBUTE_NORMAL,
4313 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4314 FILE_OPEN, 0, 0, &fnum2, NULL);
4315 if (!NT_STATUS_IS_OK(status)) {
4316 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4320 status = cli_close(cli1, fnum2);
4321 if (!NT_STATUS_IS_OK(status)) {
4322 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4326 status = cli_nt_delete_on_close(cli1, fnum1, true);
4327 if (!NT_STATUS_IS_OK(status)) {
4328 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4332 /* This should fail - no more opens once delete on close set. */
4333 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4334 FILE_ATTRIBUTE_NORMAL,
4335 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4336 FILE_OPEN, 0, 0, &fnum2, NULL);
4337 if (NT_STATUS_IS_OK(status)) {
4338 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4342 status = cli_nt_delete_on_close(cli1, fnum1, false);
4343 if (!NT_STATUS_IS_OK(status)) {
4344 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4348 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4349 FILE_ATTRIBUTE_NORMAL,
4350 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4351 FILE_OPEN, 0, 0, &fnum2, NULL);
4352 if (!NT_STATUS_IS_OK(status)) {
4353 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4357 status = cli_close(cli1, fnum2);
4358 if (!NT_STATUS_IS_OK(status)) {
4359 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4363 status = cli_close(cli1, fnum1);
4364 if (!NT_STATUS_IS_OK(status)) {
4365 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4370 * setting delete on close on the handle does
4371 * not unset the initial delete on close...
4373 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4374 FILE_ATTRIBUTE_NORMAL,
4375 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4376 FILE_OPEN, 0, 0, &fnum2, NULL);
4377 if (NT_STATUS_IS_OK(status)) {
4378 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4380 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4381 printf("ntcreate returned %s, expected "
4382 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4387 printf("twelfth delete on close test succeeded.\n");
4390 printf("finished delete test\n");
4395 /* FIXME: This will crash if we aborted before cli2 got
4396 * intialized, because these functions don't handle
4397 * uninitialized connections. */
4399 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4400 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4401 cli_setatr(cli1, fname, 0, 0);
4402 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4404 if (cli1 && !torture_close_connection(cli1)) {
4407 if (cli2 && !torture_close_connection(cli2)) {
4415 Test wildcard delete.
4417 static bool run_wild_deletetest(int dummy)
4419 struct cli_state *cli = NULL;
4420 const char *dname = "\\WTEST";
4421 const char *fname = "\\WTEST\\A";
4422 const char *wunlink_name = "\\WTEST\\*";
4423 uint16_t fnum1 = (uint16_t)-1;
4424 bool correct = false;
4427 printf("starting wildcard delete test\n");
4429 if (!torture_open_connection(&cli, 0)) {
4433 smbXcli_conn_set_sockopt(cli->conn, sockops);
4435 cli_unlink(cli, fname, 0);
4436 cli_rmdir(cli, dname);
4437 status = cli_mkdir(cli, dname);
4438 if (!NT_STATUS_IS_OK(status)) {
4439 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4442 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4443 if (!NT_STATUS_IS_OK(status)) {
4444 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4447 status = cli_close(cli, fnum1);
4451 * Note the unlink attribute-type of zero. This should
4452 * map into FILE_ATTRIBUTE_NORMAL at the server even
4453 * on a wildcard delete.
4456 status = cli_unlink(cli, wunlink_name, 0);
4457 if (!NT_STATUS_IS_OK(status)) {
4458 printf("unlink of %s failed %s!\n",
4459 wunlink_name, nt_errstr(status));
4463 printf("finished wildcard delete test\n");
4469 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4470 cli_unlink(cli, fname, 0);
4471 cli_rmdir(cli, dname);
4473 if (cli && !torture_close_connection(cli)) {
4479 static bool run_deletetest_ln(int dummy)
4481 struct cli_state *cli;
4482 const char *fname = "\\delete1";
4483 const char *fname_ln = "\\delete1_ln";
4487 bool correct = true;
4490 printf("starting deletetest-ln\n");
4492 if (!torture_open_connection(&cli, 0)) {
4496 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4497 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4499 smbXcli_conn_set_sockopt(cli->conn, sockops);
4501 /* Create the file. */
4502 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4503 if (!NT_STATUS_IS_OK(status)) {
4504 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4508 status = cli_close(cli, fnum);
4509 if (!NT_STATUS_IS_OK(status)) {
4510 printf("close1 failed (%s)\n", nt_errstr(status));
4514 /* Now create a hardlink. */
4515 status = cli_nt_hardlink(cli, fname, fname_ln);
4516 if (!NT_STATUS_IS_OK(status)) {
4517 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4521 /* Open the original file. */
4522 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4523 FILE_ATTRIBUTE_NORMAL,
4524 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4525 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4526 if (!NT_STATUS_IS_OK(status)) {
4527 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4531 /* Unlink the hard link path. */
4532 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4533 FILE_ATTRIBUTE_NORMAL,
4534 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4535 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4536 if (!NT_STATUS_IS_OK(status)) {
4537 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4540 status = cli_nt_delete_on_close(cli, fnum1, true);
4541 if (!NT_STATUS_IS_OK(status)) {
4542 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4543 __location__, fname_ln, nt_errstr(status));
4547 status = cli_close(cli, fnum1);
4548 if (!NT_STATUS_IS_OK(status)) {
4549 printf("close %s failed (%s)\n",
4550 fname_ln, nt_errstr(status));
4554 status = cli_close(cli, fnum);
4555 if (!NT_STATUS_IS_OK(status)) {
4556 printf("close %s failed (%s)\n",
4557 fname, nt_errstr(status));
4561 /* Ensure the original file is still there. */
4562 status = cli_getatr(cli, fname, NULL, NULL, &t);
4563 if (!NT_STATUS_IS_OK(status)) {
4564 printf("%s getatr on file %s failed (%s)\n",
4571 /* Ensure the link path is gone. */
4572 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4573 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4574 printf("%s, getatr for file %s returned wrong error code %s "
4575 "- should have been deleted\n",
4577 fname_ln, nt_errstr(status));
4581 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4582 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4584 if (!torture_close_connection(cli)) {
4588 printf("finished deletetest-ln\n");
4594 print out server properties
4596 static bool run_properties(int dummy)
4598 struct cli_state *cli;
4599 bool correct = True;
4601 printf("starting properties test\n");
4605 if (!torture_open_connection(&cli, 0)) {
4609 smbXcli_conn_set_sockopt(cli->conn, sockops);
4611 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4613 if (!torture_close_connection(cli)) {
4622 /* FIRST_DESIRED_ACCESS 0xf019f */
4623 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4624 FILE_READ_EA| /* 0xf */ \
4625 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4626 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4627 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4628 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4629 /* SECOND_DESIRED_ACCESS 0xe0080 */
4630 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4631 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4632 WRITE_OWNER_ACCESS /* 0xe0000 */
4635 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4636 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4638 WRITE_OWNER_ACCESS /* */
4642 Test ntcreate calls made by xcopy
4644 static bool run_xcopy(int dummy)
4646 static struct cli_state *cli1;
4647 const char *fname = "\\test.txt";
4648 bool correct = True;
4649 uint16_t fnum1, fnum2;
4652 printf("starting xcopy test\n");
4654 if (!torture_open_connection(&cli1, 0)) {
4658 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4659 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4660 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4661 if (!NT_STATUS_IS_OK(status)) {
4662 printf("First open failed - %s\n", nt_errstr(status));
4666 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4667 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4668 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4669 if (!NT_STATUS_IS_OK(status)) {
4670 printf("second open failed - %s\n", nt_errstr(status));
4674 if (!torture_close_connection(cli1)) {
4682 Test rename on files open with share delete and no share delete.
4684 static bool run_rename(int dummy)
4686 static struct cli_state *cli1;
4687 const char *fname = "\\test.txt";
4688 const char *fname1 = "\\test1.txt";
4689 bool correct = True;
4694 printf("starting rename test\n");
4696 if (!torture_open_connection(&cli1, 0)) {
4700 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4701 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4703 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4704 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4705 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4706 if (!NT_STATUS_IS_OK(status)) {
4707 printf("First open failed - %s\n", nt_errstr(status));
4711 status = cli_rename(cli1, fname, fname1);
4712 if (!NT_STATUS_IS_OK(status)) {
4713 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4715 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4719 status = cli_close(cli1, fnum1);
4720 if (!NT_STATUS_IS_OK(status)) {
4721 printf("close - 1 failed (%s)\n", nt_errstr(status));
4725 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4726 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4727 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4729 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4731 FILE_SHARE_DELETE|FILE_SHARE_READ,
4733 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4734 if (!NT_STATUS_IS_OK(status)) {
4735 printf("Second open failed - %s\n", nt_errstr(status));
4739 status = cli_rename(cli1, fname, fname1);
4740 if (!NT_STATUS_IS_OK(status)) {
4741 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4744 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4747 status = cli_close(cli1, fnum1);
4748 if (!NT_STATUS_IS_OK(status)) {
4749 printf("close - 2 failed (%s)\n", nt_errstr(status));
4753 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4754 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4756 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4757 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4758 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4759 if (!NT_STATUS_IS_OK(status)) {
4760 printf("Third open failed - %s\n", nt_errstr(status));
4769 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4770 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4771 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4774 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4775 printf("[8] setting delete_on_close on file failed !\n");
4779 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4780 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4786 status = cli_rename(cli1, fname, fname1);
4787 if (!NT_STATUS_IS_OK(status)) {
4788 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4791 printf("Third rename succeeded (SHARE_NONE)\n");
4794 status = cli_close(cli1, fnum1);
4795 if (!NT_STATUS_IS_OK(status)) {
4796 printf("close - 3 failed (%s)\n", nt_errstr(status));
4800 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4801 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4805 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4806 FILE_ATTRIBUTE_NORMAL,
4807 FILE_SHARE_READ | FILE_SHARE_WRITE,
4808 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4809 if (!NT_STATUS_IS_OK(status)) {
4810 printf("Fourth open failed - %s\n", nt_errstr(status));
4814 status = cli_rename(cli1, fname, fname1);
4815 if (!NT_STATUS_IS_OK(status)) {
4816 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4818 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4822 status = cli_close(cli1, fnum1);
4823 if (!NT_STATUS_IS_OK(status)) {
4824 printf("close - 4 failed (%s)\n", nt_errstr(status));
4828 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4829 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4833 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4834 FILE_ATTRIBUTE_NORMAL,
4835 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4836 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4837 if (!NT_STATUS_IS_OK(status)) {
4838 printf("Fifth open failed - %s\n", nt_errstr(status));
4842 status = cli_rename(cli1, fname, fname1);
4843 if (!NT_STATUS_IS_OK(status)) {
4844 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4847 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4851 * Now check if the first name still exists ...
4854 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4855 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4856 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4857 printf("Opening original file after rename of open file fails: %s\n",
4861 printf("Opening original file after rename of open file works ...\n");
4862 (void)cli_close(cli1, fnum2);
4866 status = cli_close(cli1, fnum1);
4867 if (!NT_STATUS_IS_OK(status)) {
4868 printf("close - 5 failed (%s)\n", nt_errstr(status));
4872 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4873 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4874 if (!NT_STATUS_IS_OK(status)) {
4875 printf("getatr on file %s failed - %s ! \n",
4876 fname1, nt_errstr(status));
4879 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4880 printf("Renamed file %s has wrong attr 0x%x "
4881 "(should be 0x%x)\n",
4884 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4887 printf("Renamed file %s has archive bit set\n", fname1);
4891 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4892 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4894 if (!torture_close_connection(cli1)) {
4901 static bool run_pipe_number(int dummy)
4903 struct cli_state *cli1;
4904 const char *pipe_name = "\\SPOOLSS";
4909 printf("starting pipenumber test\n");
4910 if (!torture_open_connection(&cli1, 0)) {
4914 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4916 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4917 FILE_ATTRIBUTE_NORMAL,
4918 FILE_SHARE_READ|FILE_SHARE_WRITE,
4919 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4920 if (!NT_STATUS_IS_OK(status)) {
4921 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4925 printf("\r%6d", num_pipes);
4928 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4929 torture_close_connection(cli1);
4934 Test open mode returns on read-only files.
4936 static bool run_opentest(int dummy)
4938 static struct cli_state *cli1;
4939 static struct cli_state *cli2;
4940 const char *fname = "\\readonly.file";
4941 uint16_t fnum1, fnum2;
4944 bool correct = True;
4948 printf("starting open test\n");
4950 if (!torture_open_connection(&cli1, 0)) {
4954 cli_setatr(cli1, fname, 0, 0);
4955 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4957 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4959 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4960 if (!NT_STATUS_IS_OK(status)) {
4961 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4965 status = cli_close(cli1, fnum1);
4966 if (!NT_STATUS_IS_OK(status)) {
4967 printf("close2 failed (%s)\n", nt_errstr(status));
4971 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4972 if (!NT_STATUS_IS_OK(status)) {
4973 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4977 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4978 if (!NT_STATUS_IS_OK(status)) {
4979 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4983 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4984 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4986 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4987 NT_STATUS_ACCESS_DENIED)) {
4988 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4991 printf("finished open test 1\n");
4993 cli_close(cli1, fnum1);
4995 /* Now try not readonly and ensure ERRbadshare is returned. */
4997 cli_setatr(cli1, fname, 0, 0);
4999 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5000 if (!NT_STATUS_IS_OK(status)) {
5001 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5005 /* This will fail - but the error should be ERRshare. */
5006 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5008 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5009 NT_STATUS_SHARING_VIOLATION)) {
5010 printf("correct error code ERRDOS/ERRbadshare returned\n");
5013 status = cli_close(cli1, fnum1);
5014 if (!NT_STATUS_IS_OK(status)) {
5015 printf("close2 failed (%s)\n", nt_errstr(status));
5019 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5021 printf("finished open test 2\n");
5023 /* Test truncate open disposition on file opened for read. */
5024 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5025 if (!NT_STATUS_IS_OK(status)) {
5026 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5030 /* write 20 bytes. */
5032 memset(buf, '\0', 20);
5034 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5035 if (!NT_STATUS_IS_OK(status)) {
5036 printf("write failed (%s)\n", nt_errstr(status));
5040 status = cli_close(cli1, fnum1);
5041 if (!NT_STATUS_IS_OK(status)) {
5042 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5046 /* Ensure size == 20. */
5047 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5048 if (!NT_STATUS_IS_OK(status)) {
5049 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5054 printf("(3) file size != 20\n");
5058 /* Now test if we can truncate a file opened for readonly. */
5059 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5060 if (!NT_STATUS_IS_OK(status)) {
5061 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5065 status = cli_close(cli1, fnum1);
5066 if (!NT_STATUS_IS_OK(status)) {
5067 printf("close2 failed (%s)\n", nt_errstr(status));
5071 /* Ensure size == 0. */
5072 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5073 if (!NT_STATUS_IS_OK(status)) {
5074 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5079 printf("(3) file size != 0\n");
5082 printf("finished open test 3\n");
5084 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5086 printf("Do ctemp tests\n");
5087 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5088 if (!NT_STATUS_IS_OK(status)) {
5089 printf("ctemp failed (%s)\n", nt_errstr(status));
5093 printf("ctemp gave path %s\n", tmp_path);
5094 status = cli_close(cli1, fnum1);
5095 if (!NT_STATUS_IS_OK(status)) {
5096 printf("close of temp failed (%s)\n", nt_errstr(status));
5099 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5100 if (!NT_STATUS_IS_OK(status)) {
5101 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5104 /* Test the non-io opens... */
5106 if (!torture_open_connection(&cli2, 1)) {
5110 cli_setatr(cli2, fname, 0, 0);
5111 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5113 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5115 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5116 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5117 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5118 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5119 if (!NT_STATUS_IS_OK(status)) {
5120 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5124 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5125 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5126 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5127 if (!NT_STATUS_IS_OK(status)) {
5128 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5132 status = cli_close(cli1, fnum1);
5133 if (!NT_STATUS_IS_OK(status)) {
5134 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5138 status = cli_close(cli2, fnum2);
5139 if (!NT_STATUS_IS_OK(status)) {
5140 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5144 printf("non-io open test #1 passed.\n");
5146 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5148 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5150 status = cli_ntcreate(cli1, fname, 0,
5151 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5152 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5153 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5154 if (!NT_STATUS_IS_OK(status)) {
5155 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5159 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5160 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5161 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5162 if (!NT_STATUS_IS_OK(status)) {
5163 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5167 status = cli_close(cli1, fnum1);
5168 if (!NT_STATUS_IS_OK(status)) {
5169 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5173 status = cli_close(cli2, fnum2);
5174 if (!NT_STATUS_IS_OK(status)) {
5175 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5179 printf("non-io open test #2 passed.\n");
5181 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5183 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5185 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5186 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5187 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5188 if (!NT_STATUS_IS_OK(status)) {
5189 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5193 status = cli_ntcreate(cli2, fname, 0,
5194 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5195 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5196 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5197 if (!NT_STATUS_IS_OK(status)) {
5198 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5202 status = cli_close(cli1, fnum1);
5203 if (!NT_STATUS_IS_OK(status)) {
5204 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5208 status = cli_close(cli2, fnum2);
5209 if (!NT_STATUS_IS_OK(status)) {
5210 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5214 printf("non-io open test #3 passed.\n");
5216 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5218 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5220 status = cli_ntcreate(cli1, fname, 0,
5221 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5222 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5223 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5224 if (!NT_STATUS_IS_OK(status)) {
5225 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5229 status = cli_ntcreate(cli2, fname, 0,
5230 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5231 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5232 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5233 if (NT_STATUS_IS_OK(status)) {
5234 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5238 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5240 status = cli_close(cli1, fnum1);
5241 if (!NT_STATUS_IS_OK(status)) {
5242 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5246 printf("non-io open test #4 passed.\n");
5248 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5250 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5252 status = cli_ntcreate(cli1, fname, 0,
5253 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5254 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5255 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5256 if (!NT_STATUS_IS_OK(status)) {
5257 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5261 status = cli_ntcreate(cli2, fname, 0,
5262 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5263 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5264 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5265 if (!NT_STATUS_IS_OK(status)) {
5266 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5270 status = cli_close(cli1, fnum1);
5271 if (!NT_STATUS_IS_OK(status)) {
5272 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5276 status = cli_close(cli2, fnum2);
5277 if (!NT_STATUS_IS_OK(status)) {
5278 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5282 printf("non-io open test #5 passed.\n");
5284 printf("TEST #6 testing 1 non-io open, one io open\n");
5286 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5288 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5289 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5290 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5291 if (!NT_STATUS_IS_OK(status)) {
5292 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5296 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5297 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5298 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5299 if (!NT_STATUS_IS_OK(status)) {
5300 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5304 status = cli_close(cli1, fnum1);
5305 if (!NT_STATUS_IS_OK(status)) {
5306 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5310 status = cli_close(cli2, fnum2);
5311 if (!NT_STATUS_IS_OK(status)) {
5312 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5316 printf("non-io open test #6 passed.\n");
5318 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5320 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5322 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5323 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5324 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5325 if (!NT_STATUS_IS_OK(status)) {
5326 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5330 status = cli_ntcreate(cli2, fname, 0,
5331 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5332 FILE_ATTRIBUTE_NORMAL,
5333 FILE_SHARE_READ|FILE_SHARE_DELETE,
5334 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5335 if (NT_STATUS_IS_OK(status)) {
5336 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5340 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5342 status = cli_close(cli1, fnum1);
5343 if (!NT_STATUS_IS_OK(status)) {
5344 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5348 printf("non-io open test #7 passed.\n");
5350 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5352 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5353 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5354 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5355 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5356 if (!NT_STATUS_IS_OK(status)) {
5357 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5362 /* Write to ensure we have to update the file time. */
5363 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5365 if (!NT_STATUS_IS_OK(status)) {
5366 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5371 status = cli_close(cli1, fnum1);
5372 if (!NT_STATUS_IS_OK(status)) {
5373 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5379 if (!torture_close_connection(cli1)) {
5382 if (!torture_close_connection(cli2)) {
5389 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5391 uint16_t major, minor;
5392 uint32_t caplow, caphigh;
5395 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5396 printf("Server doesn't support UNIX CIFS extensions.\n");
5397 return NT_STATUS_NOT_SUPPORTED;
5400 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5402 if (!NT_STATUS_IS_OK(status)) {
5403 printf("Server didn't return UNIX CIFS extensions: %s\n",
5408 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5410 if (!NT_STATUS_IS_OK(status)) {
5411 printf("Server doesn't support setting UNIX CIFS extensions: "
5412 "%s.\n", nt_errstr(status));
5416 return NT_STATUS_OK;
5420 Test POSIX open /mkdir calls.
5422 static bool run_simple_posix_open_test(int dummy)
5424 static struct cli_state *cli1;
5425 const char *fname = "posix:file";
5426 const char *hname = "posix:hlink";
5427 const char *sname = "posix:symlink";
5428 const char *dname = "posix:dir";
5431 uint16_t fnum1 = (uint16_t)-1;
5432 SMB_STRUCT_STAT sbuf;
5433 bool correct = false;
5436 const char *fname_windows = "windows_file";
5437 uint16_t fnum2 = (uint16_t)-1;
5439 printf("Starting simple POSIX open test\n");
5441 if (!torture_open_connection(&cli1, 0)) {
5445 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5447 status = torture_setup_unix_extensions(cli1);
5448 if (!NT_STATUS_IS_OK(status)) {
5452 cli_setatr(cli1, fname, 0, 0);
5453 cli_posix_unlink(cli1, fname);
5454 cli_setatr(cli1, dname, 0, 0);
5455 cli_posix_rmdir(cli1, dname);
5456 cli_setatr(cli1, hname, 0, 0);
5457 cli_posix_unlink(cli1, hname);
5458 cli_setatr(cli1, sname, 0, 0);
5459 cli_posix_unlink(cli1, sname);
5460 cli_setatr(cli1, fname_windows, 0, 0);
5461 cli_posix_unlink(cli1, fname_windows);
5463 /* Create a directory. */
5464 status = cli_posix_mkdir(cli1, dname, 0777);
5465 if (!NT_STATUS_IS_OK(status)) {
5466 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5470 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5472 if (!NT_STATUS_IS_OK(status)) {
5473 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5477 /* Test ftruncate - set file size. */
5478 status = cli_ftruncate(cli1, fnum1, 1000);
5479 if (!NT_STATUS_IS_OK(status)) {
5480 printf("ftruncate failed (%s)\n", nt_errstr(status));
5484 /* Ensure st_size == 1000 */
5485 status = cli_posix_stat(cli1, fname, &sbuf);
5486 if (!NT_STATUS_IS_OK(status)) {
5487 printf("stat failed (%s)\n", nt_errstr(status));
5491 if (sbuf.st_ex_size != 1000) {
5492 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5496 /* Ensure st_mode == 0600 */
5497 if ((sbuf.st_ex_mode & 07777) != 0600) {
5498 printf("posix_open - bad permissions 0%o != 0600\n",
5499 (unsigned int)(sbuf.st_ex_mode & 07777));
5503 /* Test ftruncate - set file size back to zero. */
5504 status = cli_ftruncate(cli1, fnum1, 0);
5505 if (!NT_STATUS_IS_OK(status)) {
5506 printf("ftruncate failed (%s)\n", nt_errstr(status));
5510 status = cli_close(cli1, fnum1);
5511 if (!NT_STATUS_IS_OK(status)) {
5512 printf("close failed (%s)\n", nt_errstr(status));
5516 /* Now open the file again for read only. */
5517 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5518 if (!NT_STATUS_IS_OK(status)) {
5519 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5523 /* Now unlink while open. */
5524 status = cli_posix_unlink(cli1, fname);
5525 if (!NT_STATUS_IS_OK(status)) {
5526 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5530 status = cli_close(cli1, fnum1);
5531 if (!NT_STATUS_IS_OK(status)) {
5532 printf("close(2) failed (%s)\n", nt_errstr(status));
5536 /* Ensure the file has gone. */
5537 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5538 if (NT_STATUS_IS_OK(status)) {
5539 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5543 /* Create again to test open with O_TRUNC. */
5544 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5545 if (!NT_STATUS_IS_OK(status)) {
5546 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5550 /* Test ftruncate - set file size. */
5551 status = cli_ftruncate(cli1, fnum1, 1000);
5552 if (!NT_STATUS_IS_OK(status)) {
5553 printf("ftruncate failed (%s)\n", nt_errstr(status));
5557 /* Ensure st_size == 1000 */
5558 status = cli_posix_stat(cli1, fname, &sbuf);
5559 if (!NT_STATUS_IS_OK(status)) {
5560 printf("stat failed (%s)\n", nt_errstr(status));
5564 if (sbuf.st_ex_size != 1000) {
5565 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5569 status = cli_close(cli1, fnum1);
5570 if (!NT_STATUS_IS_OK(status)) {
5571 printf("close(2) failed (%s)\n", nt_errstr(status));
5575 /* Re-open with O_TRUNC. */
5576 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5577 if (!NT_STATUS_IS_OK(status)) {
5578 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5582 /* Ensure st_size == 0 */
5583 status = cli_posix_stat(cli1, fname, &sbuf);
5584 if (!NT_STATUS_IS_OK(status)) {
5585 printf("stat failed (%s)\n", nt_errstr(status));
5589 if (sbuf.st_ex_size != 0) {
5590 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5594 status = cli_close(cli1, fnum1);
5595 if (!NT_STATUS_IS_OK(status)) {
5596 printf("close failed (%s)\n", nt_errstr(status));
5600 status = cli_posix_unlink(cli1, fname);
5601 if (!NT_STATUS_IS_OK(status)) {
5602 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5606 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5607 if (!NT_STATUS_IS_OK(status)) {
5608 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5609 dname, nt_errstr(status));
5613 cli_close(cli1, fnum1);
5615 /* What happens when we try and POSIX open a directory for write ? */
5616 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5617 if (NT_STATUS_IS_OK(status)) {
5618 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5621 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5622 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5627 /* Create the file. */
5628 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5630 if (!NT_STATUS_IS_OK(status)) {
5631 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5635 /* Write some data into it. */
5636 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5638 if (!NT_STATUS_IS_OK(status)) {
5639 printf("cli_write failed: %s\n", nt_errstr(status));
5643 cli_close(cli1, fnum1);
5645 /* Now create a hardlink. */
5646 status = cli_posix_hardlink(cli1, fname, hname);
5647 if (!NT_STATUS_IS_OK(status)) {
5648 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5652 /* Now create a symlink. */
5653 status = cli_posix_symlink(cli1, fname, sname);
5654 if (!NT_STATUS_IS_OK(status)) {
5655 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5659 /* Open the hardlink for read. */
5660 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5661 if (!NT_STATUS_IS_OK(status)) {
5662 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5666 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5667 if (!NT_STATUS_IS_OK(status)) {
5668 printf("POSIX read of %s failed (%s)\n", hname,
5671 } else if (nread != 10) {
5672 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5673 hname, (unsigned long)nread, 10);
5677 if (memcmp(buf, "TEST DATA\n", 10)) {
5678 printf("invalid data read from hardlink\n");
5682 /* Do a POSIX lock/unlock. */
5683 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5684 if (!NT_STATUS_IS_OK(status)) {
5685 printf("POSIX lock failed %s\n", nt_errstr(status));
5689 /* Punch a hole in the locked area. */
5690 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5691 if (!NT_STATUS_IS_OK(status)) {
5692 printf("POSIX unlock failed %s\n", nt_errstr(status));
5696 cli_close(cli1, fnum1);
5698 /* Open the symlink for read - this should fail. A POSIX
5699 client should not be doing opens on a symlink. */
5700 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5701 if (NT_STATUS_IS_OK(status)) {
5702 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5705 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5706 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5707 printf("POSIX open of %s should have failed "
5708 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5709 "failed with %s instead.\n",
5710 sname, nt_errstr(status));
5715 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5716 if (!NT_STATUS_IS_OK(status)) {
5717 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5721 if (strcmp(namebuf, fname) != 0) {
5722 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5723 sname, fname, namebuf);
5727 status = cli_posix_rmdir(cli1, dname);
5728 if (!NT_STATUS_IS_OK(status)) {
5729 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5733 /* Check directory opens with a specific permission. */
5734 status = cli_posix_mkdir(cli1, dname, 0700);
5735 if (!NT_STATUS_IS_OK(status)) {
5736 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5740 /* Ensure st_mode == 0700 */
5741 status = cli_posix_stat(cli1, dname, &sbuf);
5742 if (!NT_STATUS_IS_OK(status)) {
5743 printf("stat failed (%s)\n", nt_errstr(status));
5747 if ((sbuf.st_ex_mode & 07777) != 0700) {
5748 printf("posix_mkdir - bad permissions 0%o != 0700\n",
5749 (unsigned int)(sbuf.st_ex_mode & 07777));
5754 * Now create a Windows file, and attempt a POSIX unlink.
5755 * This should fail with a sharing violation but due to:
5757 * [Bug 9571] Unlink after open causes smbd to panic
5759 * ensure we've fixed the lock ordering violation.
5762 status = cli_ntcreate(cli1, fname_windows, 0,
5763 FILE_READ_DATA|FILE_WRITE_DATA, 0,
5764 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5766 0x0, 0x0, &fnum2, NULL);
5767 if (!NT_STATUS_IS_OK(status)) {
5768 printf("Windows create of %s failed (%s)\n", fname_windows,
5773 /* Now try posix_unlink. */
5774 status = cli_posix_unlink(cli1, fname_windows);
5775 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
5776 printf("POSIX unlink of %s should fail "
5777 "with NT_STATUS_SHARING_VIOLATION "
5778 "got %s instead !\n",
5784 cli_close(cli1, fnum2);
5786 printf("Simple POSIX open test passed\n");
5791 if (fnum1 != (uint16_t)-1) {
5792 cli_close(cli1, fnum1);
5793 fnum1 = (uint16_t)-1;
5796 if (fnum2 != (uint16_t)-1) {
5797 cli_close(cli1, fnum2);
5798 fnum2 = (uint16_t)-1;
5801 cli_setatr(cli1, sname, 0, 0);
5802 cli_posix_unlink(cli1, sname);
5803 cli_setatr(cli1, hname, 0, 0);
5804 cli_posix_unlink(cli1, hname);
5805 cli_setatr(cli1, fname, 0, 0);
5806 cli_posix_unlink(cli1, fname);
5807 cli_setatr(cli1, dname, 0, 0);
5808 cli_posix_rmdir(cli1, dname);
5809 cli_setatr(cli1, fname_windows, 0, 0);
5810 cli_posix_unlink(cli1, fname_windows);
5812 if (!torture_close_connection(cli1)) {
5820 Test POSIX and Windows ACLs are rejected on symlinks.
5822 static bool run_acl_symlink_test(int dummy)
5824 static struct cli_state *cli;
5825 const char *fname = "posix_file";
5826 const char *sname = "posix_symlink";
5827 uint16_t fnum = (uint16_t)-1;
5828 bool correct = false;
5830 char *posix_acl = NULL;
5831 size_t posix_acl_len = 0;
5832 char *posix_acl_sym = NULL;
5833 size_t posix_acl_len_sym = 0;
5834 struct security_descriptor *sd = NULL;
5835 struct security_descriptor *sd_sym = NULL;
5836 TALLOC_CTX *frame = NULL;
5838 frame = talloc_stackframe();
5840 printf("Starting acl symlink test\n");
5842 if (!torture_open_connection(&cli, 0)) {
5847 smbXcli_conn_set_sockopt(cli->conn, sockops);
5849 status = torture_setup_unix_extensions(cli);
5850 if (!NT_STATUS_IS_OK(status)) {
5855 cli_setatr(cli, fname, 0, 0);
5856 cli_posix_unlink(cli, fname);
5857 cli_setatr(cli, sname, 0, 0);
5858 cli_posix_unlink(cli, sname);
5860 status = cli_ntcreate(cli,
5863 READ_CONTROL_ACCESS,
5865 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5872 if (!NT_STATUS_IS_OK(status)) {
5873 printf("cli_ntcreate of %s failed (%s)\n",
5879 /* Get the Windows ACL on the file. */
5880 status = cli_query_secdesc(cli,
5884 if (!NT_STATUS_IS_OK(status)) {
5885 printf("cli_query_secdesc failed (%s)\n",
5890 /* Get the POSIX ACL on the file. */
5891 status = cli_posix_getacl(cli,
5897 if (!NT_STATUS_IS_OK(status)) {
5898 printf("cli_posix_getacl failed (%s)\n",
5903 status = cli_close(cli, fnum);
5904 if (!NT_STATUS_IS_OK(status)) {
5905 printf("close failed (%s)\n", nt_errstr(status));
5908 fnum = (uint16_t)-1;
5910 /* Now create a symlink. */
5911 status = cli_posix_symlink(cli, fname, sname);
5912 if (!NT_STATUS_IS_OK(status)) {
5913 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
5920 /* Open a handle on the symlink. */
5921 status = cli_ntcreate(cli,
5924 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
5926 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5933 if (!NT_STATUS_IS_OK(status)) {
5934 printf("cli_posix_open of %s failed (%s)\n",
5940 /* Get the Windows ACL on the symlink handle. Should fail */
5941 status = cli_query_secdesc(cli,
5946 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5947 printf("cli_query_secdesc on a symlink gave %s. "
5948 "Should be NT_STATUS_ACCESS_DENIED.\n",
5953 /* Get the POSIX ACL on the symlink pathname. Should fail. */
5954 status = cli_posix_getacl(cli,
5960 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5961 printf("cli_posix_getacl on a symlink gave %s. "
5962 "Should be NT_STATUS_ACCESS_DENIED.\n",
5967 /* Set the Windows ACL on the symlink handle. Should fail */
5968 status = cli_set_security_descriptor(cli,
5973 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5974 printf("cli_query_secdesc on a symlink gave %s. "
5975 "Should be NT_STATUS_ACCESS_DENIED.\n",
5980 /* Set the POSIX ACL on the symlink pathname. Should fail. */
5981 status = cli_posix_setacl(cli,
5986 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5987 printf("cli_posix_getacl on a symlink gave %s. "
5988 "Should be NT_STATUS_ACCESS_DENIED.\n",
5993 printf("ACL symlink test passed\n");
5998 if (fnum != (uint16_t)-1) {
5999 cli_close(cli, fnum);
6000 fnum = (uint16_t)-1;
6003 cli_setatr(cli, sname, 0, 0);
6004 cli_posix_unlink(cli, sname);
6005 cli_setatr(cli, fname, 0, 0);
6006 cli_posix_unlink(cli, fname);
6008 if (!torture_close_connection(cli)) {
6017 Test setting EA's are rejected on symlinks.
6019 static bool run_ea_symlink_test(int dummy)
6021 static struct cli_state *cli;
6022 const char *fname = "posix_file_ea";
6023 const char *sname = "posix_symlink_ea";
6024 const char *ea_name = "testea_name";
6025 const char *ea_value = "testea_value";
6026 uint16_t fnum = (uint16_t)-1;
6027 bool correct = false;
6030 struct ea_struct *eas = NULL;
6031 TALLOC_CTX *frame = NULL;
6033 frame = talloc_stackframe();
6035 printf("Starting EA symlink test\n");
6037 if (!torture_open_connection(&cli, 0)) {
6042 smbXcli_conn_set_sockopt(cli->conn, sockops);
6044 status = torture_setup_unix_extensions(cli);
6045 if (!NT_STATUS_IS_OK(status)) {
6050 cli_setatr(cli, fname, 0, 0);
6051 cli_posix_unlink(cli, fname);
6052 cli_setatr(cli, sname, 0, 0);
6053 cli_posix_unlink(cli, sname);
6055 status = cli_ntcreate(cli,
6058 READ_CONTROL_ACCESS,
6060 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6067 if (!NT_STATUS_IS_OK(status)) {
6068 printf("cli_ntcreate of %s failed (%s)\n",
6074 status = cli_close(cli, fnum);
6075 if (!NT_STATUS_IS_OK(status)) {
6076 printf("close failed (%s)\n",
6080 fnum = (uint16_t)-1;
6082 /* Set an EA on the path. */
6083 status = cli_set_ea_path(cli,
6087 strlen(ea_value)+1);
6089 if (!NT_STATUS_IS_OK(status)) {
6090 printf("cli_set_ea_path failed (%s)\n",
6095 /* Now create a symlink. */
6096 status = cli_posix_symlink(cli, fname, sname);
6097 if (!NT_STATUS_IS_OK(status)) {
6098 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6105 /* Get the EA list on the path. Should return value set. */
6106 status = cli_get_ea_list_path(cli,
6112 if (!NT_STATUS_IS_OK(status)) {
6113 printf("cli_get_ea_list_path failed (%s)\n",
6118 /* Ensure the EA we set is there. */
6119 for (i=0; i<num_eas; i++) {
6120 if (strcmp(eas[i].name, ea_name) == 0 &&
6121 eas[i].value.length == strlen(ea_value)+1 &&
6122 memcmp(eas[i].value.data,
6124 eas[i].value.length) == 0) {
6130 printf("Didn't find EA on pathname %s\n",
6138 /* Get the EA list on the symlink. Should return empty list. */
6139 status = cli_get_ea_list_path(cli,
6145 if (!NT_STATUS_IS_OK(status)) {
6146 printf("cli_get_ea_list_path failed (%s)\n",
6152 printf("cli_get_ea_list_path failed (%s)\n",
6157 /* Set an EA on the symlink. Should fail. */
6158 status = cli_set_ea_path(cli,
6162 strlen(ea_value)+1);
6164 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6165 printf("cli_set_ea_path on a symlink gave %s. "
6166 "Should be NT_STATUS_ACCESS_DENIED.\n",
6171 printf("EA symlink test passed\n");
6176 if (fnum != (uint16_t)-1) {
6177 cli_close(cli, fnum);
6178 fnum = (uint16_t)-1;
6181 cli_setatr(cli, sname, 0, 0);
6182 cli_posix_unlink(cli, sname);
6183 cli_setatr(cli, fname, 0, 0);
6184 cli_posix_unlink(cli, fname);
6186 if (!torture_close_connection(cli)) {
6195 Test POSIX locks are OFD-locks.
6197 static bool run_posix_ofd_lock_test(int dummy)
6199 static struct cli_state *cli;
6200 const char *fname = "posix_file";
6201 uint16_t fnum1 = (uint16_t)-1;
6202 uint16_t fnum2 = (uint16_t)-1;
6203 bool correct = false;
6205 TALLOC_CTX *frame = NULL;
6207 frame = talloc_stackframe();
6209 printf("Starting POSIX ofd-lock test\n");
6211 if (!torture_open_connection(&cli, 0)) {
6216 smbXcli_conn_set_sockopt(cli->conn, sockops);
6218 status = torture_setup_unix_extensions(cli);
6219 if (!NT_STATUS_IS_OK(status)) {
6224 cli_setatr(cli, fname, 0, 0);
6225 cli_posix_unlink(cli, fname);
6227 /* Open the file twice. */
6228 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
6230 if (!NT_STATUS_IS_OK(status)) {
6231 printf("First POSIX open of %s failed\n", fname);
6235 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
6236 if (!NT_STATUS_IS_OK(status)) {
6237 printf("First POSIX open of %s failed\n", fname);
6241 /* Set a 0-50 lock on fnum1. */
6242 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6243 if (!NT_STATUS_IS_OK(status)) {
6244 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
6248 /* Set a 60-100 lock on fnum2. */
6249 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
6250 if (!NT_STATUS_IS_OK(status)) {
6251 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
6255 /* close fnum1 - 0-50 lock should go away. */
6256 status = cli_close(cli, fnum1);
6257 if (!NT_STATUS_IS_OK(status)) {
6258 printf("close failed (%s)\n",
6262 fnum1 = (uint16_t)-1;
6264 /* Change the lock context. */
6265 cli_setpid(cli, cli_getpid(cli) + 1);
6267 /* Re-open fnum1. */
6268 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
6269 if (!NT_STATUS_IS_OK(status)) {
6270 printf("Third POSIX open of %s failed\n", fname);
6274 /* 60-100 lock should still be there. */
6275 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
6276 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
6277 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
6281 /* 0-50 lock should be gone. */
6282 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6283 if (!NT_STATUS_IS_OK(status)) {
6284 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
6288 printf("POSIX OFD lock test passed\n");
6293 if (fnum1 != (uint16_t)-1) {
6294 cli_close(cli, fnum1);
6295 fnum1 = (uint16_t)-1;
6297 if (fnum2 != (uint16_t)-1) {
6298 cli_close(cli, fnum2);
6299 fnum2 = (uint16_t)-1;
6302 cli_setatr(cli, fname, 0, 0);
6303 cli_posix_unlink(cli, fname);
6305 if (!torture_close_connection(cli)) {
6313 static uint32_t open_attrs_table[] = {
6314 FILE_ATTRIBUTE_NORMAL,
6315 FILE_ATTRIBUTE_ARCHIVE,
6316 FILE_ATTRIBUTE_READONLY,
6317 FILE_ATTRIBUTE_HIDDEN,
6318 FILE_ATTRIBUTE_SYSTEM,
6320 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
6321 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
6322 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
6323 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
6324 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
6325 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
6327 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
6328 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
6329 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
6330 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
6333 struct trunc_open_results {
6336 uint32_t trunc_attr;
6337 uint32_t result_attr;
6340 static struct trunc_open_results attr_results[] = {
6341 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
6342 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
6343 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
6344 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
6345 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
6346 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
6347 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6348 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6349 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
6350 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6351 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6352 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
6353 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6354 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6355 { 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 },
6356 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6357 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6358 { 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 },
6359 { 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 },
6360 { 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 },
6361 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6362 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6363 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
6364 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6365 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6366 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
6369 static bool run_openattrtest(int dummy)
6371 static struct cli_state *cli1;
6372 const char *fname = "\\openattr.file";
6374 bool correct = True;
6376 unsigned int i, j, k, l;
6379 printf("starting open attr test\n");
6381 if (!torture_open_connection(&cli1, 0)) {
6385 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6387 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
6388 cli_setatr(cli1, fname, 0, 0);
6389 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6391 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
6392 open_attrs_table[i], FILE_SHARE_NONE,
6393 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6394 if (!NT_STATUS_IS_OK(status)) {
6395 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
6399 status = cli_close(cli1, fnum1);
6400 if (!NT_STATUS_IS_OK(status)) {
6401 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
6405 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
6406 status = cli_ntcreate(cli1, fname, 0,
6407 FILE_READ_DATA|FILE_WRITE_DATA,
6408 open_attrs_table[j],
6409 FILE_SHARE_NONE, FILE_OVERWRITE,
6410 0, 0, &fnum1, NULL);
6411 if (!NT_STATUS_IS_OK(status)) {
6412 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
6413 if (attr_results[l].num == k) {
6414 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
6415 k, open_attrs_table[i],
6416 open_attrs_table[j],
6417 fname, NT_STATUS_V(status), nt_errstr(status));
6422 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6423 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
6424 k, open_attrs_table[i], open_attrs_table[j],
6429 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
6435 status = cli_close(cli1, fnum1);
6436 if (!NT_STATUS_IS_OK(status)) {
6437 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
6441 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
6442 if (!NT_STATUS_IS_OK(status)) {
6443 printf("getatr(2) failed (%s)\n", nt_errstr(status));
6448 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
6449 k, open_attrs_table[i], open_attrs_table[j], attr );
6452 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
6453 if (attr_results[l].num == k) {
6454 if (attr != attr_results[l].result_attr ||
6455 open_attrs_table[i] != attr_results[l].init_attr ||
6456 open_attrs_table[j] != attr_results[l].trunc_attr) {
6457 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
6458 open_attrs_table[i],
6459 open_attrs_table[j],
6461 attr_results[l].result_attr);
6471 cli_setatr(cli1, fname, 0, 0);
6472 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6474 printf("open attr test %s.\n", correct ? "passed" : "failed");
6476 if (!torture_close_connection(cli1)) {
6482 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
6483 const char *name, void *state)
6485 int *matched = (int *)state;
6486 if (matched != NULL) {
6489 return NT_STATUS_OK;
6493 test directory listing speed
6495 static bool run_dirtest(int dummy)
6498 static struct cli_state *cli;
6500 struct timeval core_start;
6501 bool correct = True;
6504 printf("starting directory test\n");
6506 if (!torture_open_connection(&cli, 0)) {
6510 smbXcli_conn_set_sockopt(cli->conn, sockops);
6513 for (i=0;i<torture_numops;i++) {
6515 slprintf(fname, sizeof(fname), "\\%x", (int)random());
6516 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
6517 fprintf(stderr,"Failed to open %s\n", fname);
6520 cli_close(cli, fnum);
6523 core_start = timeval_current();
6526 cli_list(cli, "a*.*", 0, list_fn, &matched);
6527 printf("Matched %d\n", matched);
6530 cli_list(cli, "b*.*", 0, list_fn, &matched);
6531 printf("Matched %d\n", matched);
6534 cli_list(cli, "xyzabc", 0, list_fn, &matched);
6535 printf("Matched %d\n", matched);
6537 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
6540 for (i=0;i<torture_numops;i++) {
6542 slprintf(fname, sizeof(fname), "\\%x", (int)random());
6543 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6546 if (!torture_close_connection(cli)) {
6550 printf("finished dirtest\n");
6555 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
6558 struct cli_state *pcli = (struct cli_state *)state;
6560 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
6562 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6563 return NT_STATUS_OK;
6565 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
6566 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6567 printf("del_fn: failed to rmdir %s\n,", fname );
6569 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
6570 printf("del_fn: failed to unlink %s\n,", fname );
6572 return NT_STATUS_OK;
6577 sees what IOCTLs are supported
6579 bool torture_ioctl_test(int dummy)
6581 static struct cli_state *cli;
6582 uint16_t device, function;
6584 const char *fname = "\\ioctl.dat";
6588 if (!torture_open_connection(&cli, 0)) {
6592 printf("starting ioctl test\n");
6594 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6596 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6597 if (!NT_STATUS_IS_OK(status)) {
6598 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
6602 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
6603 printf("ioctl device info: %s\n", nt_errstr(status));
6605 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
6606 printf("ioctl job info: %s\n", nt_errstr(status));
6608 for (device=0;device<0x100;device++) {
6609 printf("ioctl test with device = 0x%x\n", device);
6610 for (function=0;function<0x100;function++) {
6611 uint32_t code = (device<<16) | function;
6613 status = cli_raw_ioctl(cli, fnum, code, &blob);
6615 if (NT_STATUS_IS_OK(status)) {
6616 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
6618 data_blob_free(&blob);
6623 if (!torture_close_connection(cli)) {
6632 tries varients of chkpath
6634 bool torture_chkpath_test(int dummy)
6636 static struct cli_state *cli;
6641 if (!torture_open_connection(&cli, 0)) {
6645 printf("starting chkpath test\n");
6647 /* cleanup from an old run */
6648 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6649 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6650 cli_rmdir(cli, "\\chkpath.dir");
6652 status = cli_mkdir(cli, "\\chkpath.dir");
6653 if (!NT_STATUS_IS_OK(status)) {
6654 printf("mkdir1 failed : %s\n", nt_errstr(status));
6658 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
6659 if (!NT_STATUS_IS_OK(status)) {
6660 printf("mkdir2 failed : %s\n", nt_errstr(status));
6664 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
6666 if (!NT_STATUS_IS_OK(status)) {
6667 printf("open1 failed (%s)\n", nt_errstr(status));
6670 cli_close(cli, fnum);
6672 status = cli_chkpath(cli, "\\chkpath.dir");
6673 if (!NT_STATUS_IS_OK(status)) {
6674 printf("chkpath1 failed: %s\n", nt_errstr(status));
6678 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
6679 if (!NT_STATUS_IS_OK(status)) {
6680 printf("chkpath2 failed: %s\n", nt_errstr(status));
6684 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
6685 if (!NT_STATUS_IS_OK(status)) {
6686 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6687 NT_STATUS_NOT_A_DIRECTORY);
6689 printf("* chkpath on a file should fail\n");
6693 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
6694 if (!NT_STATUS_IS_OK(status)) {
6695 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
6696 NT_STATUS_OBJECT_NAME_NOT_FOUND);
6698 printf("* chkpath on a non existent file should fail\n");
6702 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6703 if (!NT_STATUS_IS_OK(status)) {
6704 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6705 NT_STATUS_OBJECT_PATH_NOT_FOUND);
6707 printf("* chkpath on a non existent component should fail\n");
6711 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6712 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6713 cli_rmdir(cli, "\\chkpath.dir");
6715 if (!torture_close_connection(cli)) {
6722 static bool run_eatest(int dummy)
6724 static struct cli_state *cli;
6725 const char *fname = "\\eatest.txt";
6726 bool correct = True;
6730 struct ea_struct *ea_list = NULL;
6731 TALLOC_CTX *mem_ctx = talloc_init("eatest");
6734 printf("starting eatest\n");
6736 if (!torture_open_connection(&cli, 0)) {
6737 talloc_destroy(mem_ctx);
6741 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6743 status = cli_ntcreate(cli, fname, 0,
6744 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6745 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6746 0x4044, 0, &fnum, NULL);
6747 if (!NT_STATUS_IS_OK(status)) {
6748 printf("open failed - %s\n", nt_errstr(status));
6749 talloc_destroy(mem_ctx);
6753 for (i = 0; i < 10; i++) {
6754 fstring ea_name, ea_val;
6756 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6757 memset(ea_val, (char)i+1, i+1);
6758 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6759 if (!NT_STATUS_IS_OK(status)) {
6760 printf("ea_set of name %s failed - %s\n", ea_name,
6762 talloc_destroy(mem_ctx);
6767 cli_close(cli, fnum);
6768 for (i = 0; i < 10; i++) {
6769 fstring ea_name, ea_val;
6771 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6772 memset(ea_val, (char)i+1, i+1);
6773 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6774 if (!NT_STATUS_IS_OK(status)) {
6775 printf("ea_set of name %s failed - %s\n", ea_name,
6777 talloc_destroy(mem_ctx);
6782 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6783 if (!NT_STATUS_IS_OK(status)) {
6784 printf("ea_get list failed - %s\n", nt_errstr(status));
6788 printf("num_eas = %d\n", (int)num_eas);
6790 if (num_eas != 20) {
6791 printf("Should be 20 EA's stored... failing.\n");
6795 for (i = 0; i < num_eas; i++) {
6796 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6797 dump_data(0, ea_list[i].value.data,
6798 ea_list[i].value.length);
6801 /* Setting EA's to zero length deletes them. Test this */
6802 printf("Now deleting all EA's - case indepenent....\n");
6805 cli_set_ea_path(cli, fname, "", "", 0);
6807 for (i = 0; i < 20; i++) {
6809 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6810 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6811 if (!NT_STATUS_IS_OK(status)) {
6812 printf("ea_set of name %s failed - %s\n", ea_name,
6814 talloc_destroy(mem_ctx);
6820 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6821 if (!NT_STATUS_IS_OK(status)) {
6822 printf("ea_get list failed - %s\n", nt_errstr(status));
6826 printf("num_eas = %d\n", (int)num_eas);
6827 for (i = 0; i < num_eas; i++) {
6828 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6829 dump_data(0, ea_list[i].value.data,
6830 ea_list[i].value.length);
6834 printf("deleting EA's failed.\n");
6838 /* Try and delete a non existent EA. */
6839 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6840 if (!NT_STATUS_IS_OK(status)) {
6841 printf("deleting non-existent EA 'foo' should succeed. %s\n",
6846 talloc_destroy(mem_ctx);
6847 if (!torture_close_connection(cli)) {
6854 static bool run_dirtest1(int dummy)
6857 static struct cli_state *cli;
6860 bool correct = True;
6862 printf("starting directory test\n");
6864 if (!torture_open_connection(&cli, 0)) {
6868 smbXcli_conn_set_sockopt(cli->conn, sockops);
6870 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6871 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6872 cli_rmdir(cli, "\\LISTDIR");
6873 cli_mkdir(cli, "\\LISTDIR");
6875 /* Create 1000 files and 1000 directories. */
6876 for (i=0;i<1000;i++) {
6878 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6879 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6880 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
6881 0, 0, &fnum, NULL))) {
6882 fprintf(stderr,"Failed to open %s\n", fname);
6885 cli_close(cli, fnum);
6887 for (i=0;i<1000;i++) {
6889 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6890 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6891 fprintf(stderr,"Failed to open %s\n", fname);
6896 /* Now ensure that doing an old list sees both files and directories. */
6898 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6899 printf("num_seen = %d\n", num_seen );
6900 /* We should see 100 files + 1000 directories + . and .. */
6901 if (num_seen != 2002)
6904 /* Ensure if we have the "must have" bits we only see the
6908 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6909 printf("num_seen = %d\n", num_seen );
6910 if (num_seen != 1002)
6914 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6915 printf("num_seen = %d\n", num_seen );
6916 if (num_seen != 1000)
6919 /* Delete everything. */
6920 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6921 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6922 cli_rmdir(cli, "\\LISTDIR");
6925 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6926 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6927 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6930 if (!torture_close_connection(cli)) {
6934 printf("finished dirtest1\n");
6939 static bool run_error_map_extract(int dummy) {
6941 static struct cli_state *c_dos;
6942 static struct cli_state *c_nt;
6954 /* NT-Error connection */
6956 disable_spnego = true;
6957 if (!(c_nt = open_nbt_connection())) {
6958 disable_spnego = false;
6961 disable_spnego = false;
6963 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
6966 if (!NT_STATUS_IS_OK(status)) {
6967 printf("%s rejected the NT-error negprot (%s)\n", host,
6973 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6974 if (!NT_STATUS_IS_OK(status)) {
6975 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6979 /* DOS-Error connection */
6981 disable_spnego = true;
6982 force_dos_errors = true;
6983 if (!(c_dos = open_nbt_connection())) {
6984 disable_spnego = false;
6985 force_dos_errors = false;
6988 disable_spnego = false;
6989 force_dos_errors = false;
6991 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
6993 if (!NT_STATUS_IS_OK(status)) {
6994 printf("%s rejected the DOS-error negprot (%s)\n", host,
6996 cli_shutdown(c_dos);
7000 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
7001 if (!NT_STATUS_IS_OK(status)) {
7002 printf("%s rejected the DOS-error initial session setup (%s)\n",
7003 host, nt_errstr(status));
7007 c_nt->map_dos_errors = false;
7008 c_dos->map_dos_errors = false;
7010 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7011 fstr_sprintf(user, "%X", error);
7013 status = cli_session_setup(c_nt, user,
7014 password, strlen(password),
7015 password, strlen(password),
7017 if (NT_STATUS_IS_OK(status)) {
7018 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7021 /* Case #1: 32-bit NT errors */
7022 if (!NT_STATUS_IS_DOS(status)) {
7025 printf("/** Dos error on NT connection! (%s) */\n",
7027 nt_status = NT_STATUS(0xc0000000);
7030 status = cli_session_setup(c_dos, user,
7031 password, strlen(password),
7032 password, strlen(password),
7034 if (NT_STATUS_IS_OK(status)) {
7035 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7038 /* Case #1: 32-bit NT errors */
7039 if (NT_STATUS_IS_DOS(status)) {
7040 printf("/** NT error on DOS connection! (%s) */\n",
7042 errnum = errclass = 0;
7044 errclass = NT_STATUS_DOS_CLASS(status);
7045 errnum = NT_STATUS_DOS_CODE(status);
7048 if (NT_STATUS_V(nt_status) != error) {
7049 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7050 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
7051 get_nt_error_c_code(talloc_tos(), nt_status));
7054 printf("\t{%s,\t%s,\t%s},\n",
7055 smb_dos_err_class(errclass),
7056 smb_dos_err_name(errclass, errnum),
7057 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7062 static bool run_sesssetup_bench(int dummy)
7064 static struct cli_state *c;
7065 const char *fname = "\\file.dat";
7070 if (!torture_open_connection(&c, 0)) {
7074 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7075 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7076 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7077 if (!NT_STATUS_IS_OK(status)) {
7078 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7082 for (i=0; i<torture_numops; i++) {
7083 status = cli_session_setup(
7085 password, strlen(password),
7086 password, strlen(password),
7088 if (!NT_STATUS_IS_OK(status)) {
7089 d_printf("(%s) cli_session_setup failed: %s\n",
7090 __location__, nt_errstr(status));
7094 d_printf("\r%d ", (int)cli_state_get_uid(c));
7096 status = cli_ulogoff(c);
7097 if (!NT_STATUS_IS_OK(status)) {
7098 d_printf("(%s) cli_ulogoff failed: %s\n",
7099 __location__, nt_errstr(status));
7107 static bool subst_test(const char *str, const char *user, const char *domain,
7108 uid_t uid, gid_t gid, const char *expected)
7113 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7115 if (strcmp(subst, expected) != 0) {
7116 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7117 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
7126 static void chain1_open_completion(struct tevent_req *req)
7130 status = cli_openx_recv(req, &fnum);
7133 d_printf("cli_openx_recv returned %s: %d\n",
7135 NT_STATUS_IS_OK(status) ? fnum : -1);
7138 static void chain1_write_completion(struct tevent_req *req)
7142 status = cli_write_andx_recv(req, &written);
7145 d_printf("cli_write_andx_recv returned %s: %d\n",
7147 NT_STATUS_IS_OK(status) ? (int)written : -1);
7150 static void chain1_close_completion(struct tevent_req *req)
7153 bool *done = (bool *)tevent_req_callback_data_void(req);
7155 status = cli_close_recv(req);
7160 d_printf("cli_close returned %s\n", nt_errstr(status));
7163 static bool run_chain1(int dummy)
7165 struct cli_state *cli1;
7166 struct tevent_context *evt = samba_tevent_context_init(NULL);
7167 struct tevent_req *reqs[3], *smbreqs[3];
7169 const char *str = "foobar";
7172 printf("starting chain1 test\n");
7173 if (!torture_open_connection(&cli1, 0)) {
7177 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7179 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
7180 O_CREAT|O_RDWR, 0, &smbreqs[0]);
7181 if (reqs[0] == NULL) return false;
7182 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
7185 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
7186 (const uint8_t *)str, 0, strlen(str)+1,
7187 smbreqs, 1, &smbreqs[1]);
7188 if (reqs[1] == NULL) return false;
7189 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
7191 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
7192 if (reqs[2] == NULL) return false;
7193 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
7195 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7196 if (!NT_STATUS_IS_OK(status)) {
7201 tevent_loop_once(evt);
7204 torture_close_connection(cli1);
7208 static void chain2_sesssetup_completion(struct tevent_req *req)
7211 status = cli_session_setup_guest_recv(req);
7212 d_printf("sesssetup returned %s\n", nt_errstr(status));
7215 static void chain2_tcon_completion(struct tevent_req *req)
7217 bool *done = (bool *)tevent_req_callback_data_void(req);
7219 status = cli_tcon_andx_recv(req);
7220 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
7224 static bool run_chain2(int dummy)
7226 struct cli_state *cli1;
7227 struct tevent_context *evt = samba_tevent_context_init(NULL);
7228 struct tevent_req *reqs[2], *smbreqs[2];
7232 printf("starting chain2 test\n");
7233 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
7234 port_to_use, SMB_SIGNING_DEFAULT, 0);
7235 if (!NT_STATUS_IS_OK(status)) {
7239 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7241 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
7243 if (reqs[0] == NULL) return false;
7244 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
7246 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
7247 "?????", NULL, 0, &smbreqs[1]);
7248 if (reqs[1] == NULL) return false;
7249 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
7251 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7252 if (!NT_STATUS_IS_OK(status)) {
7257 tevent_loop_once(evt);
7260 torture_close_connection(cli1);
7265 struct torture_createdel_state {
7266 struct tevent_context *ev;
7267 struct cli_state *cli;
7270 static void torture_createdel_created(struct tevent_req *subreq);
7271 static void torture_createdel_closed(struct tevent_req *subreq);
7273 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
7274 struct tevent_context *ev,
7275 struct cli_state *cli,
7278 struct tevent_req *req, *subreq;
7279 struct torture_createdel_state *state;
7281 req = tevent_req_create(mem_ctx, &state,
7282 struct torture_createdel_state);
7289 subreq = cli_ntcreate_send(
7290 state, ev, cli, name, 0,
7291 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
7292 FILE_ATTRIBUTE_NORMAL,
7293 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7294 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
7296 if (tevent_req_nomem(subreq, req)) {
7297 return tevent_req_post(req, ev);
7299 tevent_req_set_callback(subreq, torture_createdel_created, req);
7303 static void torture_createdel_created(struct tevent_req *subreq)
7305 struct tevent_req *req = tevent_req_callback_data(
7306 subreq, struct tevent_req);
7307 struct torture_createdel_state *state = tevent_req_data(
7308 req, struct torture_createdel_state);
7312 status = cli_ntcreate_recv(subreq, &fnum, NULL);
7313 TALLOC_FREE(subreq);
7314 if (tevent_req_nterror(req, status)) {
7315 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
7316 nt_errstr(status)));
7320 subreq = cli_close_send(state, state->ev, state->cli, fnum);
7321 if (tevent_req_nomem(subreq, req)) {
7324 tevent_req_set_callback(subreq, torture_createdel_closed, req);
7327 static void torture_createdel_closed(struct tevent_req *subreq)
7329 struct tevent_req *req = tevent_req_callback_data(
7330 subreq, struct tevent_req);
7333 status = cli_close_recv(subreq);
7334 if (tevent_req_nterror(req, status)) {
7335 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
7338 tevent_req_done(req);
7341 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
7343 return tevent_req_simple_recv_ntstatus(req);
7346 struct torture_createdels_state {
7347 struct tevent_context *ev;
7348 struct cli_state *cli;
7349 const char *base_name;
7353 struct tevent_req **reqs;
7356 static void torture_createdels_done(struct tevent_req *subreq);
7358 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
7359 struct tevent_context *ev,
7360 struct cli_state *cli,
7361 const char *base_name,
7365 struct tevent_req *req;
7366 struct torture_createdels_state *state;
7369 req = tevent_req_create(mem_ctx, &state,
7370 struct torture_createdels_state);
7376 state->base_name = talloc_strdup(state, base_name);
7377 if (tevent_req_nomem(state->base_name, req)) {
7378 return tevent_req_post(req, ev);
7380 state->num_files = MAX(num_parallel, num_files);
7382 state->received = 0;
7384 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
7385 if (tevent_req_nomem(state->reqs, req)) {
7386 return tevent_req_post(req, ev);
7389 for (i=0; i<num_parallel; i++) {
7392 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
7394 if (tevent_req_nomem(name, req)) {
7395 return tevent_req_post(req, ev);
7397 state->reqs[i] = torture_createdel_send(
7398 state->reqs, state->ev, state->cli, name);
7399 if (tevent_req_nomem(state->reqs[i], req)) {
7400 return tevent_req_post(req, ev);
7402 name = talloc_move(state->reqs[i], &name);
7403 tevent_req_set_callback(state->reqs[i],
7404 torture_createdels_done, req);
7410 static void torture_createdels_done(struct tevent_req *subreq)
7412 struct tevent_req *req = tevent_req_callback_data(
7413 subreq, struct tevent_req);
7414 struct torture_createdels_state *state = tevent_req_data(
7415 req, struct torture_createdels_state);
7416 size_t num_parallel = talloc_array_length(state->reqs);
7421 status = torture_createdel_recv(subreq);
7422 if (!NT_STATUS_IS_OK(status)){
7423 DEBUG(10, ("torture_createdel_recv returned %s\n",
7424 nt_errstr(status)));
7425 TALLOC_FREE(subreq);
7426 tevent_req_nterror(req, status);
7430 for (i=0; i<num_parallel; i++) {
7431 if (subreq == state->reqs[i]) {
7435 if (i == num_parallel) {
7436 DEBUG(10, ("received something we did not send\n"));
7437 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
7440 TALLOC_FREE(state->reqs[i]);
7442 if (state->sent >= state->num_files) {
7443 tevent_req_done(req);
7447 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
7449 if (tevent_req_nomem(name, req)) {
7452 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
7454 if (tevent_req_nomem(state->reqs[i], req)) {
7457 name = talloc_move(state->reqs[i], &name);
7458 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
7462 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
7464 return tevent_req_simple_recv_ntstatus(req);
7467 struct swallow_notify_state {
7468 struct tevent_context *ev;
7469 struct cli_state *cli;
7471 uint32_t completion_filter;
7473 bool (*fn)(uint32_t action, const char *name, void *priv);
7477 static void swallow_notify_done(struct tevent_req *subreq);
7479 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
7480 struct tevent_context *ev,
7481 struct cli_state *cli,
7483 uint32_t completion_filter,
7485 bool (*fn)(uint32_t action,
7490 struct tevent_req *req, *subreq;
7491 struct swallow_notify_state *state;
7493 req = tevent_req_create(mem_ctx, &state,
7494 struct swallow_notify_state);
7501 state->completion_filter = completion_filter;
7502 state->recursive = recursive;
7506 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
7507 0xffff, state->completion_filter,
7509 if (tevent_req_nomem(subreq, req)) {
7510 return tevent_req_post(req, ev);
7512 tevent_req_set_callback(subreq, swallow_notify_done, req);
7516 static void swallow_notify_done(struct tevent_req *subreq)
7518 struct tevent_req *req = tevent_req_callback_data(
7519 subreq, struct tevent_req);
7520 struct swallow_notify_state *state = tevent_req_data(
7521 req, struct swallow_notify_state);
7523 uint32_t i, num_changes;
7524 struct notify_change *changes;
7526 status = cli_notify_recv(subreq, state, &num_changes, &changes);
7527 TALLOC_FREE(subreq);
7528 if (!NT_STATUS_IS_OK(status)) {
7529 DEBUG(10, ("cli_notify_recv returned %s\n",
7530 nt_errstr(status)));
7531 tevent_req_nterror(req, status);
7535 for (i=0; i<num_changes; i++) {
7536 state->fn(changes[i].action, changes[i].name, state->priv);
7538 TALLOC_FREE(changes);
7540 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
7541 0xffff, state->completion_filter,
7543 if (tevent_req_nomem(subreq, req)) {
7546 tevent_req_set_callback(subreq, swallow_notify_done, req);
7549 static bool print_notifies(uint32_t action, const char *name, void *priv)
7551 if (DEBUGLEVEL > 5) {
7552 d_printf("%d %s\n", (int)action, name);
7557 static void notify_bench_done(struct tevent_req *req)
7559 int *num_finished = (int *)tevent_req_callback_data_void(req);
7563 static bool run_notify_bench(int dummy)
7565 const char *dname = "\\notify-bench";
7566 struct tevent_context *ev;
7569 struct tevent_req *req1;
7570 struct tevent_req *req2 = NULL;
7571 int i, num_unc_names;
7572 int num_finished = 0;
7574 printf("starting notify-bench test\n");
7576 if (use_multishare_conn) {
7578 unc_list = file_lines_load(multishare_conn_fname,
7579 &num_unc_names, 0, NULL);
7580 if (!unc_list || num_unc_names <= 0) {
7581 d_printf("Failed to load unc names list from '%s'\n",
7582 multishare_conn_fname);
7585 TALLOC_FREE(unc_list);
7590 ev = samba_tevent_context_init(talloc_tos());
7592 d_printf("tevent_context_init failed\n");
7596 for (i=0; i<num_unc_names; i++) {
7597 struct cli_state *cli;
7600 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
7602 if (base_fname == NULL) {
7606 if (!torture_open_connection(&cli, i)) {
7610 status = cli_ntcreate(cli, dname, 0,
7611 MAXIMUM_ALLOWED_ACCESS,
7612 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
7614 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
7617 if (!NT_STATUS_IS_OK(status)) {
7618 d_printf("Could not create %s: %s\n", dname,
7623 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
7624 FILE_NOTIFY_CHANGE_FILE_NAME |
7625 FILE_NOTIFY_CHANGE_DIR_NAME |
7626 FILE_NOTIFY_CHANGE_ATTRIBUTES |
7627 FILE_NOTIFY_CHANGE_LAST_WRITE,
7628 false, print_notifies, NULL);
7630 d_printf("Could not create notify request\n");
7634 req2 = torture_createdels_send(talloc_tos(), ev, cli,
7635 base_fname, 10, torture_numops);
7637 d_printf("Could not create createdels request\n");
7640 TALLOC_FREE(base_fname);
7642 tevent_req_set_callback(req2, notify_bench_done,
7646 while (num_finished < num_unc_names) {
7648 ret = tevent_loop_once(ev);
7650 d_printf("tevent_loop_once failed\n");
7655 if (!tevent_req_poll(req2, ev)) {
7656 d_printf("tevent_req_poll failed\n");
7659 status = torture_createdels_recv(req2);
7660 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
7665 static bool run_mangle1(int dummy)
7667 struct cli_state *cli;
7668 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
7672 time_t change_time, access_time, write_time;
7676 printf("starting mangle1 test\n");
7677 if (!torture_open_connection(&cli, 0)) {
7681 smbXcli_conn_set_sockopt(cli->conn, sockops);
7683 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7684 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7686 if (!NT_STATUS_IS_OK(status)) {
7687 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7690 cli_close(cli, fnum);
7692 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
7693 if (!NT_STATUS_IS_OK(status)) {
7694 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7698 d_printf("alt_name: %s\n", alt_name);
7700 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7701 if (!NT_STATUS_IS_OK(status)) {
7702 d_printf("cli_openx(%s) failed: %s\n", alt_name,
7706 cli_close(cli, fnum);
7708 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7709 &write_time, &size, &mode);
7710 if (!NT_STATUS_IS_OK(status)) {
7711 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7719 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7721 size_t *to_pull = (size_t *)priv;
7722 size_t thistime = *to_pull;
7724 thistime = MIN(thistime, n);
7725 if (thistime == 0) {
7729 memset(buf, 0, thistime);
7730 *to_pull -= thistime;
7734 static bool run_windows_write(int dummy)
7736 struct cli_state *cli1;
7740 const char *fname = "\\writetest.txt";
7741 struct timeval start_time;
7746 printf("starting windows_write test\n");
7747 if (!torture_open_connection(&cli1, 0)) {
7751 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7752 if (!NT_STATUS_IS_OK(status)) {
7753 printf("open failed (%s)\n", nt_errstr(status));
7757 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7759 start_time = timeval_current();
7761 for (i=0; i<torture_numops; i++) {
7763 off_t start = i * torture_blocksize;
7764 size_t to_pull = torture_blocksize - 1;
7766 status = cli_writeall(cli1, fnum, 0, &c,
7767 start + torture_blocksize - 1, 1, NULL);
7768 if (!NT_STATUS_IS_OK(status)) {
7769 printf("cli_write failed: %s\n", nt_errstr(status));
7773 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7774 null_source, &to_pull);
7775 if (!NT_STATUS_IS_OK(status)) {
7776 printf("cli_push returned: %s\n", nt_errstr(status));
7781 seconds = timeval_elapsed(&start_time);
7782 kbytes = (double)torture_blocksize * torture_numops;
7785 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7786 (double)seconds, (int)(kbytes/seconds));
7790 cli_close(cli1, fnum);
7791 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7792 torture_close_connection(cli1);
7796 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
7798 size_t max_pdu = 0x1FFFF;
7800 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
7804 if (smb1cli_conn_signing_is_active(cli->conn)) {
7808 if (smb1cli_conn_encryption_on(cli->conn)) {
7809 max_pdu = CLI_BUFFER_SIZE;
7812 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
7813 len_requested &= 0xFFFF;
7816 return MIN(len_requested,
7817 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
7820 static bool check_read_call(struct cli_state *cli,
7823 size_t len_requested)
7826 struct tevent_req *subreq = NULL;
7827 ssize_t len_read = 0;
7828 size_t len_expected = 0;
7829 struct tevent_context *ev = NULL;
7831 ev = samba_tevent_context_init(talloc_tos());
7836 subreq = cli_read_andx_send(talloc_tos(),
7843 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
7847 status = cli_read_andx_recv(subreq, &len_read, &buf);
7848 if (!NT_STATUS_IS_OK(status)) {
7849 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
7853 TALLOC_FREE(subreq);
7856 len_expected = calc_expected_return(cli, len_requested);
7858 if (len_expected > 0x10000 && len_read == 0x10000) {
7859 /* Windows servers only return a max of 0x10000,
7860 doesn't matter if you set CAP_LARGE_READX in
7861 the client sessionsetupX call or not. */
7862 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
7863 (unsigned int)len_requested);
7864 } else if (len_read != len_expected) {
7865 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
7866 (unsigned int)len_requested,
7867 (unsigned int)len_read,
7868 (unsigned int)len_expected);
7871 d_printf("Correct read reply.\n");
7877 /* Test large readX variants. */
7878 static bool large_readx_tests(struct cli_state *cli,
7882 /* A read of 0xFFFF0001 should *always* return 1 byte. */
7883 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
7886 /* A read of 0x10000 should return 0x10000 bytes. */
7887 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
7890 /* A read of 0x10000 should return 0x10001 bytes. */
7891 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
7894 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
7895 the requested number of bytes. */
7896 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
7899 /* A read of 1MB should return 1MB bytes (on Samba). */
7900 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
7904 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
7907 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
7910 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
7916 static bool run_large_readx(int dummy)
7918 uint8_t *buf = NULL;
7919 struct cli_state *cli1 = NULL;
7920 struct cli_state *cli2 = NULL;
7921 bool correct = false;
7922 const char *fname = "\\large_readx.dat";
7924 uint16_t fnum1 = UINT16_MAX;
7925 uint32_t normal_caps = 0;
7926 size_t file_size = 20*1024*1024;
7927 TALLOC_CTX *frame = talloc_stackframe();
7931 enum smb_signing_setting signing_setting;
7932 enum protocol_types protocol;
7936 .signing_setting = SMB_SIGNING_IF_REQUIRED,
7937 .protocol = PROTOCOL_NT1,
7939 .name = "NT1 - SIGNING_REQUIRED",
7940 .signing_setting = SMB_SIGNING_REQUIRED,
7941 .protocol = PROTOCOL_NT1,
7945 printf("starting large_readx test\n");
7947 if (!torture_open_connection(&cli1, 0)) {
7951 normal_caps = smb1cli_conn_capabilities(cli1->conn);
7953 if (!(normal_caps & CAP_LARGE_READX)) {
7954 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
7955 (unsigned int)normal_caps);
7959 /* Create a file of size 4MB. */
7960 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
7961 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7962 0, 0, &fnum1, NULL);
7964 if (!NT_STATUS_IS_OK(status)) {
7965 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7969 /* Write file_size bytes. */
7970 buf = talloc_zero_array(frame, uint8_t, file_size);
7975 status = cli_writeall(cli1,
7982 if (!NT_STATUS_IS_OK(status)) {
7983 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
7987 status = cli_close(cli1, fnum1);
7988 if (!NT_STATUS_IS_OK(status)) {
7989 d_printf("cli_close failed: %s\n", nt_errstr(status));
7995 for (i=0; i < ARRAY_SIZE(runs); i++) {
7996 enum smb_signing_setting saved_signing_setting = signing_state;
7997 uint16_t fnum2 = -1;
8000 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
8002 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
8006 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
8008 signing_state = runs[i].signing_setting;
8009 cli2 = open_nbt_connection();
8010 signing_state = saved_signing_setting;
8015 status = smbXcli_negprot(cli2->conn,
8019 if (!NT_STATUS_IS_OK(status)) {
8023 status = cli_session_setup(cli2,
8030 if (!NT_STATUS_IS_OK(status)) {
8034 status = cli_tree_connect(cli2,
8038 strlen(password)+1);
8039 if (!NT_STATUS_IS_OK(status)) {
8043 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
8045 normal_caps = smb1cli_conn_capabilities(cli2->conn);
8047 if (!(normal_caps & CAP_LARGE_READX)) {
8048 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8049 (unsigned int)normal_caps);
8054 if (force_cli_encryption(cli2, share) == false) {
8057 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
8058 uint16_t major, minor;
8059 uint32_t caplow, caphigh;
8061 status = cli_unix_extensions_version(cli2,
8064 if (!NT_STATUS_IS_OK(status)) {
8069 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
8070 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
8071 0, 0, &fnum2, NULL);
8072 if (!NT_STATUS_IS_OK(status)) {
8073 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
8077 /* All reads must return less than file_size bytes. */
8078 if (!large_readx_tests(cli2, fnum2, buf)) {
8082 status = cli_close(cli2, fnum2);
8083 if (!NT_STATUS_IS_OK(status)) {
8084 d_printf("cli_close failed: %s\n", nt_errstr(status));
8089 if (!torture_close_connection(cli2)) {
8096 printf("Success on large_readx test\n");
8101 if (!torture_close_connection(cli2)) {
8107 if (fnum1 != UINT16_MAX) {
8108 status = cli_close(cli1, fnum1);
8109 if (!NT_STATUS_IS_OK(status)) {
8110 d_printf("cli_close failed: %s\n", nt_errstr(status));
8115 status = cli_unlink(cli1, fname,
8116 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8117 if (!NT_STATUS_IS_OK(status)) {
8118 printf("unlink failed (%s)\n", nt_errstr(status));
8121 if (!torture_close_connection(cli1)) {
8128 printf("finished large_readx test\n");
8132 static bool run_cli_echo(int dummy)
8134 struct cli_state *cli;
8137 printf("starting cli_echo test\n");
8138 if (!torture_open_connection(&cli, 0)) {
8141 smbXcli_conn_set_sockopt(cli->conn, sockops);
8143 status = cli_echo(cli, 5, data_blob_const("hello", 5));
8145 d_printf("cli_echo returned %s\n", nt_errstr(status));
8147 torture_close_connection(cli);
8148 return NT_STATUS_IS_OK(status);
8151 static bool run_uid_regression_test(int dummy)
8153 static struct cli_state *cli;
8156 bool correct = True;
8159 printf("starting uid regression test\n");
8161 if (!torture_open_connection(&cli, 0)) {
8165 smbXcli_conn_set_sockopt(cli->conn, sockops);
8167 /* Ok - now save then logoff our current user. */
8168 old_vuid = cli_state_get_uid(cli);
8170 status = cli_ulogoff(cli);
8171 if (!NT_STATUS_IS_OK(status)) {
8172 d_printf("(%s) cli_ulogoff failed: %s\n",
8173 __location__, nt_errstr(status));
8178 cli_state_set_uid(cli, old_vuid);
8180 /* Try an operation. */
8181 status = cli_mkdir(cli, "\\uid_reg_test");
8182 if (NT_STATUS_IS_OK(status)) {
8183 d_printf("(%s) cli_mkdir succeeded\n",
8188 /* Should be bad uid. */
8189 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
8190 NT_STATUS_USER_SESSION_DELETED)) {
8196 old_cnum = cli_state_get_tid(cli);
8198 /* Now try a SMBtdis with the invald vuid set to zero. */
8199 cli_state_set_uid(cli, 0);
8201 /* This should succeed. */
8202 status = cli_tdis(cli);
8204 if (NT_STATUS_IS_OK(status)) {
8205 d_printf("First tdis with invalid vuid should succeed.\n");
8207 d_printf("First tdis failed (%s)\n", nt_errstr(status));
8212 cli_state_set_uid(cli, old_vuid);
8213 cli_state_set_tid(cli, old_cnum);
8215 /* This should fail. */
8216 status = cli_tdis(cli);
8217 if (NT_STATUS_IS_OK(status)) {
8218 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
8222 /* Should be bad tid. */
8223 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
8224 NT_STATUS_NETWORK_NAME_DELETED)) {
8230 cli_rmdir(cli, "\\uid_reg_test");
8239 static const char *illegal_chars = "*\\/?<>|\":";
8240 static char force_shortname_chars[] = " +,.[];=\177";
8242 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
8243 const char *mask, void *state)
8245 struct cli_state *pcli = (struct cli_state *)state;
8247 NTSTATUS status = NT_STATUS_OK;
8249 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
8251 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
8252 return NT_STATUS_OK;
8254 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
8255 status = cli_rmdir(pcli, fname);
8256 if (!NT_STATUS_IS_OK(status)) {
8257 printf("del_fn: failed to rmdir %s\n,", fname );
8260 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8261 if (!NT_STATUS_IS_OK(status)) {
8262 printf("del_fn: failed to unlink %s\n,", fname );
8274 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
8275 const char *name, void *state)
8277 struct sn_state *s = (struct sn_state *)state;
8281 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
8282 i, finfo->name, finfo->short_name);
8285 if (strchr(force_shortname_chars, i)) {
8286 if (!finfo->short_name) {
8287 /* Shortname not created when it should be. */
8288 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
8289 __location__, finfo->name, i);
8292 } else if (finfo->short_name){
8293 /* Shortname created when it should not be. */
8294 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
8295 __location__, finfo->short_name, finfo->name);
8299 return NT_STATUS_OK;
8302 static bool run_shortname_test(int dummy)
8304 static struct cli_state *cli;
8305 bool correct = True;
8311 printf("starting shortname test\n");
8313 if (!torture_open_connection(&cli, 0)) {
8317 smbXcli_conn_set_sockopt(cli->conn, sockops);
8319 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
8320 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
8321 cli_rmdir(cli, "\\shortname");
8323 status = cli_mkdir(cli, "\\shortname");
8324 if (!NT_STATUS_IS_OK(status)) {
8325 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
8326 __location__, nt_errstr(status));
8331 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
8335 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
8342 for (i = 32; i < 128; i++) {
8343 uint16_t fnum = (uint16_t)-1;
8347 if (strchr(illegal_chars, i)) {
8352 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
8353 FILE_SHARE_READ|FILE_SHARE_WRITE,
8354 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
8355 if (!NT_STATUS_IS_OK(status)) {
8356 d_printf("(%s) cli_nt_create of %s failed: %s\n",
8357 __location__, fname, nt_errstr(status));
8361 cli_close(cli, fnum);
8364 status = cli_list(cli, "\\shortname\\test*.*", 0,
8365 shortname_list_fn, &s);
8366 if (s.matched != 1) {
8367 d_printf("(%s) failed to list %s: %s\n",
8368 __location__, fname, nt_errstr(status));
8373 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8374 if (!NT_STATUS_IS_OK(status)) {
8375 d_printf("(%s) failed to delete %s: %s\n",
8376 __location__, fname, nt_errstr(status));
8389 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
8390 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
8391 cli_rmdir(cli, "\\shortname");
8392 torture_close_connection(cli);
8396 static void pagedsearch_cb(struct tevent_req *req)
8399 struct tldap_message *msg;
8402 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
8403 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8404 d_printf("tldap_search_paged_recv failed: %s\n",
8405 tldap_rc2string(rc));
8408 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
8412 if (!tldap_entry_dn(msg, &dn)) {
8413 d_printf("tldap_entry_dn failed\n");
8416 d_printf("%s\n", dn);
8420 static bool run_tldap(int dummy)
8422 struct tldap_context *ld;
8426 struct sockaddr_storage addr;
8427 struct tevent_context *ev;
8428 struct tevent_req *req;
8432 if (!resolve_name(host, &addr, 0, false)) {
8433 d_printf("could not find host %s\n", host);
8436 status = open_socket_out(&addr, 389, 9999, &fd);
8437 if (!NT_STATUS_IS_OK(status)) {
8438 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
8442 ld = tldap_context_create(talloc_tos(), fd);
8445 d_printf("tldap_context_create failed\n");
8449 rc = tldap_fetch_rootdse(ld);
8450 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8451 d_printf("tldap_fetch_rootdse failed: %s\n",
8452 tldap_errstr(talloc_tos(), ld, rc));
8456 basedn = tldap_talloc_single_attribute(
8457 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
8458 if (basedn == NULL) {
8459 d_printf("no defaultNamingContext\n");
8462 d_printf("defaultNamingContext: %s\n", basedn);
8464 ev = samba_tevent_context_init(talloc_tos());
8466 d_printf("tevent_context_init failed\n");
8470 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
8471 TLDAP_SCOPE_SUB, "(objectclass=*)",
8473 NULL, 0, NULL, 0, 0, 0, 0, 5);
8475 d_printf("tldap_search_paged_send failed\n");
8478 tevent_req_set_callback(req, pagedsearch_cb, NULL);
8480 tevent_req_poll(req, ev);
8484 /* test search filters against rootDSE */
8485 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
8486 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
8488 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
8489 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
8490 talloc_tos(), NULL);
8491 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8492 d_printf("tldap_search with complex filter failed: %s\n",
8493 tldap_errstr(talloc_tos(), ld, rc));
8501 /* Torture test to ensure no regression of :
8502 https://bugzilla.samba.org/show_bug.cgi?id=7084
8505 static bool run_dir_createtime(int dummy)
8507 struct cli_state *cli;
8508 const char *dname = "\\testdir";
8509 const char *fname = "\\testdir\\testfile";
8511 struct timespec create_time;
8512 struct timespec create_time1;
8516 if (!torture_open_connection(&cli, 0)) {
8520 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8521 cli_rmdir(cli, dname);
8523 status = cli_mkdir(cli, dname);
8524 if (!NT_STATUS_IS_OK(status)) {
8525 printf("mkdir failed: %s\n", nt_errstr(status));
8529 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
8531 if (!NT_STATUS_IS_OK(status)) {
8532 printf("cli_qpathinfo2 returned %s\n",
8537 /* Sleep 3 seconds, then create a file. */
8540 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
8542 if (!NT_STATUS_IS_OK(status)) {
8543 printf("cli_openx failed: %s\n", nt_errstr(status));
8547 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
8549 if (!NT_STATUS_IS_OK(status)) {
8550 printf("cli_qpathinfo2 (2) returned %s\n",
8555 if (timespec_compare(&create_time1, &create_time)) {
8556 printf("run_dir_createtime: create time was updated (error)\n");
8558 printf("run_dir_createtime: create time was not updated (correct)\n");
8564 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8565 cli_rmdir(cli, dname);
8566 if (!torture_close_connection(cli)) {
8573 static bool run_streamerror(int dummy)
8575 struct cli_state *cli;
8576 const char *dname = "\\testdir";
8577 const char *streamname =
8578 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
8580 time_t change_time, access_time, write_time;
8582 uint16_t mode, fnum;
8585 if (!torture_open_connection(&cli, 0)) {
8589 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8590 cli_rmdir(cli, dname);
8592 status = cli_mkdir(cli, dname);
8593 if (!NT_STATUS_IS_OK(status)) {
8594 printf("mkdir failed: %s\n", nt_errstr(status));
8598 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
8599 &write_time, &size, &mode);
8600 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
8601 printf("pathinfo returned %s, expected "
8602 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8607 status = cli_ntcreate(cli, streamname, 0x16,
8608 FILE_READ_DATA|FILE_READ_EA|
8609 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
8610 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
8611 FILE_OPEN, 0, 0, &fnum, NULL);
8613 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
8614 printf("ntcreate returned %s, expected "
8615 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8621 cli_rmdir(cli, dname);
8625 struct pidtest_state {
8631 static void pid_echo_done(struct tevent_req *subreq);
8633 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
8634 struct tevent_context *ev,
8635 struct cli_state *cli)
8637 struct tevent_req *req, *subreq;
8638 struct pidtest_state *state;
8640 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
8645 SSVAL(state->vwv, 0, 1);
8646 state->data = data_blob_const("hello", 5);
8648 subreq = smb1cli_req_send(state,
8653 0, 0, /* *_flags2 */
8655 0xDEADBEEF, /* pid */
8658 ARRAY_SIZE(state->vwv), state->vwv,
8659 state->data.length, state->data.data);
8661 if (tevent_req_nomem(subreq, req)) {
8662 return tevent_req_post(req, ev);
8664 tevent_req_set_callback(subreq, pid_echo_done, req);
8668 static void pid_echo_done(struct tevent_req *subreq)
8670 struct tevent_req *req = tevent_req_callback_data(
8671 subreq, struct tevent_req);
8672 struct pidtest_state *state = tevent_req_data(
8673 req, struct pidtest_state);
8676 uint8_t *bytes = NULL;
8677 struct iovec *recv_iov = NULL;
8678 uint8_t *phdr = NULL;
8679 uint16_t pidlow = 0;
8680 uint16_t pidhigh = 0;
8681 struct smb1cli_req_expected_response expected[] = {
8683 .status = NT_STATUS_OK,
8688 status = smb1cli_req_recv(subreq, state,
8693 NULL, /* pvwv_offset */
8696 NULL, /* pbytes_offset */
8698 expected, ARRAY_SIZE(expected));
8700 TALLOC_FREE(subreq);
8702 if (!NT_STATUS_IS_OK(status)) {
8703 tevent_req_nterror(req, status);
8707 if (num_bytes != state->data.length) {
8708 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8712 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
8713 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8717 /* Check pid low/high == DEADBEEF */
8718 pidlow = SVAL(phdr, HDR_PID);
8719 if (pidlow != 0xBEEF){
8720 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
8721 (unsigned int)pidlow);
8722 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8725 pidhigh = SVAL(phdr, HDR_PIDHIGH);
8726 if (pidhigh != 0xDEAD){
8727 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
8728 (unsigned int)pidhigh);
8729 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8733 tevent_req_done(req);
8736 static NTSTATUS pid_echo_recv(struct tevent_req *req)
8738 return tevent_req_simple_recv_ntstatus(req);
8741 static bool run_pidhigh(int dummy)
8743 bool success = false;
8744 struct cli_state *cli = NULL;
8746 struct tevent_context *ev = NULL;
8747 struct tevent_req *req = NULL;
8748 TALLOC_CTX *frame = talloc_stackframe();
8750 printf("starting pid high test\n");
8751 if (!torture_open_connection(&cli, 0)) {
8754 smbXcli_conn_set_sockopt(cli->conn, sockops);
8756 ev = samba_tevent_context_init(frame);
8761 req = pid_echo_send(frame, ev, cli);
8766 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
8770 status = pid_echo_recv(req);
8771 if (NT_STATUS_IS_OK(status)) {
8772 printf("pid high test ok\n");
8779 torture_close_connection(cli);
8783 static bool run_local_substitute(int dummy)
8787 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
8788 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
8789 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
8790 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
8791 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
8792 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
8793 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
8794 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
8796 /* Different captialization rules in sub_basic... */
8798 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
8804 static bool run_local_base64(int dummy)
8809 for (i=1; i<2000; i++) {
8810 DATA_BLOB blob1, blob2;
8813 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
8815 generate_random_buffer(blob1.data, blob1.length);
8817 b64 = base64_encode_data_blob(talloc_tos(), blob1);
8819 d_fprintf(stderr, "base64_encode_data_blob failed "
8820 "for %d bytes\n", i);
8823 blob2 = base64_decode_data_blob(b64);
8826 if (data_blob_cmp(&blob1, &blob2)) {
8827 d_fprintf(stderr, "data_blob_cmp failed for %d "
8831 TALLOC_FREE(blob1.data);
8832 data_blob_free(&blob2);
8837 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
8842 static bool run_local_gencache(int dummy)
8848 struct memcache *mem;
8851 mem = memcache_init(NULL, 0);
8853 d_printf("%s: memcache_init failed\n", __location__);
8856 memcache_set_global(mem);
8858 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
8859 d_printf("%s: gencache_set() failed\n", __location__);
8863 if (!gencache_get("foo", NULL, NULL, NULL)) {
8864 d_printf("%s: gencache_get() failed\n", __location__);
8868 for (i=0; i<1000000; i++) {
8869 gencache_parse("foo", parse_fn, NULL);
8872 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
8873 d_printf("%s: gencache_get() failed\n", __location__);
8878 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
8879 d_printf("%s: gencache_get() failed\n", __location__);
8883 if (strcmp(val, "bar") != 0) {
8884 d_printf("%s: gencache_get() returned %s, expected %s\n",
8885 __location__, val, "bar");
8892 if (!gencache_del("foo")) {
8893 d_printf("%s: gencache_del() failed\n", __location__);
8896 if (gencache_del("foo")) {
8897 d_printf("%s: second gencache_del() succeeded\n",
8902 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
8903 d_printf("%s: gencache_get() on deleted entry "
8904 "succeeded\n", __location__);
8908 blob = data_blob_string_const_null("bar");
8909 tm = time(NULL) + 60;
8911 if (!gencache_set_data_blob("foo", &blob, tm)) {
8912 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
8916 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
8917 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
8921 if (strcmp((const char *)blob.data, "bar") != 0) {
8922 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
8923 __location__, (const char *)blob.data, "bar");
8924 data_blob_free(&blob);
8928 data_blob_free(&blob);
8930 if (!gencache_del("foo")) {
8931 d_printf("%s: gencache_del() failed\n", __location__);
8934 if (gencache_del("foo")) {
8935 d_printf("%s: second gencache_del() succeeded\n",
8940 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
8941 d_printf("%s: gencache_get_data_blob() on deleted entry "
8942 "succeeded\n", __location__);
8947 blob.data = (uint8_t *)&v;
8948 blob.length = sizeof(v);
8950 if (!gencache_set_data_blob("blob", &blob, tm)) {
8951 d_printf("%s: gencache_set_data_blob() failed\n",
8955 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
8956 d_printf("%s: gencache_get succeeded\n", __location__);
8963 static bool rbt_testval(struct db_context *db, const char *key,
8966 struct db_record *rec;
8967 TDB_DATA data = string_tdb_data(value);
8972 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
8974 d_fprintf(stderr, "fetch_locked failed\n");
8977 status = dbwrap_record_store(rec, data, 0);
8978 if (!NT_STATUS_IS_OK(status)) {
8979 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
8984 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
8986 d_fprintf(stderr, "second fetch_locked failed\n");
8990 dbvalue = dbwrap_record_get_value(rec);
8991 if ((dbvalue.dsize != data.dsize)
8992 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
8993 d_fprintf(stderr, "Got wrong data back\n");
9003 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
9005 int *count2 = (int *)private_data;
9010 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
9012 int *count2 = (int *)private_data;
9014 dbwrap_record_delete(rec);
9018 static bool run_local_rbtree(int dummy)
9020 struct db_context *db;
9027 db = db_open_rbt(NULL);
9030 d_fprintf(stderr, "db_open_rbt failed\n");
9034 for (i=0; i<1000; i++) {
9037 if (asprintf(&key, "key%ld", random()) == -1) {
9040 if (asprintf(&value, "value%ld", random()) == -1) {
9045 if (!rbt_testval(db, key, value)) {
9052 if (asprintf(&value, "value%ld", random()) == -1) {
9057 if (!rbt_testval(db, key, value)) {
9068 count = 0; count2 = 0;
9069 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
9071 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9072 if ((count != count2) || (count != 1000)) {
9075 count = 0; count2 = 0;
9076 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
9078 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9079 if ((count != count2) || (count != 1000)) {
9082 count = 0; count2 = 0;
9083 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
9085 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9086 if ((count != count2) || (count != 0)) {
9097 local test for character set functions
9099 This is a very simple test for the functionality in convert_string_error()
9101 static bool run_local_convert_string(int dummy)
9103 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
9104 const char *test_strings[2] = { "March", "M\303\244rz" };
9108 for (i=0; i<2; i++) {
9109 const char *str = test_strings[i];
9110 int len = strlen(str);
9111 size_t converted_size;
9114 memset(dst, 'X', sizeof(dst));
9116 /* first try with real source length */
9117 ret = convert_string_error(CH_UNIX, CH_UTF8,
9122 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
9126 if (converted_size != len) {
9127 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
9128 str, len, (int)converted_size);
9132 if (strncmp(str, dst, converted_size) != 0) {
9133 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
9137 if (strlen(str) != converted_size) {
9138 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
9139 (int)strlen(str), (int)converted_size);
9143 if (dst[converted_size] != 'X') {
9144 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
9148 /* now with srclen==-1, this causes the nul to be
9150 ret = convert_string_error(CH_UNIX, CH_UTF8,
9155 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
9159 if (converted_size != len+1) {
9160 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
9161 str, len, (int)converted_size);
9165 if (strncmp(str, dst, converted_size) != 0) {
9166 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
9170 if (len+1 != converted_size) {
9171 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
9172 len+1, (int)converted_size);
9176 if (dst[converted_size] != 'X') {
9177 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
9184 TALLOC_FREE(tmp_ctx);
9187 TALLOC_FREE(tmp_ctx);
9192 struct talloc_dict_test {
9196 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
9198 int *count = (int *)priv;
9203 static bool run_local_talloc_dict(int dummy)
9205 struct talloc_dict *dict;
9206 struct talloc_dict_test *t;
9207 int key, count, res;
9210 dict = talloc_dict_init(talloc_tos());
9215 t = talloc(talloc_tos(), struct talloc_dict_test);
9222 ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
9228 res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
9246 static bool run_local_string_to_sid(int dummy) {
9249 if (string_to_sid(&sid, "S--1-5-32-545")) {
9250 printf("allowing S--1-5-32-545\n");
9253 if (string_to_sid(&sid, "S-1-5-32-+545")) {
9254 printf("allowing S-1-5-32-+545\n");
9257 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")) {
9258 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
9261 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
9262 printf("allowing S-1-5-32-545-abc\n");
9265 if (string_to_sid(&sid, "S-300-5-32-545")) {
9266 printf("allowing S-300-5-32-545\n");
9269 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
9270 printf("allowing S-1-0xfffffffffffffe-32-545\n");
9273 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
9274 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
9277 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
9278 printf("could not parse S-1-0xfffffffffffe-32-545\n");
9281 if (!string_to_sid(&sid, "S-1-5-32-545")) {
9282 printf("could not parse S-1-5-32-545\n");
9285 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
9286 printf("mis-parsed S-1-5-32-545 as %s\n",
9287 sid_string_tos(&sid));
9293 static bool sid_to_string_test(const char *expected) {
9298 if (!string_to_sid(&sid, expected)) {
9299 printf("could not parse %s\n", expected);
9303 str = dom_sid_string(NULL, &sid);
9304 if (strcmp(str, expected)) {
9305 printf("Comparison failed (%s != %s)\n", str, expected);
9312 static bool run_local_sid_to_string(int dummy) {
9313 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
9315 if (!sid_to_string_test("S-1-545"))
9317 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
9322 static bool run_local_binary_to_sid(int dummy) {
9323 struct dom_sid *sid = talloc(NULL, struct dom_sid);
9324 static const uint8_t good_binary_sid[] = {
9325 0x1, /* revision number */
9327 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9328 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9329 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9330 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9331 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9332 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9333 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9334 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9335 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9336 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9337 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9338 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9339 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9340 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9341 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9342 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9345 static const uint8_t long_binary_sid[] = {
9346 0x1, /* revision number */
9348 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9349 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9350 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9351 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9352 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9353 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9354 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9355 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9356 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9357 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9358 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9359 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9360 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9361 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9362 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9363 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9364 0x1, 0x1, 0x1, 0x1, /* auth[15] */
9365 0x1, 0x1, 0x1, 0x1, /* auth[16] */
9366 0x1, 0x1, 0x1, 0x1, /* auth[17] */
9369 static const uint8_t long_binary_sid2[] = {
9370 0x1, /* revision number */
9372 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9373 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9374 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9375 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9376 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9377 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9378 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9379 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9380 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9381 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9382 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9383 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9384 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9385 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9386 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9387 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9388 0x1, 0x1, 0x1, 0x1, /* auth[15] */
9389 0x1, 0x1, 0x1, 0x1, /* auth[16] */
9390 0x1, 0x1, 0x1, 0x1, /* auth[17] */
9391 0x1, 0x1, 0x1, 0x1, /* auth[18] */
9392 0x1, 0x1, 0x1, 0x1, /* auth[19] */
9393 0x1, 0x1, 0x1, 0x1, /* auth[20] */
9394 0x1, 0x1, 0x1, 0x1, /* auth[21] */
9395 0x1, 0x1, 0x1, 0x1, /* auth[22] */
9396 0x1, 0x1, 0x1, 0x1, /* auth[23] */
9397 0x1, 0x1, 0x1, 0x1, /* auth[24] */
9398 0x1, 0x1, 0x1, 0x1, /* auth[25] */
9399 0x1, 0x1, 0x1, 0x1, /* auth[26] */
9400 0x1, 0x1, 0x1, 0x1, /* auth[27] */
9401 0x1, 0x1, 0x1, 0x1, /* auth[28] */
9402 0x1, 0x1, 0x1, 0x1, /* auth[29] */
9403 0x1, 0x1, 0x1, 0x1, /* auth[30] */
9404 0x1, 0x1, 0x1, 0x1, /* auth[31] */
9407 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
9410 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
9413 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
9419 /* Split a path name into filename and stream name components. Canonicalise
9420 * such that an implicit $DATA token is always explicit.
9422 * The "specification" of this function can be found in the
9423 * run_local_stream_name() function in torture.c, I've tried those
9424 * combinations against a W2k3 server.
9427 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
9428 char **pbase, char **pstream)
9431 char *stream = NULL;
9432 char *sname; /* stream name */
9433 const char *stype; /* stream type */
9435 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
9437 sname = strchr_m(fname, ':');
9439 if (sname == NULL) {
9440 if (pbase != NULL) {
9441 base = talloc_strdup(mem_ctx, fname);
9442 NT_STATUS_HAVE_NO_MEMORY(base);
9447 if (pbase != NULL) {
9448 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
9449 NT_STATUS_HAVE_NO_MEMORY(base);
9454 stype = strchr_m(sname, ':');
9456 if (stype == NULL) {
9457 sname = talloc_strdup(mem_ctx, sname);
9461 if (strcasecmp_m(stype, ":$DATA") != 0) {
9463 * If there is an explicit stream type, so far we only
9464 * allow $DATA. Is there anything else allowed? -- vl
9466 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
9468 return NT_STATUS_OBJECT_NAME_INVALID;
9470 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
9474 if (sname == NULL) {
9476 return NT_STATUS_NO_MEMORY;
9479 if (sname[0] == '\0') {
9481 * no stream name, so no stream
9486 if (pstream != NULL) {
9487 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
9488 if (stream == NULL) {
9491 return NT_STATUS_NO_MEMORY;
9494 * upper-case the type field
9496 (void)strupper_m(strchr_m(stream, ':')+1);
9500 if (pbase != NULL) {
9503 if (pstream != NULL) {
9506 return NT_STATUS_OK;
9509 static bool test_stream_name(const char *fname, const char *expected_base,
9510 const char *expected_stream,
9511 NTSTATUS expected_status)
9515 char *stream = NULL;
9517 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
9518 if (!NT_STATUS_EQUAL(status, expected_status)) {
9522 if (!NT_STATUS_IS_OK(status)) {
9526 if (base == NULL) goto error;
9528 if (strcmp(expected_base, base) != 0) goto error;
9530 if ((expected_stream != NULL) && (stream == NULL)) goto error;
9531 if ((expected_stream == NULL) && (stream != NULL)) goto error;
9533 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
9537 TALLOC_FREE(stream);
9541 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
9542 fname, expected_base ? expected_base : "<NULL>",
9543 expected_stream ? expected_stream : "<NULL>",
9544 nt_errstr(expected_status));
9545 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
9546 base ? base : "<NULL>", stream ? stream : "<NULL>",
9549 TALLOC_FREE(stream);
9553 static bool run_local_stream_name(int dummy)
9557 ret &= test_stream_name(
9558 "bla", "bla", NULL, NT_STATUS_OK);
9559 ret &= test_stream_name(
9560 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
9561 ret &= test_stream_name(
9562 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
9563 ret &= test_stream_name(
9564 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
9565 ret &= test_stream_name(
9566 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
9567 ret &= test_stream_name(
9568 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
9569 ret &= test_stream_name(
9570 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
9571 ret &= test_stream_name(
9572 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
9577 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
9579 if (a.length != b.length) {
9580 printf("a.length=%d != b.length=%d\n",
9581 (int)a.length, (int)b.length);
9584 if (memcmp(a.data, b.data, a.length) != 0) {
9585 printf("a.data and b.data differ\n");
9591 static bool run_local_memcache(int dummy)
9593 struct memcache *cache;
9595 DATA_BLOB d1, d2, d3;
9596 DATA_BLOB v1, v2, v3;
9598 TALLOC_CTX *mem_ctx;
9600 size_t size1, size2;
9603 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
9605 if (cache == NULL) {
9606 printf("memcache_init failed\n");
9610 d1 = data_blob_const("d1", 2);
9611 d2 = data_blob_const("d2", 2);
9612 d3 = data_blob_const("d3", 2);
9614 k1 = data_blob_const("d1", 2);
9615 k2 = data_blob_const("d2", 2);
9617 memcache_add(cache, STAT_CACHE, k1, d1);
9618 memcache_add(cache, GETWD_CACHE, k2, d2);
9620 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
9621 printf("could not find k1\n");
9624 if (!data_blob_equal(d1, v1)) {
9628 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
9629 printf("could not find k2\n");
9632 if (!data_blob_equal(d2, v2)) {
9636 memcache_add(cache, STAT_CACHE, k1, d3);
9638 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
9639 printf("could not find replaced k1\n");
9642 if (!data_blob_equal(d3, v3)) {
9646 memcache_add(cache, GETWD_CACHE, k1, d1);
9648 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
9649 printf("Did find k2, should have been purged\n");
9655 cache = memcache_init(NULL, 0);
9657 mem_ctx = talloc_init("foo");
9659 str1 = talloc_strdup(mem_ctx, "string1");
9660 str2 = talloc_strdup(mem_ctx, "string2");
9662 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
9663 data_blob_string_const("torture"), &str1);
9664 size1 = talloc_total_size(cache);
9666 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
9667 data_blob_string_const("torture"), &str2);
9668 size2 = talloc_total_size(cache);
9670 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
9672 if (size2 > size1) {
9673 printf("memcache leaks memory!\n");
9683 static void wbclient_done(struct tevent_req *req)
9686 struct winbindd_response *wb_resp;
9687 int *i = (int *)tevent_req_callback_data_void(req);
9689 wbc_err = wb_trans_recv(req, req, &wb_resp);
9692 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
9695 static bool run_wbclient_multi_ping(int dummy)
9697 struct tevent_context *ev;
9698 struct wb_context **wb_ctx;
9699 struct winbindd_request wb_req;
9700 bool result = false;
9703 BlockSignals(True, SIGPIPE);
9705 ev = tevent_context_init(talloc_tos());
9710 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
9711 if (wb_ctx == NULL) {
9715 ZERO_STRUCT(wb_req);
9716 wb_req.cmd = WINBINDD_PING;
9718 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
9720 for (i=0; i<torture_nprocs; i++) {
9721 wb_ctx[i] = wb_context_init(ev, NULL);
9722 if (wb_ctx[i] == NULL) {
9725 for (j=0; j<torture_numops; j++) {
9726 struct tevent_req *req;
9727 req = wb_trans_send(ev, ev, wb_ctx[i],
9728 (j % 2) == 0, &wb_req);
9732 tevent_req_set_callback(req, wbclient_done, &i);
9738 while (i < torture_nprocs * torture_numops) {
9739 tevent_loop_once(ev);
9748 static void getaddrinfo_finished(struct tevent_req *req)
9750 char *name = (char *)tevent_req_callback_data_void(req);
9751 struct addrinfo *ainfo;
9754 res = getaddrinfo_recv(req, &ainfo);
9756 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
9759 d_printf("gai(%s) succeeded\n", name);
9760 freeaddrinfo(ainfo);
9763 static bool run_getaddrinfo_send(int dummy)
9765 TALLOC_CTX *frame = talloc_stackframe();
9766 struct fncall_context *ctx;
9767 struct tevent_context *ev;
9768 bool result = false;
9769 const char *names[4] = { "www.samba.org", "notfound.samba.org",
9770 "www.slashdot.org", "heise.de" };
9771 struct tevent_req *reqs[4];
9774 ev = samba_tevent_context_init(frame);
9779 ctx = fncall_context_init(frame, 4);
9781 for (i=0; i<ARRAY_SIZE(names); i++) {
9782 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
9784 if (reqs[i] == NULL) {
9787 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
9788 discard_const_p(void, names[i]));
9791 for (i=0; i<ARRAY_SIZE(reqs); i++) {
9792 tevent_loop_once(ev);
9801 static bool dbtrans_inc(struct db_context *db)
9803 struct db_record *rec;
9809 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
9811 printf(__location__ "fetch_lock failed\n");
9815 value = dbwrap_record_get_value(rec);
9817 if (value.dsize != sizeof(uint32_t)) {
9818 printf(__location__ "value.dsize = %d\n",
9823 memcpy(&val, value.dptr, sizeof(val));
9826 status = dbwrap_record_store(
9827 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
9828 if (!NT_STATUS_IS_OK(status)) {
9829 printf(__location__ "store failed: %s\n",
9840 static bool run_local_dbtrans(int dummy)
9842 struct db_context *db;
9843 struct db_record *rec;
9849 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
9850 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
9853 printf("Could not open transtest.db\n");
9857 res = dbwrap_transaction_start(db);
9859 printf(__location__ "transaction_start failed\n");
9863 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
9865 printf(__location__ "fetch_lock failed\n");
9869 value = dbwrap_record_get_value(rec);
9871 if (value.dptr == NULL) {
9873 status = dbwrap_record_store(
9874 rec, make_tdb_data((uint8_t *)&initial,
9877 if (!NT_STATUS_IS_OK(status)) {
9878 printf(__location__ "store returned %s\n",
9886 res = dbwrap_transaction_commit(db);
9888 printf(__location__ "transaction_commit failed\n");
9896 res = dbwrap_transaction_start(db);
9898 printf(__location__ "transaction_start failed\n");
9902 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
9903 if (!NT_STATUS_IS_OK(status)) {
9904 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
9909 for (i=0; i<10; i++) {
9910 if (!dbtrans_inc(db)) {
9915 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
9916 if (!NT_STATUS_IS_OK(status)) {
9917 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
9922 if (val2 != val + 10) {
9923 printf(__location__ "val=%d, val2=%d\n",
9924 (int)val, (int)val2);
9928 printf("val2=%d\r", val2);
9930 res = dbwrap_transaction_commit(db);
9932 printf(__location__ "transaction_commit failed\n");
9942 * Just a dummy test to be run under a debugger. There's no real way
9943 * to inspect the tevent_select specific function from outside of
9947 static bool run_local_tevent_select(int dummy)
9949 struct tevent_context *ev;
9950 struct tevent_fd *fd1, *fd2;
9951 bool result = false;
9953 ev = tevent_context_init_byname(NULL, "select");
9955 d_fprintf(stderr, "tevent_context_init_byname failed\n");
9959 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
9961 d_fprintf(stderr, "tevent_add_fd failed\n");
9964 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
9966 d_fprintf(stderr, "tevent_add_fd failed\n");
9971 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
9973 d_fprintf(stderr, "tevent_add_fd failed\n");
9983 static bool run_local_hex_encode_buf(int dummy)
9989 for (i=0; i<sizeof(src); i++) {
9992 hex_encode_buf(buf, src, sizeof(src));
9993 if (strcmp(buf, "0001020304050607") != 0) {
9996 hex_encode_buf(buf, NULL, 0);
9997 if (buf[0] != '\0') {
10003 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
10025 "1001:1111:1111:1000:0:1111:1111:1111",
10034 static const char *remove_duplicate_addrs2_test_strings_result[] = {
10048 "1001:1111:1111:1000:0:1111:1111:1111"
10051 static bool run_local_remove_duplicate_addrs2(int dummy)
10053 struct ip_service test_vector[28];
10056 /* Construct the sockaddr_storage test vector. */
10057 for (i = 0; i < 28; i++) {
10058 struct addrinfo hints;
10059 struct addrinfo *res = NULL;
10062 memset(&hints, '\0', sizeof(hints));
10063 hints.ai_flags = AI_NUMERICHOST;
10064 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
10069 fprintf(stderr, "getaddrinfo failed on [%s]\n",
10070 remove_duplicate_addrs2_test_strings_vector[i]);
10073 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
10074 memcpy(&test_vector[i].ss,
10080 count = remove_duplicate_addrs2(test_vector, i);
10083 fprintf(stderr, "count wrong (%d) should be 14\n",
10088 for (i = 0; i < count; i++) {
10089 char addr[INET6_ADDRSTRLEN];
10091 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
10093 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
10094 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
10097 remove_duplicate_addrs2_test_strings_result[i]);
10102 printf("run_local_remove_duplicate_addrs2: success\n");
10106 static bool run_local_tdb_opener(int dummy)
10112 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
10113 O_RDWR|O_CREAT, 0755);
10115 perror("tdb_open failed");
10126 static bool run_local_tdb_writer(int dummy)
10132 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
10134 perror("tdb_open failed");
10138 val.dptr = (uint8_t *)&v;
10139 val.dsize = sizeof(v);
10145 ret = tdb_store(t, val, val, 0);
10147 printf("%s\n", tdb_errorstr(t));
10152 data = tdb_fetch(t, val);
10153 if (data.dptr != NULL) {
10154 SAFE_FREE(data.dptr);
10160 static double create_procs(bool (*fn)(int), bool *result)
10163 volatile pid_t *child_status;
10164 volatile bool *child_status_out;
10167 struct timeval start;
10171 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
10172 if (!child_status) {
10173 printf("Failed to setup shared memory\n");
10177 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
10178 if (!child_status_out) {
10179 printf("Failed to setup result status shared memory\n");
10183 for (i = 0; i < torture_nprocs; i++) {
10184 child_status[i] = 0;
10185 child_status_out[i] = True;
10188 start = timeval_current();
10190 for (i=0;i<torture_nprocs;i++) {
10193 pid_t mypid = getpid();
10194 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
10196 slprintf(myname,sizeof(myname),"CLIENT%d", i);
10199 if (torture_open_connection(¤t_cli, i)) break;
10200 if (tries-- == 0) {
10201 printf("pid %d failed to start\n", (int)getpid());
10207 child_status[i] = getpid();
10209 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
10211 child_status_out[i] = fn(i);
10218 for (i=0;i<torture_nprocs;i++) {
10219 if (child_status[i]) synccount++;
10221 if (synccount == torture_nprocs) break;
10223 } while (timeval_elapsed(&start) < 30);
10225 if (synccount != torture_nprocs) {
10226 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
10228 return timeval_elapsed(&start);
10231 /* start the client load */
10232 start = timeval_current();
10234 for (i=0;i<torture_nprocs;i++) {
10235 child_status[i] = 0;
10238 printf("%d clients started\n", torture_nprocs);
10240 for (i=0;i<torture_nprocs;i++) {
10241 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
10246 for (i=0;i<torture_nprocs;i++) {
10247 if (!child_status_out[i]) {
10251 return timeval_elapsed(&start);
10254 #define FLAG_MULTIPROC 1
10260 } torture_ops[] = {
10261 {"FDPASS", run_fdpasstest, 0},
10262 {"LOCK1", run_locktest1, 0},
10263 {"LOCK2", run_locktest2, 0},
10264 {"LOCK3", run_locktest3, 0},
10265 {"LOCK4", run_locktest4, 0},
10266 {"LOCK5", run_locktest5, 0},
10267 {"LOCK6", run_locktest6, 0},
10268 {"LOCK7", run_locktest7, 0},
10269 {"LOCK8", run_locktest8, 0},
10270 {"LOCK9", run_locktest9, 0},
10271 {"UNLINK", run_unlinktest, 0},
10272 {"BROWSE", run_browsetest, 0},
10273 {"ATTR", run_attrtest, 0},
10274 {"TRANS2", run_trans2test, 0},
10275 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
10276 {"TORTURE",run_torture, FLAG_MULTIPROC},
10277 {"RANDOMIPC", run_randomipc, 0},
10278 {"NEGNOWAIT", run_negprot_nowait, 0},
10279 {"NBENCH", run_nbench, 0},
10280 {"NBENCH2", run_nbench2, 0},
10281 {"OPLOCK1", run_oplock1, 0},
10282 {"OPLOCK2", run_oplock2, 0},
10283 {"OPLOCK4", run_oplock4, 0},
10284 {"DIR", run_dirtest, 0},
10285 {"DIR1", run_dirtest1, 0},
10286 {"DIR-CREATETIME", run_dir_createtime, 0},
10287 {"DENY1", torture_denytest1, 0},
10288 {"DENY2", torture_denytest2, 0},
10289 {"TCON", run_tcon_test, 0},
10290 {"TCONDEV", run_tcon_devtype_test, 0},
10291 {"RW1", run_readwritetest, 0},
10292 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
10293 {"RW3", run_readwritelarge, 0},
10294 {"RW-SIGNING", run_readwritelarge_signtest, 0},
10295 {"OPEN", run_opentest, 0},
10296 {"POSIX", run_simple_posix_open_test, 0},
10297 {"POSIX-APPEND", run_posix_append, 0},
10298 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
10299 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
10300 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
10301 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
10302 {"ASYNC-ECHO", run_async_echo, 0},
10303 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
10304 { "SHORTNAME-TEST", run_shortname_test, 0},
10305 { "ADDRCHANGE", run_addrchange, 0},
10307 {"OPENATTR", run_openattrtest, 0},
10309 {"XCOPY", run_xcopy, 0},
10310 {"RENAME", run_rename, 0},
10311 {"DELETE", run_deletetest, 0},
10312 {"WILDDELETE", run_wild_deletetest, 0},
10313 {"DELETE-LN", run_deletetest_ln, 0},
10314 {"PROPERTIES", run_properties, 0},
10315 {"MANGLE", torture_mangle, 0},
10316 {"MANGLE1", run_mangle1, 0},
10317 {"W2K", run_w2ktest, 0},
10318 {"TRANS2SCAN", torture_trans2_scan, 0},
10319 {"NTTRANSSCAN", torture_nttrans_scan, 0},
10320 {"UTABLE", torture_utable, 0},
10321 {"CASETABLE", torture_casetable, 0},
10322 {"ERRMAPEXTRACT", run_error_map_extract, 0},
10323 {"PIPE_NUMBER", run_pipe_number, 0},
10324 {"TCON2", run_tcon2_test, 0},
10325 {"IOCTL", torture_ioctl_test, 0},
10326 {"CHKPATH", torture_chkpath_test, 0},
10327 {"FDSESS", run_fdsesstest, 0},
10328 { "EATEST", run_eatest, 0},
10329 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
10330 { "CHAIN1", run_chain1, 0},
10331 { "CHAIN2", run_chain2, 0},
10332 { "CHAIN3", run_chain3, 0},
10333 { "WINDOWS-WRITE", run_windows_write, 0},
10334 { "LARGE_READX", run_large_readx, 0},
10335 { "NTTRANS-CREATE", run_nttrans_create, 0},
10336 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
10337 { "CLI_ECHO", run_cli_echo, 0},
10338 { "GETADDRINFO", run_getaddrinfo_send, 0},
10339 { "TLDAP", run_tldap },
10340 { "STREAMERROR", run_streamerror },
10341 { "NOTIFY-BENCH", run_notify_bench },
10342 { "NOTIFY-BENCH2", run_notify_bench2 },
10343 { "NOTIFY-BENCH3", run_notify_bench3 },
10344 { "BAD-NBT-SESSION", run_bad_nbt_session },
10345 { "SMB-ANY-CONNECT", run_smb_any_connect },
10346 { "NOTIFY-ONLINE", run_notify_online },
10347 { "SMB2-BASIC", run_smb2_basic },
10348 { "SMB2-NEGPROT", run_smb2_negprot },
10349 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
10350 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
10351 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
10352 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
10353 { "CLEANUP1", run_cleanup1 },
10354 { "CLEANUP2", run_cleanup2 },
10355 { "CLEANUP3", run_cleanup3 },
10356 { "CLEANUP4", run_cleanup4 },
10357 { "OPLOCK-CANCEL", run_oplock_cancel },
10358 { "PIDHIGH", run_pidhigh },
10359 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
10360 { "LOCAL-GENCACHE", run_local_gencache, 0},
10361 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
10362 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
10363 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
10364 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
10365 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
10366 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
10367 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
10368 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
10369 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
10370 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
10371 { "LOCAL-BASE64", run_local_base64, 0},
10372 { "LOCAL-RBTREE", run_local_rbtree, 0},
10373 { "LOCAL-MEMCACHE", run_local_memcache, 0},
10374 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
10375 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
10376 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
10377 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
10378 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
10379 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
10380 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
10381 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
10382 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
10383 { "LOCAL-sprintf_append", run_local_sprintf_append, 0},
10384 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
10385 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
10386 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
10387 { "local-tdb-opener", run_local_tdb_opener, 0 },
10388 { "local-tdb-writer", run_local_tdb_writer, 0 },
10389 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
10390 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
10391 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
10395 * dummy function to satisfy linker dependency
10397 struct tevent_context *winbind_event_context(void);
10398 struct tevent_context *winbind_event_context(void)
10403 /****************************************************************************
10404 run a specified test or "ALL"
10405 ****************************************************************************/
10406 static bool run_test(const char *name)
10409 bool result = True;
10410 bool found = False;
10413 if (strequal(name,"ALL")) {
10414 for (i=0;torture_ops[i].name;i++) {
10415 run_test(torture_ops[i].name);
10420 for (i=0;torture_ops[i].name;i++) {
10421 fstr_sprintf(randomfname, "\\XX%x",
10422 (unsigned)random());
10424 if (strequal(name, torture_ops[i].name)) {
10426 printf("Running %s\n", name);
10427 if (torture_ops[i].flags & FLAG_MULTIPROC) {
10428 t = create_procs(torture_ops[i].fn, &result);
10431 printf("TEST %s FAILED!\n", name);
10434 struct timeval start;
10435 start = timeval_current();
10436 if (!torture_ops[i].fn(0)) {
10438 printf("TEST %s FAILED!\n", name);
10440 t = timeval_elapsed(&start);
10442 printf("%s took %g secs\n\n", name, t);
10447 printf("Did not find a test named %s\n", name);
10455 static void usage(void)
10459 printf("WARNING samba4 test suite is much more complete nowadays.\n");
10460 printf("Please use samba4 torture.\n\n");
10462 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
10464 printf("\t-d debuglevel\n");
10465 printf("\t-U user%%pass\n");
10466 printf("\t-k use kerberos\n");
10467 printf("\t-N numprocs\n");
10468 printf("\t-n my_netbios_name\n");
10469 printf("\t-W workgroup\n");
10470 printf("\t-o num_operations\n");
10471 printf("\t-O socket_options\n");
10472 printf("\t-m maximum protocol\n");
10473 printf("\t-L use oplocks\n");
10474 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
10475 printf("\t-A showall\n");
10476 printf("\t-p port\n");
10477 printf("\t-s seed\n");
10478 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
10479 printf("\t-f filename filename to test\n");
10480 printf("\t-e encrypt\n");
10483 printf("tests are:");
10484 for (i=0;torture_ops[i].name;i++) {
10485 printf(" %s", torture_ops[i].name);
10489 printf("default test is ALL\n");
10494 /****************************************************************************
10496 ****************************************************************************/
10497 int main(int argc,char *argv[])
10503 bool correct = True;
10504 TALLOC_CTX *frame = talloc_stackframe();
10505 int seed = time(NULL);
10507 #ifdef HAVE_SETBUFFER
10508 setbuffer(stdout, NULL, 0);
10511 setup_logging("smbtorture", DEBUG_STDOUT);
10516 if (is_default_dyn_CONFIGFILE()) {
10517 if(getenv("SMB_CONF_PATH")) {
10518 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
10521 lp_load_global(get_dyn_CONFIGFILE());
10528 for(p = argv[1]; *p; p++)
10532 if (strncmp(argv[1], "//", 2)) {
10536 fstrcpy(host, &argv[1][2]);
10537 p = strchr_m(&host[2],'/');
10542 fstrcpy(share, p+1);
10544 fstrcpy(myname, get_myname(talloc_tos()));
10546 fprintf(stderr, "Failed to get my hostname.\n");
10550 if (*username == 0 && getenv("LOGNAME")) {
10551 fstrcpy(username,getenv("LOGNAME"));
10557 fstrcpy(workgroup, lp_workgroup());
10559 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
10563 port_to_use = atoi(optarg);
10566 seed = atoi(optarg);
10569 fstrcpy(workgroup,optarg);
10572 lp_set_cmdline("client max protocol", optarg);
10575 torture_nprocs = atoi(optarg);
10578 torture_numops = atoi(optarg);
10581 lp_set_cmdline("log level", optarg);
10587 use_oplocks = True;
10590 local_path = optarg;
10593 torture_showall = True;
10596 fstrcpy(myname, optarg);
10599 client_txt = optarg;
10606 use_kerberos = True;
10608 d_printf("No kerberos support compiled in\n");
10614 fstrcpy(username,optarg);
10615 p = strchr_m(username,'%');
10618 fstrcpy(password, p+1);
10623 fstrcpy(multishare_conn_fname, optarg);
10624 use_multishare_conn = True;
10627 torture_blocksize = atoi(optarg);
10630 test_filename = SMB_STRDUP(optarg);
10633 printf("Unknown option %c (%d)\n", (char)opt, opt);
10638 d_printf("using seed %d\n", seed);
10642 if(use_kerberos && !gotuser) gotpass = True;
10645 char pwd[256] = {0};
10648 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
10650 fstrcpy(password, pwd);
10655 printf("host=%s share=%s user=%s myname=%s\n",
10656 host, share, username, myname);
10658 if (argc == optind) {
10659 correct = run_test("ALL");
10661 for (i=optind;i<argc;i++) {
10662 if (!run_test(argv[i])) {
10668 TALLOC_FREE(frame);