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 "async_smb.h"
35 #include "libsmb/libsmb.h"
36 #include "libsmb/clirap.h"
38 #include "libsmb/nmblib.h"
39 #include "../lib/util/tevent_ntstatus.h"
41 #include "../libcli/smb/read_smb.h"
42 #include "../libcli/smb/smbXcli_base.h"
43 #include "lib/util/sys_rw_data.h"
44 #include "lib/util/base64.h"
49 fstring host, workgroup, share, password, username, myname;
50 struct cli_credentials *torture_creds;
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 status = cli_smb1_setup_encryption(c, torture_creds);
111 if (!NT_STATUS_IS_OK(status)) {
112 d_printf("Encryption required and "
113 "setup failed with error %s.\n",
122 static struct cli_state *open_nbt_connection(void)
128 if (disable_spnego) {
129 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
133 flags |= CLI_FULL_CONNECTION_OPLOCKS;
136 if (use_level_II_oplocks) {
137 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
141 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
144 if (force_dos_errors) {
145 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
148 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
149 signing_state, flags, &c);
150 if (!NT_STATUS_IS_OK(status)) {
151 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
155 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
160 /****************************************************************************
161 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
162 ****************************************************************************/
164 static bool cli_bad_session_request(int fd,
165 struct nmb_name *calling, struct nmb_name *called)
174 uint8_t message_type;
176 struct tevent_context *ev;
177 struct tevent_req *req;
179 frame = talloc_stackframe();
181 iov[0].iov_base = len_buf;
182 iov[0].iov_len = sizeof(len_buf);
184 /* put in the destination name */
186 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
188 if (iov[1].iov_base == NULL) {
191 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
192 talloc_get_size(iov[1].iov_base));
196 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
198 if (iov[2].iov_base == NULL) {
201 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
202 talloc_get_size(iov[2].iov_base));
204 /* Deliberately corrupt the name len (first byte) */
205 *((uint8_t *)iov[2].iov_base) = 100;
207 /* send a session request (RFC 1002) */
208 /* setup the packet length
209 * Remove four bytes from the length count, since the length
210 * field in the NBT Session Service header counts the number
211 * of bytes which follow. The cli_send_smb() function knows
212 * about this and accounts for those four bytes.
216 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
217 SCVAL(len_buf,0,0x81);
219 len = write_data_iov(fd, iov, 3);
224 ev = samba_tevent_context_init(frame);
228 req = read_smb_send(frame, ev, fd);
232 if (!tevent_req_poll(req, ev)) {
235 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
242 message_type = CVAL(inbuf, 0);
243 if (message_type != 0x83) {
244 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
249 if (smb_len(inbuf) != 1) {
250 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
251 (int)smb_len(inbuf));
255 error = CVAL(inbuf, 4);
257 d_fprintf(stderr, "Expected error 0x82, got %d\n",
268 /* Insert a NULL at the first separator of the given path and return a pointer
269 * to the remainder of the string.
272 terminate_path_at_separator(char * path)
280 if ((p = strchr_m(path, '/'))) {
285 if ((p = strchr_m(path, '\\'))) {
295 parse a //server/share type UNC name
297 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
298 char **hostname, char **sharename)
302 *hostname = *sharename = NULL;
304 if (strncmp(unc_name, "\\\\", 2) &&
305 strncmp(unc_name, "//", 2)) {
309 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
310 p = terminate_path_at_separator(*hostname);
313 *sharename = talloc_strdup(mem_ctx, p);
314 terminate_path_at_separator(*sharename);
317 if (*hostname && *sharename) {
321 TALLOC_FREE(*hostname);
322 TALLOC_FREE(*sharename);
326 static bool torture_open_connection_share(struct cli_state **c,
327 const char *hostname,
328 const char *sharename,
333 status = cli_full_connection_creds(c,
343 if (!NT_STATUS_IS_OK(status)) {
344 printf("failed to open share connection: //%s/%s port:%d - %s\n",
345 hostname, sharename, port_to_use, nt_errstr(status));
349 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
352 return force_cli_encryption(*c,
358 bool torture_open_connection_flags(struct cli_state **c, int conn_index, int flags)
360 char **unc_list = NULL;
361 int num_unc_names = 0;
364 if (use_multishare_conn==True) {
366 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
367 if (!unc_list || num_unc_names <= 0) {
368 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
372 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
374 printf("Failed to parse UNC name %s\n",
375 unc_list[conn_index % num_unc_names]);
376 TALLOC_FREE(unc_list);
380 result = torture_open_connection_share(c, h, s, flags);
382 /* h, s were copied earlier */
383 TALLOC_FREE(unc_list);
387 return torture_open_connection_share(c, host, share, flags);
390 bool torture_open_connection(struct cli_state **c, int conn_index)
392 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
395 flags |= CLI_FULL_CONNECTION_OPLOCKS;
397 if (use_level_II_oplocks) {
398 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
401 return torture_open_connection_flags(c, conn_index, flags);
404 bool torture_init_connection(struct cli_state **pcli)
406 struct cli_state *cli;
408 cli = open_nbt_connection();
417 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
419 uint16_t old_vuid = cli_state_get_uid(cli);
423 cli_state_set_uid(cli, 0);
424 status = cli_session_setup_creds(cli, torture_creds);
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 uint32_t cnum1, cnum2, cnum3;
1313 struct smbXcli_tcon *orig_tcon = NULL;
1314 uint16_t vuid1, vuid2;
1319 memset(buf, '\0', sizeof(buf));
1321 if (!torture_open_connection(&cli, 0)) {
1324 smbXcli_conn_set_sockopt(cli->conn, sockops);
1326 printf("starting tcontest\n");
1328 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1330 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1331 if (!NT_STATUS_IS_OK(status)) {
1332 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1336 cnum1 = cli_state_get_tid(cli);
1337 vuid1 = cli_state_get_uid(cli);
1339 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1340 if (!NT_STATUS_IS_OK(status)) {
1341 printf("initial write failed (%s)", nt_errstr(status));
1345 orig_tcon = cli_state_save_tcon(cli);
1346 if (orig_tcon == NULL) {
1350 status = cli_tree_connect_creds(cli, share, "?????", torture_creds);
1351 if (!NT_STATUS_IS_OK(status)) {
1352 printf("%s refused 2nd tree connect (%s)\n", host,
1358 cnum2 = cli_state_get_tid(cli);
1359 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1360 vuid2 = cli_state_get_uid(cli) + 1;
1362 /* try a write with the wrong tid */
1363 cli_state_set_tid(cli, cnum2);
1365 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1366 if (NT_STATUS_IS_OK(status)) {
1367 printf("* server allows write with wrong TID\n");
1370 printf("server fails write with wrong TID : %s\n",
1375 /* try a write with an invalid tid */
1376 cli_state_set_tid(cli, cnum3);
1378 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1379 if (NT_STATUS_IS_OK(status)) {
1380 printf("* server allows write with invalid TID\n");
1383 printf("server fails write with invalid TID : %s\n",
1387 /* try a write with an invalid vuid */
1388 cli_state_set_uid(cli, vuid2);
1389 cli_state_set_tid(cli, cnum1);
1391 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1392 if (NT_STATUS_IS_OK(status)) {
1393 printf("* server allows write with invalid VUID\n");
1396 printf("server fails write with invalid VUID : %s\n",
1400 cli_state_set_tid(cli, cnum1);
1401 cli_state_set_uid(cli, vuid1);
1403 status = cli_close(cli, fnum1);
1404 if (!NT_STATUS_IS_OK(status)) {
1405 printf("close failed (%s)\n", nt_errstr(status));
1409 cli_state_set_tid(cli, cnum2);
1411 status = cli_tdis(cli);
1412 if (!NT_STATUS_IS_OK(status)) {
1413 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1417 cli_state_restore_tcon(cli, orig_tcon);
1419 cli_state_set_tid(cli, cnum1);
1421 if (!torture_close_connection(cli)) {
1430 checks for old style tcon support
1432 static bool run_tcon2_test(int dummy)
1434 static struct cli_state *cli;
1435 uint16_t cnum, max_xmit;
1439 if (!torture_open_connection(&cli, 0)) {
1442 smbXcli_conn_set_sockopt(cli->conn, sockops);
1444 printf("starting tcon2 test\n");
1446 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1450 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1454 if (!NT_STATUS_IS_OK(status)) {
1455 printf("tcon2 failed : %s\n", nt_errstr(status));
1457 printf("tcon OK : max_xmit=%d cnum=%d\n",
1458 (int)max_xmit, (int)cnum);
1461 if (!torture_close_connection(cli)) {
1465 printf("Passed tcon2 test\n");
1469 static bool tcon_devtest(struct cli_state *cli,
1470 const char *myshare, const char *devtype,
1471 const char *return_devtype,
1472 NTSTATUS expected_error)
1477 status = cli_tree_connect_creds(cli, myshare, devtype, torture_creds);
1479 if (NT_STATUS_IS_OK(expected_error)) {
1480 if (NT_STATUS_IS_OK(status)) {
1481 if (strcmp(cli->dev, return_devtype) == 0) {
1484 printf("tconX to share %s with type %s "
1485 "succeeded but returned the wrong "
1486 "device type (got [%s] but should have got [%s])\n",
1487 myshare, devtype, cli->dev, return_devtype);
1491 printf("tconX to share %s with type %s "
1492 "should have succeeded but failed\n",
1498 if (NT_STATUS_IS_OK(status)) {
1499 printf("tconx to share %s with type %s "
1500 "should have failed but succeeded\n",
1504 if (NT_STATUS_EQUAL(status, expected_error)) {
1507 printf("Returned unexpected error\n");
1516 checks for correct tconX support
1518 static bool run_tcon_devtype_test(int dummy)
1520 static struct cli_state *cli1 = NULL;
1521 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
1525 status = cli_full_connection_creds(&cli1,
1531 NULL, /* service_type */
1536 if (!NT_STATUS_IS_OK(status)) {
1537 printf("could not open connection\n");
1541 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1544 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1547 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1550 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1553 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1556 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1559 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1562 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1565 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1568 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1574 printf("Passed tcondevtest\n");
1581 This test checks that
1583 1) the server supports multiple locking contexts on the one SMB
1584 connection, distinguished by PID.
1586 2) the server correctly fails overlapping locks made by the same PID (this
1587 goes against POSIX behaviour, which is why it is tricky to implement)
1589 3) the server denies unlock requests by an incorrect client PID
1591 static bool run_locktest2(int dummy)
1593 static struct cli_state *cli;
1594 const char *fname = "\\lockt2.lck";
1595 uint16_t fnum1, fnum2, fnum3;
1596 bool correct = True;
1599 if (!torture_open_connection(&cli, 0)) {
1603 smbXcli_conn_set_sockopt(cli->conn, sockops);
1605 printf("starting locktest2\n");
1607 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1611 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1612 if (!NT_STATUS_IS_OK(status)) {
1613 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1617 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1618 if (!NT_STATUS_IS_OK(status)) {
1619 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1625 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1626 if (!NT_STATUS_IS_OK(status)) {
1627 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1633 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1634 if (!NT_STATUS_IS_OK(status)) {
1635 printf("lock1 failed (%s)\n", nt_errstr(status));
1639 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1640 if (NT_STATUS_IS_OK(status)) {
1641 printf("WRITE lock1 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, WRITE_LOCK);
1651 if (NT_STATUS_IS_OK(status)) {
1652 printf("WRITE lock2 succeeded! This is a locking bug\n");
1655 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1656 NT_STATUS_LOCK_NOT_GRANTED)) {
1661 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1662 if (NT_STATUS_IS_OK(status)) {
1663 printf("READ lock2 succeeded! This is a locking bug\n");
1666 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1667 NT_STATUS_FILE_LOCK_CONFLICT)) {
1672 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1673 if (!NT_STATUS_IS_OK(status)) {
1674 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1677 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1678 printf("unlock at 100 succeeded! This is a locking bug\n");
1682 status = cli_unlock(cli, fnum1, 0, 4);
1683 if (NT_STATUS_IS_OK(status)) {
1684 printf("unlock1 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_unlock(cli, fnum1, 0, 8);
1694 if (NT_STATUS_IS_OK(status)) {
1695 printf("unlock2 succeeded! This is a locking bug\n");
1698 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1699 NT_STATUS_RANGE_NOT_LOCKED)) {
1704 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1705 if (NT_STATUS_IS_OK(status)) {
1706 printf("lock3 succeeded! This is a locking bug\n");
1709 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1710 NT_STATUS_LOCK_NOT_GRANTED)) {
1717 status = cli_close(cli, fnum1);
1718 if (!NT_STATUS_IS_OK(status)) {
1719 printf("close1 failed (%s)\n", nt_errstr(status));
1723 status = cli_close(cli, fnum2);
1724 if (!NT_STATUS_IS_OK(status)) {
1725 printf("close2 failed (%s)\n", nt_errstr(status));
1729 status = cli_close(cli, fnum3);
1730 if (!NT_STATUS_IS_OK(status)) {
1731 printf("close3 failed (%s)\n", nt_errstr(status));
1735 if (!torture_close_connection(cli)) {
1739 printf("locktest2 finished\n");
1746 This test checks that
1748 1) the server supports the full offset range in lock requests
1750 static bool run_locktest3(int dummy)
1752 static struct cli_state *cli1, *cli2;
1753 const char *fname = "\\lockt3.lck";
1754 uint16_t fnum1, fnum2;
1757 bool correct = True;
1760 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1762 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1765 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1766 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1768 printf("starting locktest3\n");
1770 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1772 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1774 if (!NT_STATUS_IS_OK(status)) {
1775 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1779 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1780 if (!NT_STATUS_IS_OK(status)) {
1781 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1785 for (offset=i=0;i<torture_numops;i++) {
1788 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1789 if (!NT_STATUS_IS_OK(status)) {
1790 printf("lock1 %d failed (%s)\n",
1796 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1797 if (!NT_STATUS_IS_OK(status)) {
1798 printf("lock2 %d failed (%s)\n",
1805 for (offset=i=0;i<torture_numops;i++) {
1808 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1809 if (NT_STATUS_IS_OK(status)) {
1810 printf("error: lock1 %d succeeded!\n", i);
1814 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1815 if (NT_STATUS_IS_OK(status)) {
1816 printf("error: lock2 %d succeeded!\n", i);
1820 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1821 if (NT_STATUS_IS_OK(status)) {
1822 printf("error: lock3 %d succeeded!\n", i);
1826 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1827 if (NT_STATUS_IS_OK(status)) {
1828 printf("error: lock4 %d succeeded!\n", i);
1833 for (offset=i=0;i<torture_numops;i++) {
1836 status = cli_unlock(cli1, fnum1, offset-1, 1);
1837 if (!NT_STATUS_IS_OK(status)) {
1838 printf("unlock1 %d failed (%s)\n",
1844 status = cli_unlock(cli2, fnum2, offset-2, 1);
1845 if (!NT_STATUS_IS_OK(status)) {
1846 printf("unlock2 %d failed (%s)\n",
1853 status = cli_close(cli1, fnum1);
1854 if (!NT_STATUS_IS_OK(status)) {
1855 printf("close1 failed (%s)\n", nt_errstr(status));
1859 status = cli_close(cli2, fnum2);
1860 if (!NT_STATUS_IS_OK(status)) {
1861 printf("close2 failed (%s)\n", nt_errstr(status));
1865 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1866 if (!NT_STATUS_IS_OK(status)) {
1867 printf("unlink failed (%s)\n", nt_errstr(status));
1871 if (!torture_close_connection(cli1)) {
1875 if (!torture_close_connection(cli2)) {
1879 printf("finished locktest3\n");
1884 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1885 char *buf, off_t offset, size_t size,
1886 size_t *nread, size_t expect)
1891 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1893 if(!NT_STATUS_IS_OK(status)) {
1895 } else if (l_nread != expect) {
1906 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1907 printf("** "); correct = False; \
1911 looks at overlapping locks
1913 static bool run_locktest4(int dummy)
1915 static struct cli_state *cli1, *cli2;
1916 const char *fname = "\\lockt4.lck";
1917 uint16_t fnum1, fnum2, f;
1920 bool correct = True;
1923 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1927 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1928 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1930 printf("starting locktest4\n");
1932 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1934 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1935 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1937 memset(buf, 0, sizeof(buf));
1939 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1941 if (!NT_STATUS_IS_OK(status)) {
1942 printf("Failed to create file: %s\n", nt_errstr(status));
1947 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1948 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1949 EXPECTED(ret, False);
1950 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1952 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1953 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1954 EXPECTED(ret, True);
1955 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1957 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1958 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1959 EXPECTED(ret, False);
1960 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1962 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1963 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1964 EXPECTED(ret, True);
1965 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1967 ret = (cli_setpid(cli1, 1),
1968 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1969 (cli_setpid(cli1, 2),
1970 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1971 EXPECTED(ret, False);
1972 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1974 ret = (cli_setpid(cli1, 1),
1975 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1976 (cli_setpid(cli1, 2),
1977 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1978 EXPECTED(ret, True);
1979 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1981 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1982 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1983 EXPECTED(ret, True);
1984 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1986 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1987 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1988 EXPECTED(ret, False);
1989 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1991 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1992 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1993 EXPECTED(ret, False);
1994 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1996 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1997 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
1998 EXPECTED(ret, True);
1999 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2001 ret = (cli_setpid(cli1, 1),
2002 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2003 (cli_setpid(cli1, 2),
2004 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2005 EXPECTED(ret, False);
2006 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2008 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2009 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2010 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2011 EXPECTED(ret, False);
2012 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2015 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2016 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2017 EXPECTED(ret, False);
2018 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2020 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2021 ret = NT_STATUS_IS_OK(status);
2023 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2025 ret = NT_STATUS_IS_OK(status);
2027 EXPECTED(ret, False);
2028 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2031 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2032 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2033 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2034 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2035 EXPECTED(ret, True);
2036 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2039 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2040 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2041 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2042 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2043 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2045 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2046 EXPECTED(ret, True);
2047 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2049 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2050 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2051 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2053 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2054 EXPECTED(ret, True);
2055 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2057 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2058 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2059 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2061 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2062 EXPECTED(ret, True);
2063 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2065 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2066 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2067 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2068 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2070 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2071 EXPECTED(ret, True);
2072 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2074 cli_close(cli1, fnum1);
2075 cli_close(cli2, fnum2);
2076 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2077 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2078 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2079 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2080 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2081 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2082 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2084 cli_close(cli1, fnum1);
2085 EXPECTED(ret, True);
2086 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2089 cli_close(cli1, fnum1);
2090 cli_close(cli2, fnum2);
2091 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2092 torture_close_connection(cli1);
2093 torture_close_connection(cli2);
2095 printf("finished locktest4\n");
2100 looks at lock upgrade/downgrade.
2102 static bool run_locktest5(int dummy)
2104 static struct cli_state *cli1, *cli2;
2105 const char *fname = "\\lockt5.lck";
2106 uint16_t fnum1, fnum2, fnum3;
2109 bool correct = True;
2112 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2116 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2117 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2119 printf("starting locktest5\n");
2121 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2123 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2124 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2125 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2127 memset(buf, 0, sizeof(buf));
2129 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2131 if (!NT_STATUS_IS_OK(status)) {
2132 printf("Failed to create file: %s\n", nt_errstr(status));
2137 /* Check for NT bug... */
2138 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2139 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2140 cli_close(cli1, fnum1);
2141 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2142 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2143 ret = NT_STATUS_IS_OK(status);
2144 EXPECTED(ret, True);
2145 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2146 cli_close(cli1, fnum1);
2147 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2148 cli_unlock(cli1, fnum3, 0, 1);
2150 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2151 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2152 EXPECTED(ret, True);
2153 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2155 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2156 ret = NT_STATUS_IS_OK(status);
2157 EXPECTED(ret, False);
2159 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2161 /* Unlock the process 2 lock. */
2162 cli_unlock(cli2, fnum2, 0, 4);
2164 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2165 ret = NT_STATUS_IS_OK(status);
2166 EXPECTED(ret, False);
2168 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2170 /* Unlock the process 1 fnum3 lock. */
2171 cli_unlock(cli1, fnum3, 0, 4);
2173 /* Stack 2 more locks here. */
2174 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2175 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2177 EXPECTED(ret, True);
2178 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2180 /* Unlock the first process lock, then check this was the WRITE lock that was
2183 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2184 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2186 EXPECTED(ret, True);
2187 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2189 /* Unlock the process 2 lock. */
2190 cli_unlock(cli2, fnum2, 0, 4);
2192 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2194 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2195 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2196 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2198 EXPECTED(ret, True);
2199 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2201 /* Ensure the next unlock fails. */
2202 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2203 EXPECTED(ret, False);
2204 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2206 /* Ensure connection 2 can get a write lock. */
2207 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2208 ret = NT_STATUS_IS_OK(status);
2209 EXPECTED(ret, True);
2211 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2215 cli_close(cli1, fnum1);
2216 cli_close(cli2, fnum2);
2217 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2218 if (!torture_close_connection(cli1)) {
2221 if (!torture_close_connection(cli2)) {
2225 printf("finished locktest5\n");
2231 tries the unusual lockingX locktype bits
2233 static bool run_locktest6(int dummy)
2235 static struct cli_state *cli;
2236 const char *fname[1] = { "\\lock6.txt" };
2241 if (!torture_open_connection(&cli, 0)) {
2245 smbXcli_conn_set_sockopt(cli->conn, sockops);
2247 printf("starting locktest6\n");
2250 printf("Testing %s\n", fname[i]);
2252 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2254 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2255 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2256 cli_close(cli, fnum);
2257 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2259 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2260 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2261 cli_close(cli, fnum);
2262 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2264 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2267 torture_close_connection(cli);
2269 printf("finished locktest6\n");
2273 static bool run_locktest7(int dummy)
2275 struct cli_state *cli1;
2276 const char *fname = "\\lockt7.lck";
2279 bool correct = False;
2283 if (!torture_open_connection(&cli1, 0)) {
2287 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2289 printf("starting locktest7\n");
2291 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2293 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2295 memset(buf, 0, sizeof(buf));
2297 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2299 if (!NT_STATUS_IS_OK(status)) {
2300 printf("Failed to create file: %s\n", nt_errstr(status));
2304 cli_setpid(cli1, 1);
2306 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2307 if (!NT_STATUS_IS_OK(status)) {
2308 printf("Unable to apply read lock on range 130:4, "
2309 "error was %s\n", nt_errstr(status));
2312 printf("pid1 successfully locked range 130:4 for READ\n");
2315 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2316 if (!NT_STATUS_IS_OK(status)) {
2317 printf("pid1 unable to read the range 130:4, error was %s\n",
2320 } else if (nread != 4) {
2321 printf("pid1 unable to read the range 130:4, "
2322 "recv %ld req %d\n", (unsigned long)nread, 4);
2325 printf("pid1 successfully read the range 130:4\n");
2328 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2329 if (!NT_STATUS_IS_OK(status)) {
2330 printf("pid1 unable to write to the range 130:4, error was "
2331 "%s\n", nt_errstr(status));
2332 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2333 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2337 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2341 cli_setpid(cli1, 2);
2343 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2344 if (!NT_STATUS_IS_OK(status)) {
2345 printf("pid2 unable to read the range 130:4, error was %s\n",
2348 } else if (nread != 4) {
2349 printf("pid2 unable to read the range 130:4, "
2350 "recv %ld req %d\n", (unsigned long)nread, 4);
2353 printf("pid2 successfully read the range 130:4\n");
2356 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2357 if (!NT_STATUS_IS_OK(status)) {
2358 printf("pid2 unable to write to the range 130:4, error was "
2359 "%s\n", nt_errstr(status));
2360 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2361 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2365 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2369 cli_setpid(cli1, 1);
2370 cli_unlock(cli1, fnum1, 130, 4);
2372 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2373 if (!NT_STATUS_IS_OK(status)) {
2374 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2377 printf("pid1 successfully locked range 130:4 for WRITE\n");
2380 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2381 if (!NT_STATUS_IS_OK(status)) {
2382 printf("pid1 unable to read the range 130:4, error was %s\n",
2385 } else if (nread != 4) {
2386 printf("pid1 unable to read the range 130:4, "
2387 "recv %ld req %d\n", (unsigned long)nread, 4);
2390 printf("pid1 successfully read the range 130:4\n");
2393 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2394 if (!NT_STATUS_IS_OK(status)) {
2395 printf("pid1 unable to write to the range 130:4, error was "
2396 "%s\n", nt_errstr(status));
2399 printf("pid1 successfully wrote to the range 130:4\n");
2402 cli_setpid(cli1, 2);
2404 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2405 if (!NT_STATUS_IS_OK(status)) {
2406 printf("pid2 unable to read the range 130:4, error was "
2407 "%s\n", nt_errstr(status));
2408 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2409 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2413 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2414 (unsigned long)nread);
2418 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2419 if (!NT_STATUS_IS_OK(status)) {
2420 printf("pid2 unable to write to the range 130:4, error was "
2421 "%s\n", nt_errstr(status));
2422 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2423 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2427 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2431 cli_unlock(cli1, fnum1, 130, 0);
2435 cli_close(cli1, fnum1);
2436 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2437 torture_close_connection(cli1);
2439 printf("finished locktest7\n");
2444 * This demonstrates a problem with our use of GPFS share modes: A file
2445 * descriptor sitting in the pending close queue holding a GPFS share mode
2446 * blocks opening a file another time. Happens with Word 2007 temp files.
2447 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2448 * open is denied with NT_STATUS_SHARING_VIOLATION.
2451 static bool run_locktest8(int dummy)
2453 struct cli_state *cli1;
2454 const char *fname = "\\lockt8.lck";
2455 uint16_t fnum1, fnum2;
2457 bool correct = False;
2460 if (!torture_open_connection(&cli1, 0)) {
2464 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2466 printf("starting locktest8\n");
2468 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2470 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2472 if (!NT_STATUS_IS_OK(status)) {
2473 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2477 memset(buf, 0, sizeof(buf));
2479 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2480 if (!NT_STATUS_IS_OK(status)) {
2481 d_fprintf(stderr, "cli_openx second time returned %s\n",
2486 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2487 if (!NT_STATUS_IS_OK(status)) {
2488 printf("Unable to apply read lock on range 1:1, error was "
2489 "%s\n", nt_errstr(status));
2493 status = cli_close(cli1, fnum1);
2494 if (!NT_STATUS_IS_OK(status)) {
2495 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2499 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2500 if (!NT_STATUS_IS_OK(status)) {
2501 d_fprintf(stderr, "cli_openx third time returned %s\n",
2509 cli_close(cli1, fnum1);
2510 cli_close(cli1, fnum2);
2511 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2512 torture_close_connection(cli1);
2514 printf("finished locktest8\n");
2519 * This test is designed to be run in conjunction with
2520 * external NFS or POSIX locks taken in the filesystem.
2521 * It checks that the smbd server will block until the
2522 * lock is released and then acquire it. JRA.
2525 static bool got_alarm;
2526 static struct cli_state *alarm_cli;
2528 static void alarm_handler(int dummy)
2533 static void alarm_handler_parent(int dummy)
2535 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2538 static void do_local_lock(int read_fd, int write_fd)
2543 const char *local_pathname = NULL;
2546 local_pathname = talloc_asprintf(talloc_tos(),
2547 "%s/lockt9.lck", local_path);
2548 if (!local_pathname) {
2549 printf("child: alloc fail\n");
2553 unlink(local_pathname);
2554 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2556 printf("child: open of %s failed %s.\n",
2557 local_pathname, strerror(errno));
2561 /* Now take a fcntl lock. */
2562 lock.l_type = F_WRLCK;
2563 lock.l_whence = SEEK_SET;
2566 lock.l_pid = getpid();
2568 ret = fcntl(fd,F_SETLK,&lock);
2570 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2571 local_pathname, strerror(errno));
2574 printf("child: got lock 0:4 on file %s.\n",
2579 CatchSignal(SIGALRM, alarm_handler);
2581 /* Signal the parent. */
2582 if (write(write_fd, &c, 1) != 1) {
2583 printf("child: start signal fail %s.\n",
2590 /* Wait for the parent to be ready. */
2591 if (read(read_fd, &c, 1) != 1) {
2592 printf("child: reply signal fail %s.\n",
2600 printf("child: released lock 0:4 on file %s.\n",
2606 static bool run_locktest9(int dummy)
2608 struct cli_state *cli1;
2609 const char *fname = "\\lockt9.lck";
2611 bool correct = False;
2612 int pipe_in[2], pipe_out[2];
2616 struct timeval start;
2620 printf("starting locktest9\n");
2622 if (local_path == NULL) {
2623 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2627 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2632 if (child_pid == -1) {
2636 if (child_pid == 0) {
2638 do_local_lock(pipe_out[0], pipe_in[1]);
2648 ret = read(pipe_in[0], &c, 1);
2650 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2655 if (!torture_open_connection(&cli1, 0)) {
2659 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2661 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2663 if (!NT_STATUS_IS_OK(status)) {
2664 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2668 /* Ensure the child has the lock. */
2669 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2670 if (NT_STATUS_IS_OK(status)) {
2671 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2674 d_printf("Child has the lock.\n");
2677 /* Tell the child to wait 5 seconds then exit. */
2678 ret = write(pipe_out[1], &c, 1);
2680 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2685 /* Wait 20 seconds for the lock. */
2687 CatchSignal(SIGALRM, alarm_handler_parent);
2690 start = timeval_current();
2692 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2693 if (!NT_STATUS_IS_OK(status)) {
2694 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2695 "%s\n", nt_errstr(status));
2700 seconds = timeval_elapsed(&start);
2702 printf("Parent got the lock after %.2f seconds.\n",
2705 status = cli_close(cli1, fnum);
2706 if (!NT_STATUS_IS_OK(status)) {
2707 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2714 cli_close(cli1, fnum);
2715 torture_close_connection(cli1);
2719 printf("finished locktest9\n");
2724 test whether fnums and tids open on one VC are available on another (a major
2727 static bool run_fdpasstest(int dummy)
2729 struct cli_state *cli1, *cli2;
2730 const char *fname = "\\fdpass.tst";
2735 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2738 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2739 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2741 printf("starting fdpasstest\n");
2743 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2745 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2747 if (!NT_STATUS_IS_OK(status)) {
2748 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2752 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2754 if (!NT_STATUS_IS_OK(status)) {
2755 printf("write failed (%s)\n", nt_errstr(status));
2759 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2760 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2761 cli_setpid(cli2, cli_getpid(cli1));
2763 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2764 printf("read succeeded! nasty security hole [%s]\n", buf);
2768 cli_close(cli1, fnum1);
2769 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2771 torture_close_connection(cli1);
2772 torture_close_connection(cli2);
2774 printf("finished fdpasstest\n");
2778 static bool run_fdsesstest(int dummy)
2780 struct cli_state *cli;
2782 uint16_t saved_vuid;
2784 uint32_t saved_cnum;
2785 const char *fname = "\\fdsess.tst";
2786 const char *fname1 = "\\fdsess1.tst";
2793 if (!torture_open_connection(&cli, 0))
2795 smbXcli_conn_set_sockopt(cli->conn, sockops);
2797 if (!torture_cli_session_setup2(cli, &new_vuid))
2800 saved_cnum = cli_state_get_tid(cli);
2801 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", NULL)))
2803 new_cnum = cli_state_get_tid(cli);
2804 cli_state_set_tid(cli, saved_cnum);
2806 printf("starting fdsesstest\n");
2808 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2809 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2811 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2812 if (!NT_STATUS_IS_OK(status)) {
2813 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2817 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2819 if (!NT_STATUS_IS_OK(status)) {
2820 printf("write failed (%s)\n", nt_errstr(status));
2824 saved_vuid = cli_state_get_uid(cli);
2825 cli_state_set_uid(cli, new_vuid);
2827 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2828 printf("read succeeded with different vuid! "
2829 "nasty security hole [%s]\n", buf);
2832 /* Try to open a file with different vuid, samba cnum. */
2833 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2834 printf("create with different vuid, same cnum succeeded.\n");
2835 cli_close(cli, fnum2);
2836 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2838 printf("create with different vuid, same cnum failed.\n");
2839 printf("This will cause problems with service clients.\n");
2843 cli_state_set_uid(cli, saved_vuid);
2845 /* Try with same vuid, different cnum. */
2846 cli_state_set_tid(cli, new_cnum);
2848 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2849 printf("read succeeded with different cnum![%s]\n", buf);
2853 cli_state_set_tid(cli, saved_cnum);
2854 cli_close(cli, fnum1);
2855 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2857 torture_close_connection(cli);
2859 printf("finished fdsesstest\n");
2864 This test checks that
2866 1) the server does not allow an unlink on a file that is open
2868 static bool run_unlinktest(int dummy)
2870 struct cli_state *cli;
2871 const char *fname = "\\unlink.tst";
2873 bool correct = True;
2876 if (!torture_open_connection(&cli, 0)) {
2880 smbXcli_conn_set_sockopt(cli->conn, sockops);
2882 printf("starting unlink test\n");
2884 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2888 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2889 if (!NT_STATUS_IS_OK(status)) {
2890 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2894 status = cli_unlink(cli, fname,
2895 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2896 if (NT_STATUS_IS_OK(status)) {
2897 printf("error: server allowed unlink on an open file\n");
2900 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2901 NT_STATUS_SHARING_VIOLATION);
2904 cli_close(cli, fnum);
2905 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2907 if (!torture_close_connection(cli)) {
2911 printf("unlink test finished\n");
2918 test how many open files this server supports on the one socket
2920 static bool run_maxfidtest(int dummy)
2922 struct cli_state *cli;
2924 uint16_t fnums[0x11000];
2927 bool correct = True;
2933 printf("failed to connect\n");
2937 smbXcli_conn_set_sockopt(cli->conn, sockops);
2939 for (i=0; i<0x11000; i++) {
2940 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2941 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2943 if (!NT_STATUS_IS_OK(status)) {
2944 printf("open of %s failed (%s)\n",
2945 fname, nt_errstr(status));
2946 printf("maximum fnum is %d\n", i);
2954 printf("cleaning up\n");
2956 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2957 cli_close(cli, fnums[i]);
2959 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2960 if (!NT_STATUS_IS_OK(status)) {
2961 printf("unlink of %s failed (%s)\n",
2962 fname, nt_errstr(status));
2969 printf("maxfid test finished\n");
2970 if (!torture_close_connection(cli)) {
2976 /* generate a random buffer */
2977 static void rand_buf(char *buf, int len)
2980 *buf = (char)sys_random();
2985 /* send smb negprot commands, not reading the response */
2986 static bool run_negprot_nowait(int dummy)
2988 struct tevent_context *ev;
2990 struct cli_state *cli;
2991 bool correct = True;
2993 printf("starting negprot nowait test\n");
2995 ev = samba_tevent_context_init(talloc_tos());
3000 if (!(cli = open_nbt_connection())) {
3005 for (i=0;i<50000;i++) {
3006 struct tevent_req *req;
3008 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
3009 PROTOCOL_CORE, PROTOCOL_NT1, 0);
3014 if (!tevent_req_poll(req, ev)) {
3015 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3023 if (torture_close_connection(cli)) {
3027 printf("finished negprot nowait test\n");
3032 /* send smb negprot commands, not reading the response */
3033 static bool run_bad_nbt_session(int dummy)
3035 struct nmb_name called, calling;
3036 struct sockaddr_storage ss;
3041 printf("starting bad nbt session test\n");
3043 make_nmb_name(&calling, myname, 0x0);
3044 make_nmb_name(&called , host, 0x20);
3046 if (!resolve_name(host, &ss, 0x20, true)) {
3047 d_fprintf(stderr, "Could not resolve name %s\n", host);
3051 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3052 if (!NT_STATUS_IS_OK(status)) {
3053 d_fprintf(stderr, "open_socket_out failed: %s\n",
3058 ret = cli_bad_session_request(fd, &calling, &called);
3061 d_fprintf(stderr, "open_socket_out failed: %s\n",
3066 printf("finished bad nbt session test\n");
3070 /* send random IPC commands */
3071 static bool run_randomipc(int dummy)
3073 char *rparam = NULL;
3075 unsigned int rdrcnt,rprcnt;
3077 int api, param_len, i;
3078 struct cli_state *cli;
3079 bool correct = True;
3082 printf("starting random ipc test\n");
3084 if (!torture_open_connection(&cli, 0)) {
3088 for (i=0;i<count;i++) {
3089 api = sys_random() % 500;
3090 param_len = (sys_random() % 64);
3092 rand_buf(param, param_len);
3097 param, param_len, 8,
3098 NULL, 0, CLI_BUFFER_SIZE,
3102 printf("%d/%d\r", i,count);
3105 printf("%d/%d\n", i, count);
3107 if (!torture_close_connection(cli)) {
3114 printf("finished random ipc test\n");
3121 static void browse_callback(const char *sname, uint32_t stype,
3122 const char *comment, void *state)
3124 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3130 This test checks the browse list code
3133 static bool run_browsetest(int dummy)
3135 static struct cli_state *cli;
3136 bool correct = True;
3138 printf("starting browse test\n");
3140 if (!torture_open_connection(&cli, 0)) {
3144 printf("domain list:\n");
3145 cli_NetServerEnum(cli, cli->server_domain,
3146 SV_TYPE_DOMAIN_ENUM,
3147 browse_callback, NULL);
3149 printf("machine list:\n");
3150 cli_NetServerEnum(cli, cli->server_domain,
3152 browse_callback, NULL);
3154 if (!torture_close_connection(cli)) {
3158 printf("browse test finished\n");
3164 static bool check_attributes(struct cli_state *cli,
3166 uint16_t expected_attrs)
3169 NTSTATUS status = cli_getatr(cli,
3174 if (!NT_STATUS_IS_OK(status)) {
3175 printf("cli_getatr failed with %s\n",
3179 if (attrs != expected_attrs) {
3180 printf("Attributes incorrect 0x%x, should be 0x%x\n",
3181 (unsigned int)attrs,
3182 (unsigned int)expected_attrs);
3189 This checks how the getatr calls works
3191 static bool run_attrtest(int dummy)
3193 struct cli_state *cli;
3196 const char *fname = "\\attrib123456789.tst";
3197 bool correct = True;
3200 printf("starting attrib test\n");
3202 if (!torture_open_connection(&cli, 0)) {
3206 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3207 cli_openx(cli, fname,
3208 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3209 cli_close(cli, fnum);
3211 status = cli_getatr(cli, fname, NULL, NULL, &t);
3212 if (!NT_STATUS_IS_OK(status)) {
3213 printf("getatr failed (%s)\n", nt_errstr(status));
3217 if (abs(t - time(NULL)) > 60*60*24*10) {
3218 printf("ERROR: SMBgetatr bug. time is %s",
3224 t2 = t-60*60*24; /* 1 day ago */
3226 status = cli_setatr(cli, fname, 0, t2);
3227 if (!NT_STATUS_IS_OK(status)) {
3228 printf("setatr failed (%s)\n", nt_errstr(status));
3232 status = cli_getatr(cli, fname, NULL, NULL, &t);
3233 if (!NT_STATUS_IS_OK(status)) {
3234 printf("getatr failed (%s)\n", nt_errstr(status));
3239 printf("ERROR: getatr/setatr bug. times are\n%s",
3241 printf("%s", ctime(&t2));
3245 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3247 /* Check cli_setpathinfo_basic() */
3248 /* Re-create the file. */
3249 status = cli_openx(cli, fname,
3250 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3251 if (!NT_STATUS_IS_OK(status)) {
3252 printf("Failed to recreate %s (%s)\n",
3253 fname, nt_errstr(status));
3256 cli_close(cli, fnum);
3258 status = cli_setpathinfo_basic(cli,
3264 FILE_ATTRIBUTE_SYSTEM |
3265 FILE_ATTRIBUTE_HIDDEN |
3266 FILE_ATTRIBUTE_READONLY);
3267 if (!NT_STATUS_IS_OK(status)) {
3268 printf("cli_setpathinfo_basic failed with %s\n",
3273 /* Check attributes are correct. */
3274 correct = check_attributes(cli,
3276 FILE_ATTRIBUTE_SYSTEM |
3277 FILE_ATTRIBUTE_HIDDEN |
3278 FILE_ATTRIBUTE_READONLY);
3279 if (correct == false) {
3283 /* Setting to FILE_ATTRIBUTE_NORMAL should be ignored. */
3284 status = cli_setpathinfo_basic(cli,
3290 FILE_ATTRIBUTE_NORMAL);
3291 if (!NT_STATUS_IS_OK(status)) {
3292 printf("cli_setpathinfo_basic failed with %s\n",
3297 /* Check attributes are correct. */
3298 correct = check_attributes(cli,
3300 FILE_ATTRIBUTE_SYSTEM |
3301 FILE_ATTRIBUTE_HIDDEN |
3302 FILE_ATTRIBUTE_READONLY);
3303 if (correct == false) {
3307 /* Setting to (uint16_t)-1 should also be ignored. */
3308 status = cli_setpathinfo_basic(cli,
3315 if (!NT_STATUS_IS_OK(status)) {
3316 printf("cli_setpathinfo_basic failed with %s\n",
3321 /* Check attributes are correct. */
3322 correct = check_attributes(cli,
3324 FILE_ATTRIBUTE_SYSTEM |
3325 FILE_ATTRIBUTE_HIDDEN |
3326 FILE_ATTRIBUTE_READONLY);
3327 if (correct == false) {
3331 /* Setting to 0 should clear them all. */
3332 status = cli_setpathinfo_basic(cli,
3339 if (!NT_STATUS_IS_OK(status)) {
3340 printf("cli_setpathinfo_basic failed with %s\n",
3345 /* Check attributes are correct. */
3346 correct = check_attributes(cli,
3348 FILE_ATTRIBUTE_NORMAL);
3349 if (correct == false) {
3357 FILE_ATTRIBUTE_SYSTEM |
3358 FILE_ATTRIBUTE_HIDDEN|
3359 FILE_ATTRIBUTE_READONLY);
3361 if (!torture_close_connection(cli)) {
3365 printf("attrib test finished\n");
3372 This checks a couple of trans2 calls
3374 static bool run_trans2test(int dummy)
3376 struct cli_state *cli;
3379 time_t c_time, a_time, m_time;
3380 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3381 const char *fname = "\\trans2.tst";
3382 const char *dname = "\\trans2";
3383 const char *fname2 = "\\trans2\\trans2.tst";
3385 bool correct = True;
3389 printf("starting trans2 test\n");
3391 if (!torture_open_connection(&cli, 0)) {
3395 status = cli_get_fs_attr_info(cli, &fs_attr);
3396 if (!NT_STATUS_IS_OK(status)) {
3397 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3402 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3403 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3404 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3405 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3406 if (!NT_STATUS_IS_OK(status)) {
3407 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3411 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3412 if (!NT_STATUS_IS_OK(status)) {
3413 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3416 else if (strcmp(pname, fname)) {
3417 printf("qfilename gave different name? [%s] [%s]\n",
3422 cli_close(cli, fnum);
3426 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3427 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3429 if (!NT_STATUS_IS_OK(status)) {
3430 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3433 cli_close(cli, fnum);
3435 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3437 if (!NT_STATUS_IS_OK(status)) {
3438 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3441 time_t t = time(NULL);
3443 if (c_time != m_time) {
3444 printf("create time=%s", ctime(&c_time));
3445 printf("modify time=%s", ctime(&m_time));
3446 printf("This system appears to have sticky create times\n");
3448 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3449 printf("access time=%s", ctime(&a_time));
3450 printf("This system appears to set a midnight access time\n");
3454 if (abs(m_time - t) > 60*60*24*7) {
3455 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3461 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3462 cli_openx(cli, fname,
3463 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3464 cli_close(cli, fnum);
3465 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3466 &m_time_ts, &size, NULL, NULL);
3467 if (!NT_STATUS_IS_OK(status)) {
3468 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3471 if (w_time_ts.tv_sec < 60*60*24*2) {
3472 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3473 printf("This system appears to set a initial 0 write time\n");
3478 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3481 /* check if the server updates the directory modification time
3482 when creating a new file */
3483 status = cli_mkdir(cli, dname);
3484 if (!NT_STATUS_IS_OK(status)) {
3485 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3489 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3490 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3491 if (!NT_STATUS_IS_OK(status)) {
3492 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3496 cli_openx(cli, fname2,
3497 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3498 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3499 cli_close(cli, fnum);
3500 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3501 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3502 if (!NT_STATUS_IS_OK(status)) {
3503 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3506 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3508 printf("This system does not update directory modification times\n");
3512 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3513 cli_rmdir(cli, dname);
3515 if (!torture_close_connection(cli)) {
3519 printf("trans2 test finished\n");
3525 This checks new W2K calls.
3528 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3530 uint8_t *buf = NULL;
3534 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3535 CLI_BUFFER_SIZE, NULL, &buf, &len);
3536 if (!NT_STATUS_IS_OK(status)) {
3537 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3540 printf("qfileinfo: level %d, len = %u\n", level, len);
3541 dump_data(0, (uint8_t *)buf, len);
3548 static bool run_w2ktest(int dummy)
3550 struct cli_state *cli;
3552 const char *fname = "\\w2ktest\\w2k.tst";
3554 bool correct = True;
3556 printf("starting w2k test\n");
3558 if (!torture_open_connection(&cli, 0)) {
3562 cli_openx(cli, fname,
3563 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3565 for (level = 1004; level < 1040; level++) {
3566 new_trans(cli, fnum, level);
3569 cli_close(cli, fnum);
3571 if (!torture_close_connection(cli)) {
3575 printf("w2k test finished\n");
3582 this is a harness for some oplock tests
3584 static bool run_oplock1(int dummy)
3586 struct cli_state *cli1;
3587 const char *fname = "\\lockt1.lck";
3589 bool correct = True;
3592 printf("starting oplock test 1\n");
3594 if (!torture_open_connection(&cli1, 0)) {
3598 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3600 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3602 cli1->use_oplocks = True;
3604 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3606 if (!NT_STATUS_IS_OK(status)) {
3607 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3611 cli1->use_oplocks = False;
3613 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3614 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3616 status = cli_close(cli1, fnum1);
3617 if (!NT_STATUS_IS_OK(status)) {
3618 printf("close2 failed (%s)\n", nt_errstr(status));
3622 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3623 if (!NT_STATUS_IS_OK(status)) {
3624 printf("unlink failed (%s)\n", nt_errstr(status));
3628 if (!torture_close_connection(cli1)) {
3632 printf("finished oplock test 1\n");
3637 static bool run_oplock2(int dummy)
3639 struct cli_state *cli1, *cli2;
3640 const char *fname = "\\lockt2.lck";
3641 uint16_t fnum1, fnum2;
3642 int saved_use_oplocks = use_oplocks;
3644 bool correct = True;
3645 volatile bool *shared_correct;
3649 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3650 *shared_correct = True;
3652 use_level_II_oplocks = True;
3655 printf("starting oplock test 2\n");
3657 if (!torture_open_connection(&cli1, 0)) {
3658 use_level_II_oplocks = False;
3659 use_oplocks = saved_use_oplocks;
3663 if (!torture_open_connection(&cli2, 1)) {
3664 use_level_II_oplocks = False;
3665 use_oplocks = saved_use_oplocks;
3669 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3671 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3672 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3674 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3676 if (!NT_STATUS_IS_OK(status)) {
3677 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3681 /* Don't need the globals any more. */
3682 use_level_II_oplocks = False;
3683 use_oplocks = saved_use_oplocks;
3687 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3688 if (!NT_STATUS_IS_OK(status)) {
3689 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3690 *shared_correct = False;
3696 status = cli_close(cli2, fnum2);
3697 if (!NT_STATUS_IS_OK(status)) {
3698 printf("close2 failed (%s)\n", nt_errstr(status));
3699 *shared_correct = False;
3707 /* Ensure cli1 processes the break. Empty file should always return 0
3709 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3710 if (!NT_STATUS_IS_OK(status)) {
3711 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3713 } else if (nread != 0) {
3714 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3715 (unsigned long)nread, 0);
3719 /* Should now be at level II. */
3720 /* Test if sending a write locks causes a break to none. */
3721 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3722 if (!NT_STATUS_IS_OK(status)) {
3723 printf("lock failed (%s)\n", nt_errstr(status));
3727 cli_unlock(cli1, fnum1, 0, 4);
3731 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3732 if (!NT_STATUS_IS_OK(status)) {
3733 printf("lock failed (%s)\n", nt_errstr(status));
3737 cli_unlock(cli1, fnum1, 0, 4);
3741 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3743 status = cli_close(cli1, fnum1);
3744 if (!NT_STATUS_IS_OK(status)) {
3745 printf("close1 failed (%s)\n", nt_errstr(status));
3751 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3752 if (!NT_STATUS_IS_OK(status)) {
3753 printf("unlink failed (%s)\n", nt_errstr(status));
3757 if (!torture_close_connection(cli1)) {
3761 if (!*shared_correct) {
3765 printf("finished oplock test 2\n");
3770 struct oplock4_state {
3771 struct tevent_context *ev;
3772 struct cli_state *cli;
3777 static void oplock4_got_break(struct tevent_req *req);
3778 static void oplock4_got_open(struct tevent_req *req);
3780 static bool run_oplock4(int dummy)
3782 struct tevent_context *ev;
3783 struct cli_state *cli1, *cli2;
3784 struct tevent_req *oplock_req, *open_req;
3785 const char *fname = "\\lockt4.lck";
3786 const char *fname_ln = "\\lockt4_ln.lck";
3787 uint16_t fnum1, fnum2;
3788 int saved_use_oplocks = use_oplocks;
3790 bool correct = true;
3794 struct oplock4_state *state;
3796 printf("starting oplock test 4\n");
3798 if (!torture_open_connection(&cli1, 0)) {
3799 use_level_II_oplocks = false;
3800 use_oplocks = saved_use_oplocks;
3804 if (!torture_open_connection(&cli2, 1)) {
3805 use_level_II_oplocks = false;
3806 use_oplocks = saved_use_oplocks;
3810 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3811 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3813 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3814 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3816 /* Create the file. */
3817 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3819 if (!NT_STATUS_IS_OK(status)) {
3820 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3824 status = cli_close(cli1, fnum1);
3825 if (!NT_STATUS_IS_OK(status)) {
3826 printf("close1 failed (%s)\n", nt_errstr(status));
3830 /* Now create a hardlink. */
3831 status = cli_nt_hardlink(cli1, fname, fname_ln);
3832 if (!NT_STATUS_IS_OK(status)) {
3833 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3837 /* Prove that opening hardlinks cause deny modes to conflict. */
3838 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3839 if (!NT_STATUS_IS_OK(status)) {
3840 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3844 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3845 if (NT_STATUS_IS_OK(status)) {
3846 printf("open of %s succeeded - should fail with sharing violation.\n",
3851 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3852 printf("open of %s should fail with sharing violation. Got %s\n",
3853 fname_ln, nt_errstr(status));
3857 status = cli_close(cli1, fnum1);
3858 if (!NT_STATUS_IS_OK(status)) {
3859 printf("close1 failed (%s)\n", nt_errstr(status));
3863 cli1->use_oplocks = true;
3864 cli2->use_oplocks = true;
3866 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3867 if (!NT_STATUS_IS_OK(status)) {
3868 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3872 ev = samba_tevent_context_init(talloc_tos());
3874 printf("tevent_context_init failed\n");
3878 state = talloc(ev, struct oplock4_state);
3879 if (state == NULL) {
3880 printf("talloc failed\n");
3885 state->got_break = &got_break;
3886 state->fnum2 = &fnum2;
3888 oplock_req = cli_smb_oplock_break_waiter_send(
3889 talloc_tos(), ev, cli1);
3890 if (oplock_req == NULL) {
3891 printf("cli_smb_oplock_break_waiter_send failed\n");
3894 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3896 open_req = cli_openx_send(
3897 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3898 if (open_req == NULL) {
3899 printf("cli_openx_send failed\n");
3902 tevent_req_set_callback(open_req, oplock4_got_open, state);
3907 while (!got_break || fnum2 == 0xffff) {
3909 ret = tevent_loop_once(ev);
3911 printf("tevent_loop_once failed: %s\n",
3917 status = cli_close(cli2, fnum2);
3918 if (!NT_STATUS_IS_OK(status)) {
3919 printf("close2 failed (%s)\n", nt_errstr(status));
3923 status = cli_close(cli1, fnum1);
3924 if (!NT_STATUS_IS_OK(status)) {
3925 printf("close1 failed (%s)\n", nt_errstr(status));
3929 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3930 if (!NT_STATUS_IS_OK(status)) {
3931 printf("unlink failed (%s)\n", nt_errstr(status));
3935 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 printf("unlink failed (%s)\n", nt_errstr(status));
3941 if (!torture_close_connection(cli1)) {
3949 printf("finished oplock test 4\n");
3954 static void oplock4_got_break(struct tevent_req *req)
3956 struct oplock4_state *state = tevent_req_callback_data(
3957 req, struct oplock4_state);
3962 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3964 if (!NT_STATUS_IS_OK(status)) {
3965 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3969 *state->got_break = true;
3971 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3974 printf("cli_oplock_ack_send failed\n");
3979 static void oplock4_got_open(struct tevent_req *req)
3981 struct oplock4_state *state = tevent_req_callback_data(
3982 req, struct oplock4_state);
3985 status = cli_openx_recv(req, state->fnum2);
3986 if (!NT_STATUS_IS_OK(status)) {
3987 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3988 *state->fnum2 = 0xffff;
3993 Test delete on close semantics.
3995 static bool run_deletetest(int dummy)
3997 struct cli_state *cli1 = NULL;
3998 struct cli_state *cli2 = NULL;
3999 const char *fname = "\\delete.file";
4000 uint16_t fnum1 = (uint16_t)-1;
4001 uint16_t fnum2 = (uint16_t)-1;
4002 bool correct = false;
4005 printf("starting delete test\n");
4007 if (!torture_open_connection(&cli1, 0)) {
4011 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4013 /* Test 1 - this should delete the file on close. */
4015 cli_setatr(cli1, fname, 0, 0);
4016 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4018 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4019 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4020 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4021 if (!NT_STATUS_IS_OK(status)) {
4022 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
4026 status = cli_close(cli1, fnum1);
4027 if (!NT_STATUS_IS_OK(status)) {
4028 printf("[1] close failed (%s)\n", nt_errstr(status));
4032 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
4033 if (NT_STATUS_IS_OK(status)) {
4034 printf("[1] open of %s succeeded (should fail)\n", fname);
4038 printf("first delete on close test succeeded.\n");
4040 /* Test 2 - this should delete the file on close. */
4042 cli_setatr(cli1, fname, 0, 0);
4043 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4045 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
4046 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4047 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4048 if (!NT_STATUS_IS_OK(status)) {
4049 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
4053 status = cli_nt_delete_on_close(cli1, fnum1, true);
4054 if (!NT_STATUS_IS_OK(status)) {
4055 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
4059 status = cli_close(cli1, fnum1);
4060 if (!NT_STATUS_IS_OK(status)) {
4061 printf("[2] close failed (%s)\n", nt_errstr(status));
4065 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4066 if (NT_STATUS_IS_OK(status)) {
4067 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
4068 status = cli_close(cli1, fnum1);
4069 if (!NT_STATUS_IS_OK(status)) {
4070 printf("[2] close failed (%s)\n", nt_errstr(status));
4072 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4076 printf("second 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, GENERIC_ALL_ACCESS,
4083 FILE_ATTRIBUTE_NORMAL,
4084 FILE_SHARE_READ|FILE_SHARE_WRITE,
4085 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4086 if (!NT_STATUS_IS_OK(status)) {
4087 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
4091 /* This should fail with a sharing violation - open for delete is only compatible
4092 with SHARE_DELETE. */
4094 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4095 FILE_ATTRIBUTE_NORMAL,
4096 FILE_SHARE_READ|FILE_SHARE_WRITE,
4097 FILE_OPEN, 0, 0, &fnum2, NULL);
4098 if (NT_STATUS_IS_OK(status)) {
4099 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4103 /* This should succeed. */
4104 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4105 FILE_ATTRIBUTE_NORMAL,
4106 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4107 FILE_OPEN, 0, 0, &fnum2, NULL);
4108 if (!NT_STATUS_IS_OK(status)) {
4109 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
4113 status = cli_nt_delete_on_close(cli1, fnum1, true);
4114 if (!NT_STATUS_IS_OK(status)) {
4115 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4119 status = cli_close(cli1, fnum1);
4120 if (!NT_STATUS_IS_OK(status)) {
4121 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4125 status = cli_close(cli1, fnum2);
4126 if (!NT_STATUS_IS_OK(status)) {
4127 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4131 /* This should fail - file should no longer be there. */
4133 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4134 if (NT_STATUS_IS_OK(status)) {
4135 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4136 status = cli_close(cli1, fnum1);
4137 if (!NT_STATUS_IS_OK(status)) {
4138 printf("[3] close failed (%s)\n", nt_errstr(status));
4140 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4144 printf("third delete on close test succeeded.\n");
4147 cli_setatr(cli1, fname, 0, 0);
4148 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4150 status = cli_ntcreate(cli1, fname, 0,
4151 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4152 FILE_ATTRIBUTE_NORMAL,
4153 FILE_SHARE_READ|FILE_SHARE_WRITE,
4154 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4155 if (!NT_STATUS_IS_OK(status)) {
4156 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4160 /* This should succeed. */
4161 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4162 FILE_ATTRIBUTE_NORMAL,
4163 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4164 FILE_OPEN, 0, 0, &fnum2, NULL);
4165 if (!NT_STATUS_IS_OK(status)) {
4166 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4170 status = cli_close(cli1, fnum2);
4171 if (!NT_STATUS_IS_OK(status)) {
4172 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4176 status = cli_nt_delete_on_close(cli1, fnum1, true);
4177 if (!NT_STATUS_IS_OK(status)) {
4178 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4182 /* This should fail - no more opens once delete on close set. */
4183 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4184 FILE_ATTRIBUTE_NORMAL,
4185 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4186 FILE_OPEN, 0, 0, &fnum2, NULL);
4187 if (NT_STATUS_IS_OK(status)) {
4188 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4192 status = cli_close(cli1, fnum1);
4193 if (!NT_STATUS_IS_OK(status)) {
4194 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4198 printf("fourth delete on close test succeeded.\n");
4201 cli_setatr(cli1, fname, 0, 0);
4202 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4204 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4205 if (!NT_STATUS_IS_OK(status)) {
4206 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4210 /* This should fail - only allowed on NT opens with DELETE access. */
4212 status = cli_nt_delete_on_close(cli1, fnum1, true);
4213 if (NT_STATUS_IS_OK(status)) {
4214 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4218 status = cli_close(cli1, fnum1);
4219 if (!NT_STATUS_IS_OK(status)) {
4220 printf("[5] close failed (%s)\n", nt_errstr(status));
4224 printf("fifth delete on close test succeeded.\n");
4227 cli_setatr(cli1, fname, 0, 0);
4228 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4230 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4231 FILE_ATTRIBUTE_NORMAL,
4232 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4233 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4234 if (!NT_STATUS_IS_OK(status)) {
4235 printf("[6] open of %s failed (%s)\n", fname,
4240 /* This should fail - only allowed on NT opens with DELETE access. */
4242 status = cli_nt_delete_on_close(cli1, fnum1, true);
4243 if (NT_STATUS_IS_OK(status)) {
4244 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4248 status = cli_close(cli1, fnum1);
4249 if (!NT_STATUS_IS_OK(status)) {
4250 printf("[6] close failed (%s)\n", nt_errstr(status));
4254 printf("sixth 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 status = cli_ntcreate(cli1, fname, 0,
4261 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4262 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4263 0, 0, &fnum1, NULL);
4264 if (!NT_STATUS_IS_OK(status)) {
4265 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4269 status = cli_nt_delete_on_close(cli1, fnum1, true);
4270 if (!NT_STATUS_IS_OK(status)) {
4271 printf("[7] setting delete_on_close on file failed !\n");
4275 status = cli_nt_delete_on_close(cli1, fnum1, false);
4276 if (!NT_STATUS_IS_OK(status)) {
4277 printf("[7] unsetting delete_on_close on file failed !\n");
4281 status = cli_close(cli1, fnum1);
4282 if (!NT_STATUS_IS_OK(status)) {
4283 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4287 /* This next open should succeed - we reset the flag. */
4288 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4289 if (!NT_STATUS_IS_OK(status)) {
4290 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4294 status = cli_close(cli1, fnum1);
4295 if (!NT_STATUS_IS_OK(status)) {
4296 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4300 printf("seventh delete on close test succeeded.\n");
4303 cli_setatr(cli1, fname, 0, 0);
4304 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4306 if (!torture_open_connection(&cli2, 1)) {
4307 printf("[8] failed to open second connection.\n");
4311 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4313 status = cli_ntcreate(cli1, fname, 0,
4314 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4315 FILE_ATTRIBUTE_NORMAL,
4316 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4317 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4318 if (!NT_STATUS_IS_OK(status)) {
4319 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4323 status = cli_ntcreate(cli2, fname, 0,
4324 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4325 FILE_ATTRIBUTE_NORMAL,
4326 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4327 FILE_OPEN, 0, 0, &fnum2, NULL);
4328 if (!NT_STATUS_IS_OK(status)) {
4329 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4333 status = cli_nt_delete_on_close(cli1, fnum1, true);
4334 if (!NT_STATUS_IS_OK(status)) {
4335 printf("[8] setting delete_on_close on file failed !\n");
4339 status = cli_close(cli1, fnum1);
4340 if (!NT_STATUS_IS_OK(status)) {
4341 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4345 status = cli_close(cli2, fnum2);
4346 if (!NT_STATUS_IS_OK(status)) {
4347 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4351 /* This should fail.. */
4352 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4353 if (NT_STATUS_IS_OK(status)) {
4354 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4358 printf("eighth delete on close test succeeded.\n");
4362 /* This should fail - we need to set DELETE_ACCESS. */
4363 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4364 FILE_ATTRIBUTE_NORMAL,
4367 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4368 if (NT_STATUS_IS_OK(status)) {
4369 printf("[9] open of %s succeeded should have failed!\n", fname);
4373 printf("ninth delete on close test succeeded.\n");
4377 status = cli_ntcreate(cli1, fname, 0,
4378 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4379 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4380 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4382 if (!NT_STATUS_IS_OK(status)) {
4383 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4387 /* This should delete the file. */
4388 status = cli_close(cli1, fnum1);
4389 if (!NT_STATUS_IS_OK(status)) {
4390 printf("[10] close failed (%s)\n", nt_errstr(status));
4394 /* This should fail.. */
4395 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4396 if (NT_STATUS_IS_OK(status)) {
4397 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4401 printf("tenth delete on close test succeeded.\n");
4405 cli_setatr(cli1, fname, 0, 0);
4406 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4408 /* Can we open a read-only file with delete access? */
4410 /* Create a readonly file. */
4411 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4412 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4413 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4414 if (!NT_STATUS_IS_OK(status)) {
4415 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4419 status = cli_close(cli1, fnum1);
4420 if (!NT_STATUS_IS_OK(status)) {
4421 printf("[11] close failed (%s)\n", nt_errstr(status));
4425 /* Now try open for delete access. */
4426 status = cli_ntcreate(cli1, fname, 0,
4427 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4429 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4430 FILE_OPEN, 0, 0, &fnum1, NULL);
4431 if (!NT_STATUS_IS_OK(status)) {
4432 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4436 cli_close(cli1, fnum1);
4438 printf("eleventh delete on close test succeeded.\n");
4442 * like test 4 but with initial delete on close
4445 cli_setatr(cli1, fname, 0, 0);
4446 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4448 status = cli_ntcreate(cli1, fname, 0,
4449 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4450 FILE_ATTRIBUTE_NORMAL,
4451 FILE_SHARE_READ|FILE_SHARE_WRITE,
4453 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4454 if (!NT_STATUS_IS_OK(status)) {
4455 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4459 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4460 FILE_ATTRIBUTE_NORMAL,
4461 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4462 FILE_OPEN, 0, 0, &fnum2, NULL);
4463 if (!NT_STATUS_IS_OK(status)) {
4464 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4468 status = cli_close(cli1, fnum2);
4469 if (!NT_STATUS_IS_OK(status)) {
4470 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4474 status = cli_nt_delete_on_close(cli1, fnum1, true);
4475 if (!NT_STATUS_IS_OK(status)) {
4476 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4480 /* This should fail - no more opens once delete on close set. */
4481 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4482 FILE_ATTRIBUTE_NORMAL,
4483 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4484 FILE_OPEN, 0, 0, &fnum2, NULL);
4485 if (NT_STATUS_IS_OK(status)) {
4486 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4490 status = cli_nt_delete_on_close(cli1, fnum1, false);
4491 if (!NT_STATUS_IS_OK(status)) {
4492 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4496 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4497 FILE_ATTRIBUTE_NORMAL,
4498 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4499 FILE_OPEN, 0, 0, &fnum2, NULL);
4500 if (!NT_STATUS_IS_OK(status)) {
4501 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4505 status = cli_close(cli1, fnum2);
4506 if (!NT_STATUS_IS_OK(status)) {
4507 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4511 status = cli_close(cli1, fnum1);
4512 if (!NT_STATUS_IS_OK(status)) {
4513 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4518 * setting delete on close on the handle does
4519 * not unset the initial delete on close...
4521 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4522 FILE_ATTRIBUTE_NORMAL,
4523 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4524 FILE_OPEN, 0, 0, &fnum2, NULL);
4525 if (NT_STATUS_IS_OK(status)) {
4526 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4528 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4529 printf("ntcreate returned %s, expected "
4530 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4535 printf("twelfth delete on close test succeeded.\n");
4538 printf("finished delete test\n");
4543 /* FIXME: This will crash if we aborted before cli2 got
4544 * intialized, because these functions don't handle
4545 * uninitialized connections. */
4547 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4548 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4549 cli_setatr(cli1, fname, 0, 0);
4550 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4552 if (cli1 && !torture_close_connection(cli1)) {
4555 if (cli2 && !torture_close_connection(cli2)) {
4563 Test wildcard delete.
4565 static bool run_wild_deletetest(int dummy)
4567 struct cli_state *cli = NULL;
4568 const char *dname = "\\WTEST";
4569 const char *fname = "\\WTEST\\A";
4570 const char *wunlink_name = "\\WTEST\\*";
4571 uint16_t fnum1 = (uint16_t)-1;
4572 bool correct = false;
4575 printf("starting wildcard delete test\n");
4577 if (!torture_open_connection(&cli, 0)) {
4581 smbXcli_conn_set_sockopt(cli->conn, sockops);
4583 cli_unlink(cli, fname, 0);
4584 cli_rmdir(cli, dname);
4585 status = cli_mkdir(cli, dname);
4586 if (!NT_STATUS_IS_OK(status)) {
4587 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4590 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4591 if (!NT_STATUS_IS_OK(status)) {
4592 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4595 status = cli_close(cli, fnum1);
4599 * Note the unlink attribute-type of zero. This should
4600 * map into FILE_ATTRIBUTE_NORMAL at the server even
4601 * on a wildcard delete.
4604 status = cli_unlink(cli, wunlink_name, 0);
4605 if (!NT_STATUS_IS_OK(status)) {
4606 printf("unlink of %s failed %s!\n",
4607 wunlink_name, nt_errstr(status));
4611 printf("finished wildcard delete test\n");
4617 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4618 cli_unlink(cli, fname, 0);
4619 cli_rmdir(cli, dname);
4621 if (cli && !torture_close_connection(cli)) {
4627 static bool run_deletetest_ln(int dummy)
4629 struct cli_state *cli;
4630 const char *fname = "\\delete1";
4631 const char *fname_ln = "\\delete1_ln";
4635 bool correct = true;
4638 printf("starting deletetest-ln\n");
4640 if (!torture_open_connection(&cli, 0)) {
4644 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4645 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4647 smbXcli_conn_set_sockopt(cli->conn, sockops);
4649 /* Create the file. */
4650 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4651 if (!NT_STATUS_IS_OK(status)) {
4652 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4656 status = cli_close(cli, fnum);
4657 if (!NT_STATUS_IS_OK(status)) {
4658 printf("close1 failed (%s)\n", nt_errstr(status));
4662 /* Now create a hardlink. */
4663 status = cli_nt_hardlink(cli, fname, fname_ln);
4664 if (!NT_STATUS_IS_OK(status)) {
4665 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4669 /* Open the original file. */
4670 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4671 FILE_ATTRIBUTE_NORMAL,
4672 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4673 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4674 if (!NT_STATUS_IS_OK(status)) {
4675 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4679 /* Unlink the hard link path. */
4680 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4681 FILE_ATTRIBUTE_NORMAL,
4682 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4683 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4684 if (!NT_STATUS_IS_OK(status)) {
4685 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4688 status = cli_nt_delete_on_close(cli, fnum1, true);
4689 if (!NT_STATUS_IS_OK(status)) {
4690 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4691 __location__, fname_ln, nt_errstr(status));
4695 status = cli_close(cli, fnum1);
4696 if (!NT_STATUS_IS_OK(status)) {
4697 printf("close %s failed (%s)\n",
4698 fname_ln, nt_errstr(status));
4702 status = cli_close(cli, fnum);
4703 if (!NT_STATUS_IS_OK(status)) {
4704 printf("close %s failed (%s)\n",
4705 fname, nt_errstr(status));
4709 /* Ensure the original file is still there. */
4710 status = cli_getatr(cli, fname, NULL, NULL, &t);
4711 if (!NT_STATUS_IS_OK(status)) {
4712 printf("%s getatr on file %s failed (%s)\n",
4719 /* Ensure the link path is gone. */
4720 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4721 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4722 printf("%s, getatr for file %s returned wrong error code %s "
4723 "- should have been deleted\n",
4725 fname_ln, nt_errstr(status));
4729 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4730 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4732 if (!torture_close_connection(cli)) {
4736 printf("finished deletetest-ln\n");
4742 print out server properties
4744 static bool run_properties(int dummy)
4746 struct cli_state *cli;
4747 bool correct = True;
4749 printf("starting properties test\n");
4753 if (!torture_open_connection(&cli, 0)) {
4757 smbXcli_conn_set_sockopt(cli->conn, sockops);
4759 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4761 if (!torture_close_connection(cli)) {
4770 /* FIRST_DESIRED_ACCESS 0xf019f */
4771 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4772 FILE_READ_EA| /* 0xf */ \
4773 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4774 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4775 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4776 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4777 /* SECOND_DESIRED_ACCESS 0xe0080 */
4778 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4779 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4780 WRITE_OWNER_ACCESS /* 0xe0000 */
4783 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4784 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4786 WRITE_OWNER_ACCESS /* */
4790 Test ntcreate calls made by xcopy
4792 static bool run_xcopy(int dummy)
4794 static struct cli_state *cli1;
4795 const char *fname = "\\test.txt";
4796 bool correct = True;
4797 uint16_t fnum1, fnum2;
4800 printf("starting xcopy test\n");
4802 if (!torture_open_connection(&cli1, 0)) {
4806 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4807 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4808 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4809 if (!NT_STATUS_IS_OK(status)) {
4810 printf("First open failed - %s\n", nt_errstr(status));
4814 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4815 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4816 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4817 if (!NT_STATUS_IS_OK(status)) {
4818 printf("second open failed - %s\n", nt_errstr(status));
4822 if (!torture_close_connection(cli1)) {
4830 Test rename on files open with share delete and no share delete.
4832 static bool run_rename(int dummy)
4834 static struct cli_state *cli1;
4835 const char *fname = "\\test.txt";
4836 const char *fname1 = "\\test1.txt";
4837 bool correct = True;
4842 printf("starting rename test\n");
4844 if (!torture_open_connection(&cli1, 0)) {
4848 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4849 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4851 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4852 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4853 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4854 if (!NT_STATUS_IS_OK(status)) {
4855 printf("First open failed - %s\n", nt_errstr(status));
4859 status = cli_rename(cli1, fname, fname1, false);
4860 if (!NT_STATUS_IS_OK(status)) {
4861 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4863 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4867 status = cli_close(cli1, fnum1);
4868 if (!NT_STATUS_IS_OK(status)) {
4869 printf("close - 1 failed (%s)\n", nt_errstr(status));
4873 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4874 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4875 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4877 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4879 FILE_SHARE_DELETE|FILE_SHARE_READ,
4881 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4882 if (!NT_STATUS_IS_OK(status)) {
4883 printf("Second open failed - %s\n", nt_errstr(status));
4887 status = cli_rename(cli1, fname, fname1, false);
4888 if (!NT_STATUS_IS_OK(status)) {
4889 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4892 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4895 status = cli_close(cli1, fnum1);
4896 if (!NT_STATUS_IS_OK(status)) {
4897 printf("close - 2 failed (%s)\n", nt_errstr(status));
4901 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4902 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4904 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4905 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4906 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4907 if (!NT_STATUS_IS_OK(status)) {
4908 printf("Third open failed - %s\n", nt_errstr(status));
4917 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4918 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4919 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4922 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4923 printf("[8] setting delete_on_close on file failed !\n");
4927 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4928 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4934 status = cli_rename(cli1, fname, fname1, false);
4935 if (!NT_STATUS_IS_OK(status)) {
4936 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4939 printf("Third rename succeeded (SHARE_NONE)\n");
4942 status = cli_close(cli1, fnum1);
4943 if (!NT_STATUS_IS_OK(status)) {
4944 printf("close - 3 failed (%s)\n", nt_errstr(status));
4948 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4949 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4953 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4954 FILE_ATTRIBUTE_NORMAL,
4955 FILE_SHARE_READ | FILE_SHARE_WRITE,
4956 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4957 if (!NT_STATUS_IS_OK(status)) {
4958 printf("Fourth open failed - %s\n", nt_errstr(status));
4962 status = cli_rename(cli1, fname, fname1, false);
4963 if (!NT_STATUS_IS_OK(status)) {
4964 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4966 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4970 status = cli_close(cli1, fnum1);
4971 if (!NT_STATUS_IS_OK(status)) {
4972 printf("close - 4 failed (%s)\n", nt_errstr(status));
4976 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4977 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4981 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4982 FILE_ATTRIBUTE_NORMAL,
4983 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4984 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4985 if (!NT_STATUS_IS_OK(status)) {
4986 printf("Fifth open failed - %s\n", nt_errstr(status));
4990 status = cli_rename(cli1, fname, fname1, false);
4991 if (!NT_STATUS_IS_OK(status)) {
4992 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4995 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4999 * Now check if the first name still exists ...
5002 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
5003 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
5004 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
5005 printf("Opening original file after rename of open file fails: %s\n",
5009 printf("Opening original file after rename of open file works ...\n");
5010 (void)cli_close(cli1, fnum2);
5014 status = cli_close(cli1, fnum1);
5015 if (!NT_STATUS_IS_OK(status)) {
5016 printf("close - 5 failed (%s)\n", nt_errstr(status));
5020 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
5021 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
5022 if (!NT_STATUS_IS_OK(status)) {
5023 printf("getatr on file %s failed - %s ! \n",
5024 fname1, nt_errstr(status));
5027 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
5028 printf("Renamed file %s has wrong attr 0x%x "
5029 "(should be 0x%x)\n",
5032 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
5035 printf("Renamed file %s has archive bit set\n", fname1);
5039 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5040 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5042 if (!torture_close_connection(cli1)) {
5050 Test rename into a directory with an ACL denying it.
5052 static bool run_rename_access(int dummy)
5054 static struct cli_state *cli = NULL;
5055 static struct cli_state *posix_cli = NULL;
5056 const char *src = "test.txt";
5057 const char *dname = "dir";
5058 const char *dst = "dir\\test.txt";
5059 const char *dsrc = "test.dir";
5060 const char *ddst = "dir\\test.dir";
5061 uint16_t fnum = (uint16_t)-1;
5062 struct security_descriptor *sd = NULL;
5063 struct security_descriptor *newsd = NULL;
5065 TALLOC_CTX *frame = NULL;
5067 frame = talloc_stackframe();
5068 printf("starting rename access test\n");
5070 /* Windows connection. */
5071 if (!torture_open_connection(&cli, 0)) {
5075 smbXcli_conn_set_sockopt(cli->conn, sockops);
5077 /* Posix connection. */
5078 if (!torture_open_connection(&posix_cli, 0)) {
5082 smbXcli_conn_set_sockopt(posix_cli->conn, sockops);
5084 status = torture_setup_unix_extensions(posix_cli);
5085 if (!NT_STATUS_IS_OK(status)) {
5089 /* Start with a clean slate. */
5090 cli_unlink(cli, src, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5091 cli_unlink(cli, dst, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5092 cli_rmdir(cli, dsrc);
5093 cli_rmdir(cli, ddst);
5094 cli_rmdir(cli, dname);
5097 * Setup the destination directory with a DENY ACE to
5098 * prevent new files within it.
5100 status = cli_ntcreate(cli,
5103 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS|
5104 WRITE_DAC_ACCESS|FILE_READ_DATA|
5106 FILE_ATTRIBUTE_DIRECTORY,
5107 FILE_SHARE_READ|FILE_SHARE_WRITE,
5109 FILE_DIRECTORY_FILE,
5113 if (!NT_STATUS_IS_OK(status)) {
5114 printf("Create of %s - %s\n", dname, nt_errstr(status));
5118 status = cli_query_secdesc(cli,
5122 if (!NT_STATUS_IS_OK(status)) {
5123 printf("cli_query_secdesc failed for %s (%s)\n",
5124 dname, nt_errstr(status));
5128 newsd = security_descriptor_dacl_create(frame,
5133 SEC_ACE_TYPE_ACCESS_DENIED,
5134 SEC_DIR_ADD_FILE|SEC_DIR_ADD_SUBDIR,
5137 if (newsd == NULL) {
5140 sd->dacl = security_acl_concatenate(frame,
5143 if (sd->dacl == NULL) {
5146 status = cli_set_secdesc(cli, fnum, sd);
5147 if (!NT_STATUS_IS_OK(status)) {
5148 printf("cli_set_secdesc failed for %s (%s)\n",
5149 dname, nt_errstr(status));
5152 status = cli_close(cli, fnum);
5153 if (!NT_STATUS_IS_OK(status)) {
5154 printf("close failed for %s (%s)\n",
5155 dname, nt_errstr(status));
5158 /* Now go around the back and chmod to 777 via POSIX. */
5159 status = cli_posix_chmod(posix_cli, dname, 0777);
5160 if (!NT_STATUS_IS_OK(status)) {
5161 printf("cli_posix_chmod failed for %s (%s)\n",
5162 dname, nt_errstr(status));
5166 /* Check we can't create a file within dname via Windows. */
5167 status = cli_openx(cli, dst, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5168 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5169 cli_close(posix_cli, fnum);
5170 printf("Create of %s should be ACCESS denied, was %s\n",
5171 dst, nt_errstr(status));
5175 /* Make the sample file/directory. */
5176 status = cli_openx(cli, src, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5177 if (!NT_STATUS_IS_OK(status)) {
5178 printf("open of %s failed (%s)\n", src, nt_errstr(status));
5181 status = cli_close(cli, fnum);
5182 if (!NT_STATUS_IS_OK(status)) {
5183 printf("cli_close failed (%s)\n", nt_errstr(status));
5187 status = cli_mkdir(cli, dsrc);
5188 if (!NT_STATUS_IS_OK(status)) {
5189 printf("cli_mkdir of %s failed (%s)\n",
5190 dsrc, nt_errstr(status));
5195 * OK - renames of the new file and directory into the
5196 * dst directory should fail.
5199 status = cli_rename(cli, src, dst, false);
5200 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5201 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5202 src, dst, nt_errstr(status));
5205 status = cli_rename(cli, dsrc, ddst, false);
5206 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5207 printf("rename of %s -> %s should be ACCESS denied, was %s\n",
5208 src, dst, nt_errstr(status));
5218 torture_close_connection(posix_cli);
5222 if (fnum != (uint64_t)-1) {
5223 cli_close(cli, fnum);
5225 cli_unlink(cli, src,
5226 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5227 cli_unlink(cli, dst,
5228 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5229 cli_rmdir(cli, dsrc);
5230 cli_rmdir(cli, ddst);
5231 cli_rmdir(cli, dname);
5233 torture_close_connection(cli);
5241 Test owner rights ACE.
5243 static bool run_owner_rights(int dummy)
5245 static struct cli_state *cli = NULL;
5246 const char *fname = "owner_rights.txt";
5247 uint16_t fnum = (uint16_t)-1;
5248 struct security_descriptor *sd = NULL;
5249 struct security_descriptor *newsd = NULL;
5251 TALLOC_CTX *frame = NULL;
5253 frame = talloc_stackframe();
5254 printf("starting owner rights test\n");
5256 /* Windows connection. */
5257 if (!torture_open_connection(&cli, 0)) {
5261 smbXcli_conn_set_sockopt(cli->conn, sockops);
5263 /* Start with a clean slate. */
5264 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5266 /* Create the test file. */
5267 /* Now try and open for read and write-dac. */
5268 status = cli_ntcreate(cli,
5272 FILE_ATTRIBUTE_NORMAL,
5273 FILE_SHARE_READ|FILE_SHARE_WRITE|
5280 if (!NT_STATUS_IS_OK(status)) {
5281 printf("Create of %s - %s\n", fname, nt_errstr(status));
5285 /* Get the original SD. */
5286 status = cli_query_secdesc(cli,
5290 if (!NT_STATUS_IS_OK(status)) {
5291 printf("cli_query_secdesc failed for %s (%s)\n",
5292 fname, nt_errstr(status));
5297 * Add an "owner-rights" ACE denying WRITE_DATA,
5298 * and an "owner-rights" ACE allowing READ_DATA.
5301 newsd = security_descriptor_dacl_create(frame,
5306 SEC_ACE_TYPE_ACCESS_DENIED,
5310 SEC_ACE_TYPE_ACCESS_ALLOWED,
5314 if (newsd == NULL) {
5317 sd->dacl = security_acl_concatenate(frame,
5320 if (sd->dacl == NULL) {
5323 status = cli_set_secdesc(cli, fnum, sd);
5324 if (!NT_STATUS_IS_OK(status)) {
5325 printf("cli_set_secdesc failed for %s (%s)\n",
5326 fname, nt_errstr(status));
5329 status = cli_close(cli, fnum);
5330 if (!NT_STATUS_IS_OK(status)) {
5331 printf("close failed for %s (%s)\n",
5332 fname, nt_errstr(status));
5335 fnum = (uint16_t)-1;
5337 /* Try and open for FILE_WRITE_DATA */
5338 status = cli_ntcreate(cli,
5342 FILE_ATTRIBUTE_NORMAL,
5343 FILE_SHARE_READ|FILE_SHARE_WRITE|
5350 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5351 printf("Open of %s - %s\n", fname, nt_errstr(status));
5355 /* Now try and open for FILE_READ_DATA */
5356 status = cli_ntcreate(cli,
5360 FILE_ATTRIBUTE_NORMAL,
5361 FILE_SHARE_READ|FILE_SHARE_WRITE|
5368 if (!NT_STATUS_IS_OK(status)) {
5369 printf("Open of %s - %s\n", fname, nt_errstr(status));
5373 status = cli_close(cli, fnum);
5374 if (!NT_STATUS_IS_OK(status)) {
5375 printf("close failed for %s (%s)\n",
5376 fname, nt_errstr(status));
5380 /* Restore clean slate. */
5382 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5384 /* Create the test file. */
5385 status = cli_ntcreate(cli,
5389 FILE_ATTRIBUTE_NORMAL,
5390 FILE_SHARE_READ|FILE_SHARE_WRITE|
5397 if (!NT_STATUS_IS_OK(status)) {
5398 printf("Create of %s - %s\n", fname, nt_errstr(status));
5402 /* Get the original SD. */
5403 status = cli_query_secdesc(cli,
5407 if (!NT_STATUS_IS_OK(status)) {
5408 printf("cli_query_secdesc failed for %s (%s)\n",
5409 fname, nt_errstr(status));
5414 * Add an "owner-rights ACE denying WRITE_DATA,
5415 * and an "owner-rights ACE allowing READ_DATA|WRITE_DATA.
5418 newsd = security_descriptor_dacl_create(frame,
5423 SEC_ACE_TYPE_ACCESS_DENIED,
5427 SEC_ACE_TYPE_ACCESS_ALLOWED,
5428 FILE_READ_DATA|FILE_WRITE_DATA,
5431 if (newsd == NULL) {
5434 sd->dacl = security_acl_concatenate(frame,
5437 if (sd->dacl == NULL) {
5440 status = cli_set_secdesc(cli, fnum, sd);
5441 if (!NT_STATUS_IS_OK(status)) {
5442 printf("cli_set_secdesc failed for %s (%s)\n",
5443 fname, nt_errstr(status));
5446 status = cli_close(cli, fnum);
5447 if (!NT_STATUS_IS_OK(status)) {
5448 printf("close failed for %s (%s)\n",
5449 fname, nt_errstr(status));
5452 fnum = (uint16_t)-1;
5454 /* Try and open for FILE_WRITE_DATA */
5455 status = cli_ntcreate(cli,
5459 FILE_ATTRIBUTE_NORMAL,
5460 FILE_SHARE_READ|FILE_SHARE_WRITE|
5467 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5468 printf("Open of %s - %s\n", fname, nt_errstr(status));
5472 /* Now try and open for FILE_READ_DATA */
5473 status = cli_ntcreate(cli,
5477 FILE_ATTRIBUTE_NORMAL,
5478 FILE_SHARE_READ|FILE_SHARE_WRITE|
5485 if (!NT_STATUS_IS_OK(status)) {
5486 printf("Open of %s - %s\n", fname, nt_errstr(status));
5490 status = cli_close(cli, fnum);
5491 if (!NT_STATUS_IS_OK(status)) {
5492 printf("close failed for %s (%s)\n",
5493 fname, nt_errstr(status));
5497 /* Restore clean slate. */
5499 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5502 /* Create the test file. */
5503 status = cli_ntcreate(cli,
5507 FILE_ATTRIBUTE_NORMAL,
5508 FILE_SHARE_READ|FILE_SHARE_WRITE|
5515 if (!NT_STATUS_IS_OK(status)) {
5516 printf("Create of %s - %s\n", fname, nt_errstr(status));
5520 /* Get the original SD. */
5521 status = cli_query_secdesc(cli,
5525 if (!NT_STATUS_IS_OK(status)) {
5526 printf("cli_query_secdesc failed for %s (%s)\n",
5527 fname, nt_errstr(status));
5532 * Add an "authenticated users" ACE allowing READ_DATA,
5533 * add an "owner-rights" denying READ_DATA,
5534 * and an "authenticated users" ACE allowing WRITE_DATA.
5537 newsd = security_descriptor_dacl_create(frame,
5541 SID_NT_AUTHENTICATED_USERS,
5542 SEC_ACE_TYPE_ACCESS_ALLOWED,
5546 SEC_ACE_TYPE_ACCESS_DENIED,
5549 SID_NT_AUTHENTICATED_USERS,
5550 SEC_ACE_TYPE_ACCESS_ALLOWED,
5554 if (newsd == NULL) {
5555 printf("newsd == NULL\n");
5558 sd->dacl = security_acl_concatenate(frame,
5561 if (sd->dacl == NULL) {
5562 printf("sd->dacl == NULL\n");
5565 status = cli_set_secdesc(cli, fnum, sd);
5566 if (!NT_STATUS_IS_OK(status)) {
5567 printf("cli_set_secdesc failed for %s (%s)\n",
5568 fname, nt_errstr(status));
5571 status = cli_close(cli, fnum);
5572 if (!NT_STATUS_IS_OK(status)) {
5573 printf("close failed for %s (%s)\n",
5574 fname, nt_errstr(status));
5577 fnum = (uint16_t)-1;
5579 /* Now try and open for FILE_READ_DATA|FILE_WRITE_DATA */
5580 status = cli_ntcreate(cli,
5583 FILE_READ_DATA|FILE_WRITE_DATA,
5584 FILE_ATTRIBUTE_NORMAL,
5585 FILE_SHARE_READ|FILE_SHARE_WRITE|
5592 if (!NT_STATUS_IS_OK(status)) {
5593 printf("Open of %s - %s\n", fname, nt_errstr(status));
5597 status = cli_close(cli, fnum);
5598 if (!NT_STATUS_IS_OK(status)) {
5599 printf("close failed for %s (%s)\n",
5600 fname, nt_errstr(status));
5604 cli_unlink(cli, fname,
5605 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5613 if (fnum != (uint16_t)-1) {
5614 cli_close(cli, fnum);
5616 cli_unlink(cli, fname,
5617 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5618 torture_close_connection(cli);
5625 static bool run_pipe_number(int dummy)
5627 struct cli_state *cli1;
5628 const char *pipe_name = "\\SPOOLSS";
5633 printf("starting pipenumber test\n");
5634 if (!torture_open_connection(&cli1, 0)) {
5638 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5640 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
5641 FILE_ATTRIBUTE_NORMAL,
5642 FILE_SHARE_READ|FILE_SHARE_WRITE,
5643 FILE_OPEN_IF, 0, 0, &fnum, NULL);
5644 if (!NT_STATUS_IS_OK(status)) {
5645 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
5649 printf("\r%6d", num_pipes);
5652 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
5653 torture_close_connection(cli1);
5658 Test open mode returns on read-only files.
5660 static bool run_opentest(int dummy)
5662 static struct cli_state *cli1;
5663 static struct cli_state *cli2;
5664 const char *fname = "\\readonly.file";
5665 uint16_t fnum1, fnum2;
5668 bool correct = True;
5672 printf("starting open test\n");
5674 if (!torture_open_connection(&cli1, 0)) {
5678 cli_setatr(cli1, fname, 0, 0);
5679 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5681 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5683 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5684 if (!NT_STATUS_IS_OK(status)) {
5685 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5689 status = cli_close(cli1, fnum1);
5690 if (!NT_STATUS_IS_OK(status)) {
5691 printf("close2 failed (%s)\n", nt_errstr(status));
5695 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
5696 if (!NT_STATUS_IS_OK(status)) {
5697 printf("cli_setatr failed (%s)\n", nt_errstr(status));
5701 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5702 if (!NT_STATUS_IS_OK(status)) {
5703 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5707 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
5708 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5710 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
5711 NT_STATUS_ACCESS_DENIED)) {
5712 printf("correct error code ERRDOS/ERRnoaccess returned\n");
5715 printf("finished open test 1\n");
5717 cli_close(cli1, fnum1);
5719 /* Now try not readonly and ensure ERRbadshare is returned. */
5721 cli_setatr(cli1, fname, 0, 0);
5723 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
5724 if (!NT_STATUS_IS_OK(status)) {
5725 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5729 /* This will fail - but the error should be ERRshare. */
5730 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5732 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5733 NT_STATUS_SHARING_VIOLATION)) {
5734 printf("correct error code ERRDOS/ERRbadshare returned\n");
5737 status = cli_close(cli1, fnum1);
5738 if (!NT_STATUS_IS_OK(status)) {
5739 printf("close2 failed (%s)\n", nt_errstr(status));
5743 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5745 printf("finished open test 2\n");
5747 /* Test truncate open disposition on file opened for read. */
5748 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5749 if (!NT_STATUS_IS_OK(status)) {
5750 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5754 /* write 20 bytes. */
5756 memset(buf, '\0', 20);
5758 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5759 if (!NT_STATUS_IS_OK(status)) {
5760 printf("write failed (%s)\n", nt_errstr(status));
5764 status = cli_close(cli1, fnum1);
5765 if (!NT_STATUS_IS_OK(status)) {
5766 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5770 /* Ensure size == 20. */
5771 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5772 if (!NT_STATUS_IS_OK(status)) {
5773 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5778 printf("(3) file size != 20\n");
5782 /* Now test if we can truncate a file opened for readonly. */
5783 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5784 if (!NT_STATUS_IS_OK(status)) {
5785 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5789 status = cli_close(cli1, fnum1);
5790 if (!NT_STATUS_IS_OK(status)) {
5791 printf("close2 failed (%s)\n", nt_errstr(status));
5795 /* Ensure size == 0. */
5796 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5797 if (!NT_STATUS_IS_OK(status)) {
5798 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5803 printf("(3) file size != 0\n");
5806 printf("finished open test 3\n");
5808 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5810 printf("Do ctemp tests\n");
5811 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5812 if (!NT_STATUS_IS_OK(status)) {
5813 printf("ctemp failed (%s)\n", nt_errstr(status));
5817 printf("ctemp gave path %s\n", tmp_path);
5818 status = cli_close(cli1, fnum1);
5819 if (!NT_STATUS_IS_OK(status)) {
5820 printf("close of temp failed (%s)\n", nt_errstr(status));
5823 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5824 if (!NT_STATUS_IS_OK(status)) {
5825 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5828 /* Test the non-io opens... */
5830 if (!torture_open_connection(&cli2, 1)) {
5834 cli_setatr(cli2, fname, 0, 0);
5835 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5837 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5839 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5840 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5841 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5842 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5843 if (!NT_STATUS_IS_OK(status)) {
5844 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5848 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5849 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5850 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5851 if (!NT_STATUS_IS_OK(status)) {
5852 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5856 status = cli_close(cli1, fnum1);
5857 if (!NT_STATUS_IS_OK(status)) {
5858 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5862 status = cli_close(cli2, fnum2);
5863 if (!NT_STATUS_IS_OK(status)) {
5864 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5868 printf("non-io open test #1 passed.\n");
5870 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5872 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5874 status = cli_ntcreate(cli1, fname, 0,
5875 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5876 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5877 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5878 if (!NT_STATUS_IS_OK(status)) {
5879 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5883 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5884 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5885 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5886 if (!NT_STATUS_IS_OK(status)) {
5887 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5891 status = cli_close(cli1, fnum1);
5892 if (!NT_STATUS_IS_OK(status)) {
5893 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5897 status = cli_close(cli2, fnum2);
5898 if (!NT_STATUS_IS_OK(status)) {
5899 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5903 printf("non-io open test #2 passed.\n");
5905 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5907 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5909 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5910 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5911 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5912 if (!NT_STATUS_IS_OK(status)) {
5913 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5917 status = cli_ntcreate(cli2, fname, 0,
5918 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5919 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5920 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5921 if (!NT_STATUS_IS_OK(status)) {
5922 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5926 status = cli_close(cli1, fnum1);
5927 if (!NT_STATUS_IS_OK(status)) {
5928 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5932 status = cli_close(cli2, fnum2);
5933 if (!NT_STATUS_IS_OK(status)) {
5934 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5938 printf("non-io open test #3 passed.\n");
5940 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5942 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5944 status = cli_ntcreate(cli1, fname, 0,
5945 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5946 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5947 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5948 if (!NT_STATUS_IS_OK(status)) {
5949 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5953 status = cli_ntcreate(cli2, fname, 0,
5954 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5955 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5956 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5957 if (NT_STATUS_IS_OK(status)) {
5958 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5962 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5964 status = cli_close(cli1, fnum1);
5965 if (!NT_STATUS_IS_OK(status)) {
5966 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5970 printf("non-io open test #4 passed.\n");
5972 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5974 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5976 status = cli_ntcreate(cli1, fname, 0,
5977 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5978 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5979 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5980 if (!NT_STATUS_IS_OK(status)) {
5981 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5985 status = cli_ntcreate(cli2, fname, 0,
5986 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5987 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5988 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5989 if (!NT_STATUS_IS_OK(status)) {
5990 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5994 status = cli_close(cli1, fnum1);
5995 if (!NT_STATUS_IS_OK(status)) {
5996 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6000 status = cli_close(cli2, fnum2);
6001 if (!NT_STATUS_IS_OK(status)) {
6002 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6006 printf("non-io open test #5 passed.\n");
6008 printf("TEST #6 testing 1 non-io open, one io open\n");
6010 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6012 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6013 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6014 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6015 if (!NT_STATUS_IS_OK(status)) {
6016 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6020 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
6021 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6022 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6023 if (!NT_STATUS_IS_OK(status)) {
6024 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
6028 status = cli_close(cli1, fnum1);
6029 if (!NT_STATUS_IS_OK(status)) {
6030 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6034 status = cli_close(cli2, fnum2);
6035 if (!NT_STATUS_IS_OK(status)) {
6036 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
6040 printf("non-io open test #6 passed.\n");
6042 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
6044 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6046 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
6047 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
6048 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6049 if (!NT_STATUS_IS_OK(status)) {
6050 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
6054 status = cli_ntcreate(cli2, fname, 0,
6055 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
6056 FILE_ATTRIBUTE_NORMAL,
6057 FILE_SHARE_READ|FILE_SHARE_DELETE,
6058 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
6059 if (NT_STATUS_IS_OK(status)) {
6060 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
6064 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
6066 status = cli_close(cli1, fnum1);
6067 if (!NT_STATUS_IS_OK(status)) {
6068 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
6072 printf("non-io open test #7 passed.\n");
6074 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6076 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
6077 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
6078 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6079 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6080 if (!NT_STATUS_IS_OK(status)) {
6081 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
6086 /* Write to ensure we have to update the file time. */
6087 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6089 if (!NT_STATUS_IS_OK(status)) {
6090 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
6095 status = cli_close(cli1, fnum1);
6096 if (!NT_STATUS_IS_OK(status)) {
6097 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
6103 if (!torture_close_connection(cli1)) {
6106 if (!torture_close_connection(cli2)) {
6113 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
6115 uint16_t major, minor;
6116 uint32_t caplow, caphigh;
6119 if (!SERVER_HAS_UNIX_CIFS(cli)) {
6120 printf("Server doesn't support UNIX CIFS extensions.\n");
6121 return NT_STATUS_NOT_SUPPORTED;
6124 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
6126 if (!NT_STATUS_IS_OK(status)) {
6127 printf("Server didn't return UNIX CIFS extensions: %s\n",
6132 status = cli_set_unix_extensions_capabilities(cli, major, minor,
6134 if (!NT_STATUS_IS_OK(status)) {
6135 printf("Server doesn't support setting UNIX CIFS extensions: "
6136 "%s.\n", nt_errstr(status));
6140 return NT_STATUS_OK;
6144 Test POSIX open /mkdir calls.
6146 static bool run_simple_posix_open_test(int dummy)
6148 static struct cli_state *cli1;
6149 const char *fname = "posix:file";
6150 const char *hname = "posix:hlink";
6151 const char *sname = "posix:symlink";
6152 const char *dname = "posix:dir";
6155 uint16_t fnum1 = (uint16_t)-1;
6156 SMB_STRUCT_STAT sbuf;
6157 bool correct = false;
6160 const char *fname_windows = "windows_file";
6161 uint16_t fnum2 = (uint16_t)-1;
6163 printf("Starting simple POSIX open test\n");
6165 if (!torture_open_connection(&cli1, 0)) {
6169 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6171 status = torture_setup_unix_extensions(cli1);
6172 if (!NT_STATUS_IS_OK(status)) {
6176 cli_setatr(cli1, fname, 0, 0);
6177 cli_posix_unlink(cli1, fname);
6178 cli_setatr(cli1, dname, 0, 0);
6179 cli_posix_rmdir(cli1, dname);
6180 cli_setatr(cli1, hname, 0, 0);
6181 cli_posix_unlink(cli1, hname);
6182 cli_setatr(cli1, sname, 0, 0);
6183 cli_posix_unlink(cli1, sname);
6184 cli_setatr(cli1, fname_windows, 0, 0);
6185 cli_posix_unlink(cli1, fname_windows);
6187 /* Create a directory. */
6188 status = cli_posix_mkdir(cli1, dname, 0777);
6189 if (!NT_STATUS_IS_OK(status)) {
6190 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6194 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6196 if (!NT_STATUS_IS_OK(status)) {
6197 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6201 /* Test ftruncate - set file size. */
6202 status = cli_ftruncate(cli1, fnum1, 1000);
6203 if (!NT_STATUS_IS_OK(status)) {
6204 printf("ftruncate failed (%s)\n", nt_errstr(status));
6208 /* Ensure st_size == 1000 */
6209 status = cli_posix_stat(cli1, fname, &sbuf);
6210 if (!NT_STATUS_IS_OK(status)) {
6211 printf("stat failed (%s)\n", nt_errstr(status));
6215 if (sbuf.st_ex_size != 1000) {
6216 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6220 /* Ensure st_mode == 0600 */
6221 if ((sbuf.st_ex_mode & 07777) != 0600) {
6222 printf("posix_open - bad permissions 0%o != 0600\n",
6223 (unsigned int)(sbuf.st_ex_mode & 07777));
6227 /* Test ftruncate - set file size back to zero. */
6228 status = cli_ftruncate(cli1, fnum1, 0);
6229 if (!NT_STATUS_IS_OK(status)) {
6230 printf("ftruncate failed (%s)\n", nt_errstr(status));
6234 status = cli_close(cli1, fnum1);
6235 if (!NT_STATUS_IS_OK(status)) {
6236 printf("close failed (%s)\n", nt_errstr(status));
6240 /* Now open the file again for read only. */
6241 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6242 if (!NT_STATUS_IS_OK(status)) {
6243 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
6247 /* Now unlink while open. */
6248 status = cli_posix_unlink(cli1, fname);
6249 if (!NT_STATUS_IS_OK(status)) {
6250 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6254 status = cli_close(cli1, fnum1);
6255 if (!NT_STATUS_IS_OK(status)) {
6256 printf("close(2) failed (%s)\n", nt_errstr(status));
6260 /* Ensure the file has gone. */
6261 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
6262 if (NT_STATUS_IS_OK(status)) {
6263 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
6267 /* Create again to test open with O_TRUNC. */
6268 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
6269 if (!NT_STATUS_IS_OK(status)) {
6270 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6274 /* Test ftruncate - set file size. */
6275 status = cli_ftruncate(cli1, fnum1, 1000);
6276 if (!NT_STATUS_IS_OK(status)) {
6277 printf("ftruncate failed (%s)\n", nt_errstr(status));
6281 /* Ensure st_size == 1000 */
6282 status = cli_posix_stat(cli1, fname, &sbuf);
6283 if (!NT_STATUS_IS_OK(status)) {
6284 printf("stat failed (%s)\n", nt_errstr(status));
6288 if (sbuf.st_ex_size != 1000) {
6289 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
6293 status = cli_close(cli1, fnum1);
6294 if (!NT_STATUS_IS_OK(status)) {
6295 printf("close(2) failed (%s)\n", nt_errstr(status));
6299 /* Re-open with O_TRUNC. */
6300 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
6301 if (!NT_STATUS_IS_OK(status)) {
6302 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6306 /* Ensure st_size == 0 */
6307 status = cli_posix_stat(cli1, fname, &sbuf);
6308 if (!NT_STATUS_IS_OK(status)) {
6309 printf("stat failed (%s)\n", nt_errstr(status));
6313 if (sbuf.st_ex_size != 0) {
6314 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
6318 status = cli_close(cli1, fnum1);
6319 if (!NT_STATUS_IS_OK(status)) {
6320 printf("close failed (%s)\n", nt_errstr(status));
6324 status = cli_posix_unlink(cli1, fname);
6325 if (!NT_STATUS_IS_OK(status)) {
6326 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
6330 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
6331 if (!NT_STATUS_IS_OK(status)) {
6332 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
6333 dname, nt_errstr(status));
6337 cli_close(cli1, fnum1);
6339 /* What happens when we try and POSIX open a directory for write ? */
6340 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
6341 if (NT_STATUS_IS_OK(status)) {
6342 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
6345 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
6346 NT_STATUS_FILE_IS_A_DIRECTORY)) {
6351 /* Create the file. */
6352 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
6354 if (!NT_STATUS_IS_OK(status)) {
6355 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
6359 /* Write some data into it. */
6360 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
6362 if (!NT_STATUS_IS_OK(status)) {
6363 printf("cli_write failed: %s\n", nt_errstr(status));
6367 cli_close(cli1, fnum1);
6369 /* Now create a hardlink. */
6370 status = cli_posix_hardlink(cli1, fname, hname);
6371 if (!NT_STATUS_IS_OK(status)) {
6372 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
6376 /* Now create a symlink. */
6377 status = cli_posix_symlink(cli1, fname, sname);
6378 if (!NT_STATUS_IS_OK(status)) {
6379 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
6383 /* Open the hardlink for read. */
6384 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
6385 if (!NT_STATUS_IS_OK(status)) {
6386 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
6390 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
6391 if (!NT_STATUS_IS_OK(status)) {
6392 printf("POSIX read of %s failed (%s)\n", hname,
6395 } else if (nread != 10) {
6396 printf("POSIX read of %s failed. Received %ld, expected %d\n",
6397 hname, (unsigned long)nread, 10);
6401 if (memcmp(buf, "TEST DATA\n", 10)) {
6402 printf("invalid data read from hardlink\n");
6406 /* Do a POSIX lock/unlock. */
6407 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
6408 if (!NT_STATUS_IS_OK(status)) {
6409 printf("POSIX lock failed %s\n", nt_errstr(status));
6413 /* Punch a hole in the locked area. */
6414 status = cli_posix_unlock(cli1, fnum1, 10, 80);
6415 if (!NT_STATUS_IS_OK(status)) {
6416 printf("POSIX unlock failed %s\n", nt_errstr(status));
6420 cli_close(cli1, fnum1);
6422 /* Open the symlink for read - this should fail. A POSIX
6423 client should not be doing opens on a symlink. */
6424 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
6425 if (NT_STATUS_IS_OK(status)) {
6426 printf("POSIX open of %s succeeded (should have failed)\n", sname);
6429 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
6430 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
6431 printf("POSIX open of %s should have failed "
6432 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
6433 "failed with %s instead.\n",
6434 sname, nt_errstr(status));
6439 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
6440 if (!NT_STATUS_IS_OK(status)) {
6441 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
6445 if (strcmp(namebuf, fname) != 0) {
6446 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
6447 sname, fname, namebuf);
6451 status = cli_posix_rmdir(cli1, dname);
6452 if (!NT_STATUS_IS_OK(status)) {
6453 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
6457 /* Check directory opens with a specific permission. */
6458 status = cli_posix_mkdir(cli1, dname, 0700);
6459 if (!NT_STATUS_IS_OK(status)) {
6460 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
6464 /* Ensure st_mode == 0700 */
6465 status = cli_posix_stat(cli1, dname, &sbuf);
6466 if (!NT_STATUS_IS_OK(status)) {
6467 printf("stat failed (%s)\n", nt_errstr(status));
6471 if ((sbuf.st_ex_mode & 07777) != 0700) {
6472 printf("posix_mkdir - bad permissions 0%o != 0700\n",
6473 (unsigned int)(sbuf.st_ex_mode & 07777));
6478 * Now create a Windows file, and attempt a POSIX unlink.
6479 * This should fail with a sharing violation but due to:
6481 * [Bug 9571] Unlink after open causes smbd to panic
6483 * ensure we've fixed the lock ordering violation.
6486 status = cli_ntcreate(cli1, fname_windows, 0,
6487 FILE_READ_DATA|FILE_WRITE_DATA, 0,
6488 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6490 0x0, 0x0, &fnum2, NULL);
6491 if (!NT_STATUS_IS_OK(status)) {
6492 printf("Windows create of %s failed (%s)\n", fname_windows,
6497 /* Now try posix_unlink. */
6498 status = cli_posix_unlink(cli1, fname_windows);
6499 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6500 printf("POSIX unlink of %s should fail "
6501 "with NT_STATUS_SHARING_VIOLATION "
6502 "got %s instead !\n",
6508 cli_close(cli1, fnum2);
6510 printf("Simple POSIX open test passed\n");
6515 if (fnum1 != (uint16_t)-1) {
6516 cli_close(cli1, fnum1);
6517 fnum1 = (uint16_t)-1;
6520 if (fnum2 != (uint16_t)-1) {
6521 cli_close(cli1, fnum2);
6522 fnum2 = (uint16_t)-1;
6525 cli_setatr(cli1, sname, 0, 0);
6526 cli_posix_unlink(cli1, sname);
6527 cli_setatr(cli1, hname, 0, 0);
6528 cli_posix_unlink(cli1, hname);
6529 cli_setatr(cli1, fname, 0, 0);
6530 cli_posix_unlink(cli1, fname);
6531 cli_setatr(cli1, dname, 0, 0);
6532 cli_posix_rmdir(cli1, dname);
6533 cli_setatr(cli1, fname_windows, 0, 0);
6534 cli_posix_unlink(cli1, fname_windows);
6536 if (!torture_close_connection(cli1)) {
6544 Test POSIX and Windows ACLs are rejected on symlinks.
6546 static bool run_acl_symlink_test(int dummy)
6548 static struct cli_state *cli;
6549 const char *fname = "posix_file";
6550 const char *sname = "posix_symlink";
6551 uint16_t fnum = (uint16_t)-1;
6552 bool correct = false;
6554 char *posix_acl = NULL;
6555 size_t posix_acl_len = 0;
6556 char *posix_acl_sym = NULL;
6557 size_t posix_acl_len_sym = 0;
6558 struct security_descriptor *sd = NULL;
6559 struct security_descriptor *sd_sym = NULL;
6560 TALLOC_CTX *frame = NULL;
6562 frame = talloc_stackframe();
6564 printf("Starting acl symlink test\n");
6566 if (!torture_open_connection(&cli, 0)) {
6571 smbXcli_conn_set_sockopt(cli->conn, sockops);
6573 status = torture_setup_unix_extensions(cli);
6574 if (!NT_STATUS_IS_OK(status)) {
6579 cli_setatr(cli, fname, 0, 0);
6580 cli_posix_unlink(cli, fname);
6581 cli_setatr(cli, sname, 0, 0);
6582 cli_posix_unlink(cli, sname);
6584 status = cli_ntcreate(cli,
6587 READ_CONTROL_ACCESS,
6589 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6596 if (!NT_STATUS_IS_OK(status)) {
6597 printf("cli_ntcreate of %s failed (%s)\n",
6603 /* Get the Windows ACL on the file. */
6604 status = cli_query_secdesc(cli,
6608 if (!NT_STATUS_IS_OK(status)) {
6609 printf("cli_query_secdesc failed (%s)\n",
6614 /* Get the POSIX ACL on the file. */
6615 status = cli_posix_getacl(cli,
6621 if (!NT_STATUS_IS_OK(status)) {
6622 printf("cli_posix_getacl failed (%s)\n",
6627 status = cli_close(cli, fnum);
6628 if (!NT_STATUS_IS_OK(status)) {
6629 printf("close failed (%s)\n", nt_errstr(status));
6632 fnum = (uint16_t)-1;
6634 /* Now create a symlink. */
6635 status = cli_posix_symlink(cli, fname, sname);
6636 if (!NT_STATUS_IS_OK(status)) {
6637 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6644 /* Open a handle on the symlink. */
6645 status = cli_ntcreate(cli,
6648 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
6650 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6657 if (!NT_STATUS_IS_OK(status)) {
6658 printf("cli_posix_open of %s failed (%s)\n",
6664 /* Get the Windows ACL on the symlink handle. Should fail */
6665 status = cli_query_secdesc(cli,
6670 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6671 printf("cli_query_secdesc on a symlink gave %s. "
6672 "Should be NT_STATUS_ACCESS_DENIED.\n",
6677 /* Get the POSIX ACL on the symlink pathname. Should fail. */
6678 status = cli_posix_getacl(cli,
6684 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6685 printf("cli_posix_getacl on a symlink gave %s. "
6686 "Should be NT_STATUS_ACCESS_DENIED.\n",
6691 /* Set the Windows ACL on the symlink handle. Should fail */
6692 status = cli_set_security_descriptor(cli,
6697 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6698 printf("cli_query_secdesc on a symlink gave %s. "
6699 "Should be NT_STATUS_ACCESS_DENIED.\n",
6704 /* Set the POSIX ACL on the symlink pathname. Should fail. */
6705 status = cli_posix_setacl(cli,
6710 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6711 printf("cli_posix_getacl on a symlink gave %s. "
6712 "Should be NT_STATUS_ACCESS_DENIED.\n",
6717 printf("ACL symlink test passed\n");
6722 if (fnum != (uint16_t)-1) {
6723 cli_close(cli, fnum);
6724 fnum = (uint16_t)-1;
6727 cli_setatr(cli, sname, 0, 0);
6728 cli_posix_unlink(cli, sname);
6729 cli_setatr(cli, fname, 0, 0);
6730 cli_posix_unlink(cli, fname);
6732 if (!torture_close_connection(cli)) {
6741 Test POSIX can delete a file containing streams.
6743 static bool run_posix_stream_delete(int dummy)
6745 struct cli_state *cli1 = NULL;
6746 struct cli_state *cli2 = NULL;
6747 const char *fname = "streamfile";
6748 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6749 uint16_t fnum1 = (uint16_t)-1;
6750 bool correct = false;
6752 TALLOC_CTX *frame = NULL;
6754 frame = talloc_stackframe();
6756 printf("Starting POSIX stream delete test\n");
6758 if (!torture_open_connection(&cli1, 0) ||
6759 !torture_open_connection(&cli2, 1)) {
6764 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6765 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6767 status = torture_setup_unix_extensions(cli2);
6768 if (!NT_STATUS_IS_OK(status)) {
6772 cli_setatr(cli1, fname, 0, 0);
6773 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6775 /* Create the file. */
6776 status = cli_ntcreate(cli1,
6779 READ_CONTROL_ACCESS,
6781 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6788 if (!NT_STATUS_IS_OK(status)) {
6789 printf("cli_ntcreate of %s failed (%s)\n",
6795 status = cli_close(cli1, fnum1);
6796 if (!NT_STATUS_IS_OK(status)) {
6797 printf("cli_close of %s failed (%s)\n",
6802 fnum1 = (uint16_t)-1;
6804 /* Now create the stream. */
6805 status = cli_ntcreate(cli1,
6810 FILE_SHARE_READ|FILE_SHARE_WRITE,
6817 if (!NT_STATUS_IS_OK(status)) {
6818 printf("cli_ntcreate of %s failed (%s)\n",
6824 /* Leave the stream handle open... */
6826 /* POSIX unlink should fail. */
6827 status = cli_posix_unlink(cli2, fname);
6828 if (NT_STATUS_IS_OK(status)) {
6829 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6834 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6835 printf("cli_posix_unlink of %s failed with (%s) "
6836 "should have been NT_STATUS_SHARING_VIOLATION\n",
6842 /* Close the stream handle. */
6843 status = cli_close(cli1, fnum1);
6844 if (!NT_STATUS_IS_OK(status)) {
6845 printf("cli_close of %s failed (%s)\n",
6850 fnum1 = (uint16_t)-1;
6852 /* POSIX unlink after stream handle closed should succeed. */
6853 status = cli_posix_unlink(cli2, fname);
6854 if (!NT_STATUS_IS_OK(status)) {
6855 printf("cli_posix_unlink of %s failed (%s)\n",
6861 printf("POSIX stream delete test passed\n");
6866 if (fnum1 != (uint16_t)-1) {
6867 cli_close(cli1, fnum1);
6868 fnum1 = (uint16_t)-1;
6871 cli_setatr(cli1, fname, 0, 0);
6872 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6874 if (!torture_close_connection(cli1)) {
6877 if (!torture_close_connection(cli2)) {
6886 Test setting EA's are rejected on symlinks.
6888 static bool run_ea_symlink_test(int dummy)
6890 static struct cli_state *cli;
6891 const char *fname = "posix_file_ea";
6892 const char *sname = "posix_symlink_ea";
6893 const char *ea_name = "testea_name";
6894 const char *ea_value = "testea_value";
6895 uint16_t fnum = (uint16_t)-1;
6896 bool correct = false;
6899 struct ea_struct *eas = NULL;
6900 TALLOC_CTX *frame = NULL;
6902 frame = talloc_stackframe();
6904 printf("Starting EA symlink test\n");
6906 if (!torture_open_connection(&cli, 0)) {
6911 smbXcli_conn_set_sockopt(cli->conn, sockops);
6913 status = torture_setup_unix_extensions(cli);
6914 if (!NT_STATUS_IS_OK(status)) {
6919 cli_setatr(cli, fname, 0, 0);
6920 cli_posix_unlink(cli, fname);
6921 cli_setatr(cli, sname, 0, 0);
6922 cli_posix_unlink(cli, sname);
6924 status = cli_ntcreate(cli,
6927 READ_CONTROL_ACCESS,
6929 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6936 if (!NT_STATUS_IS_OK(status)) {
6937 printf("cli_ntcreate of %s failed (%s)\n",
6943 status = cli_close(cli, fnum);
6944 if (!NT_STATUS_IS_OK(status)) {
6945 printf("close failed (%s)\n",
6949 fnum = (uint16_t)-1;
6951 /* Set an EA on the path. */
6952 status = cli_set_ea_path(cli,
6956 strlen(ea_value)+1);
6958 if (!NT_STATUS_IS_OK(status)) {
6959 printf("cli_set_ea_path failed (%s)\n",
6964 /* Now create a symlink. */
6965 status = cli_posix_symlink(cli, fname, sname);
6966 if (!NT_STATUS_IS_OK(status)) {
6967 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6974 /* Get the EA list on the path. Should return value set. */
6975 status = cli_get_ea_list_path(cli,
6981 if (!NT_STATUS_IS_OK(status)) {
6982 printf("cli_get_ea_list_path failed (%s)\n",
6987 /* Ensure the EA we set is there. */
6988 for (i=0; i<num_eas; i++) {
6989 if (strcmp(eas[i].name, ea_name) == 0 &&
6990 eas[i].value.length == strlen(ea_value)+1 &&
6991 memcmp(eas[i].value.data,
6993 eas[i].value.length) == 0) {
6999 printf("Didn't find EA on pathname %s\n",
7007 /* Get the EA list on the symlink. Should return empty list. */
7008 status = cli_get_ea_list_path(cli,
7014 if (!NT_STATUS_IS_OK(status)) {
7015 printf("cli_get_ea_list_path failed (%s)\n",
7021 printf("cli_get_ea_list_path failed (%s)\n",
7026 /* Set an EA on the symlink. Should fail. */
7027 status = cli_set_ea_path(cli,
7031 strlen(ea_value)+1);
7033 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7034 printf("cli_set_ea_path on a symlink gave %s. "
7035 "Should be NT_STATUS_ACCESS_DENIED.\n",
7040 printf("EA symlink test passed\n");
7045 if (fnum != (uint16_t)-1) {
7046 cli_close(cli, fnum);
7047 fnum = (uint16_t)-1;
7050 cli_setatr(cli, sname, 0, 0);
7051 cli_posix_unlink(cli, sname);
7052 cli_setatr(cli, fname, 0, 0);
7053 cli_posix_unlink(cli, fname);
7055 if (!torture_close_connection(cli)) {
7064 Test POSIX locks are OFD-locks.
7066 static bool run_posix_ofd_lock_test(int dummy)
7068 static struct cli_state *cli;
7069 const char *fname = "posix_file";
7070 uint16_t fnum1 = (uint16_t)-1;
7071 uint16_t fnum2 = (uint16_t)-1;
7072 bool correct = false;
7074 TALLOC_CTX *frame = NULL;
7076 frame = talloc_stackframe();
7078 printf("Starting POSIX ofd-lock test\n");
7080 if (!torture_open_connection(&cli, 0)) {
7085 smbXcli_conn_set_sockopt(cli->conn, sockops);
7087 status = torture_setup_unix_extensions(cli);
7088 if (!NT_STATUS_IS_OK(status)) {
7093 cli_setatr(cli, fname, 0, 0);
7094 cli_posix_unlink(cli, fname);
7096 /* Open the file twice. */
7097 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
7099 if (!NT_STATUS_IS_OK(status)) {
7100 printf("First POSIX open of %s failed\n", fname);
7104 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
7105 if (!NT_STATUS_IS_OK(status)) {
7106 printf("First POSIX open of %s failed\n", fname);
7110 /* Set a 0-50 lock on fnum1. */
7111 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7112 if (!NT_STATUS_IS_OK(status)) {
7113 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
7117 /* Set a 60-100 lock on fnum2. */
7118 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
7119 if (!NT_STATUS_IS_OK(status)) {
7120 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
7124 /* close fnum1 - 0-50 lock should go away. */
7125 status = cli_close(cli, fnum1);
7126 if (!NT_STATUS_IS_OK(status)) {
7127 printf("close failed (%s)\n",
7131 fnum1 = (uint16_t)-1;
7133 /* Change the lock context. */
7134 cli_setpid(cli, cli_getpid(cli) + 1);
7136 /* Re-open fnum1. */
7137 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
7138 if (!NT_STATUS_IS_OK(status)) {
7139 printf("Third POSIX open of %s failed\n", fname);
7143 /* 60-100 lock should still be there. */
7144 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
7145 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
7146 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
7150 /* 0-50 lock should be gone. */
7151 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
7152 if (!NT_STATUS_IS_OK(status)) {
7153 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
7157 printf("POSIX OFD lock test passed\n");
7162 if (fnum1 != (uint16_t)-1) {
7163 cli_close(cli, fnum1);
7164 fnum1 = (uint16_t)-1;
7166 if (fnum2 != (uint16_t)-1) {
7167 cli_close(cli, fnum2);
7168 fnum2 = (uint16_t)-1;
7171 cli_setatr(cli, fname, 0, 0);
7172 cli_posix_unlink(cli, fname);
7174 if (!torture_close_connection(cli)) {
7182 static uint32_t open_attrs_table[] = {
7183 FILE_ATTRIBUTE_NORMAL,
7184 FILE_ATTRIBUTE_ARCHIVE,
7185 FILE_ATTRIBUTE_READONLY,
7186 FILE_ATTRIBUTE_HIDDEN,
7187 FILE_ATTRIBUTE_SYSTEM,
7189 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
7190 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
7191 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
7192 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7193 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7194 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7196 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
7197 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
7198 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
7199 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
7202 struct trunc_open_results {
7205 uint32_t trunc_attr;
7206 uint32_t result_attr;
7209 static struct trunc_open_results attr_results[] = {
7210 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7211 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7212 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7213 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
7214 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
7215 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
7216 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7217 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7218 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7219 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7220 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7221 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
7222 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7223 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7224 { 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 },
7225 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7226 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7227 { 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 },
7228 { 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 },
7229 { 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 },
7230 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7231 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
7232 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
7233 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7234 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
7235 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
7238 static bool run_openattrtest(int dummy)
7240 static struct cli_state *cli1;
7241 const char *fname = "\\openattr.file";
7243 bool correct = True;
7245 unsigned int i, j, k, l;
7248 printf("starting open attr test\n");
7250 if (!torture_open_connection(&cli1, 0)) {
7254 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7256 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
7257 cli_setatr(cli1, fname, 0, 0);
7258 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7260 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
7261 open_attrs_table[i], FILE_SHARE_NONE,
7262 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
7263 if (!NT_STATUS_IS_OK(status)) {
7264 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7268 status = cli_close(cli1, fnum1);
7269 if (!NT_STATUS_IS_OK(status)) {
7270 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
7274 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
7275 status = cli_ntcreate(cli1, fname, 0,
7276 FILE_READ_DATA|FILE_WRITE_DATA,
7277 open_attrs_table[j],
7278 FILE_SHARE_NONE, FILE_OVERWRITE,
7279 0, 0, &fnum1, NULL);
7280 if (!NT_STATUS_IS_OK(status)) {
7281 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7282 if (attr_results[l].num == k) {
7283 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
7284 k, open_attrs_table[i],
7285 open_attrs_table[j],
7286 fname, NT_STATUS_V(status), nt_errstr(status));
7291 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
7292 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
7293 k, open_attrs_table[i], open_attrs_table[j],
7298 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
7304 status = cli_close(cli1, fnum1);
7305 if (!NT_STATUS_IS_OK(status)) {
7306 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
7310 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
7311 if (!NT_STATUS_IS_OK(status)) {
7312 printf("getatr(2) failed (%s)\n", nt_errstr(status));
7317 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
7318 k, open_attrs_table[i], open_attrs_table[j], attr );
7321 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
7322 if (attr_results[l].num == k) {
7323 if (attr != attr_results[l].result_attr ||
7324 open_attrs_table[i] != attr_results[l].init_attr ||
7325 open_attrs_table[j] != attr_results[l].trunc_attr) {
7326 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
7327 open_attrs_table[i],
7328 open_attrs_table[j],
7330 attr_results[l].result_attr);
7340 cli_setatr(cli1, fname, 0, 0);
7341 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7343 printf("open attr test %s.\n", correct ? "passed" : "failed");
7345 if (!torture_close_connection(cli1)) {
7351 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
7352 const char *name, void *state)
7354 int *matched = (int *)state;
7355 if (matched != NULL) {
7358 return NT_STATUS_OK;
7362 test directory listing speed
7364 static bool run_dirtest(int dummy)
7367 static struct cli_state *cli;
7369 struct timeval core_start;
7370 bool correct = True;
7373 printf("starting directory test\n");
7375 if (!torture_open_connection(&cli, 0)) {
7379 smbXcli_conn_set_sockopt(cli->conn, sockops);
7382 for (i=0;i<torture_numops;i++) {
7384 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7385 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
7386 fprintf(stderr,"Failed to open %s\n", fname);
7389 cli_close(cli, fnum);
7392 core_start = timeval_current();
7395 cli_list(cli, "a*.*", 0, list_fn, &matched);
7396 printf("Matched %d\n", matched);
7399 cli_list(cli, "b*.*", 0, list_fn, &matched);
7400 printf("Matched %d\n", matched);
7403 cli_list(cli, "xyzabc", 0, list_fn, &matched);
7404 printf("Matched %d\n", matched);
7406 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
7409 for (i=0;i<torture_numops;i++) {
7411 slprintf(fname, sizeof(fname), "\\%x", (int)random());
7412 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7415 if (!torture_close_connection(cli)) {
7419 printf("finished dirtest\n");
7424 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
7427 struct cli_state *pcli = (struct cli_state *)state;
7429 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
7431 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7432 return NT_STATUS_OK;
7434 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7435 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
7436 printf("del_fn: failed to rmdir %s\n,", fname );
7438 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
7439 printf("del_fn: failed to unlink %s\n,", fname );
7441 return NT_STATUS_OK;
7446 sees what IOCTLs are supported
7448 bool torture_ioctl_test(int dummy)
7450 static struct cli_state *cli;
7451 uint16_t device, function;
7453 const char *fname = "\\ioctl.dat";
7457 if (!torture_open_connection(&cli, 0)) {
7461 printf("starting ioctl test\n");
7463 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7465 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7466 if (!NT_STATUS_IS_OK(status)) {
7467 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
7471 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
7472 printf("ioctl device info: %s\n", nt_errstr(status));
7474 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
7475 printf("ioctl job info: %s\n", nt_errstr(status));
7477 for (device=0;device<0x100;device++) {
7478 printf("ioctl test with device = 0x%x\n", device);
7479 for (function=0;function<0x100;function++) {
7480 uint32_t code = (device<<16) | function;
7482 status = cli_raw_ioctl(cli, fnum, code, &blob);
7484 if (NT_STATUS_IS_OK(status)) {
7485 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
7487 data_blob_free(&blob);
7492 if (!torture_close_connection(cli)) {
7501 tries varients of chkpath
7503 bool torture_chkpath_test(int dummy)
7505 static struct cli_state *cli;
7510 if (!torture_open_connection(&cli, 0)) {
7514 printf("starting chkpath test\n");
7516 /* cleanup from an old run */
7517 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7518 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7519 cli_rmdir(cli, "\\chkpath.dir");
7521 status = cli_mkdir(cli, "\\chkpath.dir");
7522 if (!NT_STATUS_IS_OK(status)) {
7523 printf("mkdir1 failed : %s\n", nt_errstr(status));
7527 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
7528 if (!NT_STATUS_IS_OK(status)) {
7529 printf("mkdir2 failed : %s\n", nt_errstr(status));
7533 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
7535 if (!NT_STATUS_IS_OK(status)) {
7536 printf("open1 failed (%s)\n", nt_errstr(status));
7539 cli_close(cli, fnum);
7541 status = cli_chkpath(cli, "\\chkpath.dir");
7542 if (!NT_STATUS_IS_OK(status)) {
7543 printf("chkpath1 failed: %s\n", nt_errstr(status));
7547 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
7548 if (!NT_STATUS_IS_OK(status)) {
7549 printf("chkpath2 failed: %s\n", nt_errstr(status));
7553 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
7554 if (!NT_STATUS_IS_OK(status)) {
7555 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7556 NT_STATUS_NOT_A_DIRECTORY);
7558 printf("* chkpath on a file should fail\n");
7562 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
7563 if (!NT_STATUS_IS_OK(status)) {
7564 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
7565 NT_STATUS_OBJECT_NAME_NOT_FOUND);
7567 printf("* chkpath on a non existent file should fail\n");
7571 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
7572 if (!NT_STATUS_IS_OK(status)) {
7573 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
7574 NT_STATUS_OBJECT_PATH_NOT_FOUND);
7576 printf("* chkpath on a non existent component should fail\n");
7580 cli_rmdir(cli, "\\chkpath.dir\\dir2");
7581 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7582 cli_rmdir(cli, "\\chkpath.dir");
7584 if (!torture_close_connection(cli)) {
7591 static bool run_eatest(int dummy)
7593 static struct cli_state *cli;
7594 const char *fname = "\\eatest.txt";
7595 bool correct = True;
7599 struct ea_struct *ea_list = NULL;
7600 TALLOC_CTX *mem_ctx = talloc_init("eatest");
7603 printf("starting eatest\n");
7605 if (!torture_open_connection(&cli, 0)) {
7606 talloc_destroy(mem_ctx);
7610 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7612 status = cli_ntcreate(cli, fname, 0,
7613 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7614 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
7615 0x4044, 0, &fnum, NULL);
7616 if (!NT_STATUS_IS_OK(status)) {
7617 printf("open failed - %s\n", nt_errstr(status));
7618 talloc_destroy(mem_ctx);
7622 for (i = 0; i < 10; i++) {
7623 fstring ea_name, ea_val;
7625 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
7626 memset(ea_val, (char)i+1, i+1);
7627 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
7628 if (!NT_STATUS_IS_OK(status)) {
7629 printf("ea_set of name %s failed - %s\n", ea_name,
7631 talloc_destroy(mem_ctx);
7636 cli_close(cli, fnum);
7637 for (i = 0; i < 10; i++) {
7638 fstring ea_name, ea_val;
7640 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
7641 memset(ea_val, (char)i+1, i+1);
7642 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
7643 if (!NT_STATUS_IS_OK(status)) {
7644 printf("ea_set of name %s failed - %s\n", ea_name,
7646 talloc_destroy(mem_ctx);
7651 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7652 if (!NT_STATUS_IS_OK(status)) {
7653 printf("ea_get list failed - %s\n", nt_errstr(status));
7657 printf("num_eas = %d\n", (int)num_eas);
7659 if (num_eas != 20) {
7660 printf("Should be 20 EA's stored... failing.\n");
7664 for (i = 0; i < num_eas; i++) {
7665 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7666 dump_data(0, ea_list[i].value.data,
7667 ea_list[i].value.length);
7670 /* Setting EA's to zero length deletes them. Test this */
7671 printf("Now deleting all EA's - case indepenent....\n");
7674 cli_set_ea_path(cli, fname, "", "", 0);
7676 for (i = 0; i < 20; i++) {
7678 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
7679 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
7680 if (!NT_STATUS_IS_OK(status)) {
7681 printf("ea_set of name %s failed - %s\n", ea_name,
7683 talloc_destroy(mem_ctx);
7689 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
7690 if (!NT_STATUS_IS_OK(status)) {
7691 printf("ea_get list failed - %s\n", nt_errstr(status));
7695 printf("num_eas = %d\n", (int)num_eas);
7696 for (i = 0; i < num_eas; i++) {
7697 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
7698 dump_data(0, ea_list[i].value.data,
7699 ea_list[i].value.length);
7703 printf("deleting EA's failed.\n");
7707 /* Try and delete a non existent EA. */
7708 status = cli_set_ea_path(cli, fname, "foo", "", 0);
7709 if (!NT_STATUS_IS_OK(status)) {
7710 printf("deleting non-existent EA 'foo' should succeed. %s\n",
7715 talloc_destroy(mem_ctx);
7716 if (!torture_close_connection(cli)) {
7723 static bool run_dirtest1(int dummy)
7726 static struct cli_state *cli;
7729 bool correct = True;
7731 printf("starting directory test\n");
7733 if (!torture_open_connection(&cli, 0)) {
7737 smbXcli_conn_set_sockopt(cli->conn, sockops);
7739 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7740 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7741 cli_rmdir(cli, "\\LISTDIR");
7742 cli_mkdir(cli, "\\LISTDIR");
7744 /* Create 1000 files and 1000 directories. */
7745 for (i=0;i<1000;i++) {
7747 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7748 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7749 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7750 0, 0, &fnum, NULL))) {
7751 fprintf(stderr,"Failed to open %s\n", fname);
7754 cli_close(cli, fnum);
7756 for (i=0;i<1000;i++) {
7758 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7759 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7760 fprintf(stderr,"Failed to open %s\n", fname);
7765 /* Now ensure that doing an old list sees both files and directories. */
7767 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7768 printf("num_seen = %d\n", num_seen );
7769 /* We should see 100 files + 1000 directories + . and .. */
7770 if (num_seen != 2002)
7773 /* Ensure if we have the "must have" bits we only see the
7777 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7778 printf("num_seen = %d\n", num_seen );
7779 if (num_seen != 1002)
7783 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7784 printf("num_seen = %d\n", num_seen );
7785 if (num_seen != 1000)
7788 /* Delete everything. */
7789 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7790 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7791 cli_rmdir(cli, "\\LISTDIR");
7794 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7795 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7796 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7799 if (!torture_close_connection(cli)) {
7803 printf("finished dirtest1\n");
7808 static bool run_error_map_extract(int dummy) {
7810 static struct cli_state *c_dos;
7811 static struct cli_state *c_nt;
7823 /* NT-Error connection */
7825 disable_spnego = true;
7826 if (!(c_nt = open_nbt_connection())) {
7827 disable_spnego = false;
7830 disable_spnego = false;
7832 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7835 if (!NT_STATUS_IS_OK(status)) {
7836 printf("%s rejected the NT-error negprot (%s)\n", host,
7842 status = cli_session_setup_anon(c_nt);
7843 if (!NT_STATUS_IS_OK(status)) {
7844 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7848 /* DOS-Error connection */
7850 disable_spnego = true;
7851 force_dos_errors = true;
7852 if (!(c_dos = open_nbt_connection())) {
7853 disable_spnego = false;
7854 force_dos_errors = false;
7857 disable_spnego = false;
7858 force_dos_errors = false;
7860 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7862 if (!NT_STATUS_IS_OK(status)) {
7863 printf("%s rejected the DOS-error negprot (%s)\n", host,
7865 cli_shutdown(c_dos);
7869 status = cli_session_setup_anon(c_dos);
7870 if (!NT_STATUS_IS_OK(status)) {
7871 printf("%s rejected the DOS-error initial session setup (%s)\n",
7872 host, nt_errstr(status));
7876 c_nt->map_dos_errors = false;
7877 c_dos->map_dos_errors = false;
7879 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7880 struct cli_credentials *user_creds = NULL;
7882 fstr_sprintf(user, "%X", error);
7884 user_creds = cli_session_creds_init(talloc_tos(),
7889 false, /* use_kerberos */
7890 false, /* fallback_after_kerberos */
7891 false, /* use_ccache */
7892 false); /* password_is_nt_hash */
7893 if (user_creds == NULL) {
7894 printf("cli_session_creds_init(%s) failed\n", user);
7898 status = cli_session_setup_creds(c_nt, user_creds);
7899 if (NT_STATUS_IS_OK(status)) {
7900 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7903 /* Case #1: 32-bit NT errors */
7904 if (!NT_STATUS_IS_DOS(status)) {
7907 printf("/** Dos error on NT connection! (%s) */\n",
7909 nt_status = NT_STATUS(0xc0000000);
7912 status = cli_session_setup_creds(c_dos, user_creds);
7913 if (NT_STATUS_IS_OK(status)) {
7914 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7917 /* Case #1: 32-bit NT errors */
7918 if (NT_STATUS_IS_DOS(status)) {
7919 printf("/** NT error on DOS connection! (%s) */\n",
7921 errnum = errclass = 0;
7923 errclass = NT_STATUS_DOS_CLASS(status);
7924 errnum = NT_STATUS_DOS_CODE(status);
7927 if (NT_STATUS_V(nt_status) != error) {
7928 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7929 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
7930 get_nt_error_c_code(talloc_tos(), nt_status));
7933 printf("\t{%s,\t%s,\t%s},\n",
7934 smb_dos_err_class(errclass),
7935 smb_dos_err_name(errclass, errnum),
7936 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7938 TALLOC_FREE(user_creds);
7943 static bool run_sesssetup_bench(int dummy)
7945 static struct cli_state *c;
7946 const char *fname = "\\file.dat";
7951 if (!torture_open_connection(&c, 0)) {
7955 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7956 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7957 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7958 if (!NT_STATUS_IS_OK(status)) {
7959 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7963 for (i=0; i<torture_numops; i++) {
7964 status = cli_session_setup_creds(c, torture_creds);
7965 if (!NT_STATUS_IS_OK(status)) {
7966 d_printf("(%s) cli_session_setup_creds failed: %s\n",
7967 __location__, nt_errstr(status));
7971 d_printf("\r%d ", (int)cli_state_get_uid(c));
7973 status = cli_ulogoff(c);
7974 if (!NT_STATUS_IS_OK(status)) {
7975 d_printf("(%s) cli_ulogoff failed: %s\n",
7976 __location__, nt_errstr(status));
7984 static bool subst_test(const char *str, const char *user, const char *domain,
7985 uid_t uid, gid_t gid, const char *expected)
7990 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7992 if (strcmp(subst, expected) != 0) {
7993 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7994 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
8003 static void chain1_open_completion(struct tevent_req *req)
8007 status = cli_openx_recv(req, &fnum);
8010 d_printf("cli_openx_recv returned %s: %d\n",
8012 NT_STATUS_IS_OK(status) ? fnum : -1);
8015 static void chain1_write_completion(struct tevent_req *req)
8019 status = cli_write_andx_recv(req, &written);
8022 d_printf("cli_write_andx_recv returned %s: %d\n",
8024 NT_STATUS_IS_OK(status) ? (int)written : -1);
8027 static void chain1_close_completion(struct tevent_req *req)
8030 bool *done = (bool *)tevent_req_callback_data_void(req);
8032 status = cli_close_recv(req);
8037 d_printf("cli_close returned %s\n", nt_errstr(status));
8040 static bool run_chain1(int dummy)
8042 struct cli_state *cli1;
8043 struct tevent_context *evt = samba_tevent_context_init(NULL);
8044 struct tevent_req *reqs[3], *smbreqs[3];
8046 const char *str = "foobar";
8049 printf("starting chain1 test\n");
8050 if (!torture_open_connection(&cli1, 0)) {
8054 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8056 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
8057 O_CREAT|O_RDWR, 0, &smbreqs[0]);
8058 if (reqs[0] == NULL) return false;
8059 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
8062 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
8063 (const uint8_t *)str, 0, strlen(str)+1,
8064 smbreqs, 1, &smbreqs[1]);
8065 if (reqs[1] == NULL) return false;
8066 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
8068 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
8069 if (reqs[2] == NULL) return false;
8070 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
8072 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8073 if (!NT_STATUS_IS_OK(status)) {
8078 tevent_loop_once(evt);
8081 torture_close_connection(cli1);
8085 static void chain2_sesssetup_completion(struct tevent_req *req)
8088 status = cli_session_setup_guest_recv(req);
8089 d_printf("sesssetup returned %s\n", nt_errstr(status));
8092 static void chain2_tcon_completion(struct tevent_req *req)
8094 bool *done = (bool *)tevent_req_callback_data_void(req);
8096 status = cli_tcon_andx_recv(req);
8097 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
8101 static bool run_chain2(int dummy)
8103 struct cli_state *cli1;
8104 struct tevent_context *evt = samba_tevent_context_init(NULL);
8105 struct tevent_req *reqs[2], *smbreqs[2];
8108 int flags = CLI_FULL_CONNECTION_FORCE_SMB1;
8110 printf("starting chain2 test\n");
8111 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
8112 port_to_use, SMB_SIGNING_DEFAULT, flags);
8113 if (!NT_STATUS_IS_OK(status)) {
8117 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8119 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
8121 if (reqs[0] == NULL) return false;
8122 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
8124 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
8125 "?????", NULL, 0, &smbreqs[1]);
8126 if (reqs[1] == NULL) return false;
8127 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
8129 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
8130 if (!NT_STATUS_IS_OK(status)) {
8135 tevent_loop_once(evt);
8138 torture_close_connection(cli1);
8143 struct torture_createdel_state {
8144 struct tevent_context *ev;
8145 struct cli_state *cli;
8148 static void torture_createdel_created(struct tevent_req *subreq);
8149 static void torture_createdel_closed(struct tevent_req *subreq);
8151 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
8152 struct tevent_context *ev,
8153 struct cli_state *cli,
8156 struct tevent_req *req, *subreq;
8157 struct torture_createdel_state *state;
8159 req = tevent_req_create(mem_ctx, &state,
8160 struct torture_createdel_state);
8167 subreq = cli_ntcreate_send(
8168 state, ev, cli, name, 0,
8169 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
8170 FILE_ATTRIBUTE_NORMAL,
8171 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
8172 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
8174 if (tevent_req_nomem(subreq, req)) {
8175 return tevent_req_post(req, ev);
8177 tevent_req_set_callback(subreq, torture_createdel_created, req);
8181 static void torture_createdel_created(struct tevent_req *subreq)
8183 struct tevent_req *req = tevent_req_callback_data(
8184 subreq, struct tevent_req);
8185 struct torture_createdel_state *state = tevent_req_data(
8186 req, struct torture_createdel_state);
8190 status = cli_ntcreate_recv(subreq, &fnum, NULL);
8191 TALLOC_FREE(subreq);
8192 if (tevent_req_nterror(req, status)) {
8193 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
8194 nt_errstr(status)));
8198 subreq = cli_close_send(state, state->ev, state->cli, fnum);
8199 if (tevent_req_nomem(subreq, req)) {
8202 tevent_req_set_callback(subreq, torture_createdel_closed, req);
8205 static void torture_createdel_closed(struct tevent_req *subreq)
8207 struct tevent_req *req = tevent_req_callback_data(
8208 subreq, struct tevent_req);
8211 status = cli_close_recv(subreq);
8212 if (tevent_req_nterror(req, status)) {
8213 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
8216 tevent_req_done(req);
8219 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
8221 return tevent_req_simple_recv_ntstatus(req);
8224 struct torture_createdels_state {
8225 struct tevent_context *ev;
8226 struct cli_state *cli;
8227 const char *base_name;
8231 struct tevent_req **reqs;
8234 static void torture_createdels_done(struct tevent_req *subreq);
8236 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
8237 struct tevent_context *ev,
8238 struct cli_state *cli,
8239 const char *base_name,
8243 struct tevent_req *req;
8244 struct torture_createdels_state *state;
8247 req = tevent_req_create(mem_ctx, &state,
8248 struct torture_createdels_state);
8254 state->base_name = talloc_strdup(state, base_name);
8255 if (tevent_req_nomem(state->base_name, req)) {
8256 return tevent_req_post(req, ev);
8258 state->num_files = MAX(num_parallel, num_files);
8260 state->received = 0;
8262 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
8263 if (tevent_req_nomem(state->reqs, req)) {
8264 return tevent_req_post(req, ev);
8267 for (i=0; i<num_parallel; i++) {
8270 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8272 if (tevent_req_nomem(name, req)) {
8273 return tevent_req_post(req, ev);
8275 state->reqs[i] = torture_createdel_send(
8276 state->reqs, state->ev, state->cli, name);
8277 if (tevent_req_nomem(state->reqs[i], req)) {
8278 return tevent_req_post(req, ev);
8280 name = talloc_move(state->reqs[i], &name);
8281 tevent_req_set_callback(state->reqs[i],
8282 torture_createdels_done, req);
8288 static void torture_createdels_done(struct tevent_req *subreq)
8290 struct tevent_req *req = tevent_req_callback_data(
8291 subreq, struct tevent_req);
8292 struct torture_createdels_state *state = tevent_req_data(
8293 req, struct torture_createdels_state);
8294 size_t num_parallel = talloc_array_length(state->reqs);
8299 status = torture_createdel_recv(subreq);
8300 if (!NT_STATUS_IS_OK(status)){
8301 DEBUG(10, ("torture_createdel_recv returned %s\n",
8302 nt_errstr(status)));
8303 TALLOC_FREE(subreq);
8304 tevent_req_nterror(req, status);
8308 for (i=0; i<num_parallel; i++) {
8309 if (subreq == state->reqs[i]) {
8313 if (i == num_parallel) {
8314 DEBUG(10, ("received something we did not send\n"));
8315 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
8318 TALLOC_FREE(state->reqs[i]);
8320 if (state->sent >= state->num_files) {
8321 tevent_req_done(req);
8325 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
8327 if (tevent_req_nomem(name, req)) {
8330 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
8332 if (tevent_req_nomem(state->reqs[i], req)) {
8335 name = talloc_move(state->reqs[i], &name);
8336 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
8340 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
8342 return tevent_req_simple_recv_ntstatus(req);
8345 struct swallow_notify_state {
8346 struct tevent_context *ev;
8347 struct cli_state *cli;
8349 uint32_t completion_filter;
8351 bool (*fn)(uint32_t action, const char *name, void *priv);
8355 static void swallow_notify_done(struct tevent_req *subreq);
8357 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
8358 struct tevent_context *ev,
8359 struct cli_state *cli,
8361 uint32_t completion_filter,
8363 bool (*fn)(uint32_t action,
8368 struct tevent_req *req, *subreq;
8369 struct swallow_notify_state *state;
8371 req = tevent_req_create(mem_ctx, &state,
8372 struct swallow_notify_state);
8379 state->completion_filter = completion_filter;
8380 state->recursive = recursive;
8384 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8385 0xffff, state->completion_filter,
8387 if (tevent_req_nomem(subreq, req)) {
8388 return tevent_req_post(req, ev);
8390 tevent_req_set_callback(subreq, swallow_notify_done, req);
8394 static void swallow_notify_done(struct tevent_req *subreq)
8396 struct tevent_req *req = tevent_req_callback_data(
8397 subreq, struct tevent_req);
8398 struct swallow_notify_state *state = tevent_req_data(
8399 req, struct swallow_notify_state);
8401 uint32_t i, num_changes;
8402 struct notify_change *changes;
8404 status = cli_notify_recv(subreq, state, &num_changes, &changes);
8405 TALLOC_FREE(subreq);
8406 if (!NT_STATUS_IS_OK(status)) {
8407 DEBUG(10, ("cli_notify_recv returned %s\n",
8408 nt_errstr(status)));
8409 tevent_req_nterror(req, status);
8413 for (i=0; i<num_changes; i++) {
8414 state->fn(changes[i].action, changes[i].name, state->priv);
8416 TALLOC_FREE(changes);
8418 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
8419 0xffff, state->completion_filter,
8421 if (tevent_req_nomem(subreq, req)) {
8424 tevent_req_set_callback(subreq, swallow_notify_done, req);
8427 static bool print_notifies(uint32_t action, const char *name, void *priv)
8429 if (DEBUGLEVEL > 5) {
8430 d_printf("%d %s\n", (int)action, name);
8435 static void notify_bench_done(struct tevent_req *req)
8437 int *num_finished = (int *)tevent_req_callback_data_void(req);
8441 static bool run_notify_bench(int dummy)
8443 const char *dname = "\\notify-bench";
8444 struct tevent_context *ev;
8447 struct tevent_req *req1;
8448 struct tevent_req *req2 = NULL;
8449 int i, num_unc_names;
8450 int num_finished = 0;
8452 printf("starting notify-bench test\n");
8454 if (use_multishare_conn) {
8456 unc_list = file_lines_load(multishare_conn_fname,
8457 &num_unc_names, 0, NULL);
8458 if (!unc_list || num_unc_names <= 0) {
8459 d_printf("Failed to load unc names list from '%s'\n",
8460 multishare_conn_fname);
8463 TALLOC_FREE(unc_list);
8468 ev = samba_tevent_context_init(talloc_tos());
8470 d_printf("tevent_context_init failed\n");
8474 for (i=0; i<num_unc_names; i++) {
8475 struct cli_state *cli;
8478 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
8480 if (base_fname == NULL) {
8484 if (!torture_open_connection(&cli, i)) {
8488 status = cli_ntcreate(cli, dname, 0,
8489 MAXIMUM_ALLOWED_ACCESS,
8490 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
8492 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
8495 if (!NT_STATUS_IS_OK(status)) {
8496 d_printf("Could not create %s: %s\n", dname,
8501 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
8502 FILE_NOTIFY_CHANGE_FILE_NAME |
8503 FILE_NOTIFY_CHANGE_DIR_NAME |
8504 FILE_NOTIFY_CHANGE_ATTRIBUTES |
8505 FILE_NOTIFY_CHANGE_LAST_WRITE,
8506 false, print_notifies, NULL);
8508 d_printf("Could not create notify request\n");
8512 req2 = torture_createdels_send(talloc_tos(), ev, cli,
8513 base_fname, 10, torture_numops);
8515 d_printf("Could not create createdels request\n");
8518 TALLOC_FREE(base_fname);
8520 tevent_req_set_callback(req2, notify_bench_done,
8524 while (num_finished < num_unc_names) {
8526 ret = tevent_loop_once(ev);
8528 d_printf("tevent_loop_once failed\n");
8533 if (!tevent_req_poll(req2, ev)) {
8534 d_printf("tevent_req_poll failed\n");
8537 status = torture_createdels_recv(req2);
8538 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
8543 static bool run_mangle1(int dummy)
8545 struct cli_state *cli;
8546 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
8550 time_t change_time, access_time, write_time;
8554 printf("starting mangle1 test\n");
8555 if (!torture_open_connection(&cli, 0)) {
8559 smbXcli_conn_set_sockopt(cli->conn, sockops);
8561 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8562 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8564 if (!NT_STATUS_IS_OK(status)) {
8565 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8568 cli_close(cli, fnum);
8570 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
8571 if (!NT_STATUS_IS_OK(status)) {
8572 d_printf("cli_qpathinfo_alt_name failed: %s\n",
8576 d_printf("alt_name: %s\n", alt_name);
8578 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
8579 if (!NT_STATUS_IS_OK(status)) {
8580 d_printf("cli_openx(%s) failed: %s\n", alt_name,
8584 cli_close(cli, fnum);
8586 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
8587 &write_time, &size, &mode);
8588 if (!NT_STATUS_IS_OK(status)) {
8589 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
8597 static NTSTATUS mangle_illegal_list_shortname_fn(const char *mntpoint,
8598 struct file_info *f,
8602 if (f->short_name == NULL) {
8603 return NT_STATUS_OK;
8606 if (strlen(f->short_name) == 0) {
8607 return NT_STATUS_OK;
8610 printf("unexpected shortname: %s\n", f->short_name);
8612 return NT_STATUS_OBJECT_NAME_INVALID;
8615 static NTSTATUS mangle_illegal_list_name_fn(const char *mntpoint,
8616 struct file_info *f,
8622 printf("name: %s\n", f->name);
8623 fstrcpy(name, f->name);
8624 return NT_STATUS_OK;
8627 static bool run_mangle_illegal(int dummy)
8629 struct cli_state *cli = NULL;
8630 struct cli_state *cli_posix = NULL;
8631 const char *fname = "\\MANGLE_ILLEGAL\\this_is_a_long_fname_to_be_mangled.txt";
8632 const char *illegal_fname = "MANGLE_ILLEGAL/foo:bar";
8633 char *mangled_path = NULL;
8639 printf("starting mangle-illegal test\n");
8641 if (!torture_open_connection(&cli, 0)) {
8645 smbXcli_conn_set_sockopt(cli->conn, sockops);
8647 if (!torture_open_connection(&cli_posix, 0)) {
8651 smbXcli_conn_set_sockopt(cli_posix->conn, sockops);
8653 status = torture_setup_unix_extensions(cli_posix);
8654 if (!NT_STATUS_IS_OK(status)) {
8658 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8659 status = cli_mkdir(cli, "\\MANGLE_ILLEGAL");
8660 if (!NT_STATUS_IS_OK(status)) {
8661 printf("mkdir1 failed : %s\n", nt_errstr(status));
8666 * Create a file with illegal NTFS characters and test that we
8667 * get a usable mangled name
8670 cli_setatr(cli_posix, illegal_fname, 0, 0);
8671 cli_posix_unlink(cli_posix, illegal_fname);
8673 status = cli_posix_open(cli_posix, illegal_fname, O_RDWR|O_CREAT|O_EXCL,
8675 if (!NT_STATUS_IS_OK(status)) {
8676 printf("POSIX create of %s failed (%s)\n",
8677 illegal_fname, nt_errstr(status));
8681 status = cli_close(cli_posix, fnum);
8682 if (!NT_STATUS_IS_OK(status)) {
8683 printf("close failed (%s)\n", nt_errstr(status));
8687 status = cli_list(cli, "\\MANGLE_ILLEGAL\\*", 0, mangle_illegal_list_name_fn, &name);
8688 if (!NT_STATUS_IS_OK(status)) {
8689 d_printf("cli_list failed: %s\n", nt_errstr(status));
8693 mangled_path = talloc_asprintf(talloc_tos(), "\\MANGLE_ILLEGAL\\%s", name);
8694 if (mangled_path == NULL) {
8698 status = cli_openx(cli, mangled_path, O_RDONLY, DENY_NONE, &fnum);
8699 if (!NT_STATUS_IS_OK(status)) {
8700 d_printf("cli_openx(%s) failed: %s\n", mangled_path, nt_errstr(status));
8701 TALLOC_FREE(mangled_path);
8704 TALLOC_FREE(mangled_path);
8705 cli_close(cli, fnum);
8707 cli_setatr(cli_posix, illegal_fname, 0, 0);
8708 cli_posix_unlink(cli_posix, illegal_fname);
8711 * Create a file with a long name and check that we got *no* short name.
8714 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
8715 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8717 if (!NT_STATUS_IS_OK(status)) {
8718 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8721 cli_close(cli, fnum);
8723 status = cli_list(cli, fname, 0, mangle_illegal_list_shortname_fn, &alt_name);
8724 if (!NT_STATUS_IS_OK(status)) {
8725 d_printf("cli_list failed\n");
8729 cli_unlink(cli, fname, 0);
8730 cli_rmdir(cli, "\\MANGLE_ILLEGAL");
8732 if (!torture_close_connection(cli_posix)) {
8736 if (!torture_close_connection(cli)) {
8743 static size_t null_source(uint8_t *buf, size_t n, void *priv)
8745 size_t *to_pull = (size_t *)priv;
8746 size_t thistime = *to_pull;
8748 thistime = MIN(thistime, n);
8749 if (thistime == 0) {
8753 memset(buf, 0, thistime);
8754 *to_pull -= thistime;
8758 static bool run_windows_write(int dummy)
8760 struct cli_state *cli1;
8764 const char *fname = "\\writetest.txt";
8765 struct timeval start_time;
8770 printf("starting windows_write test\n");
8771 if (!torture_open_connection(&cli1, 0)) {
8775 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
8776 if (!NT_STATUS_IS_OK(status)) {
8777 printf("open failed (%s)\n", nt_errstr(status));
8781 smbXcli_conn_set_sockopt(cli1->conn, sockops);
8783 start_time = timeval_current();
8785 for (i=0; i<torture_numops; i++) {
8787 off_t start = i * torture_blocksize;
8788 size_t to_pull = torture_blocksize - 1;
8790 status = cli_writeall(cli1, fnum, 0, &c,
8791 start + torture_blocksize - 1, 1, NULL);
8792 if (!NT_STATUS_IS_OK(status)) {
8793 printf("cli_write failed: %s\n", nt_errstr(status));
8797 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
8798 null_source, &to_pull);
8799 if (!NT_STATUS_IS_OK(status)) {
8800 printf("cli_push returned: %s\n", nt_errstr(status));
8805 seconds = timeval_elapsed(&start_time);
8806 kbytes = (double)torture_blocksize * torture_numops;
8809 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
8810 (double)seconds, (int)(kbytes/seconds));
8814 cli_close(cli1, fnum);
8815 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8816 torture_close_connection(cli1);
8820 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
8822 size_t max_pdu = 0x1FFFF;
8824 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
8828 if (smb1cli_conn_signing_is_active(cli->conn)) {
8832 if (smb1cli_conn_encryption_on(cli->conn)) {
8833 max_pdu = CLI_BUFFER_SIZE;
8836 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
8837 len_requested &= 0xFFFF;
8840 return MIN(len_requested,
8841 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
8844 static bool check_read_call(struct cli_state *cli,
8847 size_t len_requested)
8850 struct tevent_req *subreq = NULL;
8851 ssize_t len_read = 0;
8852 size_t len_expected = 0;
8853 struct tevent_context *ev = NULL;
8855 ev = samba_tevent_context_init(talloc_tos());
8860 subreq = cli_read_andx_send(talloc_tos(),
8867 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
8871 status = cli_read_andx_recv(subreq, &len_read, &buf);
8872 if (!NT_STATUS_IS_OK(status)) {
8873 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
8877 TALLOC_FREE(subreq);
8880 len_expected = calc_expected_return(cli, len_requested);
8882 if (len_expected > 0x10000 && len_read == 0x10000) {
8883 /* Windows servers only return a max of 0x10000,
8884 doesn't matter if you set CAP_LARGE_READX in
8885 the client sessionsetupX call or not. */
8886 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8887 (unsigned int)len_requested);
8888 } else if (len_read != len_expected) {
8889 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8890 (unsigned int)len_requested,
8891 (unsigned int)len_read,
8892 (unsigned int)len_expected);
8895 d_printf("Correct read reply.\n");
8901 /* Test large readX variants. */
8902 static bool large_readx_tests(struct cli_state *cli,
8906 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8907 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8910 /* A read of 0x10000 should return 0x10000 bytes. */
8911 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8914 /* A read of 0x10000 should return 0x10001 bytes. */
8915 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8918 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8919 the requested number of bytes. */
8920 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8923 /* A read of 1MB should return 1MB bytes (on Samba). */
8924 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
8928 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
8931 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
8934 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
8940 static bool run_large_readx(int dummy)
8942 uint8_t *buf = NULL;
8943 struct cli_state *cli1 = NULL;
8944 struct cli_state *cli2 = NULL;
8945 bool correct = false;
8946 const char *fname = "\\large_readx.dat";
8948 uint16_t fnum1 = UINT16_MAX;
8949 uint32_t normal_caps = 0;
8950 size_t file_size = 20*1024*1024;
8951 TALLOC_CTX *frame = talloc_stackframe();
8955 enum smb_signing_setting signing_setting;
8956 enum protocol_types protocol;
8960 .signing_setting = SMB_SIGNING_IF_REQUIRED,
8961 .protocol = PROTOCOL_NT1,
8963 .name = "NT1 - SIGNING_REQUIRED",
8964 .signing_setting = SMB_SIGNING_REQUIRED,
8965 .protocol = PROTOCOL_NT1,
8969 printf("starting large_readx test\n");
8971 if (!torture_open_connection(&cli1, 0)) {
8975 normal_caps = smb1cli_conn_capabilities(cli1->conn);
8977 if (!(normal_caps & CAP_LARGE_READX)) {
8978 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8979 (unsigned int)normal_caps);
8983 /* Create a file of size 4MB. */
8984 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
8985 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8986 0, 0, &fnum1, NULL);
8988 if (!NT_STATUS_IS_OK(status)) {
8989 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8993 /* Write file_size bytes. */
8994 buf = talloc_zero_array(frame, uint8_t, file_size);
8999 status = cli_writeall(cli1,
9006 if (!NT_STATUS_IS_OK(status)) {
9007 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
9011 status = cli_close(cli1, fnum1);
9012 if (!NT_STATUS_IS_OK(status)) {
9013 d_printf("cli_close failed: %s\n", nt_errstr(status));
9019 for (i=0; i < ARRAY_SIZE(runs); i++) {
9020 enum smb_signing_setting saved_signing_setting = signing_state;
9021 uint16_t fnum2 = -1;
9024 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
9026 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
9030 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
9032 signing_state = runs[i].signing_setting;
9033 cli2 = open_nbt_connection();
9034 signing_state = saved_signing_setting;
9039 status = smbXcli_negprot(cli2->conn,
9043 if (!NT_STATUS_IS_OK(status)) {
9047 status = cli_session_setup_creds(cli2, torture_creds);
9048 if (!NT_STATUS_IS_OK(status)) {
9052 status = cli_tree_connect(cli2,
9056 if (!NT_STATUS_IS_OK(status)) {
9060 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
9062 normal_caps = smb1cli_conn_capabilities(cli2->conn);
9064 if (!(normal_caps & CAP_LARGE_READX)) {
9065 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
9066 (unsigned int)normal_caps);
9071 if (force_cli_encryption(cli2, share) == false) {
9074 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
9075 uint16_t major, minor;
9076 uint32_t caplow, caphigh;
9078 status = cli_unix_extensions_version(cli2,
9081 if (!NT_STATUS_IS_OK(status)) {
9086 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
9087 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
9088 0, 0, &fnum2, NULL);
9089 if (!NT_STATUS_IS_OK(status)) {
9090 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
9094 /* All reads must return less than file_size bytes. */
9095 if (!large_readx_tests(cli2, fnum2, buf)) {
9099 status = cli_close(cli2, fnum2);
9100 if (!NT_STATUS_IS_OK(status)) {
9101 d_printf("cli_close failed: %s\n", nt_errstr(status));
9106 if (!torture_close_connection(cli2)) {
9113 printf("Success on large_readx test\n");
9118 if (!torture_close_connection(cli2)) {
9124 if (fnum1 != UINT16_MAX) {
9125 status = cli_close(cli1, fnum1);
9126 if (!NT_STATUS_IS_OK(status)) {
9127 d_printf("cli_close failed: %s\n", nt_errstr(status));
9132 status = cli_unlink(cli1, fname,
9133 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9134 if (!NT_STATUS_IS_OK(status)) {
9135 printf("unlink failed (%s)\n", nt_errstr(status));
9138 if (!torture_close_connection(cli1)) {
9145 printf("finished large_readx test\n");
9149 static bool run_cli_echo(int dummy)
9151 struct cli_state *cli;
9154 printf("starting cli_echo test\n");
9155 if (!torture_open_connection(&cli, 0)) {
9158 smbXcli_conn_set_sockopt(cli->conn, sockops);
9160 status = cli_echo(cli, 5, data_blob_const("hello", 5));
9162 d_printf("cli_echo returned %s\n", nt_errstr(status));
9164 torture_close_connection(cli);
9165 return NT_STATUS_IS_OK(status);
9168 static bool run_uid_regression_test(int dummy)
9170 static struct cli_state *cli;
9173 bool correct = True;
9174 struct smbXcli_tcon *orig_tcon = NULL;
9177 printf("starting uid regression test\n");
9179 if (!torture_open_connection(&cli, 0)) {
9183 smbXcli_conn_set_sockopt(cli->conn, sockops);
9185 /* Ok - now save then logoff our current user. */
9186 old_vuid = cli_state_get_uid(cli);
9188 status = cli_ulogoff(cli);
9189 if (!NT_STATUS_IS_OK(status)) {
9190 d_printf("(%s) cli_ulogoff failed: %s\n",
9191 __location__, nt_errstr(status));
9196 cli_state_set_uid(cli, old_vuid);
9198 /* Try an operation. */
9199 status = cli_mkdir(cli, "\\uid_reg_test");
9200 if (NT_STATUS_IS_OK(status)) {
9201 d_printf("(%s) cli_mkdir succeeded\n",
9206 /* Should be bad uid. */
9207 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
9208 NT_STATUS_USER_SESSION_DELETED)) {
9214 old_cnum = cli_state_get_tid(cli);
9215 orig_tcon = cli_state_save_tcon(cli);
9216 if (orig_tcon == NULL) {
9221 /* Now try a SMBtdis with the invald vuid set to zero. */
9222 cli_state_set_uid(cli, 0);
9224 /* This should succeed. */
9225 status = cli_tdis(cli);
9227 if (NT_STATUS_IS_OK(status)) {
9228 d_printf("First tdis with invalid vuid should succeed.\n");
9230 d_printf("First tdis failed (%s)\n", nt_errstr(status));
9232 cli_state_restore_tcon(cli, orig_tcon);
9236 cli_state_restore_tcon(cli, orig_tcon);
9237 cli_state_set_uid(cli, old_vuid);
9238 cli_state_set_tid(cli, old_cnum);
9240 /* This should fail. */
9241 status = cli_tdis(cli);
9242 if (NT_STATUS_IS_OK(status)) {
9243 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
9247 /* Should be bad tid. */
9248 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
9249 NT_STATUS_NETWORK_NAME_DELETED)) {
9255 cli_rmdir(cli, "\\uid_reg_test");
9264 static const char *illegal_chars = "*\\/?<>|\":";
9265 static char force_shortname_chars[] = " +,.[];=\177";
9267 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
9268 const char *mask, void *state)
9270 struct cli_state *pcli = (struct cli_state *)state;
9272 NTSTATUS status = NT_STATUS_OK;
9274 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
9276 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
9277 return NT_STATUS_OK;
9279 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
9280 status = cli_rmdir(pcli, fname);
9281 if (!NT_STATUS_IS_OK(status)) {
9282 printf("del_fn: failed to rmdir %s\n,", fname );
9285 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9286 if (!NT_STATUS_IS_OK(status)) {
9287 printf("del_fn: failed to unlink %s\n,", fname );
9299 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
9300 const char *name, void *state)
9302 struct sn_state *s = (struct sn_state *)state;
9306 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
9307 i, finfo->name, finfo->short_name);
9310 if (strchr(force_shortname_chars, i)) {
9311 if (!finfo->short_name) {
9312 /* Shortname not created when it should be. */
9313 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
9314 __location__, finfo->name, i);
9317 } else if (finfo->short_name){
9318 /* Shortname created when it should not be. */
9319 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
9320 __location__, finfo->short_name, finfo->name);
9324 return NT_STATUS_OK;
9327 static bool run_shortname_test(int dummy)
9329 static struct cli_state *cli;
9330 bool correct = True;
9336 printf("starting shortname test\n");
9338 if (!torture_open_connection(&cli, 0)) {
9342 smbXcli_conn_set_sockopt(cli->conn, sockops);
9344 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9345 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9346 cli_rmdir(cli, "\\shortname");
9348 status = cli_mkdir(cli, "\\shortname");
9349 if (!NT_STATUS_IS_OK(status)) {
9350 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
9351 __location__, nt_errstr(status));
9356 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
9360 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
9367 for (i = 32; i < 128; i++) {
9368 uint16_t fnum = (uint16_t)-1;
9372 if (strchr(illegal_chars, i)) {
9377 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
9378 FILE_SHARE_READ|FILE_SHARE_WRITE,
9379 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
9380 if (!NT_STATUS_IS_OK(status)) {
9381 d_printf("(%s) cli_nt_create of %s failed: %s\n",
9382 __location__, fname, nt_errstr(status));
9386 cli_close(cli, fnum);
9389 status = cli_list(cli, "\\shortname\\test*.*", 0,
9390 shortname_list_fn, &s);
9391 if (s.matched != 1) {
9392 d_printf("(%s) failed to list %s: %s\n",
9393 __location__, fname, nt_errstr(status));
9398 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9399 if (!NT_STATUS_IS_OK(status)) {
9400 d_printf("(%s) failed to delete %s: %s\n",
9401 __location__, fname, nt_errstr(status));
9414 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
9415 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
9416 cli_rmdir(cli, "\\shortname");
9417 torture_close_connection(cli);
9421 static void pagedsearch_cb(struct tevent_req *req)
9424 struct tldap_message *msg;
9427 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
9428 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9429 d_printf("tldap_search_paged_recv failed: %s\n",
9430 tldap_rc2string(rc));
9433 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
9437 if (!tldap_entry_dn(msg, &dn)) {
9438 d_printf("tldap_entry_dn failed\n");
9441 d_printf("%s\n", dn);
9445 static bool run_tldap(int dummy)
9447 struct tldap_context *ld;
9451 struct sockaddr_storage addr;
9452 struct tevent_context *ev;
9453 struct tevent_req *req;
9457 if (!resolve_name(host, &addr, 0, false)) {
9458 d_printf("could not find host %s\n", host);
9461 status = open_socket_out(&addr, 389, 9999, &fd);
9462 if (!NT_STATUS_IS_OK(status)) {
9463 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
9467 ld = tldap_context_create(talloc_tos(), fd);
9470 d_printf("tldap_context_create failed\n");
9474 rc = tldap_fetch_rootdse(ld);
9475 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9476 d_printf("tldap_fetch_rootdse failed: %s\n",
9477 tldap_errstr(talloc_tos(), ld, rc));
9481 basedn = tldap_talloc_single_attribute(
9482 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
9483 if (basedn == NULL) {
9484 d_printf("no defaultNamingContext\n");
9487 d_printf("defaultNamingContext: %s\n", basedn);
9489 ev = samba_tevent_context_init(talloc_tos());
9491 d_printf("tevent_context_init failed\n");
9495 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
9496 TLDAP_SCOPE_SUB, "(objectclass=*)",
9498 NULL, 0, NULL, 0, 0, 0, 0, 5);
9500 d_printf("tldap_search_paged_send failed\n");
9503 tevent_req_set_callback(req, pagedsearch_cb, NULL);
9505 tevent_req_poll(req, ev);
9509 /* test search filters against rootDSE */
9510 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
9511 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
9513 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
9514 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
9515 talloc_tos(), NULL);
9516 if (!TLDAP_RC_IS_SUCCESS(rc)) {
9517 d_printf("tldap_search with complex filter failed: %s\n",
9518 tldap_errstr(talloc_tos(), ld, rc));
9526 /* Torture test to ensure no regression of :
9527 https://bugzilla.samba.org/show_bug.cgi?id=7084
9530 static bool run_dir_createtime(int dummy)
9532 struct cli_state *cli;
9533 const char *dname = "\\testdir";
9534 const char *fname = "\\testdir\\testfile";
9536 struct timespec create_time;
9537 struct timespec create_time1;
9541 if (!torture_open_connection(&cli, 0)) {
9545 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9546 cli_rmdir(cli, dname);
9548 status = cli_mkdir(cli, dname);
9549 if (!NT_STATUS_IS_OK(status)) {
9550 printf("mkdir failed: %s\n", nt_errstr(status));
9554 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
9556 if (!NT_STATUS_IS_OK(status)) {
9557 printf("cli_qpathinfo2 returned %s\n",
9562 /* Sleep 3 seconds, then create a file. */
9565 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
9567 if (!NT_STATUS_IS_OK(status)) {
9568 printf("cli_openx failed: %s\n", nt_errstr(status));
9572 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
9574 if (!NT_STATUS_IS_OK(status)) {
9575 printf("cli_qpathinfo2 (2) returned %s\n",
9580 if (timespec_compare(&create_time1, &create_time)) {
9581 printf("run_dir_createtime: create time was updated (error)\n");
9583 printf("run_dir_createtime: create time was not updated (correct)\n");
9589 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9590 cli_rmdir(cli, dname);
9591 if (!torture_close_connection(cli)) {
9598 static bool run_streamerror(int dummy)
9600 struct cli_state *cli;
9601 const char *dname = "\\testdir";
9602 const char *streamname =
9603 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
9605 time_t change_time, access_time, write_time;
9607 uint16_t mode, fnum;
9610 if (!torture_open_connection(&cli, 0)) {
9614 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
9615 cli_rmdir(cli, dname);
9617 status = cli_mkdir(cli, dname);
9618 if (!NT_STATUS_IS_OK(status)) {
9619 printf("mkdir failed: %s\n", nt_errstr(status));
9623 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
9624 &write_time, &size, &mode);
9625 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9626 printf("pathinfo returned %s, expected "
9627 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9632 status = cli_ntcreate(cli, streamname, 0x16,
9633 FILE_READ_DATA|FILE_READ_EA|
9634 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
9635 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
9636 FILE_OPEN, 0, 0, &fnum, NULL);
9638 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
9639 printf("ntcreate returned %s, expected "
9640 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
9646 cli_rmdir(cli, dname);
9650 struct pidtest_state {
9656 static void pid_echo_done(struct tevent_req *subreq);
9658 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
9659 struct tevent_context *ev,
9660 struct cli_state *cli)
9662 struct tevent_req *req, *subreq;
9663 struct pidtest_state *state;
9665 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
9670 SSVAL(state->vwv, 0, 1);
9671 state->data = data_blob_const("hello", 5);
9673 subreq = smb1cli_req_send(state,
9678 0, 0, /* *_flags2 */
9680 0xDEADBEEF, /* pid */
9683 ARRAY_SIZE(state->vwv), state->vwv,
9684 state->data.length, state->data.data);
9686 if (tevent_req_nomem(subreq, req)) {
9687 return tevent_req_post(req, ev);
9689 tevent_req_set_callback(subreq, pid_echo_done, req);
9693 static void pid_echo_done(struct tevent_req *subreq)
9695 struct tevent_req *req = tevent_req_callback_data(
9696 subreq, struct tevent_req);
9697 struct pidtest_state *state = tevent_req_data(
9698 req, struct pidtest_state);
9701 uint8_t *bytes = NULL;
9702 struct iovec *recv_iov = NULL;
9703 uint8_t *phdr = NULL;
9704 uint16_t pidlow = 0;
9705 uint16_t pidhigh = 0;
9706 struct smb1cli_req_expected_response expected[] = {
9708 .status = NT_STATUS_OK,
9713 status = smb1cli_req_recv(subreq, state,
9718 NULL, /* pvwv_offset */
9721 NULL, /* pbytes_offset */
9723 expected, ARRAY_SIZE(expected));
9725 TALLOC_FREE(subreq);
9727 if (!NT_STATUS_IS_OK(status)) {
9728 tevent_req_nterror(req, status);
9732 if (num_bytes != state->data.length) {
9733 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9737 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
9738 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9742 /* Check pid low/high == DEADBEEF */
9743 pidlow = SVAL(phdr, HDR_PID);
9744 if (pidlow != 0xBEEF){
9745 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
9746 (unsigned int)pidlow);
9747 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9750 pidhigh = SVAL(phdr, HDR_PIDHIGH);
9751 if (pidhigh != 0xDEAD){
9752 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
9753 (unsigned int)pidhigh);
9754 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
9758 tevent_req_done(req);
9761 static NTSTATUS pid_echo_recv(struct tevent_req *req)
9763 return tevent_req_simple_recv_ntstatus(req);
9766 static bool run_pidhigh(int dummy)
9768 bool success = false;
9769 struct cli_state *cli = NULL;
9771 struct tevent_context *ev = NULL;
9772 struct tevent_req *req = NULL;
9773 TALLOC_CTX *frame = talloc_stackframe();
9775 printf("starting pid high test\n");
9776 if (!torture_open_connection(&cli, 0)) {
9779 smbXcli_conn_set_sockopt(cli->conn, sockops);
9781 ev = samba_tevent_context_init(frame);
9786 req = pid_echo_send(frame, ev, cli);
9791 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
9795 status = pid_echo_recv(req);
9796 if (NT_STATUS_IS_OK(status)) {
9797 printf("pid high test ok\n");
9804 torture_close_connection(cli);
9809 Test Windows open on a bad POSIX symlink.
9811 static bool run_symlink_open_test(int dummy)
9813 static struct cli_state *cli;
9814 const char *fname = "non_existant_file";
9815 const char *sname = "dangling_symlink";
9816 uint16_t fnum = (uint16_t)-1;
9817 bool correct = false;
9819 TALLOC_CTX *frame = NULL;
9821 frame = talloc_stackframe();
9823 printf("Starting Windows bad symlink open test\n");
9825 if (!torture_open_connection(&cli, 0)) {
9830 smbXcli_conn_set_sockopt(cli->conn, sockops);
9832 status = torture_setup_unix_extensions(cli);
9833 if (!NT_STATUS_IS_OK(status)) {
9838 /* Ensure nothing exists. */
9839 cli_setatr(cli, fname, 0, 0);
9840 cli_posix_unlink(cli, fname);
9841 cli_setatr(cli, sname, 0, 0);
9842 cli_posix_unlink(cli, sname);
9844 /* Create a symlink pointing nowhere. */
9845 status = cli_posix_symlink(cli, fname, sname);
9846 if (!NT_STATUS_IS_OK(status)) {
9847 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
9854 /* Now ensure that a Windows open doesn't hang. */
9855 status = cli_ntcreate(cli,
9858 FILE_READ_DATA|FILE_WRITE_DATA,
9860 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
9868 * We get either NT_STATUS_OBJECT_NAME_NOT_FOUND or
9869 * NT_STATUS_OBJECT_PATH_NOT_FOUND depending on if
9870 * we use O_NOFOLLOW on the server or not.
9872 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
9873 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND))
9877 printf("cli_ntcreate of %s returned %s - should return"
9878 " either (%s) or (%s)\n",
9881 nt_errstr(NT_STATUS_OBJECT_NAME_NOT_FOUND),
9882 nt_errstr(NT_STATUS_OBJECT_PATH_NOT_FOUND));
9890 if (fnum != (uint16_t)-1) {
9891 cli_close(cli, fnum);
9892 fnum = (uint16_t)-1;
9895 cli_setatr(cli, sname, 0, 0);
9896 cli_posix_unlink(cli, sname);
9897 cli_setatr(cli, fname, 0, 0);
9898 cli_posix_unlink(cli, fname);
9900 if (!torture_close_connection(cli)) {
9908 static bool run_local_substitute(int dummy)
9912 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
9913 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
9914 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
9915 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
9916 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
9917 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
9918 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
9919 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
9921 /* Different captialization rules in sub_basic... */
9923 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
9929 static bool run_local_base64(int dummy)
9934 for (i=1; i<2000; i++) {
9935 DATA_BLOB blob1, blob2;
9938 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
9940 generate_random_buffer(blob1.data, blob1.length);
9942 b64 = base64_encode_data_blob(talloc_tos(), blob1);
9944 d_fprintf(stderr, "base64_encode_data_blob failed "
9945 "for %d bytes\n", i);
9948 blob2 = base64_decode_data_blob(b64);
9951 if (data_blob_cmp(&blob1, &blob2)) {
9952 d_fprintf(stderr, "data_blob_cmp failed for %d "
9956 TALLOC_FREE(blob1.data);
9957 data_blob_free(&blob2);
9962 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
9967 static bool run_local_gencache(int dummy)
9973 struct memcache *mem;
9976 mem = memcache_init(NULL, 0);
9978 d_printf("%s: memcache_init failed\n", __location__);
9981 memcache_set_global(mem);
9983 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
9984 d_printf("%s: gencache_set() failed\n", __location__);
9988 if (!gencache_get("foo", NULL, NULL, NULL)) {
9989 d_printf("%s: gencache_get() failed\n", __location__);
9993 for (i=0; i<1000000; i++) {
9994 gencache_parse("foo", parse_fn, NULL);
9997 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9998 d_printf("%s: gencache_get() failed\n", __location__);
10003 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
10004 d_printf("%s: gencache_get() failed\n", __location__);
10008 if (strcmp(val, "bar") != 0) {
10009 d_printf("%s: gencache_get() returned %s, expected %s\n",
10010 __location__, val, "bar");
10017 if (!gencache_del("foo")) {
10018 d_printf("%s: gencache_del() failed\n", __location__);
10021 if (gencache_del("foo")) {
10022 d_printf("%s: second gencache_del() succeeded\n",
10027 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
10028 d_printf("%s: gencache_get() on deleted entry "
10029 "succeeded\n", __location__);
10033 blob = data_blob_string_const_null("bar");
10034 tm = time(NULL) + 60;
10036 if (!gencache_set_data_blob("foo", &blob, tm)) {
10037 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
10041 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10042 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
10046 if (strcmp((const char *)blob.data, "bar") != 0) {
10047 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
10048 __location__, (const char *)blob.data, "bar");
10049 data_blob_free(&blob);
10053 data_blob_free(&blob);
10055 if (!gencache_del("foo")) {
10056 d_printf("%s: gencache_del() failed\n", __location__);
10059 if (gencache_del("foo")) {
10060 d_printf("%s: second gencache_del() succeeded\n",
10065 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
10066 d_printf("%s: gencache_get_data_blob() on deleted entry "
10067 "succeeded\n", __location__);
10072 blob.data = (uint8_t *)&v;
10073 blob.length = sizeof(v);
10075 if (!gencache_set_data_blob("blob", &blob, tm)) {
10076 d_printf("%s: gencache_set_data_blob() failed\n",
10080 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
10081 d_printf("%s: gencache_get succeeded\n", __location__);
10088 static bool rbt_testval(struct db_context *db, const char *key,
10091 struct db_record *rec;
10092 TDB_DATA data = string_tdb_data(value);
10097 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10099 d_fprintf(stderr, "fetch_locked failed\n");
10102 status = dbwrap_record_store(rec, data, 0);
10103 if (!NT_STATUS_IS_OK(status)) {
10104 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
10109 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
10111 d_fprintf(stderr, "second fetch_locked failed\n");
10115 dbvalue = dbwrap_record_get_value(rec);
10116 if ((dbvalue.dsize != data.dsize)
10117 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
10118 d_fprintf(stderr, "Got wrong data back\n");
10128 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
10130 int *count2 = (int *)private_data;
10135 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
10137 int *count2 = (int *)private_data;
10139 dbwrap_record_delete(rec);
10143 static bool run_local_rbtree(int dummy)
10145 struct db_context *db;
10152 db = db_open_rbt(NULL);
10155 d_fprintf(stderr, "db_open_rbt failed\n");
10159 for (i=0; i<1000; i++) {
10162 if (asprintf(&key, "key%ld", random()) == -1) {
10165 if (asprintf(&value, "value%ld", random()) == -1) {
10170 if (!rbt_testval(db, key, value)) {
10177 if (asprintf(&value, "value%ld", random()) == -1) {
10182 if (!rbt_testval(db, key, value)) {
10193 count = 0; count2 = 0;
10194 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10196 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10197 if ((count != count2) || (count != 1000)) {
10200 count = 0; count2 = 0;
10201 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
10203 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10204 if ((count != count2) || (count != 1000)) {
10207 count = 0; count2 = 0;
10208 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
10210 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
10211 if ((count != count2) || (count != 0)) {
10222 local test for character set functions
10224 This is a very simple test for the functionality in convert_string_error()
10226 static bool run_local_convert_string(int dummy)
10228 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
10229 const char *test_strings[2] = { "March", "M\303\244rz" };
10233 for (i=0; i<2; i++) {
10234 const char *str = test_strings[i];
10235 int len = strlen(str);
10236 size_t converted_size;
10239 memset(dst, 'X', sizeof(dst));
10241 /* first try with real source length */
10242 ret = convert_string_error(CH_UNIX, CH_UTF8,
10247 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10251 if (converted_size != len) {
10252 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10253 str, len, (int)converted_size);
10257 if (strncmp(str, dst, converted_size) != 0) {
10258 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10262 if (strlen(str) != converted_size) {
10263 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10264 (int)strlen(str), (int)converted_size);
10268 if (dst[converted_size] != 'X') {
10269 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10273 /* now with srclen==-1, this causes the nul to be
10275 ret = convert_string_error(CH_UNIX, CH_UTF8,
10280 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
10284 if (converted_size != len+1) {
10285 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
10286 str, len, (int)converted_size);
10290 if (strncmp(str, dst, converted_size) != 0) {
10291 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
10295 if (len+1 != converted_size) {
10296 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
10297 len+1, (int)converted_size);
10301 if (dst[converted_size] != 'X') {
10302 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
10309 TALLOC_FREE(tmp_ctx);
10312 TALLOC_FREE(tmp_ctx);
10316 static bool run_local_string_to_sid(int dummy) {
10317 struct dom_sid sid;
10319 if (string_to_sid(&sid, "S--1-5-32-545")) {
10320 printf("allowing S--1-5-32-545\n");
10323 if (string_to_sid(&sid, "S-1-5-32-+545")) {
10324 printf("allowing S-1-5-32-+545\n");
10327 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")) {
10328 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
10331 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
10332 printf("allowing S-1-5-32-545-abc\n");
10335 if (string_to_sid(&sid, "S-300-5-32-545")) {
10336 printf("allowing S-300-5-32-545\n");
10339 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
10340 printf("allowing S-1-0xfffffffffffffe-32-545\n");
10343 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
10344 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
10347 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
10348 printf("could not parse S-1-0xfffffffffffe-32-545\n");
10351 if (!string_to_sid(&sid, "S-1-5-32-545")) {
10352 printf("could not parse S-1-5-32-545\n");
10355 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
10356 printf("mis-parsed S-1-5-32-545 as %s\n",
10357 sid_string_tos(&sid));
10363 static bool sid_to_string_test(const char *expected) {
10366 struct dom_sid sid;
10368 if (!string_to_sid(&sid, expected)) {
10369 printf("could not parse %s\n", expected);
10373 str = dom_sid_string(NULL, &sid);
10374 if (strcmp(str, expected)) {
10375 printf("Comparison failed (%s != %s)\n", str, expected);
10382 static bool run_local_sid_to_string(int dummy) {
10383 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
10385 if (!sid_to_string_test("S-1-545"))
10387 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
10392 static bool run_local_binary_to_sid(int dummy) {
10393 struct dom_sid *sid = talloc(NULL, struct dom_sid);
10394 static const uint8_t good_binary_sid[] = {
10395 0x1, /* revision number */
10396 15, /* num auths */
10397 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10398 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10399 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10400 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10401 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10402 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10403 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10404 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10405 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10406 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10407 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10408 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10409 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10410 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10411 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10412 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10415 static const uint8_t long_binary_sid[] = {
10416 0x1, /* revision number */
10417 15, /* num auths */
10418 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10419 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10420 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10421 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10422 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10423 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10424 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10425 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10426 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10427 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10428 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10429 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10430 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10431 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10432 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10433 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10434 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10435 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10436 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10439 static const uint8_t long_binary_sid2[] = {
10440 0x1, /* revision number */
10441 32, /* num auths */
10442 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
10443 0x1, 0x1, 0x1, 0x1, /* auth[0] */
10444 0x1, 0x1, 0x1, 0x1, /* auth[1] */
10445 0x1, 0x1, 0x1, 0x1, /* auth[2] */
10446 0x1, 0x1, 0x1, 0x1, /* auth[3] */
10447 0x1, 0x1, 0x1, 0x1, /* auth[4] */
10448 0x1, 0x1, 0x1, 0x1, /* auth[5] */
10449 0x1, 0x1, 0x1, 0x1, /* auth[6] */
10450 0x1, 0x1, 0x1, 0x1, /* auth[7] */
10451 0x1, 0x1, 0x1, 0x1, /* auth[8] */
10452 0x1, 0x1, 0x1, 0x1, /* auth[9] */
10453 0x1, 0x1, 0x1, 0x1, /* auth[10] */
10454 0x1, 0x1, 0x1, 0x1, /* auth[11] */
10455 0x1, 0x1, 0x1, 0x1, /* auth[12] */
10456 0x1, 0x1, 0x1, 0x1, /* auth[13] */
10457 0x1, 0x1, 0x1, 0x1, /* auth[14] */
10458 0x1, 0x1, 0x1, 0x1, /* auth[15] */
10459 0x1, 0x1, 0x1, 0x1, /* auth[16] */
10460 0x1, 0x1, 0x1, 0x1, /* auth[17] */
10461 0x1, 0x1, 0x1, 0x1, /* auth[18] */
10462 0x1, 0x1, 0x1, 0x1, /* auth[19] */
10463 0x1, 0x1, 0x1, 0x1, /* auth[20] */
10464 0x1, 0x1, 0x1, 0x1, /* auth[21] */
10465 0x1, 0x1, 0x1, 0x1, /* auth[22] */
10466 0x1, 0x1, 0x1, 0x1, /* auth[23] */
10467 0x1, 0x1, 0x1, 0x1, /* auth[24] */
10468 0x1, 0x1, 0x1, 0x1, /* auth[25] */
10469 0x1, 0x1, 0x1, 0x1, /* auth[26] */
10470 0x1, 0x1, 0x1, 0x1, /* auth[27] */
10471 0x1, 0x1, 0x1, 0x1, /* auth[28] */
10472 0x1, 0x1, 0x1, 0x1, /* auth[29] */
10473 0x1, 0x1, 0x1, 0x1, /* auth[30] */
10474 0x1, 0x1, 0x1, 0x1, /* auth[31] */
10477 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
10480 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
10483 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
10489 /* Split a path name into filename and stream name components. Canonicalise
10490 * such that an implicit $DATA token is always explicit.
10492 * The "specification" of this function can be found in the
10493 * run_local_stream_name() function in torture.c, I've tried those
10494 * combinations against a W2k3 server.
10497 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
10498 char **pbase, char **pstream)
10501 char *stream = NULL;
10502 char *sname; /* stream name */
10503 const char *stype; /* stream type */
10505 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
10507 sname = strchr_m(fname, ':');
10509 if (sname == NULL) {
10510 if (pbase != NULL) {
10511 base = talloc_strdup(mem_ctx, fname);
10512 NT_STATUS_HAVE_NO_MEMORY(base);
10517 if (pbase != NULL) {
10518 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
10519 NT_STATUS_HAVE_NO_MEMORY(base);
10524 stype = strchr_m(sname, ':');
10526 if (stype == NULL) {
10527 sname = talloc_strdup(mem_ctx, sname);
10531 if (strcasecmp_m(stype, ":$DATA") != 0) {
10533 * If there is an explicit stream type, so far we only
10534 * allow $DATA. Is there anything else allowed? -- vl
10536 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
10538 return NT_STATUS_OBJECT_NAME_INVALID;
10540 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
10544 if (sname == NULL) {
10546 return NT_STATUS_NO_MEMORY;
10549 if (sname[0] == '\0') {
10551 * no stream name, so no stream
10556 if (pstream != NULL) {
10557 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
10558 if (stream == NULL) {
10559 TALLOC_FREE(sname);
10561 return NT_STATUS_NO_MEMORY;
10564 * upper-case the type field
10566 (void)strupper_m(strchr_m(stream, ':')+1);
10570 if (pbase != NULL) {
10573 if (pstream != NULL) {
10576 return NT_STATUS_OK;
10579 static bool test_stream_name(const char *fname, const char *expected_base,
10580 const char *expected_stream,
10581 NTSTATUS expected_status)
10585 char *stream = NULL;
10587 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
10588 if (!NT_STATUS_EQUAL(status, expected_status)) {
10592 if (!NT_STATUS_IS_OK(status)) {
10596 if (base == NULL) goto error;
10598 if (strcmp(expected_base, base) != 0) goto error;
10600 if ((expected_stream != NULL) && (stream == NULL)) goto error;
10601 if ((expected_stream == NULL) && (stream != NULL)) goto error;
10603 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
10607 TALLOC_FREE(stream);
10611 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
10612 fname, expected_base ? expected_base : "<NULL>",
10613 expected_stream ? expected_stream : "<NULL>",
10614 nt_errstr(expected_status));
10615 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
10616 base ? base : "<NULL>", stream ? stream : "<NULL>",
10617 nt_errstr(status));
10619 TALLOC_FREE(stream);
10623 static bool run_local_stream_name(int dummy)
10627 ret &= test_stream_name(
10628 "bla", "bla", NULL, NT_STATUS_OK);
10629 ret &= test_stream_name(
10630 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
10631 ret &= test_stream_name(
10632 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10633 ret &= test_stream_name(
10634 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
10635 ret &= test_stream_name(
10636 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
10637 ret &= test_stream_name(
10638 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
10639 ret &= test_stream_name(
10640 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
10641 ret &= test_stream_name(
10642 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
10647 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
10649 if (a.length != b.length) {
10650 printf("a.length=%d != b.length=%d\n",
10651 (int)a.length, (int)b.length);
10654 if (memcmp(a.data, b.data, a.length) != 0) {
10655 printf("a.data and b.data differ\n");
10661 static bool run_local_memcache(int dummy)
10663 struct memcache *cache;
10664 DATA_BLOB k1, k2, k3;
10668 TALLOC_CTX *mem_ctx;
10673 size_t size1, size2;
10676 mem_ctx = talloc_init("foo");
10677 if (mem_ctx == NULL) {
10681 /* STAT_CACHE TESTS */
10683 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10685 if (cache == NULL) {
10686 printf("memcache_init failed\n");
10690 d1 = data_blob_const("d1", 2);
10691 d3 = data_blob_const("d3", 2);
10693 k1 = data_blob_const("d1", 2);
10694 k2 = data_blob_const("d2", 2);
10695 k3 = data_blob_const("d3", 2);
10697 memcache_add(cache, STAT_CACHE, k1, d1);
10699 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
10700 printf("could not find k1\n");
10703 if (!data_blob_equal(d1, v1)) {
10707 memcache_add(cache, STAT_CACHE, k1, d3);
10709 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
10710 printf("could not find replaced k1\n");
10713 if (!data_blob_equal(d3, v3)) {
10717 TALLOC_FREE(cache);
10719 /* GETWD_CACHE TESTS */
10720 str1 = talloc_strdup(mem_ctx, "string1");
10721 if (str1 == NULL) {
10724 ptr2 = str1; /* Keep an alias for comparison. */
10726 str2 = talloc_strdup(mem_ctx, "string2");
10727 if (str2 == NULL) {
10731 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
10732 if (cache == NULL) {
10733 printf("memcache_init failed\n");
10737 memcache_add_talloc(cache, GETWD_CACHE, k2, &str1);
10738 /* str1 == NULL now. */
10739 ptr1 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
10740 if (ptr1 == NULL) {
10741 printf("could not find k2\n");
10744 if (ptr1 != ptr2) {
10745 printf("fetch of k2 got wrong string\n");
10749 /* Add a blob to ensure k2 gets purged. */
10750 d3 = data_blob_talloc_zero(mem_ctx, 180);
10751 memcache_add(cache, STAT_CACHE, k3, d3);
10753 ptr2 = memcache_lookup_talloc(cache, GETWD_CACHE, k2);
10754 if (ptr2 != NULL) {
10755 printf("Did find k2, should have been purged\n");
10759 TALLOC_FREE(cache);
10760 TALLOC_FREE(mem_ctx);
10762 mem_ctx = talloc_init("foo");
10763 if (mem_ctx == NULL) {
10767 cache = memcache_init(NULL, 0);
10768 if (cache == NULL) {
10772 str1 = talloc_strdup(mem_ctx, "string1");
10773 if (str1 == NULL) {
10776 str2 = talloc_strdup(mem_ctx, "string2");
10777 if (str2 == NULL) {
10780 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10781 data_blob_string_const("torture"), &str1);
10782 size1 = talloc_total_size(cache);
10784 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
10785 data_blob_string_const("torture"), &str2);
10786 size2 = talloc_total_size(cache);
10788 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
10790 if (size2 > size1) {
10791 printf("memcache leaks memory!\n");
10797 TALLOC_FREE(cache);
10801 static void wbclient_done(struct tevent_req *req)
10804 struct winbindd_response *wb_resp;
10805 int *i = (int *)tevent_req_callback_data_void(req);
10807 wbc_err = wb_trans_recv(req, req, &wb_resp);
10810 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
10813 static bool run_wbclient_multi_ping(int dummy)
10815 struct tevent_context *ev;
10816 struct wb_context **wb_ctx;
10817 struct winbindd_request wb_req;
10818 bool result = false;
10821 BlockSignals(True, SIGPIPE);
10823 ev = tevent_context_init(talloc_tos());
10828 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
10829 if (wb_ctx == NULL) {
10833 ZERO_STRUCT(wb_req);
10834 wb_req.cmd = WINBINDD_PING;
10836 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
10838 for (i=0; i<torture_nprocs; i++) {
10839 wb_ctx[i] = wb_context_init(ev, NULL);
10840 if (wb_ctx[i] == NULL) {
10843 for (j=0; j<torture_numops; j++) {
10844 struct tevent_req *req;
10845 req = wb_trans_send(ev, ev, wb_ctx[i],
10846 (j % 2) == 0, &wb_req);
10850 tevent_req_set_callback(req, wbclient_done, &i);
10856 while (i < torture_nprocs * torture_numops) {
10857 tevent_loop_once(ev);
10866 static bool dbtrans_inc(struct db_context *db)
10868 struct db_record *rec;
10874 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10876 printf(__location__ "fetch_lock failed\n");
10880 value = dbwrap_record_get_value(rec);
10882 if (value.dsize != sizeof(uint32_t)) {
10883 printf(__location__ "value.dsize = %d\n",
10888 memcpy(&val, value.dptr, sizeof(val));
10891 status = dbwrap_record_store(
10892 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
10893 if (!NT_STATUS_IS_OK(status)) {
10894 printf(__location__ "store failed: %s\n",
10895 nt_errstr(status));
10905 static bool run_local_dbtrans(int dummy)
10907 struct db_context *db;
10908 struct db_record *rec;
10914 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
10915 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
10918 printf("Could not open transtest.db\n");
10922 res = dbwrap_transaction_start(db);
10924 printf(__location__ "transaction_start failed\n");
10928 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10930 printf(__location__ "fetch_lock failed\n");
10934 value = dbwrap_record_get_value(rec);
10936 if (value.dptr == NULL) {
10938 status = dbwrap_record_store(
10939 rec, make_tdb_data((uint8_t *)&initial,
10942 if (!NT_STATUS_IS_OK(status)) {
10943 printf(__location__ "store returned %s\n",
10944 nt_errstr(status));
10951 res = dbwrap_transaction_commit(db);
10953 printf(__location__ "transaction_commit failed\n");
10958 uint32_t val, val2;
10961 res = dbwrap_transaction_start(db);
10963 printf(__location__ "transaction_start failed\n");
10967 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
10968 if (!NT_STATUS_IS_OK(status)) {
10969 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10970 nt_errstr(status));
10974 for (i=0; i<10; i++) {
10975 if (!dbtrans_inc(db)) {
10980 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
10981 if (!NT_STATUS_IS_OK(status)) {
10982 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10983 nt_errstr(status));
10987 if (val2 != val + 10) {
10988 printf(__location__ "val=%d, val2=%d\n",
10989 (int)val, (int)val2);
10993 printf("val2=%d\r", val2);
10995 res = dbwrap_transaction_commit(db);
10997 printf(__location__ "transaction_commit failed\n");
11007 * Just a dummy test to be run under a debugger. There's no real way
11008 * to inspect the tevent_poll specific function from outside of
11012 static bool run_local_tevent_poll(int dummy)
11014 struct tevent_context *ev;
11015 struct tevent_fd *fd1, *fd2;
11016 bool result = false;
11018 ev = tevent_context_init_byname(NULL, "poll");
11020 d_fprintf(stderr, "tevent_context_init_byname failed\n");
11024 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
11026 d_fprintf(stderr, "tevent_add_fd failed\n");
11029 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
11031 d_fprintf(stderr, "tevent_add_fd failed\n");
11036 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
11038 d_fprintf(stderr, "tevent_add_fd failed\n");
11048 static bool run_local_hex_encode_buf(int dummy)
11054 for (i=0; i<sizeof(src); i++) {
11057 hex_encode_buf(buf, src, sizeof(src));
11058 if (strcmp(buf, "0001020304050607") != 0) {
11061 hex_encode_buf(buf, NULL, 0);
11062 if (buf[0] != '\0') {
11068 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
11090 "1001:1111:1111:1000:0:1111:1111:1111",
11099 static const char *remove_duplicate_addrs2_test_strings_result[] = {
11113 "1001:1111:1111:1000:0:1111:1111:1111"
11116 static bool run_local_remove_duplicate_addrs2(int dummy)
11118 struct ip_service test_vector[28];
11121 /* Construct the sockaddr_storage test vector. */
11122 for (i = 0; i < 28; i++) {
11123 struct addrinfo hints;
11124 struct addrinfo *res = NULL;
11127 memset(&hints, '\0', sizeof(hints));
11128 hints.ai_flags = AI_NUMERICHOST;
11129 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
11134 fprintf(stderr, "getaddrinfo failed on [%s]\n",
11135 remove_duplicate_addrs2_test_strings_vector[i]);
11138 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
11139 memcpy(&test_vector[i].ss,
11145 count = remove_duplicate_addrs2(test_vector, i);
11148 fprintf(stderr, "count wrong (%d) should be 14\n",
11153 for (i = 0; i < count; i++) {
11154 char addr[INET6_ADDRSTRLEN];
11156 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
11158 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
11159 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
11162 remove_duplicate_addrs2_test_strings_result[i]);
11167 printf("run_local_remove_duplicate_addrs2: success\n");
11171 static bool run_local_tdb_opener(int dummy)
11177 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
11178 O_RDWR|O_CREAT, 0755);
11180 perror("tdb_open failed");
11191 static bool run_local_tdb_writer(int dummy)
11197 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
11199 perror("tdb_open failed");
11203 val.dptr = (uint8_t *)&v;
11204 val.dsize = sizeof(v);
11210 ret = tdb_store(t, val, val, 0);
11212 printf("%s\n", tdb_errorstr(t));
11217 data = tdb_fetch(t, val);
11218 if (data.dptr != NULL) {
11219 SAFE_FREE(data.dptr);
11225 static bool run_local_canonicalize_path(int dummy)
11227 const char *src[] = {
11234 ".././././../../../boo",
11238 const char *dst[] = {
11251 for (i = 0; src[i] != NULL; i++) {
11252 char *d = canonicalize_absolute_path(talloc_tos(), src[i]);
11254 perror("talloc fail\n");
11257 if (strcmp(d, dst[i]) != 0) {
11259 "canonicalize missmatch %s -> %s != %s",
11260 src[i], d, dst[i]);
11268 static bool run_ign_bad_negprot(int dummy)
11270 struct tevent_context *ev;
11271 struct tevent_req *req;
11272 struct smbXcli_conn *conn;
11273 struct sockaddr_storage ss;
11278 printf("starting ignore bad negprot\n");
11280 ok = resolve_name(host, &ss, 0x20, true);
11282 d_fprintf(stderr, "Could not resolve name %s\n", host);
11286 status = open_socket_out(&ss, 445, 10000, &fd);
11287 if (!NT_STATUS_IS_OK(status)) {
11288 d_fprintf(stderr, "open_socket_out failed: %s\n",
11289 nt_errstr(status));
11293 conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
11295 if (conn == NULL) {
11296 d_fprintf(stderr, "smbXcli_conn_create failed\n");
11300 status = smbXcli_negprot(conn, 0, PROTOCOL_CORE, PROTOCOL_CORE);
11301 if (NT_STATUS_IS_OK(status)) {
11302 d_fprintf(stderr, "smbXcli_negprot succeeded!\n");
11306 ev = samba_tevent_context_init(talloc_tos());
11308 d_fprintf(stderr, "samba_tevent_context_init failed\n");
11312 req = smb1cli_session_setup_nt1_send(
11313 ev, ev, conn, 0, getpid(), NULL, 65503, 2, 1, 0, "", "",
11314 data_blob_null, data_blob_null, 0x40,
11315 "Windows 2000 2195", "Windows 2000 5.0");
11317 d_fprintf(stderr, "smb1cli_session_setup_nt1_send failed\n");
11321 ok = tevent_req_poll_ntstatus(req, ev, &status);
11323 d_fprintf(stderr, "tevent_req_poll failed\n");
11327 status = smb1cli_session_setup_nt1_recv(req, NULL, NULL, NULL, NULL,
11329 if (!NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_RESET)) {
11330 d_fprintf(stderr, "smb1cli_session_setup_nt1_recv returned "
11331 "%s, expected NT_STATUS_CONNECTION_RESET\n",
11332 nt_errstr(status));
11338 printf("starting ignore bad negprot\n");
11343 static double create_procs(bool (*fn)(int), bool *result)
11346 volatile pid_t *child_status;
11347 volatile bool *child_status_out;
11350 struct timeval start;
11354 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
11355 if (!child_status) {
11356 printf("Failed to setup shared memory\n");
11360 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
11361 if (!child_status_out) {
11362 printf("Failed to setup result status shared memory\n");
11366 for (i = 0; i < torture_nprocs; i++) {
11367 child_status[i] = 0;
11368 child_status_out[i] = True;
11371 start = timeval_current();
11373 for (i=0;i<torture_nprocs;i++) {
11376 pid_t mypid = getpid();
11377 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
11379 slprintf(myname,sizeof(myname),"CLIENT%d", i);
11382 if (torture_open_connection(¤t_cli, i)) break;
11383 if (tries-- == 0) {
11384 printf("pid %d failed to start\n", (int)getpid());
11390 child_status[i] = getpid();
11392 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
11394 child_status_out[i] = fn(i);
11401 for (i=0;i<torture_nprocs;i++) {
11402 if (child_status[i]) synccount++;
11404 if (synccount == torture_nprocs) break;
11406 } while (timeval_elapsed(&start) < 30);
11408 if (synccount != torture_nprocs) {
11409 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
11411 return timeval_elapsed(&start);
11414 /* start the client load */
11415 start = timeval_current();
11417 for (i=0;i<torture_nprocs;i++) {
11418 child_status[i] = 0;
11421 printf("%d clients started\n", torture_nprocs);
11423 for (i=0;i<torture_nprocs;i++) {
11424 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
11429 for (i=0;i<torture_nprocs;i++) {
11430 if (!child_status_out[i]) {
11434 return timeval_elapsed(&start);
11437 #define FLAG_MULTIPROC 1
11443 } torture_ops[] = {
11444 {"FDPASS", run_fdpasstest, 0},
11445 {"LOCK1", run_locktest1, 0},
11446 {"LOCK2", run_locktest2, 0},
11447 {"LOCK3", run_locktest3, 0},
11448 {"LOCK4", run_locktest4, 0},
11449 {"LOCK5", run_locktest5, 0},
11450 {"LOCK6", run_locktest6, 0},
11451 {"LOCK7", run_locktest7, 0},
11452 {"LOCK8", run_locktest8, 0},
11453 {"LOCK9", run_locktest9, 0},
11454 {"UNLINK", run_unlinktest, 0},
11455 {"BROWSE", run_browsetest, 0},
11456 {"ATTR", run_attrtest, 0},
11457 {"TRANS2", run_trans2test, 0},
11458 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
11459 {"TORTURE",run_torture, FLAG_MULTIPROC},
11460 {"RANDOMIPC", run_randomipc, 0},
11461 {"NEGNOWAIT", run_negprot_nowait, 0},
11462 {"NBENCH", run_nbench, 0},
11463 {"NBENCH2", run_nbench2, 0},
11464 {"OPLOCK1", run_oplock1, 0},
11465 {"OPLOCK2", run_oplock2, 0},
11466 {"OPLOCK4", run_oplock4, 0},
11467 {"DIR", run_dirtest, 0},
11468 {"DIR1", run_dirtest1, 0},
11469 {"DIR-CREATETIME", run_dir_createtime, 0},
11470 {"DENY1", torture_denytest1, 0},
11471 {"DENY2", torture_denytest2, 0},
11472 {"TCON", run_tcon_test, 0},
11473 {"TCONDEV", run_tcon_devtype_test, 0},
11474 {"RW1", run_readwritetest, 0},
11475 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
11476 {"RW3", run_readwritelarge, 0},
11477 {"RW-SIGNING", run_readwritelarge_signtest, 0},
11478 {"OPEN", run_opentest, 0},
11479 {"POSIX", run_simple_posix_open_test, 0},
11480 {"POSIX-APPEND", run_posix_append, 0},
11481 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
11482 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
11483 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
11484 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
11485 {"WINDOWS-BAD-SYMLINK", run_symlink_open_test, 0},
11486 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
11487 {"ASYNC-ECHO", run_async_echo, 0},
11488 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
11489 { "SHORTNAME-TEST", run_shortname_test, 0},
11490 { "ADDRCHANGE", run_addrchange, 0},
11492 {"OPENATTR", run_openattrtest, 0},
11494 {"XCOPY", run_xcopy, 0},
11495 {"RENAME", run_rename, 0},
11496 {"RENAME-ACCESS", run_rename_access, 0},
11497 {"OWNER-RIGHTS", run_owner_rights, 0},
11498 {"DELETE", run_deletetest, 0},
11499 {"WILDDELETE", run_wild_deletetest, 0},
11500 {"DELETE-LN", run_deletetest_ln, 0},
11501 {"PROPERTIES", run_properties, 0},
11502 {"MANGLE", torture_mangle, 0},
11503 {"MANGLE1", run_mangle1, 0},
11504 {"MANGLE-ILLEGAL", run_mangle_illegal, 0},
11505 {"W2K", run_w2ktest, 0},
11506 {"TRANS2SCAN", torture_trans2_scan, 0},
11507 {"NTTRANSSCAN", torture_nttrans_scan, 0},
11508 {"UTABLE", torture_utable, 0},
11509 {"CASETABLE", torture_casetable, 0},
11510 {"ERRMAPEXTRACT", run_error_map_extract, 0},
11511 {"PIPE_NUMBER", run_pipe_number, 0},
11512 {"TCON2", run_tcon2_test, 0},
11513 {"IOCTL", torture_ioctl_test, 0},
11514 {"CHKPATH", torture_chkpath_test, 0},
11515 {"FDSESS", run_fdsesstest, 0},
11516 { "EATEST", run_eatest, 0},
11517 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
11518 { "CHAIN1", run_chain1, 0},
11519 { "CHAIN2", run_chain2, 0},
11520 { "CHAIN3", run_chain3, 0},
11521 { "WINDOWS-WRITE", run_windows_write, 0},
11522 { "LARGE_READX", run_large_readx, 0},
11523 { "NTTRANS-CREATE", run_nttrans_create, 0},
11524 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
11525 { "CLI_ECHO", run_cli_echo, 0},
11526 { "TLDAP", run_tldap },
11527 { "STREAMERROR", run_streamerror },
11528 { "NOTIFY-BENCH", run_notify_bench },
11529 { "NOTIFY-BENCH2", run_notify_bench2 },
11530 { "NOTIFY-BENCH3", run_notify_bench3 },
11531 { "BAD-NBT-SESSION", run_bad_nbt_session },
11532 { "IGN-BAD-NEGPROT", run_ign_bad_negprot },
11533 { "SMB-ANY-CONNECT", run_smb_any_connect },
11534 { "NOTIFY-ONLINE", run_notify_online },
11535 { "SMB2-BASIC", run_smb2_basic },
11536 { "SMB2-NEGPROT", run_smb2_negprot },
11537 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
11538 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
11539 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
11540 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
11541 { "SMB2-FTRUNCATE", run_smb2_ftruncate },
11542 { "CLEANUP1", run_cleanup1 },
11543 { "CLEANUP2", run_cleanup2 },
11544 { "CLEANUP3", run_cleanup3 },
11545 { "CLEANUP4", run_cleanup4 },
11546 { "OPLOCK-CANCEL", run_oplock_cancel },
11547 { "PIDHIGH", run_pidhigh },
11548 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
11549 { "LOCAL-GENCACHE", run_local_gencache, 0},
11550 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
11551 { "LOCAL-DBWRAP-WATCH2", run_dbwrap_watch2, 0 },
11552 { "LOCAL-DBWRAP-DO-LOCKED1", run_dbwrap_do_locked1, 0 },
11553 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
11554 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
11555 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
11556 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
11557 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
11558 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
11559 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
11560 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
11561 { "LOCAL-BASE64", run_local_base64, 0},
11562 { "LOCAL-RBTREE", run_local_rbtree, 0},
11563 { "LOCAL-MEMCACHE", run_local_memcache, 0},
11564 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
11565 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
11566 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
11567 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
11568 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
11569 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
11570 { "LOCAL-TEVENT-POLL", run_local_tevent_poll, 0},
11571 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
11572 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
11573 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
11574 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
11575 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
11576 { "local-tdb-opener", run_local_tdb_opener, 0 },
11577 { "local-tdb-writer", run_local_tdb_writer, 0 },
11578 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
11579 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
11580 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
11581 { "LOCAL-G-LOCK1", run_g_lock1, 0 },
11582 { "LOCAL-G-LOCK2", run_g_lock2, 0 },
11583 { "LOCAL-G-LOCK3", run_g_lock3, 0 },
11584 { "LOCAL-G-LOCK4", run_g_lock4, 0 },
11585 { "LOCAL-G-LOCK5", run_g_lock5, 0 },
11586 { "LOCAL-G-LOCK-PING-PONG", run_g_lock_ping_pong, 0 },
11587 { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 },
11588 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
11591 /****************************************************************************
11592 run a specified test or "ALL"
11593 ****************************************************************************/
11594 static bool run_test(const char *name)
11597 bool result = True;
11598 bool found = False;
11601 if (strequal(name,"ALL")) {
11602 for (i=0;torture_ops[i].name;i++) {
11603 run_test(torture_ops[i].name);
11608 for (i=0;torture_ops[i].name;i++) {
11609 fstr_sprintf(randomfname, "\\XX%x",
11610 (unsigned)random());
11612 if (strequal(name, torture_ops[i].name)) {
11614 printf("Running %s\n", name);
11615 if (torture_ops[i].flags & FLAG_MULTIPROC) {
11616 t = create_procs(torture_ops[i].fn, &result);
11619 printf("TEST %s FAILED!\n", name);
11622 struct timeval start;
11623 start = timeval_current();
11624 if (!torture_ops[i].fn(0)) {
11626 printf("TEST %s FAILED!\n", name);
11628 t = timeval_elapsed(&start);
11630 printf("%s took %g secs\n\n", name, t);
11635 printf("Did not find a test named %s\n", name);
11643 static void usage(void)
11647 printf("WARNING samba4 test suite is much more complete nowadays.\n");
11648 printf("Please use samba4 torture.\n\n");
11650 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
11652 printf("\t-d debuglevel\n");
11653 printf("\t-U user%%pass\n");
11654 printf("\t-k use kerberos\n");
11655 printf("\t-N numprocs\n");
11656 printf("\t-n my_netbios_name\n");
11657 printf("\t-W workgroup\n");
11658 printf("\t-o num_operations\n");
11659 printf("\t-O socket_options\n");
11660 printf("\t-m maximum protocol\n");
11661 printf("\t-L use oplocks\n");
11662 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
11663 printf("\t-A showall\n");
11664 printf("\t-p port\n");
11665 printf("\t-s seed\n");
11666 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
11667 printf("\t-f filename filename to test\n");
11668 printf("\t-e encrypt\n");
11671 printf("tests are:");
11672 for (i=0;torture_ops[i].name;i++) {
11673 printf(" %s", torture_ops[i].name);
11677 printf("default test is ALL\n");
11682 /****************************************************************************
11684 ****************************************************************************/
11685 int main(int argc,char *argv[])
11691 bool correct = True;
11692 TALLOC_CTX *frame = talloc_stackframe();
11693 int seed = time(NULL);
11695 #ifdef HAVE_SETBUFFER
11696 setbuffer(stdout, NULL, 0);
11699 setup_logging("smbtorture", DEBUG_STDOUT);
11704 if (is_default_dyn_CONFIGFILE()) {
11705 if(getenv("SMB_CONF_PATH")) {
11706 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
11709 lp_load_global(get_dyn_CONFIGFILE());
11716 for(p = argv[1]; *p; p++)
11720 if (strncmp(argv[1], "//", 2)) {
11724 fstrcpy(host, &argv[1][2]);
11725 p = strchr_m(&host[2],'/');
11730 fstrcpy(share, p+1);
11732 fstrcpy(myname, get_myname(talloc_tos()));
11734 fprintf(stderr, "Failed to get my hostname.\n");
11738 if (*username == 0 && getenv("LOGNAME")) {
11739 fstrcpy(username,getenv("LOGNAME"));
11745 fstrcpy(workgroup, lp_workgroup());
11747 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
11751 port_to_use = atoi(optarg);
11754 seed = atoi(optarg);
11757 fstrcpy(workgroup,optarg);
11760 lp_set_cmdline("client max protocol", optarg);
11763 torture_nprocs = atoi(optarg);
11766 torture_numops = atoi(optarg);
11769 lp_set_cmdline("log level", optarg);
11775 use_oplocks = True;
11778 local_path = optarg;
11781 torture_showall = True;
11784 fstrcpy(myname, optarg);
11787 client_txt = optarg;
11794 use_kerberos = True;
11796 d_printf("No kerberos support compiled in\n");
11802 fstrcpy(username,optarg);
11803 p = strchr_m(username,'%');
11806 fstrcpy(password, p+1);
11811 fstrcpy(multishare_conn_fname, optarg);
11812 use_multishare_conn = True;
11815 torture_blocksize = atoi(optarg);
11818 test_filename = SMB_STRDUP(optarg);
11821 printf("Unknown option %c (%d)\n", (char)opt, opt);
11826 d_printf("using seed %d\n", seed);
11830 if(use_kerberos && !gotuser) gotpass = True;
11833 char pwd[256] = {0};
11836 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
11838 fstrcpy(password, pwd);
11843 printf("host=%s share=%s user=%s myname=%s\n",
11844 host, share, username, myname);
11846 torture_creds = cli_session_creds_init(frame,
11852 false, /* fallback_after_kerberos */
11853 false, /* use_ccache */
11854 false); /* password_is_nt_hash */
11855 if (torture_creds == NULL) {
11856 d_printf("cli_session_creds_init() failed.\n");
11860 if (argc == optind) {
11861 correct = run_test("ALL");
11863 for (i=optind;i<argc;i++) {
11864 if (!run_test(argv[i])) {
11870 TALLOC_FREE(frame);