2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
29 #include "../lib/util/memcache.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap/dbwrap.h"
32 #include "dbwrap/dbwrap_open.h"
33 #include "dbwrap/dbwrap_rbt.h"
34 #include "talloc_dict.h"
35 #include "async_smb.h"
36 #include "libsmb/libsmb.h"
37 #include "libsmb/clirap.h"
39 #include "libsmb/nmblib.h"
40 #include "../lib/util/tevent_ntstatus.h"
42 #include "../libcli/smb/read_smb.h"
43 #include "../libcli/smb/smbXcli_base.h"
44 #include "lib/util/sys_rw_data.h"
45 #include "lib/util/base64.h"
50 fstring host, workgroup, share, password, username, myname;
51 struct cli_credentials *torture_creds;
52 static const char *sockops="TCP_NODELAY";
54 static int port_to_use=0;
55 int torture_numops=100;
56 int torture_blocksize=1024*1024;
57 static int procnum; /* records process count number when forking */
58 static struct cli_state *current_cli;
59 static fstring randomfname;
60 static bool use_oplocks;
61 static bool use_level_II_oplocks;
62 static const char *client_txt = "client_oplocks.txt";
63 static bool disable_spnego;
64 static bool use_kerberos;
65 static bool force_dos_errors;
66 static fstring multishare_conn_fname;
67 static bool use_multishare_conn = False;
68 static bool do_encrypt;
69 static const char *local_path = NULL;
70 static enum smb_signing_setting signing_state = SMB_SIGNING_DEFAULT;
73 bool torture_showall = False;
75 static double create_procs(bool (*fn)(int), bool *result);
77 /********************************************************************
78 Ensure a connection is encrypted.
79 ********************************************************************/
81 static bool force_cli_encryption(struct cli_state *c,
82 const char *sharename)
84 uint16_t major, minor;
85 uint32_t caplow, caphigh;
88 if (!SERVER_HAS_UNIX_CIFS(c)) {
89 d_printf("Encryption required and "
90 "server that doesn't support "
91 "UNIX extensions - failing connect\n");
95 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
97 if (!NT_STATUS_IS_OK(status)) {
98 d_printf("Encryption required and "
99 "can't get UNIX CIFS extensions "
100 "version from server: %s\n", nt_errstr(status));
104 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
105 d_printf("Encryption required and "
106 "share %s doesn't support "
107 "encryption.\n", sharename);
111 if (c->use_kerberos) {
112 status = cli_gss_smb_encryption_start(c);
114 status = cli_raw_ntlm_smb_encryption_start(c,
120 if (!NT_STATUS_IS_OK(status)) {
121 d_printf("Encryption required and "
122 "setup failed with error %s.\n",
131 static struct cli_state *open_nbt_connection(void)
137 if (disable_spnego) {
138 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
142 flags |= CLI_FULL_CONNECTION_OPLOCKS;
145 if (use_level_II_oplocks) {
146 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
150 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
153 if (force_dos_errors) {
154 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
157 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
158 signing_state, flags, &c);
159 if (!NT_STATUS_IS_OK(status)) {
160 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
164 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
169 /****************************************************************************
170 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
171 ****************************************************************************/
173 static bool cli_bad_session_request(int fd,
174 struct nmb_name *calling, struct nmb_name *called)
183 uint8_t message_type;
185 struct tevent_context *ev;
186 struct tevent_req *req;
188 frame = talloc_stackframe();
190 iov[0].iov_base = len_buf;
191 iov[0].iov_len = sizeof(len_buf);
193 /* put in the destination name */
195 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
197 if (iov[1].iov_base == NULL) {
200 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
201 talloc_get_size(iov[1].iov_base));
205 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
207 if (iov[2].iov_base == NULL) {
210 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
211 talloc_get_size(iov[2].iov_base));
213 /* Deliberately corrupt the name len (first byte) */
214 *((uint8_t *)iov[2].iov_base) = 100;
216 /* send a session request (RFC 1002) */
217 /* setup the packet length
218 * Remove four bytes from the length count, since the length
219 * field in the NBT Session Service header counts the number
220 * of bytes which follow. The cli_send_smb() function knows
221 * about this and accounts for those four bytes.
225 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
226 SCVAL(len_buf,0,0x81);
228 len = write_data_iov(fd, iov, 3);
233 ev = samba_tevent_context_init(frame);
237 req = read_smb_send(frame, ev, fd);
241 if (!tevent_req_poll(req, ev)) {
244 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
251 message_type = CVAL(inbuf, 0);
252 if (message_type != 0x83) {
253 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
258 if (smb_len(inbuf) != 1) {
259 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
260 (int)smb_len(inbuf));
264 error = CVAL(inbuf, 4);
266 d_fprintf(stderr, "Expected error 0x82, got %d\n",
277 /* Insert a NULL at the first separator of the given path and return a pointer
278 * to the remainder of the string.
281 terminate_path_at_separator(char * path)
289 if ((p = strchr_m(path, '/'))) {
294 if ((p = strchr_m(path, '\\'))) {
304 parse a //server/share type UNC name
306 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
307 char **hostname, char **sharename)
311 *hostname = *sharename = NULL;
313 if (strncmp(unc_name, "\\\\", 2) &&
314 strncmp(unc_name, "//", 2)) {
318 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
319 p = terminate_path_at_separator(*hostname);
322 *sharename = talloc_strdup(mem_ctx, p);
323 terminate_path_at_separator(*sharename);
326 if (*hostname && *sharename) {
330 TALLOC_FREE(*hostname);
331 TALLOC_FREE(*sharename);
335 static bool torture_open_connection_share(struct cli_state **c,
336 const char *hostname,
337 const char *sharename)
343 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
345 flags |= CLI_FULL_CONNECTION_OPLOCKS;
346 if (use_level_II_oplocks)
347 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
349 status = cli_full_connection(c, myname,
350 hostname, NULL, port_to_use,
353 password, flags, signing_state);
354 if (!NT_STATUS_IS_OK(status)) {
355 printf("failed to open share connection: //%s/%s port:%d - %s\n",
356 hostname, sharename, port_to_use, nt_errstr(status));
360 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
363 return force_cli_encryption(*c,
369 bool torture_open_connection(struct cli_state **c, int conn_index)
371 char **unc_list = NULL;
372 int num_unc_names = 0;
375 if (use_multishare_conn==True) {
377 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
378 if (!unc_list || num_unc_names <= 0) {
379 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
383 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
385 printf("Failed to parse UNC name %s\n",
386 unc_list[conn_index % num_unc_names]);
387 TALLOC_FREE(unc_list);
391 result = torture_open_connection_share(c, h, s);
393 /* h, s were copied earlier */
394 TALLOC_FREE(unc_list);
398 return torture_open_connection_share(c, host, share);
401 bool torture_init_connection(struct cli_state **pcli)
403 struct cli_state *cli;
405 cli = open_nbt_connection();
414 bool torture_cli_session_setup2(struct cli_state *cli, uint16_t *new_vuid)
416 uint16_t old_vuid = cli_state_get_uid(cli);
420 cli_state_set_uid(cli, 0);
421 status = cli_session_setup(cli, username,
424 ret = NT_STATUS_IS_OK(status);
425 *new_vuid = cli_state_get_uid(cli);
426 cli_state_set_uid(cli, old_vuid);
431 bool torture_close_connection(struct cli_state *c)
436 status = cli_tdis(c);
437 if (!NT_STATUS_IS_OK(status)) {
438 printf("tdis failed (%s)\n", nt_errstr(status));
448 /* check if the server produced the expected dos or nt error code */
449 static bool check_both_error(int line, NTSTATUS status,
450 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
452 if (NT_STATUS_IS_DOS(status)) {
456 /* Check DOS error */
457 cclass = NT_STATUS_DOS_CLASS(status);
458 num = NT_STATUS_DOS_CODE(status);
460 if (eclass != cclass || ecode != num) {
461 printf("unexpected error code class=%d code=%d\n",
462 (int)cclass, (int)num);
463 printf(" expected %d/%d %s (line=%d)\n",
464 (int)eclass, (int)ecode, nt_errstr(nterr), line);
469 if (!NT_STATUS_EQUAL(nterr, status)) {
470 printf("unexpected error code %s\n",
472 printf(" expected %s (line=%d)\n",
473 nt_errstr(nterr), line);
482 /* check if the server produced the expected error code */
483 static bool check_error(int line, NTSTATUS status,
484 uint8_t eclass, uint32_t ecode, NTSTATUS nterr)
486 if (NT_STATUS_IS_DOS(status)) {
490 /* Check DOS error */
492 cclass = NT_STATUS_DOS_CLASS(status);
493 num = NT_STATUS_DOS_CODE(status);
495 if (eclass != cclass || ecode != num) {
496 printf("unexpected error code class=%d code=%d\n",
497 (int)cclass, (int)num);
498 printf(" expected %d/%d %s (line=%d)\n",
499 (int)eclass, (int)ecode, nt_errstr(nterr),
507 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
508 printf("unexpected error code %s\n",
510 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
520 static bool wait_lock(struct cli_state *c, int fnum, uint32_t offset, uint32_t len)
524 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
526 while (!NT_STATUS_IS_OK(status)) {
527 if (!check_both_error(__LINE__, status, ERRDOS,
528 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
532 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
539 static bool rw_torture(struct cli_state *c)
541 const char *lockfname = "\\torture.lck";
545 pid_t pid2, pid = getpid();
552 memset(buf, '\0', sizeof(buf));
554 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
556 if (!NT_STATUS_IS_OK(status)) {
557 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
559 if (!NT_STATUS_IS_OK(status)) {
560 printf("open of %s failed (%s)\n",
561 lockfname, nt_errstr(status));
565 for (i=0;i<torture_numops;i++) {
566 unsigned n = (unsigned)sys_random()%10;
569 printf("%d\r", i); fflush(stdout);
571 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
573 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
577 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
579 if (!NT_STATUS_IS_OK(status)) {
580 printf("open failed (%s)\n", nt_errstr(status));
585 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
587 if (!NT_STATUS_IS_OK(status)) {
588 printf("write failed (%s)\n", nt_errstr(status));
593 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
594 sizeof(pid)+(j*sizeof(buf)),
596 if (!NT_STATUS_IS_OK(status)) {
597 printf("write failed (%s)\n",
605 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
607 if (!NT_STATUS_IS_OK(status)) {
608 printf("read failed (%s)\n", nt_errstr(status));
610 } else if (nread != sizeof(pid)) {
611 printf("read/write compare failed: "
612 "recv %ld req %ld\n", (unsigned long)nread,
613 (unsigned long)sizeof(pid));
618 printf("data corruption!\n");
622 status = cli_close(c, fnum);
623 if (!NT_STATUS_IS_OK(status)) {
624 printf("close failed (%s)\n", nt_errstr(status));
628 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
629 if (!NT_STATUS_IS_OK(status)) {
630 printf("unlink failed (%s)\n", nt_errstr(status));
634 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
635 if (!NT_STATUS_IS_OK(status)) {
636 printf("unlock failed (%s)\n", nt_errstr(status));
642 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
649 static bool run_torture(int dummy)
651 struct cli_state *cli;
656 smbXcli_conn_set_sockopt(cli->conn, sockops);
658 ret = rw_torture(cli);
660 if (!torture_close_connection(cli)) {
667 static bool rw_torture3(struct cli_state *c, char *lockfname)
669 uint16_t fnum = (uint16_t)-1;
674 unsigned countprev = 0;
677 NTSTATUS status = NT_STATUS_OK;
680 for (i = 0; i < sizeof(buf); i += sizeof(uint32_t))
682 SIVAL(buf, i, sys_random());
689 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
690 if (!NT_STATUS_IS_OK(status)) {
691 printf("unlink failed (%s) (normal, this file should "
692 "not exist)\n", nt_errstr(status));
695 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
697 if (!NT_STATUS_IS_OK(status)) {
698 printf("first open read/write of %s failed (%s)\n",
699 lockfname, nt_errstr(status));
705 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
707 status = cli_openx(c, lockfname, O_RDONLY,
709 if (NT_STATUS_IS_OK(status)) {
714 if (!NT_STATUS_IS_OK(status)) {
715 printf("second open read-only of %s failed (%s)\n",
716 lockfname, nt_errstr(status));
722 for (count = 0; count < sizeof(buf); count += sent)
724 if (count >= countprev) {
725 printf("%d %8d\r", i, count);
728 countprev += (sizeof(buf) / 20);
733 sent = ((unsigned)sys_random()%(20))+ 1;
734 if (sent > sizeof(buf) - count)
736 sent = sizeof(buf) - count;
739 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
741 if (!NT_STATUS_IS_OK(status)) {
742 printf("write failed (%s)\n",
749 status = cli_read(c, fnum, buf_rd+count, count,
750 sizeof(buf)-count, &sent);
751 if(!NT_STATUS_IS_OK(status)) {
752 printf("read failed offset:%d size:%ld (%s)\n",
753 count, (unsigned long)sizeof(buf)-count,
757 } else if (sent > 0) {
758 if (memcmp(buf_rd+count, buf+count, sent) != 0)
760 printf("read/write compare failed\n");
761 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
770 status = cli_close(c, fnum);
771 if (!NT_STATUS_IS_OK(status)) {
772 printf("close failed (%s)\n", nt_errstr(status));
779 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
781 const char *lockfname = "\\torture2.lck";
791 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
792 if (!NT_STATUS_IS_OK(status)) {
793 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
796 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
798 if (!NT_STATUS_IS_OK(status)) {
799 printf("first open read/write of %s failed (%s)\n",
800 lockfname, nt_errstr(status));
804 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
805 if (!NT_STATUS_IS_OK(status)) {
806 printf("second open read-only of %s failed (%s)\n",
807 lockfname, nt_errstr(status));
808 cli_close(c1, fnum1);
812 for (i = 0; i < torture_numops; i++)
814 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
816 printf("%d\r", i); fflush(stdout);
819 generate_random_buffer((unsigned char *)buf, buf_size);
821 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
823 if (!NT_STATUS_IS_OK(status)) {
824 printf("write failed (%s)\n", nt_errstr(status));
829 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
830 if(!NT_STATUS_IS_OK(status)) {
831 printf("read failed (%s)\n", nt_errstr(status));
834 } else if (bytes_read != buf_size) {
835 printf("read failed\n");
836 printf("read %ld, expected %ld\n",
837 (unsigned long)bytes_read,
838 (unsigned long)buf_size);
843 if (memcmp(buf_rd, buf, buf_size) != 0)
845 printf("read/write compare failed\n");
851 status = cli_close(c2, fnum2);
852 if (!NT_STATUS_IS_OK(status)) {
853 printf("close failed (%s)\n", nt_errstr(status));
857 status = cli_close(c1, fnum1);
858 if (!NT_STATUS_IS_OK(status)) {
859 printf("close failed (%s)\n", nt_errstr(status));
863 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
864 if (!NT_STATUS_IS_OK(status)) {
865 printf("unlink failed (%s)\n", nt_errstr(status));
872 static bool run_readwritetest(int dummy)
874 struct cli_state *cli1, *cli2;
875 bool test1, test2 = False;
877 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
880 smbXcli_conn_set_sockopt(cli1->conn, sockops);
881 smbXcli_conn_set_sockopt(cli2->conn, sockops);
883 printf("starting readwritetest\n");
885 test1 = rw_torture2(cli1, cli2);
886 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
889 test2 = rw_torture2(cli1, cli1);
890 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
893 if (!torture_close_connection(cli1)) {
897 if (!torture_close_connection(cli2)) {
901 return (test1 && test2);
904 static bool run_readwritemulti(int dummy)
906 struct cli_state *cli;
911 smbXcli_conn_set_sockopt(cli->conn, sockops);
913 printf("run_readwritemulti: fname %s\n", randomfname);
914 test = rw_torture3(cli, randomfname);
916 if (!torture_close_connection(cli)) {
923 static bool run_readwritelarge_internal(void)
925 static struct cli_state *cli1;
927 const char *lockfname = "\\large.dat";
933 if (!torture_open_connection(&cli1, 0)) {
936 smbXcli_conn_set_sockopt(cli1->conn, sockops);
937 memset(buf,'\0',sizeof(buf));
939 printf("starting readwritelarge_internal\n");
941 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
943 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
945 if (!NT_STATUS_IS_OK(status)) {
946 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
950 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
952 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
954 if (!NT_STATUS_IS_OK(status)) {
955 printf("qfileinfo failed (%s)\n", nt_errstr(status));
959 if (fsize == sizeof(buf))
960 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
961 (unsigned long)fsize);
963 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
964 (unsigned long)fsize);
968 status = cli_close(cli1, fnum1);
969 if (!NT_STATUS_IS_OK(status)) {
970 printf("close failed (%s)\n", nt_errstr(status));
974 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
975 if (!NT_STATUS_IS_OK(status)) {
976 printf("unlink failed (%s)\n", nt_errstr(status));
980 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
982 if (!NT_STATUS_IS_OK(status)) {
983 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
987 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
989 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
991 if (!NT_STATUS_IS_OK(status)) {
992 printf("qfileinfo failed (%s)\n", nt_errstr(status));
996 if (fsize == sizeof(buf))
997 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
998 (unsigned long)fsize);
1000 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1001 (unsigned long)fsize);
1006 /* ToDo - set allocation. JRA */
1007 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1008 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1011 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1013 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1017 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1020 status = cli_close(cli1, fnum1);
1021 if (!NT_STATUS_IS_OK(status)) {
1022 printf("close failed (%s)\n", nt_errstr(status));
1026 if (!torture_close_connection(cli1)) {
1032 static bool run_readwritelarge(int dummy)
1034 return run_readwritelarge_internal();
1037 static bool run_readwritelarge_signtest(int dummy)
1040 signing_state = SMB_SIGNING_REQUIRED;
1041 ret = run_readwritelarge_internal();
1042 signing_state = SMB_SIGNING_DEFAULT;
1049 #define ival(s) strtol(s, NULL, 0)
1051 /* run a test that simulates an approximate netbench client load */
1052 static bool run_netbench(int client)
1054 struct cli_state *cli;
1059 const char *params[20];
1060 bool correct = True;
1066 smbXcli_conn_set_sockopt(cli->conn, sockops);
1070 slprintf(cname,sizeof(cname)-1, "client%d", client);
1072 f = fopen(client_txt, "r");
1079 while (fgets(line, sizeof(line)-1, f)) {
1083 line[strlen(line)-1] = 0;
1085 /* printf("[%d] %s\n", line_count, line); */
1087 all_string_sub(line,"client1", cname, sizeof(line));
1089 /* parse the command parameters */
1090 params[0] = strtok_r(line, " ", &saveptr);
1092 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1096 if (i < 2) continue;
1098 if (!strncmp(params[0],"SMB", 3)) {
1099 printf("ERROR: You are using a dbench 1 load file\n");
1103 if (!strcmp(params[0],"NTCreateX")) {
1104 nb_createx(params[1], ival(params[2]), ival(params[3]),
1106 } else if (!strcmp(params[0],"Close")) {
1107 nb_close(ival(params[1]));
1108 } else if (!strcmp(params[0],"Rename")) {
1109 nb_rename(params[1], params[2]);
1110 } else if (!strcmp(params[0],"Unlink")) {
1111 nb_unlink(params[1]);
1112 } else if (!strcmp(params[0],"Deltree")) {
1113 nb_deltree(params[1]);
1114 } else if (!strcmp(params[0],"Rmdir")) {
1115 nb_rmdir(params[1]);
1116 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1117 nb_qpathinfo(params[1]);
1118 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1119 nb_qfileinfo(ival(params[1]));
1120 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1121 nb_qfsinfo(ival(params[1]));
1122 } else if (!strcmp(params[0],"FIND_FIRST")) {
1123 nb_findfirst(params[1]);
1124 } else if (!strcmp(params[0],"WriteX")) {
1125 nb_writex(ival(params[1]),
1126 ival(params[2]), ival(params[3]), ival(params[4]));
1127 } else if (!strcmp(params[0],"ReadX")) {
1128 nb_readx(ival(params[1]),
1129 ival(params[2]), ival(params[3]), ival(params[4]));
1130 } else if (!strcmp(params[0],"Flush")) {
1131 nb_flush(ival(params[1]));
1133 printf("Unknown operation %s\n", params[0]);
1141 if (!torture_close_connection(cli)) {
1149 /* run a test that simulates an approximate netbench client load */
1150 static bool run_nbench(int dummy)
1153 bool correct = True;
1155 nbio_shmem(torture_nprocs);
1159 signal(SIGALRM, nb_alarm);
1161 t = create_procs(run_netbench, &correct);
1164 printf("\nThroughput %g MB/sec\n",
1165 1.0e-6 * nbio_total() / t);
1171 This test checks for two things:
1173 1) correct support for retaining locks over a close (ie. the server
1174 must not use posix semantics)
1175 2) support for lock timeouts
1177 static bool run_locktest1(int dummy)
1179 struct cli_state *cli1, *cli2;
1180 const char *fname = "\\lockt1.lck";
1181 uint16_t fnum1, fnum2, fnum3;
1183 unsigned lock_timeout;
1186 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1189 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1190 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1192 printf("starting locktest1\n");
1194 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1196 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1198 if (!NT_STATUS_IS_OK(status)) {
1199 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1203 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1204 if (!NT_STATUS_IS_OK(status)) {
1205 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1209 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1210 if (!NT_STATUS_IS_OK(status)) {
1211 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1215 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1216 if (!NT_STATUS_IS_OK(status)) {
1217 printf("lock1 failed (%s)\n", nt_errstr(status));
1221 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1222 if (NT_STATUS_IS_OK(status)) {
1223 printf("lock2 succeeded! This is a locking bug\n");
1226 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1227 NT_STATUS_LOCK_NOT_GRANTED)) {
1232 lock_timeout = (1 + (random() % 20));
1233 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1235 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1236 if (NT_STATUS_IS_OK(status)) {
1237 printf("lock3 succeeded! This is a locking bug\n");
1240 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1241 NT_STATUS_FILE_LOCK_CONFLICT)) {
1247 if (ABS(t2 - t1) < lock_timeout-1) {
1248 printf("error: This server appears not to support timed lock requests\n");
1251 printf("server slept for %u seconds for a %u second timeout\n",
1252 (unsigned int)(t2-t1), lock_timeout);
1254 status = cli_close(cli1, fnum2);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 printf("close1 failed (%s)\n", nt_errstr(status));
1260 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1261 if (NT_STATUS_IS_OK(status)) {
1262 printf("lock4 succeeded! This is a locking bug\n");
1265 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1266 NT_STATUS_FILE_LOCK_CONFLICT)) {
1271 status = cli_close(cli1, fnum1);
1272 if (!NT_STATUS_IS_OK(status)) {
1273 printf("close2 failed (%s)\n", nt_errstr(status));
1277 status = cli_close(cli2, fnum3);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 printf("close3 failed (%s)\n", nt_errstr(status));
1283 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1284 if (!NT_STATUS_IS_OK(status)) {
1285 printf("unlink failed (%s)\n", nt_errstr(status));
1290 if (!torture_close_connection(cli1)) {
1294 if (!torture_close_connection(cli2)) {
1298 printf("Passed locktest1\n");
1303 this checks to see if a secondary tconx can use open files from an
1306 static bool run_tcon_test(int dummy)
1308 static struct cli_state *cli;
1309 const char *fname = "\\tcontest.tmp";
1311 uint16_t cnum1, cnum2, cnum3;
1312 uint16_t vuid1, vuid2;
1317 memset(buf, '\0', sizeof(buf));
1319 if (!torture_open_connection(&cli, 0)) {
1322 smbXcli_conn_set_sockopt(cli->conn, sockops);
1324 printf("starting tcontest\n");
1326 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1328 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1329 if (!NT_STATUS_IS_OK(status)) {
1330 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1334 cnum1 = cli_state_get_tid(cli);
1335 vuid1 = cli_state_get_uid(cli);
1337 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 printf("initial write failed (%s)", nt_errstr(status));
1343 status = cli_tree_connect(cli, share, "?????",
1344 password, strlen(password)+1);
1345 if (!NT_STATUS_IS_OK(status)) {
1346 printf("%s refused 2nd tree connect (%s)\n", host,
1352 cnum2 = cli_state_get_tid(cli);
1353 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1354 vuid2 = cli_state_get_uid(cli) + 1;
1356 /* try a write with the wrong tid */
1357 cli_state_set_tid(cli, cnum2);
1359 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1360 if (NT_STATUS_IS_OK(status)) {
1361 printf("* server allows write with wrong TID\n");
1364 printf("server fails write with wrong TID : %s\n",
1369 /* try a write with an invalid tid */
1370 cli_state_set_tid(cli, cnum3);
1372 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1373 if (NT_STATUS_IS_OK(status)) {
1374 printf("* server allows write with invalid TID\n");
1377 printf("server fails write with invalid TID : %s\n",
1381 /* try a write with an invalid vuid */
1382 cli_state_set_uid(cli, vuid2);
1383 cli_state_set_tid(cli, cnum1);
1385 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1386 if (NT_STATUS_IS_OK(status)) {
1387 printf("* server allows write with invalid VUID\n");
1390 printf("server fails write with invalid VUID : %s\n",
1394 cli_state_set_tid(cli, cnum1);
1395 cli_state_set_uid(cli, vuid1);
1397 status = cli_close(cli, fnum1);
1398 if (!NT_STATUS_IS_OK(status)) {
1399 printf("close failed (%s)\n", nt_errstr(status));
1403 cli_state_set_tid(cli, cnum2);
1405 status = cli_tdis(cli);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1411 cli_state_set_tid(cli, cnum1);
1413 if (!torture_close_connection(cli)) {
1422 checks for old style tcon support
1424 static bool run_tcon2_test(int dummy)
1426 static struct cli_state *cli;
1427 uint16_t cnum, max_xmit;
1431 if (!torture_open_connection(&cli, 0)) {
1434 smbXcli_conn_set_sockopt(cli->conn, sockops);
1436 printf("starting tcon2 test\n");
1438 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1442 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1446 if (!NT_STATUS_IS_OK(status)) {
1447 printf("tcon2 failed : %s\n", nt_errstr(status));
1449 printf("tcon OK : max_xmit=%d cnum=%d\n",
1450 (int)max_xmit, (int)cnum);
1453 if (!torture_close_connection(cli)) {
1457 printf("Passed tcon2 test\n");
1461 static bool tcon_devtest(struct cli_state *cli,
1462 const char *myshare, const char *devtype,
1463 const char *return_devtype,
1464 NTSTATUS expected_error)
1469 status = cli_tree_connect(cli, myshare, devtype,
1470 password, strlen(password)+1);
1472 if (NT_STATUS_IS_OK(expected_error)) {
1473 if (NT_STATUS_IS_OK(status)) {
1474 if (strcmp(cli->dev, return_devtype) == 0) {
1477 printf("tconX to share %s with type %s "
1478 "succeeded but returned the wrong "
1479 "device type (got [%s] but should have got [%s])\n",
1480 myshare, devtype, cli->dev, return_devtype);
1484 printf("tconX to share %s with type %s "
1485 "should have succeeded but failed\n",
1491 if (NT_STATUS_IS_OK(status)) {
1492 printf("tconx to share %s with type %s "
1493 "should have failed but succeeded\n",
1497 if (NT_STATUS_EQUAL(status, expected_error)) {
1500 printf("Returned unexpected error\n");
1509 checks for correct tconX support
1511 static bool run_tcon_devtype_test(int dummy)
1513 static struct cli_state *cli1 = NULL;
1518 status = cli_full_connection(&cli1, myname,
1519 host, NULL, port_to_use,
1521 username, workgroup,
1522 password, flags, signing_state);
1524 if (!NT_STATUS_IS_OK(status)) {
1525 printf("could not open connection\n");
1529 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1532 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1535 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1538 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1541 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1544 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1547 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1550 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1553 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1556 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1562 printf("Passed tcondevtest\n");
1569 This test checks that
1571 1) the server supports multiple locking contexts on the one SMB
1572 connection, distinguished by PID.
1574 2) the server correctly fails overlapping locks made by the same PID (this
1575 goes against POSIX behaviour, which is why it is tricky to implement)
1577 3) the server denies unlock requests by an incorrect client PID
1579 static bool run_locktest2(int dummy)
1581 static struct cli_state *cli;
1582 const char *fname = "\\lockt2.lck";
1583 uint16_t fnum1, fnum2, fnum3;
1584 bool correct = True;
1587 if (!torture_open_connection(&cli, 0)) {
1591 smbXcli_conn_set_sockopt(cli->conn, sockops);
1593 printf("starting locktest2\n");
1595 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1599 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1600 if (!NT_STATUS_IS_OK(status)) {
1601 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1605 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1606 if (!NT_STATUS_IS_OK(status)) {
1607 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1613 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1614 if (!NT_STATUS_IS_OK(status)) {
1615 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1621 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1622 if (!NT_STATUS_IS_OK(status)) {
1623 printf("lock1 failed (%s)\n", nt_errstr(status));
1627 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1628 if (NT_STATUS_IS_OK(status)) {
1629 printf("WRITE lock1 succeeded! This is a locking bug\n");
1632 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1633 NT_STATUS_LOCK_NOT_GRANTED)) {
1638 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1639 if (NT_STATUS_IS_OK(status)) {
1640 printf("WRITE lock2 succeeded! This is a locking bug\n");
1643 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1644 NT_STATUS_LOCK_NOT_GRANTED)) {
1649 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1650 if (NT_STATUS_IS_OK(status)) {
1651 printf("READ lock2 succeeded! This is a locking bug\n");
1654 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1655 NT_STATUS_FILE_LOCK_CONFLICT)) {
1660 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1661 if (!NT_STATUS_IS_OK(status)) {
1662 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1665 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1666 printf("unlock at 100 succeeded! This is a locking bug\n");
1670 status = cli_unlock(cli, fnum1, 0, 4);
1671 if (NT_STATUS_IS_OK(status)) {
1672 printf("unlock1 succeeded! This is a locking bug\n");
1675 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1676 NT_STATUS_RANGE_NOT_LOCKED)) {
1681 status = cli_unlock(cli, fnum1, 0, 8);
1682 if (NT_STATUS_IS_OK(status)) {
1683 printf("unlock2 succeeded! This is a locking bug\n");
1686 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1687 NT_STATUS_RANGE_NOT_LOCKED)) {
1692 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1693 if (NT_STATUS_IS_OK(status)) {
1694 printf("lock3 succeeded! This is a locking bug\n");
1697 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1698 NT_STATUS_LOCK_NOT_GRANTED)) {
1705 status = cli_close(cli, fnum1);
1706 if (!NT_STATUS_IS_OK(status)) {
1707 printf("close1 failed (%s)\n", nt_errstr(status));
1711 status = cli_close(cli, fnum2);
1712 if (!NT_STATUS_IS_OK(status)) {
1713 printf("close2 failed (%s)\n", nt_errstr(status));
1717 status = cli_close(cli, fnum3);
1718 if (!NT_STATUS_IS_OK(status)) {
1719 printf("close3 failed (%s)\n", nt_errstr(status));
1723 if (!torture_close_connection(cli)) {
1727 printf("locktest2 finished\n");
1734 This test checks that
1736 1) the server supports the full offset range in lock requests
1738 static bool run_locktest3(int dummy)
1740 static struct cli_state *cli1, *cli2;
1741 const char *fname = "\\lockt3.lck";
1742 uint16_t fnum1, fnum2;
1745 bool correct = True;
1748 #define NEXT_OFFSET offset += (~(uint32_t)0) / torture_numops
1750 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1753 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1754 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1756 printf("starting locktest3\n");
1758 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1760 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1762 if (!NT_STATUS_IS_OK(status)) {
1763 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1767 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1768 if (!NT_STATUS_IS_OK(status)) {
1769 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1773 for (offset=i=0;i<torture_numops;i++) {
1776 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1777 if (!NT_STATUS_IS_OK(status)) {
1778 printf("lock1 %d failed (%s)\n",
1784 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1785 if (!NT_STATUS_IS_OK(status)) {
1786 printf("lock2 %d failed (%s)\n",
1793 for (offset=i=0;i<torture_numops;i++) {
1796 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1797 if (NT_STATUS_IS_OK(status)) {
1798 printf("error: lock1 %d succeeded!\n", i);
1802 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1803 if (NT_STATUS_IS_OK(status)) {
1804 printf("error: lock2 %d succeeded!\n", i);
1808 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1809 if (NT_STATUS_IS_OK(status)) {
1810 printf("error: lock3 %d succeeded!\n", i);
1814 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1815 if (NT_STATUS_IS_OK(status)) {
1816 printf("error: lock4 %d succeeded!\n", i);
1821 for (offset=i=0;i<torture_numops;i++) {
1824 status = cli_unlock(cli1, fnum1, offset-1, 1);
1825 if (!NT_STATUS_IS_OK(status)) {
1826 printf("unlock1 %d failed (%s)\n",
1832 status = cli_unlock(cli2, fnum2, offset-2, 1);
1833 if (!NT_STATUS_IS_OK(status)) {
1834 printf("unlock2 %d failed (%s)\n",
1841 status = cli_close(cli1, fnum1);
1842 if (!NT_STATUS_IS_OK(status)) {
1843 printf("close1 failed (%s)\n", nt_errstr(status));
1847 status = cli_close(cli2, fnum2);
1848 if (!NT_STATUS_IS_OK(status)) {
1849 printf("close2 failed (%s)\n", nt_errstr(status));
1853 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1854 if (!NT_STATUS_IS_OK(status)) {
1855 printf("unlink failed (%s)\n", nt_errstr(status));
1859 if (!torture_close_connection(cli1)) {
1863 if (!torture_close_connection(cli2)) {
1867 printf("finished locktest3\n");
1872 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1873 char *buf, off_t offset, size_t size,
1874 size_t *nread, size_t expect)
1879 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1881 if(!NT_STATUS_IS_OK(status)) {
1883 } else if (l_nread != expect) {
1894 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1895 printf("** "); correct = False; \
1899 looks at overlapping locks
1901 static bool run_locktest4(int dummy)
1903 static struct cli_state *cli1, *cli2;
1904 const char *fname = "\\lockt4.lck";
1905 uint16_t fnum1, fnum2, f;
1908 bool correct = True;
1911 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1915 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1916 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1918 printf("starting locktest4\n");
1920 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1922 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1923 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1925 memset(buf, 0, sizeof(buf));
1927 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1929 if (!NT_STATUS_IS_OK(status)) {
1930 printf("Failed to create file: %s\n", nt_errstr(status));
1935 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1936 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1937 EXPECTED(ret, False);
1938 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1940 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1941 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1942 EXPECTED(ret, True);
1943 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1945 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1946 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1947 EXPECTED(ret, False);
1948 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1950 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
1951 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
1952 EXPECTED(ret, True);
1953 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1955 ret = (cli_setpid(cli1, 1),
1956 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
1957 (cli_setpid(cli1, 2),
1958 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
1959 EXPECTED(ret, False);
1960 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1962 ret = (cli_setpid(cli1, 1),
1963 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
1964 (cli_setpid(cli1, 2),
1965 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
1966 EXPECTED(ret, True);
1967 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1969 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
1970 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
1971 EXPECTED(ret, True);
1972 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1974 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
1975 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
1976 EXPECTED(ret, False);
1977 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1979 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
1980 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
1981 EXPECTED(ret, False);
1982 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1984 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
1985 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
1986 EXPECTED(ret, True);
1987 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1989 ret = (cli_setpid(cli1, 1),
1990 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
1991 (cli_setpid(cli1, 2),
1992 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
1993 EXPECTED(ret, False);
1994 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1996 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
1997 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
1998 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1999 EXPECTED(ret, False);
2000 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2003 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2004 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2005 EXPECTED(ret, False);
2006 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2008 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2009 ret = NT_STATUS_IS_OK(status);
2011 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2013 ret = NT_STATUS_IS_OK(status);
2015 EXPECTED(ret, False);
2016 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2019 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2020 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2021 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2022 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2023 EXPECTED(ret, True);
2024 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2027 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2028 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2029 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2030 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2031 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2033 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2034 EXPECTED(ret, True);
2035 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2037 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2038 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2039 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2041 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2042 EXPECTED(ret, True);
2043 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2045 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2046 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2047 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2049 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2050 EXPECTED(ret, True);
2051 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2053 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2054 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2055 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2056 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2058 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2059 EXPECTED(ret, True);
2060 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2062 cli_close(cli1, fnum1);
2063 cli_close(cli2, fnum2);
2064 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2065 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2066 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2067 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2068 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2069 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2070 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2072 cli_close(cli1, fnum1);
2073 EXPECTED(ret, True);
2074 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2077 cli_close(cli1, fnum1);
2078 cli_close(cli2, fnum2);
2079 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2080 torture_close_connection(cli1);
2081 torture_close_connection(cli2);
2083 printf("finished locktest4\n");
2088 looks at lock upgrade/downgrade.
2090 static bool run_locktest5(int dummy)
2092 static struct cli_state *cli1, *cli2;
2093 const char *fname = "\\lockt5.lck";
2094 uint16_t fnum1, fnum2, fnum3;
2097 bool correct = True;
2100 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2104 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2105 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2107 printf("starting locktest5\n");
2109 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2111 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2112 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2113 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2115 memset(buf, 0, sizeof(buf));
2117 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2119 if (!NT_STATUS_IS_OK(status)) {
2120 printf("Failed to create file: %s\n", nt_errstr(status));
2125 /* Check for NT bug... */
2126 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2127 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2128 cli_close(cli1, fnum1);
2129 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2130 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2131 ret = NT_STATUS_IS_OK(status);
2132 EXPECTED(ret, True);
2133 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2134 cli_close(cli1, fnum1);
2135 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2136 cli_unlock(cli1, fnum3, 0, 1);
2138 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2139 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2140 EXPECTED(ret, True);
2141 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2143 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2144 ret = NT_STATUS_IS_OK(status);
2145 EXPECTED(ret, False);
2147 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2149 /* Unlock the process 2 lock. */
2150 cli_unlock(cli2, fnum2, 0, 4);
2152 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2153 ret = NT_STATUS_IS_OK(status);
2154 EXPECTED(ret, False);
2156 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2158 /* Unlock the process 1 fnum3 lock. */
2159 cli_unlock(cli1, fnum3, 0, 4);
2161 /* Stack 2 more locks here. */
2162 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2163 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2165 EXPECTED(ret, True);
2166 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2168 /* Unlock the first process lock, then check this was the WRITE lock that was
2171 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2172 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2174 EXPECTED(ret, True);
2175 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2177 /* Unlock the process 2 lock. */
2178 cli_unlock(cli2, fnum2, 0, 4);
2180 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2182 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2183 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2184 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2186 EXPECTED(ret, True);
2187 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2189 /* Ensure the next unlock fails. */
2190 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2191 EXPECTED(ret, False);
2192 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2194 /* Ensure connection 2 can get a write lock. */
2195 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2196 ret = NT_STATUS_IS_OK(status);
2197 EXPECTED(ret, True);
2199 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2203 cli_close(cli1, fnum1);
2204 cli_close(cli2, fnum2);
2205 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2206 if (!torture_close_connection(cli1)) {
2209 if (!torture_close_connection(cli2)) {
2213 printf("finished locktest5\n");
2219 tries the unusual lockingX locktype bits
2221 static bool run_locktest6(int dummy)
2223 static struct cli_state *cli;
2224 const char *fname[1] = { "\\lock6.txt" };
2229 if (!torture_open_connection(&cli, 0)) {
2233 smbXcli_conn_set_sockopt(cli->conn, sockops);
2235 printf("starting locktest6\n");
2238 printf("Testing %s\n", fname[i]);
2240 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2242 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2243 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2244 cli_close(cli, fnum);
2245 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2247 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2248 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2249 cli_close(cli, fnum);
2250 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2252 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2255 torture_close_connection(cli);
2257 printf("finished locktest6\n");
2261 static bool run_locktest7(int dummy)
2263 struct cli_state *cli1;
2264 const char *fname = "\\lockt7.lck";
2267 bool correct = False;
2271 if (!torture_open_connection(&cli1, 0)) {
2275 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2277 printf("starting locktest7\n");
2279 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2281 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2283 memset(buf, 0, sizeof(buf));
2285 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2287 if (!NT_STATUS_IS_OK(status)) {
2288 printf("Failed to create file: %s\n", nt_errstr(status));
2292 cli_setpid(cli1, 1);
2294 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2295 if (!NT_STATUS_IS_OK(status)) {
2296 printf("Unable to apply read lock on range 130:4, "
2297 "error was %s\n", nt_errstr(status));
2300 printf("pid1 successfully locked range 130:4 for READ\n");
2303 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2304 if (!NT_STATUS_IS_OK(status)) {
2305 printf("pid1 unable to read the range 130:4, error was %s\n",
2308 } else if (nread != 4) {
2309 printf("pid1 unable to read the range 130:4, "
2310 "recv %ld req %d\n", (unsigned long)nread, 4);
2313 printf("pid1 successfully read the range 130:4\n");
2316 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2317 if (!NT_STATUS_IS_OK(status)) {
2318 printf("pid1 unable to write to the range 130:4, error was "
2319 "%s\n", nt_errstr(status));
2320 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2321 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2325 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2329 cli_setpid(cli1, 2);
2331 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2332 if (!NT_STATUS_IS_OK(status)) {
2333 printf("pid2 unable to read the range 130:4, error was %s\n",
2336 } else if (nread != 4) {
2337 printf("pid2 unable to read the range 130:4, "
2338 "recv %ld req %d\n", (unsigned long)nread, 4);
2341 printf("pid2 successfully read the range 130:4\n");
2344 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2345 if (!NT_STATUS_IS_OK(status)) {
2346 printf("pid2 unable to write to the range 130:4, error was "
2347 "%s\n", nt_errstr(status));
2348 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2349 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2353 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2357 cli_setpid(cli1, 1);
2358 cli_unlock(cli1, fnum1, 130, 4);
2360 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2361 if (!NT_STATUS_IS_OK(status)) {
2362 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2365 printf("pid1 successfully locked range 130:4 for WRITE\n");
2368 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2369 if (!NT_STATUS_IS_OK(status)) {
2370 printf("pid1 unable to read the range 130:4, error was %s\n",
2373 } else if (nread != 4) {
2374 printf("pid1 unable to read the range 130:4, "
2375 "recv %ld req %d\n", (unsigned long)nread, 4);
2378 printf("pid1 successfully read the range 130:4\n");
2381 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2382 if (!NT_STATUS_IS_OK(status)) {
2383 printf("pid1 unable to write to the range 130:4, error was "
2384 "%s\n", nt_errstr(status));
2387 printf("pid1 successfully wrote to the range 130:4\n");
2390 cli_setpid(cli1, 2);
2392 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2393 if (!NT_STATUS_IS_OK(status)) {
2394 printf("pid2 unable to read the range 130:4, error was "
2395 "%s\n", nt_errstr(status));
2396 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2397 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2401 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2402 (unsigned long)nread);
2406 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2407 if (!NT_STATUS_IS_OK(status)) {
2408 printf("pid2 unable to write to the range 130:4, error was "
2409 "%s\n", nt_errstr(status));
2410 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2411 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2415 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2419 cli_unlock(cli1, fnum1, 130, 0);
2423 cli_close(cli1, fnum1);
2424 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2425 torture_close_connection(cli1);
2427 printf("finished locktest7\n");
2432 * This demonstrates a problem with our use of GPFS share modes: A file
2433 * descriptor sitting in the pending close queue holding a GPFS share mode
2434 * blocks opening a file another time. Happens with Word 2007 temp files.
2435 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2436 * open is denied with NT_STATUS_SHARING_VIOLATION.
2439 static bool run_locktest8(int dummy)
2441 struct cli_state *cli1;
2442 const char *fname = "\\lockt8.lck";
2443 uint16_t fnum1, fnum2;
2445 bool correct = False;
2448 if (!torture_open_connection(&cli1, 0)) {
2452 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2454 printf("starting locktest8\n");
2456 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2458 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2460 if (!NT_STATUS_IS_OK(status)) {
2461 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2465 memset(buf, 0, sizeof(buf));
2467 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2468 if (!NT_STATUS_IS_OK(status)) {
2469 d_fprintf(stderr, "cli_openx second time returned %s\n",
2474 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2475 if (!NT_STATUS_IS_OK(status)) {
2476 printf("Unable to apply read lock on range 1:1, error was "
2477 "%s\n", nt_errstr(status));
2481 status = cli_close(cli1, fnum1);
2482 if (!NT_STATUS_IS_OK(status)) {
2483 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2487 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2488 if (!NT_STATUS_IS_OK(status)) {
2489 d_fprintf(stderr, "cli_openx third time returned %s\n",
2497 cli_close(cli1, fnum1);
2498 cli_close(cli1, fnum2);
2499 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2500 torture_close_connection(cli1);
2502 printf("finished locktest8\n");
2507 * This test is designed to be run in conjunction with
2508 * external NFS or POSIX locks taken in the filesystem.
2509 * It checks that the smbd server will block until the
2510 * lock is released and then acquire it. JRA.
2513 static bool got_alarm;
2514 static struct cli_state *alarm_cli;
2516 static void alarm_handler(int dummy)
2521 static void alarm_handler_parent(int dummy)
2523 smbXcli_conn_disconnect(alarm_cli->conn, NT_STATUS_OK);
2526 static void do_local_lock(int read_fd, int write_fd)
2531 const char *local_pathname = NULL;
2534 local_pathname = talloc_asprintf(talloc_tos(),
2535 "%s/lockt9.lck", local_path);
2536 if (!local_pathname) {
2537 printf("child: alloc fail\n");
2541 unlink(local_pathname);
2542 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2544 printf("child: open of %s failed %s.\n",
2545 local_pathname, strerror(errno));
2549 /* Now take a fcntl lock. */
2550 lock.l_type = F_WRLCK;
2551 lock.l_whence = SEEK_SET;
2554 lock.l_pid = getpid();
2556 ret = fcntl(fd,F_SETLK,&lock);
2558 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2559 local_pathname, strerror(errno));
2562 printf("child: got lock 0:4 on file %s.\n",
2567 CatchSignal(SIGALRM, alarm_handler);
2569 /* Signal the parent. */
2570 if (write(write_fd, &c, 1) != 1) {
2571 printf("child: start signal fail %s.\n",
2578 /* Wait for the parent to be ready. */
2579 if (read(read_fd, &c, 1) != 1) {
2580 printf("child: reply signal fail %s.\n",
2588 printf("child: released lock 0:4 on file %s.\n",
2594 static bool run_locktest9(int dummy)
2596 struct cli_state *cli1;
2597 const char *fname = "\\lockt9.lck";
2599 bool correct = False;
2600 int pipe_in[2], pipe_out[2];
2604 struct timeval start;
2608 printf("starting locktest9\n");
2610 if (local_path == NULL) {
2611 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2615 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2620 if (child_pid == -1) {
2624 if (child_pid == 0) {
2626 do_local_lock(pipe_out[0], pipe_in[1]);
2636 ret = read(pipe_in[0], &c, 1);
2638 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2643 if (!torture_open_connection(&cli1, 0)) {
2647 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2649 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2651 if (!NT_STATUS_IS_OK(status)) {
2652 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2656 /* Ensure the child has the lock. */
2657 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2658 if (NT_STATUS_IS_OK(status)) {
2659 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2662 d_printf("Child has the lock.\n");
2665 /* Tell the child to wait 5 seconds then exit. */
2666 ret = write(pipe_out[1], &c, 1);
2668 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2673 /* Wait 20 seconds for the lock. */
2675 CatchSignal(SIGALRM, alarm_handler_parent);
2678 start = timeval_current();
2680 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2681 if (!NT_STATUS_IS_OK(status)) {
2682 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2683 "%s\n", nt_errstr(status));
2688 seconds = timeval_elapsed(&start);
2690 printf("Parent got the lock after %.2f seconds.\n",
2693 status = cli_close(cli1, fnum);
2694 if (!NT_STATUS_IS_OK(status)) {
2695 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2702 cli_close(cli1, fnum);
2703 torture_close_connection(cli1);
2707 printf("finished locktest9\n");
2712 test whether fnums and tids open on one VC are available on another (a major
2715 static bool run_fdpasstest(int dummy)
2717 struct cli_state *cli1, *cli2;
2718 const char *fname = "\\fdpass.tst";
2723 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2726 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2727 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2729 printf("starting fdpasstest\n");
2731 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2733 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2735 if (!NT_STATUS_IS_OK(status)) {
2736 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2740 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2742 if (!NT_STATUS_IS_OK(status)) {
2743 printf("write failed (%s)\n", nt_errstr(status));
2747 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2748 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2749 cli_setpid(cli2, cli_getpid(cli1));
2751 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2752 printf("read succeeded! nasty security hole [%s]\n", buf);
2756 cli_close(cli1, fnum1);
2757 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2759 torture_close_connection(cli1);
2760 torture_close_connection(cli2);
2762 printf("finished fdpasstest\n");
2766 static bool run_fdsesstest(int dummy)
2768 struct cli_state *cli;
2770 uint16_t saved_vuid;
2772 uint16_t saved_cnum;
2773 const char *fname = "\\fdsess.tst";
2774 const char *fname1 = "\\fdsess1.tst";
2781 if (!torture_open_connection(&cli, 0))
2783 smbXcli_conn_set_sockopt(cli->conn, sockops);
2785 if (!torture_cli_session_setup2(cli, &new_vuid))
2788 saved_cnum = cli_state_get_tid(cli);
2789 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", "", 1)))
2791 new_cnum = cli_state_get_tid(cli);
2792 cli_state_set_tid(cli, saved_cnum);
2794 printf("starting fdsesstest\n");
2796 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2797 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2799 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2800 if (!NT_STATUS_IS_OK(status)) {
2801 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2805 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2807 if (!NT_STATUS_IS_OK(status)) {
2808 printf("write failed (%s)\n", nt_errstr(status));
2812 saved_vuid = cli_state_get_uid(cli);
2813 cli_state_set_uid(cli, new_vuid);
2815 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2816 printf("read succeeded with different vuid! "
2817 "nasty security hole [%s]\n", buf);
2820 /* Try to open a file with different vuid, samba cnum. */
2821 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2822 printf("create with different vuid, same cnum succeeded.\n");
2823 cli_close(cli, fnum2);
2824 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2826 printf("create with different vuid, same cnum failed.\n");
2827 printf("This will cause problems with service clients.\n");
2831 cli_state_set_uid(cli, saved_vuid);
2833 /* Try with same vuid, different cnum. */
2834 cli_state_set_tid(cli, new_cnum);
2836 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2837 printf("read succeeded with different cnum![%s]\n", buf);
2841 cli_state_set_tid(cli, saved_cnum);
2842 cli_close(cli, fnum1);
2843 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2845 torture_close_connection(cli);
2847 printf("finished fdsesstest\n");
2852 This test checks that
2854 1) the server does not allow an unlink on a file that is open
2856 static bool run_unlinktest(int dummy)
2858 struct cli_state *cli;
2859 const char *fname = "\\unlink.tst";
2861 bool correct = True;
2864 if (!torture_open_connection(&cli, 0)) {
2868 smbXcli_conn_set_sockopt(cli->conn, sockops);
2870 printf("starting unlink test\n");
2872 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2876 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2877 if (!NT_STATUS_IS_OK(status)) {
2878 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2882 status = cli_unlink(cli, fname,
2883 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2884 if (NT_STATUS_IS_OK(status)) {
2885 printf("error: server allowed unlink on an open file\n");
2888 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2889 NT_STATUS_SHARING_VIOLATION);
2892 cli_close(cli, fnum);
2893 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2895 if (!torture_close_connection(cli)) {
2899 printf("unlink test finished\n");
2906 test how many open files this server supports on the one socket
2908 static bool run_maxfidtest(int dummy)
2910 struct cli_state *cli;
2912 uint16_t fnums[0x11000];
2915 bool correct = True;
2921 printf("failed to connect\n");
2925 smbXcli_conn_set_sockopt(cli->conn, sockops);
2927 for (i=0; i<0x11000; i++) {
2928 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2929 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2931 if (!NT_STATUS_IS_OK(status)) {
2932 printf("open of %s failed (%s)\n",
2933 fname, nt_errstr(status));
2934 printf("maximum fnum is %d\n", i);
2942 printf("cleaning up\n");
2944 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2945 cli_close(cli, fnums[i]);
2947 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2948 if (!NT_STATUS_IS_OK(status)) {
2949 printf("unlink of %s failed (%s)\n",
2950 fname, nt_errstr(status));
2957 printf("maxfid test finished\n");
2958 if (!torture_close_connection(cli)) {
2964 /* generate a random buffer */
2965 static void rand_buf(char *buf, int len)
2968 *buf = (char)sys_random();
2973 /* send smb negprot commands, not reading the response */
2974 static bool run_negprot_nowait(int dummy)
2976 struct tevent_context *ev;
2978 struct cli_state *cli;
2979 bool correct = True;
2981 printf("starting negprot nowait test\n");
2983 ev = samba_tevent_context_init(talloc_tos());
2988 if (!(cli = open_nbt_connection())) {
2993 for (i=0;i<50000;i++) {
2994 struct tevent_req *req;
2996 req = smbXcli_negprot_send(ev, ev, cli->conn, cli->timeout,
2997 PROTOCOL_CORE, PROTOCOL_NT1);
3002 if (!tevent_req_poll(req, ev)) {
3003 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3011 if (torture_close_connection(cli)) {
3015 printf("finished negprot nowait test\n");
3020 /* send smb negprot commands, not reading the response */
3021 static bool run_bad_nbt_session(int dummy)
3023 struct nmb_name called, calling;
3024 struct sockaddr_storage ss;
3029 printf("starting bad nbt session test\n");
3031 make_nmb_name(&calling, myname, 0x0);
3032 make_nmb_name(&called , host, 0x20);
3034 if (!resolve_name(host, &ss, 0x20, true)) {
3035 d_fprintf(stderr, "Could not resolve name %s\n", host);
3039 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3040 if (!NT_STATUS_IS_OK(status)) {
3041 d_fprintf(stderr, "open_socket_out failed: %s\n",
3046 ret = cli_bad_session_request(fd, &calling, &called);
3049 d_fprintf(stderr, "open_socket_out failed: %s\n",
3054 printf("finished bad nbt session test\n");
3058 /* send random IPC commands */
3059 static bool run_randomipc(int dummy)
3061 char *rparam = NULL;
3063 unsigned int rdrcnt,rprcnt;
3065 int api, param_len, i;
3066 struct cli_state *cli;
3067 bool correct = True;
3070 printf("starting random ipc test\n");
3072 if (!torture_open_connection(&cli, 0)) {
3076 for (i=0;i<count;i++) {
3077 api = sys_random() % 500;
3078 param_len = (sys_random() % 64);
3080 rand_buf(param, param_len);
3085 param, param_len, 8,
3086 NULL, 0, CLI_BUFFER_SIZE,
3090 printf("%d/%d\r", i,count);
3093 printf("%d/%d\n", i, count);
3095 if (!torture_close_connection(cli)) {
3102 printf("finished random ipc test\n");
3109 static void browse_callback(const char *sname, uint32_t stype,
3110 const char *comment, void *state)
3112 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3118 This test checks the browse list code
3121 static bool run_browsetest(int dummy)
3123 static struct cli_state *cli;
3124 bool correct = True;
3126 printf("starting browse test\n");
3128 if (!torture_open_connection(&cli, 0)) {
3132 printf("domain list:\n");
3133 cli_NetServerEnum(cli, cli->server_domain,
3134 SV_TYPE_DOMAIN_ENUM,
3135 browse_callback, NULL);
3137 printf("machine list:\n");
3138 cli_NetServerEnum(cli, cli->server_domain,
3140 browse_callback, NULL);
3142 if (!torture_close_connection(cli)) {
3146 printf("browse test finished\n");
3154 This checks how the getatr calls works
3156 static bool run_attrtest(int dummy)
3158 struct cli_state *cli;
3161 const char *fname = "\\attrib123456789.tst";
3162 bool correct = True;
3165 printf("starting attrib test\n");
3167 if (!torture_open_connection(&cli, 0)) {
3171 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3172 cli_openx(cli, fname,
3173 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3174 cli_close(cli, fnum);
3176 status = cli_getatr(cli, fname, NULL, NULL, &t);
3177 if (!NT_STATUS_IS_OK(status)) {
3178 printf("getatr failed (%s)\n", nt_errstr(status));
3182 if (abs(t - time(NULL)) > 60*60*24*10) {
3183 printf("ERROR: SMBgetatr bug. time is %s",
3189 t2 = t-60*60*24; /* 1 day ago */
3191 status = cli_setatr(cli, fname, 0, t2);
3192 if (!NT_STATUS_IS_OK(status)) {
3193 printf("setatr failed (%s)\n", nt_errstr(status));
3197 status = cli_getatr(cli, fname, NULL, NULL, &t);
3198 if (!NT_STATUS_IS_OK(status)) {
3199 printf("getatr failed (%s)\n", nt_errstr(status));
3204 printf("ERROR: getatr/setatr bug. times are\n%s",
3206 printf("%s", ctime(&t2));
3210 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3212 if (!torture_close_connection(cli)) {
3216 printf("attrib test finished\n");
3223 This checks a couple of trans2 calls
3225 static bool run_trans2test(int dummy)
3227 struct cli_state *cli;
3230 time_t c_time, a_time, m_time;
3231 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3232 const char *fname = "\\trans2.tst";
3233 const char *dname = "\\trans2";
3234 const char *fname2 = "\\trans2\\trans2.tst";
3236 bool correct = True;
3240 printf("starting trans2 test\n");
3242 if (!torture_open_connection(&cli, 0)) {
3246 status = cli_get_fs_attr_info(cli, &fs_attr);
3247 if (!NT_STATUS_IS_OK(status)) {
3248 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3253 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3254 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3255 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3256 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3257 if (!NT_STATUS_IS_OK(status)) {
3258 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3262 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3263 if (!NT_STATUS_IS_OK(status)) {
3264 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3267 else if (strcmp(pname, fname)) {
3268 printf("qfilename gave different name? [%s] [%s]\n",
3273 cli_close(cli, fnum);
3277 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3278 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3280 if (!NT_STATUS_IS_OK(status)) {
3281 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3284 cli_close(cli, fnum);
3286 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3288 if (!NT_STATUS_IS_OK(status)) {
3289 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3292 time_t t = time(NULL);
3294 if (c_time != m_time) {
3295 printf("create time=%s", ctime(&c_time));
3296 printf("modify time=%s", ctime(&m_time));
3297 printf("This system appears to have sticky create times\n");
3299 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3300 printf("access time=%s", ctime(&a_time));
3301 printf("This system appears to set a midnight access time\n");
3305 if (abs(m_time - t) > 60*60*24*7) {
3306 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3312 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3313 cli_openx(cli, fname,
3314 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3315 cli_close(cli, fnum);
3316 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3317 &m_time_ts, &size, NULL, NULL);
3318 if (!NT_STATUS_IS_OK(status)) {
3319 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3322 if (w_time_ts.tv_sec < 60*60*24*2) {
3323 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3324 printf("This system appears to set a initial 0 write time\n");
3329 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3332 /* check if the server updates the directory modification time
3333 when creating a new file */
3334 status = cli_mkdir(cli, dname);
3335 if (!NT_STATUS_IS_OK(status)) {
3336 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3340 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3341 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3342 if (!NT_STATUS_IS_OK(status)) {
3343 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3347 cli_openx(cli, fname2,
3348 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3349 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3350 cli_close(cli, fnum);
3351 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3352 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3353 if (!NT_STATUS_IS_OK(status)) {
3354 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3357 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3359 printf("This system does not update directory modification times\n");
3363 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3364 cli_rmdir(cli, dname);
3366 if (!torture_close_connection(cli)) {
3370 printf("trans2 test finished\n");
3376 This checks new W2K calls.
3379 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3381 uint8_t *buf = NULL;
3385 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3386 CLI_BUFFER_SIZE, NULL, &buf, &len);
3387 if (!NT_STATUS_IS_OK(status)) {
3388 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3391 printf("qfileinfo: level %d, len = %u\n", level, len);
3392 dump_data(0, (uint8_t *)buf, len);
3399 static bool run_w2ktest(int dummy)
3401 struct cli_state *cli;
3403 const char *fname = "\\w2ktest\\w2k.tst";
3405 bool correct = True;
3407 printf("starting w2k test\n");
3409 if (!torture_open_connection(&cli, 0)) {
3413 cli_openx(cli, fname,
3414 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3416 for (level = 1004; level < 1040; level++) {
3417 new_trans(cli, fnum, level);
3420 cli_close(cli, fnum);
3422 if (!torture_close_connection(cli)) {
3426 printf("w2k test finished\n");
3433 this is a harness for some oplock tests
3435 static bool run_oplock1(int dummy)
3437 struct cli_state *cli1;
3438 const char *fname = "\\lockt1.lck";
3440 bool correct = True;
3443 printf("starting oplock test 1\n");
3445 if (!torture_open_connection(&cli1, 0)) {
3449 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3451 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3453 cli1->use_oplocks = True;
3455 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3457 if (!NT_STATUS_IS_OK(status)) {
3458 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3462 cli1->use_oplocks = False;
3464 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3465 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3467 status = cli_close(cli1, fnum1);
3468 if (!NT_STATUS_IS_OK(status)) {
3469 printf("close2 failed (%s)\n", nt_errstr(status));
3473 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3474 if (!NT_STATUS_IS_OK(status)) {
3475 printf("unlink failed (%s)\n", nt_errstr(status));
3479 if (!torture_close_connection(cli1)) {
3483 printf("finished oplock test 1\n");
3488 static bool run_oplock2(int dummy)
3490 struct cli_state *cli1, *cli2;
3491 const char *fname = "\\lockt2.lck";
3492 uint16_t fnum1, fnum2;
3493 int saved_use_oplocks = use_oplocks;
3495 bool correct = True;
3496 volatile bool *shared_correct;
3500 shared_correct = (volatile bool *)anonymous_shared_allocate(sizeof(bool));
3501 *shared_correct = True;
3503 use_level_II_oplocks = True;
3506 printf("starting oplock test 2\n");
3508 if (!torture_open_connection(&cli1, 0)) {
3509 use_level_II_oplocks = False;
3510 use_oplocks = saved_use_oplocks;
3514 if (!torture_open_connection(&cli2, 1)) {
3515 use_level_II_oplocks = False;
3516 use_oplocks = saved_use_oplocks;
3520 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3522 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3523 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3525 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3527 if (!NT_STATUS_IS_OK(status)) {
3528 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3532 /* Don't need the globals any more. */
3533 use_level_II_oplocks = False;
3534 use_oplocks = saved_use_oplocks;
3538 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3539 if (!NT_STATUS_IS_OK(status)) {
3540 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3541 *shared_correct = False;
3547 status = cli_close(cli2, fnum2);
3548 if (!NT_STATUS_IS_OK(status)) {
3549 printf("close2 failed (%s)\n", nt_errstr(status));
3550 *shared_correct = False;
3558 /* Ensure cli1 processes the break. Empty file should always return 0
3560 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3561 if (!NT_STATUS_IS_OK(status)) {
3562 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3564 } else if (nread != 0) {
3565 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3566 (unsigned long)nread, 0);
3570 /* Should now be at level II. */
3571 /* Test if sending a write locks causes a break to none. */
3572 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3573 if (!NT_STATUS_IS_OK(status)) {
3574 printf("lock failed (%s)\n", nt_errstr(status));
3578 cli_unlock(cli1, fnum1, 0, 4);
3582 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3583 if (!NT_STATUS_IS_OK(status)) {
3584 printf("lock failed (%s)\n", nt_errstr(status));
3588 cli_unlock(cli1, fnum1, 0, 4);
3592 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3594 status = cli_close(cli1, fnum1);
3595 if (!NT_STATUS_IS_OK(status)) {
3596 printf("close1 failed (%s)\n", nt_errstr(status));
3602 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3603 if (!NT_STATUS_IS_OK(status)) {
3604 printf("unlink failed (%s)\n", nt_errstr(status));
3608 if (!torture_close_connection(cli1)) {
3612 if (!*shared_correct) {
3616 printf("finished oplock test 2\n");
3621 struct oplock4_state {
3622 struct tevent_context *ev;
3623 struct cli_state *cli;
3628 static void oplock4_got_break(struct tevent_req *req);
3629 static void oplock4_got_open(struct tevent_req *req);
3631 static bool run_oplock4(int dummy)
3633 struct tevent_context *ev;
3634 struct cli_state *cli1, *cli2;
3635 struct tevent_req *oplock_req, *open_req;
3636 const char *fname = "\\lockt4.lck";
3637 const char *fname_ln = "\\lockt4_ln.lck";
3638 uint16_t fnum1, fnum2;
3639 int saved_use_oplocks = use_oplocks;
3641 bool correct = true;
3645 struct oplock4_state *state;
3647 printf("starting oplock test 4\n");
3649 if (!torture_open_connection(&cli1, 0)) {
3650 use_level_II_oplocks = false;
3651 use_oplocks = saved_use_oplocks;
3655 if (!torture_open_connection(&cli2, 1)) {
3656 use_level_II_oplocks = false;
3657 use_oplocks = saved_use_oplocks;
3661 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3662 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3664 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3665 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3667 /* Create the file. */
3668 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3670 if (!NT_STATUS_IS_OK(status)) {
3671 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3675 status = cli_close(cli1, fnum1);
3676 if (!NT_STATUS_IS_OK(status)) {
3677 printf("close1 failed (%s)\n", nt_errstr(status));
3681 /* Now create a hardlink. */
3682 status = cli_nt_hardlink(cli1, fname, fname_ln);
3683 if (!NT_STATUS_IS_OK(status)) {
3684 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3688 /* Prove that opening hardlinks cause deny modes to conflict. */
3689 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3690 if (!NT_STATUS_IS_OK(status)) {
3691 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3695 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3696 if (NT_STATUS_IS_OK(status)) {
3697 printf("open of %s succeeded - should fail with sharing violation.\n",
3702 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3703 printf("open of %s should fail with sharing violation. Got %s\n",
3704 fname_ln, nt_errstr(status));
3708 status = cli_close(cli1, fnum1);
3709 if (!NT_STATUS_IS_OK(status)) {
3710 printf("close1 failed (%s)\n", nt_errstr(status));
3714 cli1->use_oplocks = true;
3715 cli2->use_oplocks = true;
3717 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3718 if (!NT_STATUS_IS_OK(status)) {
3719 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3723 ev = samba_tevent_context_init(talloc_tos());
3725 printf("tevent_context_init failed\n");
3729 state = talloc(ev, struct oplock4_state);
3730 if (state == NULL) {
3731 printf("talloc failed\n");
3736 state->got_break = &got_break;
3737 state->fnum2 = &fnum2;
3739 oplock_req = cli_smb_oplock_break_waiter_send(
3740 talloc_tos(), ev, cli1);
3741 if (oplock_req == NULL) {
3742 printf("cli_smb_oplock_break_waiter_send failed\n");
3745 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3747 open_req = cli_openx_send(
3748 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3749 if (open_req == NULL) {
3750 printf("cli_openx_send failed\n");
3753 tevent_req_set_callback(open_req, oplock4_got_open, state);
3758 while (!got_break || fnum2 == 0xffff) {
3760 ret = tevent_loop_once(ev);
3762 printf("tevent_loop_once failed: %s\n",
3768 status = cli_close(cli2, fnum2);
3769 if (!NT_STATUS_IS_OK(status)) {
3770 printf("close2 failed (%s)\n", nt_errstr(status));
3774 status = cli_close(cli1, fnum1);
3775 if (!NT_STATUS_IS_OK(status)) {
3776 printf("close1 failed (%s)\n", nt_errstr(status));
3780 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3781 if (!NT_STATUS_IS_OK(status)) {
3782 printf("unlink failed (%s)\n", nt_errstr(status));
3786 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3787 if (!NT_STATUS_IS_OK(status)) {
3788 printf("unlink failed (%s)\n", nt_errstr(status));
3792 if (!torture_close_connection(cli1)) {
3800 printf("finished oplock test 4\n");
3805 static void oplock4_got_break(struct tevent_req *req)
3807 struct oplock4_state *state = tevent_req_callback_data(
3808 req, struct oplock4_state);
3813 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3815 if (!NT_STATUS_IS_OK(status)) {
3816 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3820 *state->got_break = true;
3822 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3825 printf("cli_oplock_ack_send failed\n");
3830 static void oplock4_got_open(struct tevent_req *req)
3832 struct oplock4_state *state = tevent_req_callback_data(
3833 req, struct oplock4_state);
3836 status = cli_openx_recv(req, state->fnum2);
3837 if (!NT_STATUS_IS_OK(status)) {
3838 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3839 *state->fnum2 = 0xffff;
3844 Test delete on close semantics.
3846 static bool run_deletetest(int dummy)
3848 struct cli_state *cli1 = NULL;
3849 struct cli_state *cli2 = NULL;
3850 const char *fname = "\\delete.file";
3851 uint16_t fnum1 = (uint16_t)-1;
3852 uint16_t fnum2 = (uint16_t)-1;
3853 bool correct = false;
3856 printf("starting delete test\n");
3858 if (!torture_open_connection(&cli1, 0)) {
3862 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3864 /* Test 1 - this should delete the file on close. */
3866 cli_setatr(cli1, fname, 0, 0);
3867 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3869 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3870 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3871 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
3872 if (!NT_STATUS_IS_OK(status)) {
3873 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3877 status = cli_close(cli1, fnum1);
3878 if (!NT_STATUS_IS_OK(status)) {
3879 printf("[1] close failed (%s)\n", nt_errstr(status));
3883 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3884 if (NT_STATUS_IS_OK(status)) {
3885 printf("[1] open of %s succeeded (should fail)\n", fname);
3889 printf("first delete on close test succeeded.\n");
3891 /* Test 2 - this should delete the file on close. */
3893 cli_setatr(cli1, fname, 0, 0);
3894 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3896 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3897 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3898 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3899 if (!NT_STATUS_IS_OK(status)) {
3900 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3904 status = cli_nt_delete_on_close(cli1, fnum1, true);
3905 if (!NT_STATUS_IS_OK(status)) {
3906 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3910 status = cli_close(cli1, fnum1);
3911 if (!NT_STATUS_IS_OK(status)) {
3912 printf("[2] close failed (%s)\n", nt_errstr(status));
3916 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3917 if (NT_STATUS_IS_OK(status)) {
3918 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3919 status = cli_close(cli1, fnum1);
3920 if (!NT_STATUS_IS_OK(status)) {
3921 printf("[2] close failed (%s)\n", nt_errstr(status));
3923 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3927 printf("second delete on close test succeeded.\n");
3930 cli_setatr(cli1, fname, 0, 0);
3931 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3933 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3934 FILE_ATTRIBUTE_NORMAL,
3935 FILE_SHARE_READ|FILE_SHARE_WRITE,
3936 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
3937 if (!NT_STATUS_IS_OK(status)) {
3938 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3942 /* This should fail with a sharing violation - open for delete is only compatible
3943 with SHARE_DELETE. */
3945 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3946 FILE_ATTRIBUTE_NORMAL,
3947 FILE_SHARE_READ|FILE_SHARE_WRITE,
3948 FILE_OPEN, 0, 0, &fnum2, NULL);
3949 if (NT_STATUS_IS_OK(status)) {
3950 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3954 /* This should succeed. */
3955 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3956 FILE_ATTRIBUTE_NORMAL,
3957 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3958 FILE_OPEN, 0, 0, &fnum2, NULL);
3959 if (!NT_STATUS_IS_OK(status)) {
3960 printf("[3] open - 3 of %s failed (%s)\n", fname, nt_errstr(status));
3964 status = cli_nt_delete_on_close(cli1, fnum1, true);
3965 if (!NT_STATUS_IS_OK(status)) {
3966 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3970 status = cli_close(cli1, fnum1);
3971 if (!NT_STATUS_IS_OK(status)) {
3972 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3976 status = cli_close(cli1, fnum2);
3977 if (!NT_STATUS_IS_OK(status)) {
3978 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3982 /* This should fail - file should no longer be there. */
3984 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
3985 if (NT_STATUS_IS_OK(status)) {
3986 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3987 status = cli_close(cli1, fnum1);
3988 if (!NT_STATUS_IS_OK(status)) {
3989 printf("[3] close failed (%s)\n", nt_errstr(status));
3991 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3995 printf("third delete on close test succeeded.\n");
3998 cli_setatr(cli1, fname, 0, 0);
3999 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4001 status = cli_ntcreate(cli1, fname, 0,
4002 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4003 FILE_ATTRIBUTE_NORMAL,
4004 FILE_SHARE_READ|FILE_SHARE_WRITE,
4005 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4006 if (!NT_STATUS_IS_OK(status)) {
4007 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4011 /* This should succeed. */
4012 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4013 FILE_ATTRIBUTE_NORMAL,
4014 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4015 FILE_OPEN, 0, 0, &fnum2, NULL);
4016 if (!NT_STATUS_IS_OK(status)) {
4017 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4021 status = cli_close(cli1, fnum2);
4022 if (!NT_STATUS_IS_OK(status)) {
4023 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4027 status = cli_nt_delete_on_close(cli1, fnum1, true);
4028 if (!NT_STATUS_IS_OK(status)) {
4029 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4033 /* This should fail - no more opens once delete on close set. */
4034 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4035 FILE_ATTRIBUTE_NORMAL,
4036 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4037 FILE_OPEN, 0, 0, &fnum2, NULL);
4038 if (NT_STATUS_IS_OK(status)) {
4039 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4043 status = cli_close(cli1, fnum1);
4044 if (!NT_STATUS_IS_OK(status)) {
4045 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4049 printf("fourth delete on close test succeeded.\n");
4052 cli_setatr(cli1, fname, 0, 0);
4053 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4055 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4056 if (!NT_STATUS_IS_OK(status)) {
4057 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4061 /* This should fail - only allowed on NT opens with DELETE access. */
4063 status = cli_nt_delete_on_close(cli1, fnum1, true);
4064 if (NT_STATUS_IS_OK(status)) {
4065 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4069 status = cli_close(cli1, fnum1);
4070 if (!NT_STATUS_IS_OK(status)) {
4071 printf("[5] close failed (%s)\n", nt_errstr(status));
4075 printf("fifth delete on close test succeeded.\n");
4078 cli_setatr(cli1, fname, 0, 0);
4079 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4081 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4082 FILE_ATTRIBUTE_NORMAL,
4083 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4084 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4085 if (!NT_STATUS_IS_OK(status)) {
4086 printf("[6] open of %s failed (%s)\n", fname,
4091 /* This should fail - only allowed on NT opens with DELETE access. */
4093 status = cli_nt_delete_on_close(cli1, fnum1, true);
4094 if (NT_STATUS_IS_OK(status)) {
4095 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4099 status = cli_close(cli1, fnum1);
4100 if (!NT_STATUS_IS_OK(status)) {
4101 printf("[6] close failed (%s)\n", nt_errstr(status));
4105 printf("sixth delete on close test succeeded.\n");
4108 cli_setatr(cli1, fname, 0, 0);
4109 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4111 status = cli_ntcreate(cli1, fname, 0,
4112 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4113 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4114 0, 0, &fnum1, NULL);
4115 if (!NT_STATUS_IS_OK(status)) {
4116 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4120 status = cli_nt_delete_on_close(cli1, fnum1, true);
4121 if (!NT_STATUS_IS_OK(status)) {
4122 printf("[7] setting delete_on_close on file failed !\n");
4126 status = cli_nt_delete_on_close(cli1, fnum1, false);
4127 if (!NT_STATUS_IS_OK(status)) {
4128 printf("[7] unsetting delete_on_close on file failed !\n");
4132 status = cli_close(cli1, fnum1);
4133 if (!NT_STATUS_IS_OK(status)) {
4134 printf("[7] close - 1 failed (%s)\n", nt_errstr(status));
4138 /* This next open should succeed - we reset the flag. */
4139 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4140 if (!NT_STATUS_IS_OK(status)) {
4141 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4145 status = cli_close(cli1, fnum1);
4146 if (!NT_STATUS_IS_OK(status)) {
4147 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4151 printf("seventh delete on close test succeeded.\n");
4154 cli_setatr(cli1, fname, 0, 0);
4155 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4157 if (!torture_open_connection(&cli2, 1)) {
4158 printf("[8] failed to open second connection.\n");
4162 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4164 status = cli_ntcreate(cli1, fname, 0,
4165 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4166 FILE_ATTRIBUTE_NORMAL,
4167 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4168 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4169 if (!NT_STATUS_IS_OK(status)) {
4170 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4174 status = cli_ntcreate(cli2, fname, 0,
4175 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4176 FILE_ATTRIBUTE_NORMAL,
4177 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4178 FILE_OPEN, 0, 0, &fnum2, NULL);
4179 if (!NT_STATUS_IS_OK(status)) {
4180 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4184 status = cli_nt_delete_on_close(cli1, fnum1, true);
4185 if (!NT_STATUS_IS_OK(status)) {
4186 printf("[8] setting delete_on_close on file failed !\n");
4190 status = cli_close(cli1, fnum1);
4191 if (!NT_STATUS_IS_OK(status)) {
4192 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4196 status = cli_close(cli2, fnum2);
4197 if (!NT_STATUS_IS_OK(status)) {
4198 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4202 /* This should fail.. */
4203 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4204 if (NT_STATUS_IS_OK(status)) {
4205 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4209 printf("eighth delete on close test succeeded.\n");
4213 /* This should fail - we need to set DELETE_ACCESS. */
4214 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4215 FILE_ATTRIBUTE_NORMAL,
4218 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4219 if (NT_STATUS_IS_OK(status)) {
4220 printf("[9] open of %s succeeded should have failed!\n", fname);
4224 printf("ninth delete on close test succeeded.\n");
4228 status = cli_ntcreate(cli1, fname, 0,
4229 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4230 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4231 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4233 if (!NT_STATUS_IS_OK(status)) {
4234 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4238 /* This should delete the file. */
4239 status = cli_close(cli1, fnum1);
4240 if (!NT_STATUS_IS_OK(status)) {
4241 printf("[10] close failed (%s)\n", nt_errstr(status));
4245 /* This should fail.. */
4246 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4247 if (NT_STATUS_IS_OK(status)) {
4248 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4252 printf("tenth delete on close test succeeded.\n");
4256 cli_setatr(cli1, fname, 0, 0);
4257 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4259 /* Can we open a read-only file with delete access? */
4261 /* Create a readonly file. */
4262 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4263 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4264 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4265 if (!NT_STATUS_IS_OK(status)) {
4266 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4270 status = cli_close(cli1, fnum1);
4271 if (!NT_STATUS_IS_OK(status)) {
4272 printf("[11] close failed (%s)\n", nt_errstr(status));
4276 /* Now try open for delete access. */
4277 status = cli_ntcreate(cli1, fname, 0,
4278 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4280 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4281 FILE_OPEN, 0, 0, &fnum1, NULL);
4282 if (!NT_STATUS_IS_OK(status)) {
4283 printf("[11] open of %s failed: %s\n", fname, nt_errstr(status));
4287 cli_close(cli1, fnum1);
4289 printf("eleventh delete on close test succeeded.\n");
4293 * like test 4 but with initial delete on close
4296 cli_setatr(cli1, fname, 0, 0);
4297 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4299 status = cli_ntcreate(cli1, fname, 0,
4300 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4301 FILE_ATTRIBUTE_NORMAL,
4302 FILE_SHARE_READ|FILE_SHARE_WRITE,
4304 FILE_DELETE_ON_CLOSE, 0, &fnum1, NULL);
4305 if (!NT_STATUS_IS_OK(status)) {
4306 printf("[12] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4310 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4311 FILE_ATTRIBUTE_NORMAL,
4312 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4313 FILE_OPEN, 0, 0, &fnum2, NULL);
4314 if (!NT_STATUS_IS_OK(status)) {
4315 printf("[12] open 2 of %s failed(%s).\n", fname, nt_errstr(status));
4319 status = cli_close(cli1, fnum2);
4320 if (!NT_STATUS_IS_OK(status)) {
4321 printf("[12] close 1 failed (%s)\n", nt_errstr(status));
4325 status = cli_nt_delete_on_close(cli1, fnum1, true);
4326 if (!NT_STATUS_IS_OK(status)) {
4327 printf("[12] setting delete_on_close failed (%s)\n", nt_errstr(status));
4331 /* This should fail - no more opens once delete on close set. */
4332 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4333 FILE_ATTRIBUTE_NORMAL,
4334 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4335 FILE_OPEN, 0, 0, &fnum2, NULL);
4336 if (NT_STATUS_IS_OK(status)) {
4337 printf("[12] open 3 of %s succeeded - should fail).\n", fname);
4341 status = cli_nt_delete_on_close(cli1, fnum1, false);
4342 if (!NT_STATUS_IS_OK(status)) {
4343 printf("[12] unsetting delete_on_close failed (%s)\n", nt_errstr(status));
4347 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4348 FILE_ATTRIBUTE_NORMAL,
4349 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4350 FILE_OPEN, 0, 0, &fnum2, NULL);
4351 if (!NT_STATUS_IS_OK(status)) {
4352 printf("[12] open 4 of %s failed (%s)\n", fname, nt_errstr(status));
4356 status = cli_close(cli1, fnum2);
4357 if (!NT_STATUS_IS_OK(status)) {
4358 printf("[12] close 2 failed (%s)\n", nt_errstr(status));
4362 status = cli_close(cli1, fnum1);
4363 if (!NT_STATUS_IS_OK(status)) {
4364 printf("[12] close 3 failed (%s)\n", nt_errstr(status));
4369 * setting delete on close on the handle does
4370 * not unset the initial delete on close...
4372 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4373 FILE_ATTRIBUTE_NORMAL,
4374 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4375 FILE_OPEN, 0, 0, &fnum2, NULL);
4376 if (NT_STATUS_IS_OK(status)) {
4377 printf("[12] open 5 of %s succeeded - should fail).\n", fname);
4379 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4380 printf("ntcreate returned %s, expected "
4381 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
4386 printf("twelfth delete on close test succeeded.\n");
4389 printf("finished delete test\n");
4394 /* FIXME: This will crash if we aborted before cli2 got
4395 * intialized, because these functions don't handle
4396 * uninitialized connections. */
4398 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4399 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4400 cli_setatr(cli1, fname, 0, 0);
4401 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4403 if (cli1 && !torture_close_connection(cli1)) {
4406 if (cli2 && !torture_close_connection(cli2)) {
4414 Test wildcard delete.
4416 static bool run_wild_deletetest(int dummy)
4418 struct cli_state *cli = NULL;
4419 const char *dname = "\\WTEST";
4420 const char *fname = "\\WTEST\\A";
4421 const char *wunlink_name = "\\WTEST\\*";
4422 uint16_t fnum1 = (uint16_t)-1;
4423 bool correct = false;
4426 printf("starting wildcard delete test\n");
4428 if (!torture_open_connection(&cli, 0)) {
4432 smbXcli_conn_set_sockopt(cli->conn, sockops);
4434 cli_unlink(cli, fname, 0);
4435 cli_rmdir(cli, dname);
4436 status = cli_mkdir(cli, dname);
4437 if (!NT_STATUS_IS_OK(status)) {
4438 printf("mkdir of %s failed %s!\n", dname, nt_errstr(status));
4441 status = cli_openx(cli, fname, O_CREAT|O_RDONLY, DENY_NONE, &fnum1);
4442 if (!NT_STATUS_IS_OK(status)) {
4443 printf("open of %s failed %s!\n", fname, nt_errstr(status));
4446 status = cli_close(cli, fnum1);
4450 * Note the unlink attribute-type of zero. This should
4451 * map into FILE_ATTRIBUTE_NORMAL at the server even
4452 * on a wildcard delete.
4455 status = cli_unlink(cli, wunlink_name, 0);
4456 if (!NT_STATUS_IS_OK(status)) {
4457 printf("unlink of %s failed %s!\n",
4458 wunlink_name, nt_errstr(status));
4462 printf("finished wildcard delete test\n");
4468 if (fnum1 != (uint16_t)-1) cli_close(cli, fnum1);
4469 cli_unlink(cli, fname, 0);
4470 cli_rmdir(cli, dname);
4472 if (cli && !torture_close_connection(cli)) {
4478 static bool run_deletetest_ln(int dummy)
4480 struct cli_state *cli;
4481 const char *fname = "\\delete1";
4482 const char *fname_ln = "\\delete1_ln";
4486 bool correct = true;
4489 printf("starting deletetest-ln\n");
4491 if (!torture_open_connection(&cli, 0)) {
4495 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4496 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4498 smbXcli_conn_set_sockopt(cli->conn, sockops);
4500 /* Create the file. */
4501 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4502 if (!NT_STATUS_IS_OK(status)) {
4503 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4507 status = cli_close(cli, fnum);
4508 if (!NT_STATUS_IS_OK(status)) {
4509 printf("close1 failed (%s)\n", nt_errstr(status));
4513 /* Now create a hardlink. */
4514 status = cli_nt_hardlink(cli, fname, fname_ln);
4515 if (!NT_STATUS_IS_OK(status)) {
4516 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4520 /* Open the original file. */
4521 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4522 FILE_ATTRIBUTE_NORMAL,
4523 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4524 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4525 if (!NT_STATUS_IS_OK(status)) {
4526 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4530 /* Unlink the hard link path. */
4531 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4532 FILE_ATTRIBUTE_NORMAL,
4533 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4534 FILE_OPEN_IF, 0, 0, &fnum1, NULL);
4535 if (!NT_STATUS_IS_OK(status)) {
4536 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4539 status = cli_nt_delete_on_close(cli, fnum1, true);
4540 if (!NT_STATUS_IS_OK(status)) {
4541 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4542 __location__, fname_ln, nt_errstr(status));
4546 status = cli_close(cli, fnum1);
4547 if (!NT_STATUS_IS_OK(status)) {
4548 printf("close %s failed (%s)\n",
4549 fname_ln, nt_errstr(status));
4553 status = cli_close(cli, fnum);
4554 if (!NT_STATUS_IS_OK(status)) {
4555 printf("close %s failed (%s)\n",
4556 fname, nt_errstr(status));
4560 /* Ensure the original file is still there. */
4561 status = cli_getatr(cli, fname, NULL, NULL, &t);
4562 if (!NT_STATUS_IS_OK(status)) {
4563 printf("%s getatr on file %s failed (%s)\n",
4570 /* Ensure the link path is gone. */
4571 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4572 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4573 printf("%s, getatr for file %s returned wrong error code %s "
4574 "- should have been deleted\n",
4576 fname_ln, nt_errstr(status));
4580 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4581 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4583 if (!torture_close_connection(cli)) {
4587 printf("finished deletetest-ln\n");
4593 print out server properties
4595 static bool run_properties(int dummy)
4597 struct cli_state *cli;
4598 bool correct = True;
4600 printf("starting properties test\n");
4604 if (!torture_open_connection(&cli, 0)) {
4608 smbXcli_conn_set_sockopt(cli->conn, sockops);
4610 d_printf("Capabilities 0x%08x\n", smb1cli_conn_capabilities(cli->conn));
4612 if (!torture_close_connection(cli)) {
4621 /* FIRST_DESIRED_ACCESS 0xf019f */
4622 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4623 FILE_READ_EA| /* 0xf */ \
4624 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4625 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4626 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4627 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4628 /* SECOND_DESIRED_ACCESS 0xe0080 */
4629 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4630 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4631 WRITE_OWNER_ACCESS /* 0xe0000 */
4634 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4635 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4637 WRITE_OWNER_ACCESS /* */
4641 Test ntcreate calls made by xcopy
4643 static bool run_xcopy(int dummy)
4645 static struct cli_state *cli1;
4646 const char *fname = "\\test.txt";
4647 bool correct = True;
4648 uint16_t fnum1, fnum2;
4651 printf("starting xcopy test\n");
4653 if (!torture_open_connection(&cli1, 0)) {
4657 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4658 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4659 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1, NULL);
4660 if (!NT_STATUS_IS_OK(status)) {
4661 printf("First open failed - %s\n", nt_errstr(status));
4665 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4666 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4667 FILE_OPEN, 0x200000, 0, &fnum2, NULL);
4668 if (!NT_STATUS_IS_OK(status)) {
4669 printf("second open failed - %s\n", nt_errstr(status));
4673 if (!torture_close_connection(cli1)) {
4681 Test rename on files open with share delete and no share delete.
4683 static bool run_rename(int dummy)
4685 static struct cli_state *cli1;
4686 const char *fname = "\\test.txt";
4687 const char *fname1 = "\\test1.txt";
4688 bool correct = True;
4693 printf("starting rename test\n");
4695 if (!torture_open_connection(&cli1, 0)) {
4699 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4700 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4702 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4703 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4704 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4705 if (!NT_STATUS_IS_OK(status)) {
4706 printf("First open failed - %s\n", nt_errstr(status));
4710 status = cli_rename(cli1, fname, fname1);
4711 if (!NT_STATUS_IS_OK(status)) {
4712 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4714 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4718 status = cli_close(cli1, fnum1);
4719 if (!NT_STATUS_IS_OK(status)) {
4720 printf("close - 1 failed (%s)\n", nt_errstr(status));
4724 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4725 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4726 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4728 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4730 FILE_SHARE_DELETE|FILE_SHARE_READ,
4732 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4733 if (!NT_STATUS_IS_OK(status)) {
4734 printf("Second open failed - %s\n", nt_errstr(status));
4738 status = cli_rename(cli1, fname, fname1);
4739 if (!NT_STATUS_IS_OK(status)) {
4740 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4743 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4746 status = cli_close(cli1, fnum1);
4747 if (!NT_STATUS_IS_OK(status)) {
4748 printf("close - 2 failed (%s)\n", nt_errstr(status));
4752 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4753 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4755 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4756 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4757 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4758 if (!NT_STATUS_IS_OK(status)) {
4759 printf("Third open failed - %s\n", nt_errstr(status));
4768 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4769 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4770 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4773 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4774 printf("[8] setting delete_on_close on file failed !\n");
4778 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4779 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4785 status = cli_rename(cli1, fname, fname1);
4786 if (!NT_STATUS_IS_OK(status)) {
4787 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4790 printf("Third rename succeeded (SHARE_NONE)\n");
4793 status = cli_close(cli1, fnum1);
4794 if (!NT_STATUS_IS_OK(status)) {
4795 printf("close - 3 failed (%s)\n", nt_errstr(status));
4799 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4800 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4804 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4805 FILE_ATTRIBUTE_NORMAL,
4806 FILE_SHARE_READ | FILE_SHARE_WRITE,
4807 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4808 if (!NT_STATUS_IS_OK(status)) {
4809 printf("Fourth open failed - %s\n", nt_errstr(status));
4813 status = cli_rename(cli1, fname, fname1);
4814 if (!NT_STATUS_IS_OK(status)) {
4815 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4817 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4821 status = cli_close(cli1, fnum1);
4822 if (!NT_STATUS_IS_OK(status)) {
4823 printf("close - 4 failed (%s)\n", nt_errstr(status));
4827 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4828 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4832 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4833 FILE_ATTRIBUTE_NORMAL,
4834 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4835 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
4836 if (!NT_STATUS_IS_OK(status)) {
4837 printf("Fifth open failed - %s\n", nt_errstr(status));
4841 status = cli_rename(cli1, fname, fname1);
4842 if (!NT_STATUS_IS_OK(status)) {
4843 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4846 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4850 * Now check if the first name still exists ...
4853 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4854 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4855 FILE_OVERWRITE_IF, 0, 0, &fnum2, NULL))) {
4856 printf("Opening original file after rename of open file fails: %s\n",
4860 printf("Opening original file after rename of open file works ...\n");
4861 (void)cli_close(cli1, fnum2);
4865 status = cli_close(cli1, fnum1);
4866 if (!NT_STATUS_IS_OK(status)) {
4867 printf("close - 5 failed (%s)\n", nt_errstr(status));
4871 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4872 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4873 if (!NT_STATUS_IS_OK(status)) {
4874 printf("getatr on file %s failed - %s ! \n",
4875 fname1, nt_errstr(status));
4878 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4879 printf("Renamed file %s has wrong attr 0x%x "
4880 "(should be 0x%x)\n",
4883 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4886 printf("Renamed file %s has archive bit set\n", fname1);
4890 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4891 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4893 if (!torture_close_connection(cli1)) {
4900 static bool run_pipe_number(int dummy)
4902 struct cli_state *cli1;
4903 const char *pipe_name = "\\SPOOLSS";
4908 printf("starting pipenumber test\n");
4909 if (!torture_open_connection(&cli1, 0)) {
4913 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4915 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4916 FILE_ATTRIBUTE_NORMAL,
4917 FILE_SHARE_READ|FILE_SHARE_WRITE,
4918 FILE_OPEN_IF, 0, 0, &fnum, NULL);
4919 if (!NT_STATUS_IS_OK(status)) {
4920 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4924 printf("\r%6d", num_pipes);
4927 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4928 torture_close_connection(cli1);
4933 Test open mode returns on read-only files.
4935 static bool run_opentest(int dummy)
4937 static struct cli_state *cli1;
4938 static struct cli_state *cli2;
4939 const char *fname = "\\readonly.file";
4940 uint16_t fnum1, fnum2;
4943 bool correct = True;
4947 printf("starting open test\n");
4949 if (!torture_open_connection(&cli1, 0)) {
4953 cli_setatr(cli1, fname, 0, 0);
4954 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4956 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4958 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4959 if (!NT_STATUS_IS_OK(status)) {
4960 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4964 status = cli_close(cli1, fnum1);
4965 if (!NT_STATUS_IS_OK(status)) {
4966 printf("close2 failed (%s)\n", nt_errstr(status));
4970 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4971 if (!NT_STATUS_IS_OK(status)) {
4972 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4976 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4977 if (!NT_STATUS_IS_OK(status)) {
4978 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4982 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4983 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4985 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4986 NT_STATUS_ACCESS_DENIED)) {
4987 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4990 printf("finished open test 1\n");
4992 cli_close(cli1, fnum1);
4994 /* Now try not readonly and ensure ERRbadshare is returned. */
4996 cli_setatr(cli1, fname, 0, 0);
4998 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4999 if (!NT_STATUS_IS_OK(status)) {
5000 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5004 /* This will fail - but the error should be ERRshare. */
5005 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
5007 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
5008 NT_STATUS_SHARING_VIOLATION)) {
5009 printf("correct error code ERRDOS/ERRbadshare returned\n");
5012 status = cli_close(cli1, fnum1);
5013 if (!NT_STATUS_IS_OK(status)) {
5014 printf("close2 failed (%s)\n", nt_errstr(status));
5018 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5020 printf("finished open test 2\n");
5022 /* Test truncate open disposition on file opened for read. */
5023 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
5024 if (!NT_STATUS_IS_OK(status)) {
5025 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
5029 /* write 20 bytes. */
5031 memset(buf, '\0', 20);
5033 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
5034 if (!NT_STATUS_IS_OK(status)) {
5035 printf("write failed (%s)\n", nt_errstr(status));
5039 status = cli_close(cli1, fnum1);
5040 if (!NT_STATUS_IS_OK(status)) {
5041 printf("(3) close1 failed (%s)\n", nt_errstr(status));
5045 /* Ensure size == 20. */
5046 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5047 if (!NT_STATUS_IS_OK(status)) {
5048 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5053 printf("(3) file size != 20\n");
5057 /* Now test if we can truncate a file opened for readonly. */
5058 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
5059 if (!NT_STATUS_IS_OK(status)) {
5060 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
5064 status = cli_close(cli1, fnum1);
5065 if (!NT_STATUS_IS_OK(status)) {
5066 printf("close2 failed (%s)\n", nt_errstr(status));
5070 /* Ensure size == 0. */
5071 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
5072 if (!NT_STATUS_IS_OK(status)) {
5073 printf("(3) getatr failed (%s)\n", nt_errstr(status));
5078 printf("(3) file size != 0\n");
5081 printf("finished open test 3\n");
5083 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5085 printf("Do ctemp tests\n");
5086 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5087 if (!NT_STATUS_IS_OK(status)) {
5088 printf("ctemp failed (%s)\n", nt_errstr(status));
5092 printf("ctemp gave path %s\n", tmp_path);
5093 status = cli_close(cli1, fnum1);
5094 if (!NT_STATUS_IS_OK(status)) {
5095 printf("close of temp failed (%s)\n", nt_errstr(status));
5098 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5099 if (!NT_STATUS_IS_OK(status)) {
5100 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5103 /* Test the non-io opens... */
5105 if (!torture_open_connection(&cli2, 1)) {
5109 cli_setatr(cli2, fname, 0, 0);
5110 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5112 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5114 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5115 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5116 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5117 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5118 if (!NT_STATUS_IS_OK(status)) {
5119 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5123 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5124 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5125 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5126 if (!NT_STATUS_IS_OK(status)) {
5127 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5131 status = cli_close(cli1, fnum1);
5132 if (!NT_STATUS_IS_OK(status)) {
5133 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5137 status = cli_close(cli2, fnum2);
5138 if (!NT_STATUS_IS_OK(status)) {
5139 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5143 printf("non-io open test #1 passed.\n");
5145 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5147 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5149 status = cli_ntcreate(cli1, fname, 0,
5150 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5151 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5152 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5153 if (!NT_STATUS_IS_OK(status)) {
5154 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5158 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5159 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5160 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5161 if (!NT_STATUS_IS_OK(status)) {
5162 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5166 status = cli_close(cli1, fnum1);
5167 if (!NT_STATUS_IS_OK(status)) {
5168 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5172 status = cli_close(cli2, fnum2);
5173 if (!NT_STATUS_IS_OK(status)) {
5174 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5178 printf("non-io open test #2 passed.\n");
5180 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5182 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5184 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5185 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5186 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5187 if (!NT_STATUS_IS_OK(status)) {
5188 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5192 status = cli_ntcreate(cli2, fname, 0,
5193 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5194 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5195 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5196 if (!NT_STATUS_IS_OK(status)) {
5197 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5201 status = cli_close(cli1, fnum1);
5202 if (!NT_STATUS_IS_OK(status)) {
5203 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5207 status = cli_close(cli2, fnum2);
5208 if (!NT_STATUS_IS_OK(status)) {
5209 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5213 printf("non-io open test #3 passed.\n");
5215 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5217 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5219 status = cli_ntcreate(cli1, fname, 0,
5220 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5221 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5222 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5223 if (!NT_STATUS_IS_OK(status)) {
5224 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5228 status = cli_ntcreate(cli2, fname, 0,
5229 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5230 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5231 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5232 if (NT_STATUS_IS_OK(status)) {
5233 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5237 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5239 status = cli_close(cli1, fnum1);
5240 if (!NT_STATUS_IS_OK(status)) {
5241 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5245 printf("non-io open test #4 passed.\n");
5247 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5249 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5251 status = cli_ntcreate(cli1, fname, 0,
5252 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5253 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5254 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5255 if (!NT_STATUS_IS_OK(status)) {
5256 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5260 status = cli_ntcreate(cli2, fname, 0,
5261 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5262 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5263 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5264 if (!NT_STATUS_IS_OK(status)) {
5265 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5269 status = cli_close(cli1, fnum1);
5270 if (!NT_STATUS_IS_OK(status)) {
5271 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5275 status = cli_close(cli2, fnum2);
5276 if (!NT_STATUS_IS_OK(status)) {
5277 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5281 printf("non-io open test #5 passed.\n");
5283 printf("TEST #6 testing 1 non-io open, one io open\n");
5285 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5287 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5288 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5289 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5290 if (!NT_STATUS_IS_OK(status)) {
5291 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5295 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5296 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5297 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5298 if (!NT_STATUS_IS_OK(status)) {
5299 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5303 status = cli_close(cli1, fnum1);
5304 if (!NT_STATUS_IS_OK(status)) {
5305 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5309 status = cli_close(cli2, fnum2);
5310 if (!NT_STATUS_IS_OK(status)) {
5311 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5315 printf("non-io open test #6 passed.\n");
5317 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5319 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5321 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5322 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5323 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5324 if (!NT_STATUS_IS_OK(status)) {
5325 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5329 status = cli_ntcreate(cli2, fname, 0,
5330 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5331 FILE_ATTRIBUTE_NORMAL,
5332 FILE_SHARE_READ|FILE_SHARE_DELETE,
5333 FILE_OPEN_IF, 0, 0, &fnum2, NULL);
5334 if (NT_STATUS_IS_OK(status)) {
5335 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5339 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5341 status = cli_close(cli1, fnum1);
5342 if (!NT_STATUS_IS_OK(status)) {
5343 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5347 printf("non-io open test #7 passed.\n");
5349 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5351 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5352 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5353 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5354 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
5355 if (!NT_STATUS_IS_OK(status)) {
5356 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5361 /* Write to ensure we have to update the file time. */
5362 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5364 if (!NT_STATUS_IS_OK(status)) {
5365 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5370 status = cli_close(cli1, fnum1);
5371 if (!NT_STATUS_IS_OK(status)) {
5372 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5378 if (!torture_close_connection(cli1)) {
5381 if (!torture_close_connection(cli2)) {
5388 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5390 uint16_t major, minor;
5391 uint32_t caplow, caphigh;
5394 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5395 printf("Server doesn't support UNIX CIFS extensions.\n");
5396 return NT_STATUS_NOT_SUPPORTED;
5399 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5401 if (!NT_STATUS_IS_OK(status)) {
5402 printf("Server didn't return UNIX CIFS extensions: %s\n",
5407 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5409 if (!NT_STATUS_IS_OK(status)) {
5410 printf("Server doesn't support setting UNIX CIFS extensions: "
5411 "%s.\n", nt_errstr(status));
5415 return NT_STATUS_OK;
5419 Test POSIX open /mkdir calls.
5421 static bool run_simple_posix_open_test(int dummy)
5423 static struct cli_state *cli1;
5424 const char *fname = "posix:file";
5425 const char *hname = "posix:hlink";
5426 const char *sname = "posix:symlink";
5427 const char *dname = "posix:dir";
5430 uint16_t fnum1 = (uint16_t)-1;
5431 SMB_STRUCT_STAT sbuf;
5432 bool correct = false;
5435 const char *fname_windows = "windows_file";
5436 uint16_t fnum2 = (uint16_t)-1;
5438 printf("Starting simple POSIX open test\n");
5440 if (!torture_open_connection(&cli1, 0)) {
5444 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5446 status = torture_setup_unix_extensions(cli1);
5447 if (!NT_STATUS_IS_OK(status)) {
5451 cli_setatr(cli1, fname, 0, 0);
5452 cli_posix_unlink(cli1, fname);
5453 cli_setatr(cli1, dname, 0, 0);
5454 cli_posix_rmdir(cli1, dname);
5455 cli_setatr(cli1, hname, 0, 0);
5456 cli_posix_unlink(cli1, hname);
5457 cli_setatr(cli1, sname, 0, 0);
5458 cli_posix_unlink(cli1, sname);
5459 cli_setatr(cli1, fname_windows, 0, 0);
5460 cli_posix_unlink(cli1, fname_windows);
5462 /* Create a directory. */
5463 status = cli_posix_mkdir(cli1, dname, 0777);
5464 if (!NT_STATUS_IS_OK(status)) {
5465 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5469 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5471 if (!NT_STATUS_IS_OK(status)) {
5472 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5476 /* Test ftruncate - set file size. */
5477 status = cli_ftruncate(cli1, fnum1, 1000);
5478 if (!NT_STATUS_IS_OK(status)) {
5479 printf("ftruncate failed (%s)\n", nt_errstr(status));
5483 /* Ensure st_size == 1000 */
5484 status = cli_posix_stat(cli1, fname, &sbuf);
5485 if (!NT_STATUS_IS_OK(status)) {
5486 printf("stat failed (%s)\n", nt_errstr(status));
5490 if (sbuf.st_ex_size != 1000) {
5491 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5495 /* Ensure st_mode == 0600 */
5496 if ((sbuf.st_ex_mode & 07777) != 0600) {
5497 printf("posix_open - bad permissions 0%o != 0600\n",
5498 (unsigned int)(sbuf.st_ex_mode & 07777));
5502 /* Test ftruncate - set file size back to zero. */
5503 status = cli_ftruncate(cli1, fnum1, 0);
5504 if (!NT_STATUS_IS_OK(status)) {
5505 printf("ftruncate failed (%s)\n", nt_errstr(status));
5509 status = cli_close(cli1, fnum1);
5510 if (!NT_STATUS_IS_OK(status)) {
5511 printf("close failed (%s)\n", nt_errstr(status));
5515 /* Now open the file again for read only. */
5516 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5517 if (!NT_STATUS_IS_OK(status)) {
5518 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5522 /* Now unlink while open. */
5523 status = cli_posix_unlink(cli1, fname);
5524 if (!NT_STATUS_IS_OK(status)) {
5525 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5529 status = cli_close(cli1, fnum1);
5530 if (!NT_STATUS_IS_OK(status)) {
5531 printf("close(2) failed (%s)\n", nt_errstr(status));
5535 /* Ensure the file has gone. */
5536 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5537 if (NT_STATUS_IS_OK(status)) {
5538 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5542 /* Create again to test open with O_TRUNC. */
5543 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5544 if (!NT_STATUS_IS_OK(status)) {
5545 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5549 /* Test ftruncate - set file size. */
5550 status = cli_ftruncate(cli1, fnum1, 1000);
5551 if (!NT_STATUS_IS_OK(status)) {
5552 printf("ftruncate failed (%s)\n", nt_errstr(status));
5556 /* Ensure st_size == 1000 */
5557 status = cli_posix_stat(cli1, fname, &sbuf);
5558 if (!NT_STATUS_IS_OK(status)) {
5559 printf("stat failed (%s)\n", nt_errstr(status));
5563 if (sbuf.st_ex_size != 1000) {
5564 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5568 status = cli_close(cli1, fnum1);
5569 if (!NT_STATUS_IS_OK(status)) {
5570 printf("close(2) failed (%s)\n", nt_errstr(status));
5574 /* Re-open with O_TRUNC. */
5575 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5576 if (!NT_STATUS_IS_OK(status)) {
5577 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5581 /* Ensure st_size == 0 */
5582 status = cli_posix_stat(cli1, fname, &sbuf);
5583 if (!NT_STATUS_IS_OK(status)) {
5584 printf("stat failed (%s)\n", nt_errstr(status));
5588 if (sbuf.st_ex_size != 0) {
5589 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5593 status = cli_close(cli1, fnum1);
5594 if (!NT_STATUS_IS_OK(status)) {
5595 printf("close failed (%s)\n", nt_errstr(status));
5599 status = cli_posix_unlink(cli1, fname);
5600 if (!NT_STATUS_IS_OK(status)) {
5601 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5605 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5606 if (!NT_STATUS_IS_OK(status)) {
5607 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5608 dname, nt_errstr(status));
5612 cli_close(cli1, fnum1);
5614 /* What happens when we try and POSIX open a directory for write ? */
5615 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5616 if (NT_STATUS_IS_OK(status)) {
5617 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5620 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5621 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5626 /* Create the file. */
5627 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5629 if (!NT_STATUS_IS_OK(status)) {
5630 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5634 /* Write some data into it. */
5635 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5637 if (!NT_STATUS_IS_OK(status)) {
5638 printf("cli_write failed: %s\n", nt_errstr(status));
5642 cli_close(cli1, fnum1);
5644 /* Now create a hardlink. */
5645 status = cli_posix_hardlink(cli1, fname, hname);
5646 if (!NT_STATUS_IS_OK(status)) {
5647 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5651 /* Now create a symlink. */
5652 status = cli_posix_symlink(cli1, fname, sname);
5653 if (!NT_STATUS_IS_OK(status)) {
5654 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5658 /* Open the hardlink for read. */
5659 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5660 if (!NT_STATUS_IS_OK(status)) {
5661 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5665 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5666 if (!NT_STATUS_IS_OK(status)) {
5667 printf("POSIX read of %s failed (%s)\n", hname,
5670 } else if (nread != 10) {
5671 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5672 hname, (unsigned long)nread, 10);
5676 if (memcmp(buf, "TEST DATA\n", 10)) {
5677 printf("invalid data read from hardlink\n");
5681 /* Do a POSIX lock/unlock. */
5682 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5683 if (!NT_STATUS_IS_OK(status)) {
5684 printf("POSIX lock failed %s\n", nt_errstr(status));
5688 /* Punch a hole in the locked area. */
5689 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5690 if (!NT_STATUS_IS_OK(status)) {
5691 printf("POSIX unlock failed %s\n", nt_errstr(status));
5695 cli_close(cli1, fnum1);
5697 /* Open the symlink for read - this should fail. A POSIX
5698 client should not be doing opens on a symlink. */
5699 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5700 if (NT_STATUS_IS_OK(status)) {
5701 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5704 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5705 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5706 printf("POSIX open of %s should have failed "
5707 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5708 "failed with %s instead.\n",
5709 sname, nt_errstr(status));
5714 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5715 if (!NT_STATUS_IS_OK(status)) {
5716 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5720 if (strcmp(namebuf, fname) != 0) {
5721 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5722 sname, fname, namebuf);
5726 status = cli_posix_rmdir(cli1, dname);
5727 if (!NT_STATUS_IS_OK(status)) {
5728 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5732 /* Check directory opens with a specific permission. */
5733 status = cli_posix_mkdir(cli1, dname, 0700);
5734 if (!NT_STATUS_IS_OK(status)) {
5735 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5739 /* Ensure st_mode == 0700 */
5740 status = cli_posix_stat(cli1, dname, &sbuf);
5741 if (!NT_STATUS_IS_OK(status)) {
5742 printf("stat failed (%s)\n", nt_errstr(status));
5746 if ((sbuf.st_ex_mode & 07777) != 0700) {
5747 printf("posix_mkdir - bad permissions 0%o != 0700\n",
5748 (unsigned int)(sbuf.st_ex_mode & 07777));
5753 * Now create a Windows file, and attempt a POSIX unlink.
5754 * This should fail with a sharing violation but due to:
5756 * [Bug 9571] Unlink after open causes smbd to panic
5758 * ensure we've fixed the lock ordering violation.
5761 status = cli_ntcreate(cli1, fname_windows, 0,
5762 FILE_READ_DATA|FILE_WRITE_DATA, 0,
5763 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5765 0x0, 0x0, &fnum2, NULL);
5766 if (!NT_STATUS_IS_OK(status)) {
5767 printf("Windows create of %s failed (%s)\n", fname_windows,
5772 /* Now try posix_unlink. */
5773 status = cli_posix_unlink(cli1, fname_windows);
5774 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
5775 printf("POSIX unlink of %s should fail "
5776 "with NT_STATUS_SHARING_VIOLATION "
5777 "got %s instead !\n",
5783 cli_close(cli1, fnum2);
5785 printf("Simple POSIX open test passed\n");
5790 if (fnum1 != (uint16_t)-1) {
5791 cli_close(cli1, fnum1);
5792 fnum1 = (uint16_t)-1;
5795 if (fnum2 != (uint16_t)-1) {
5796 cli_close(cli1, fnum2);
5797 fnum2 = (uint16_t)-1;
5800 cli_setatr(cli1, sname, 0, 0);
5801 cli_posix_unlink(cli1, sname);
5802 cli_setatr(cli1, hname, 0, 0);
5803 cli_posix_unlink(cli1, hname);
5804 cli_setatr(cli1, fname, 0, 0);
5805 cli_posix_unlink(cli1, fname);
5806 cli_setatr(cli1, dname, 0, 0);
5807 cli_posix_rmdir(cli1, dname);
5808 cli_setatr(cli1, fname_windows, 0, 0);
5809 cli_posix_unlink(cli1, fname_windows);
5811 if (!torture_close_connection(cli1)) {
5819 Test POSIX and Windows ACLs are rejected on symlinks.
5821 static bool run_acl_symlink_test(int dummy)
5823 static struct cli_state *cli;
5824 const char *fname = "posix_file";
5825 const char *sname = "posix_symlink";
5826 uint16_t fnum = (uint16_t)-1;
5827 bool correct = false;
5829 char *posix_acl = NULL;
5830 size_t posix_acl_len = 0;
5831 char *posix_acl_sym = NULL;
5832 size_t posix_acl_len_sym = 0;
5833 struct security_descriptor *sd = NULL;
5834 struct security_descriptor *sd_sym = NULL;
5835 TALLOC_CTX *frame = NULL;
5837 frame = talloc_stackframe();
5839 printf("Starting acl symlink test\n");
5841 if (!torture_open_connection(&cli, 0)) {
5846 smbXcli_conn_set_sockopt(cli->conn, sockops);
5848 status = torture_setup_unix_extensions(cli);
5849 if (!NT_STATUS_IS_OK(status)) {
5854 cli_setatr(cli, fname, 0, 0);
5855 cli_posix_unlink(cli, fname);
5856 cli_setatr(cli, sname, 0, 0);
5857 cli_posix_unlink(cli, sname);
5859 status = cli_ntcreate(cli,
5862 READ_CONTROL_ACCESS,
5864 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5871 if (!NT_STATUS_IS_OK(status)) {
5872 printf("cli_ntcreate of %s failed (%s)\n",
5878 /* Get the Windows ACL on the file. */
5879 status = cli_query_secdesc(cli,
5883 if (!NT_STATUS_IS_OK(status)) {
5884 printf("cli_query_secdesc failed (%s)\n",
5889 /* Get the POSIX ACL on the file. */
5890 status = cli_posix_getacl(cli,
5896 if (!NT_STATUS_IS_OK(status)) {
5897 printf("cli_posix_getacl failed (%s)\n",
5902 status = cli_close(cli, fnum);
5903 if (!NT_STATUS_IS_OK(status)) {
5904 printf("close failed (%s)\n", nt_errstr(status));
5907 fnum = (uint16_t)-1;
5909 /* Now create a symlink. */
5910 status = cli_posix_symlink(cli, fname, sname);
5911 if (!NT_STATUS_IS_OK(status)) {
5912 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
5919 /* Open a handle on the symlink. */
5920 status = cli_ntcreate(cli,
5923 READ_CONTROL_ACCESS|SEC_STD_WRITE_DAC,
5925 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5932 if (!NT_STATUS_IS_OK(status)) {
5933 printf("cli_posix_open of %s failed (%s)\n",
5939 /* Get the Windows ACL on the symlink handle. Should fail */
5940 status = cli_query_secdesc(cli,
5945 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5946 printf("cli_query_secdesc on a symlink gave %s. "
5947 "Should be NT_STATUS_ACCESS_DENIED.\n",
5952 /* Get the POSIX ACL on the symlink pathname. Should fail. */
5953 status = cli_posix_getacl(cli,
5959 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5960 printf("cli_posix_getacl on a symlink gave %s. "
5961 "Should be NT_STATUS_ACCESS_DENIED.\n",
5966 /* Set the Windows ACL on the symlink handle. Should fail */
5967 status = cli_set_security_descriptor(cli,
5972 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5973 printf("cli_query_secdesc on a symlink gave %s. "
5974 "Should be NT_STATUS_ACCESS_DENIED.\n",
5979 /* Set the POSIX ACL on the symlink pathname. Should fail. */
5980 status = cli_posix_setacl(cli,
5985 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5986 printf("cli_posix_getacl on a symlink gave %s. "
5987 "Should be NT_STATUS_ACCESS_DENIED.\n",
5992 printf("ACL symlink test passed\n");
5997 if (fnum != (uint16_t)-1) {
5998 cli_close(cli, fnum);
5999 fnum = (uint16_t)-1;
6002 cli_setatr(cli, sname, 0, 0);
6003 cli_posix_unlink(cli, sname);
6004 cli_setatr(cli, fname, 0, 0);
6005 cli_posix_unlink(cli, fname);
6007 if (!torture_close_connection(cli)) {
6016 Test POSIX can delete a file containing streams.
6018 static bool run_posix_stream_delete(int dummy)
6020 struct cli_state *cli1 = NULL;
6021 struct cli_state *cli2 = NULL;
6022 const char *fname = "streamfile";
6023 const char *stream_fname = "streamfile:Zone.Identifier:$DATA";
6024 uint16_t fnum1 = (uint16_t)-1;
6025 bool correct = false;
6027 TALLOC_CTX *frame = NULL;
6029 frame = talloc_stackframe();
6031 printf("Starting POSIX stream delete test\n");
6033 if (!torture_open_connection(&cli1, 0) ||
6034 !torture_open_connection(&cli2, 1)) {
6039 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6040 smbXcli_conn_set_sockopt(cli2->conn, sockops);
6042 status = torture_setup_unix_extensions(cli2);
6043 if (!NT_STATUS_IS_OK(status)) {
6047 cli_setatr(cli1, fname, 0, 0);
6048 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6050 /* Create the file. */
6051 status = cli_ntcreate(cli1,
6054 READ_CONTROL_ACCESS,
6056 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6063 if (!NT_STATUS_IS_OK(status)) {
6064 printf("cli_ntcreate of %s failed (%s)\n",
6070 status = cli_close(cli1, fnum1);
6071 if (!NT_STATUS_IS_OK(status)) {
6072 printf("cli_close of %s failed (%s)\n",
6077 fnum1 = (uint16_t)-1;
6079 /* Now create the stream. */
6080 status = cli_ntcreate(cli1,
6085 FILE_SHARE_READ|FILE_SHARE_WRITE,
6092 if (!NT_STATUS_IS_OK(status)) {
6093 printf("cli_ntcreate of %s failed (%s)\n",
6099 /* Leave the stream handle open... */
6101 /* POSIX unlink should fail. */
6102 status = cli_posix_unlink(cli2, fname);
6103 if (NT_STATUS_IS_OK(status)) {
6104 printf("cli_posix_unlink of %s succeeded, should have failed\n",
6109 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
6110 printf("cli_posix_unlink of %s failed with (%s) "
6111 "should have been NT_STATUS_SHARING_VIOLATION\n",
6117 /* Close the stream handle. */
6118 status = cli_close(cli1, fnum1);
6119 if (!NT_STATUS_IS_OK(status)) {
6120 printf("cli_close of %s failed (%s)\n",
6125 fnum1 = (uint16_t)-1;
6127 /* POSIX unlink after stream handle closed should succeed. */
6128 status = cli_posix_unlink(cli2, fname);
6129 if (!NT_STATUS_IS_OK(status)) {
6130 printf("cli_posix_unlink of %s failed (%s)\n",
6136 printf("POSIX stream delete test passed\n");
6141 if (fnum1 != (uint16_t)-1) {
6142 cli_close(cli1, fnum1);
6143 fnum1 = (uint16_t)-1;
6146 cli_setatr(cli1, fname, 0, 0);
6147 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6149 if (!torture_close_connection(cli1)) {
6152 if (!torture_close_connection(cli2)) {
6161 Test setting EA's are rejected on symlinks.
6163 static bool run_ea_symlink_test(int dummy)
6165 static struct cli_state *cli;
6166 const char *fname = "posix_file_ea";
6167 const char *sname = "posix_symlink_ea";
6168 const char *ea_name = "testea_name";
6169 const char *ea_value = "testea_value";
6170 uint16_t fnum = (uint16_t)-1;
6171 bool correct = false;
6174 struct ea_struct *eas = NULL;
6175 TALLOC_CTX *frame = NULL;
6177 frame = talloc_stackframe();
6179 printf("Starting EA symlink test\n");
6181 if (!torture_open_connection(&cli, 0)) {
6186 smbXcli_conn_set_sockopt(cli->conn, sockops);
6188 status = torture_setup_unix_extensions(cli);
6189 if (!NT_STATUS_IS_OK(status)) {
6194 cli_setatr(cli, fname, 0, 0);
6195 cli_posix_unlink(cli, fname);
6196 cli_setatr(cli, sname, 0, 0);
6197 cli_posix_unlink(cli, sname);
6199 status = cli_ntcreate(cli,
6202 READ_CONTROL_ACCESS,
6204 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6211 if (!NT_STATUS_IS_OK(status)) {
6212 printf("cli_ntcreate of %s failed (%s)\n",
6218 status = cli_close(cli, fnum);
6219 if (!NT_STATUS_IS_OK(status)) {
6220 printf("close failed (%s)\n",
6224 fnum = (uint16_t)-1;
6226 /* Set an EA on the path. */
6227 status = cli_set_ea_path(cli,
6231 strlen(ea_value)+1);
6233 if (!NT_STATUS_IS_OK(status)) {
6234 printf("cli_set_ea_path failed (%s)\n",
6239 /* Now create a symlink. */
6240 status = cli_posix_symlink(cli, fname, sname);
6241 if (!NT_STATUS_IS_OK(status)) {
6242 printf("cli_posix_symlink of %s -> %s failed (%s)\n",
6249 /* Get the EA list on the path. Should return value set. */
6250 status = cli_get_ea_list_path(cli,
6256 if (!NT_STATUS_IS_OK(status)) {
6257 printf("cli_get_ea_list_path failed (%s)\n",
6262 /* Ensure the EA we set is there. */
6263 for (i=0; i<num_eas; i++) {
6264 if (strcmp(eas[i].name, ea_name) == 0 &&
6265 eas[i].value.length == strlen(ea_value)+1 &&
6266 memcmp(eas[i].value.data,
6268 eas[i].value.length) == 0) {
6274 printf("Didn't find EA on pathname %s\n",
6282 /* Get the EA list on the symlink. Should return empty list. */
6283 status = cli_get_ea_list_path(cli,
6289 if (!NT_STATUS_IS_OK(status)) {
6290 printf("cli_get_ea_list_path failed (%s)\n",
6296 printf("cli_get_ea_list_path failed (%s)\n",
6301 /* Set an EA on the symlink. Should fail. */
6302 status = cli_set_ea_path(cli,
6306 strlen(ea_value)+1);
6308 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6309 printf("cli_set_ea_path on a symlink gave %s. "
6310 "Should be NT_STATUS_ACCESS_DENIED.\n",
6315 printf("EA symlink test passed\n");
6320 if (fnum != (uint16_t)-1) {
6321 cli_close(cli, fnum);
6322 fnum = (uint16_t)-1;
6325 cli_setatr(cli, sname, 0, 0);
6326 cli_posix_unlink(cli, sname);
6327 cli_setatr(cli, fname, 0, 0);
6328 cli_posix_unlink(cli, fname);
6330 if (!torture_close_connection(cli)) {
6339 Test POSIX locks are OFD-locks.
6341 static bool run_posix_ofd_lock_test(int dummy)
6343 static struct cli_state *cli;
6344 const char *fname = "posix_file";
6345 uint16_t fnum1 = (uint16_t)-1;
6346 uint16_t fnum2 = (uint16_t)-1;
6347 bool correct = false;
6349 TALLOC_CTX *frame = NULL;
6351 frame = talloc_stackframe();
6353 printf("Starting POSIX ofd-lock test\n");
6355 if (!torture_open_connection(&cli, 0)) {
6360 smbXcli_conn_set_sockopt(cli->conn, sockops);
6362 status = torture_setup_unix_extensions(cli);
6363 if (!NT_STATUS_IS_OK(status)) {
6368 cli_setatr(cli, fname, 0, 0);
6369 cli_posix_unlink(cli, fname);
6371 /* Open the file twice. */
6372 status = cli_posix_open(cli, fname, O_RDWR|O_CREAT|O_EXCL,
6374 if (!NT_STATUS_IS_OK(status)) {
6375 printf("First POSIX open of %s failed\n", fname);
6379 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum2);
6380 if (!NT_STATUS_IS_OK(status)) {
6381 printf("First POSIX open of %s failed\n", fname);
6385 /* Set a 0-50 lock on fnum1. */
6386 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6387 if (!NT_STATUS_IS_OK(status)) {
6388 printf("POSIX lock (1) failed %s\n", nt_errstr(status));
6392 /* Set a 60-100 lock on fnum2. */
6393 status = cli_posix_lock(cli, fnum2, 60, 100, false, WRITE_LOCK);
6394 if (!NT_STATUS_IS_OK(status)) {
6395 printf("POSIX lock (2) failed %s\n", nt_errstr(status));
6399 /* close fnum1 - 0-50 lock should go away. */
6400 status = cli_close(cli, fnum1);
6401 if (!NT_STATUS_IS_OK(status)) {
6402 printf("close failed (%s)\n",
6406 fnum1 = (uint16_t)-1;
6408 /* Change the lock context. */
6409 cli_setpid(cli, cli_getpid(cli) + 1);
6411 /* Re-open fnum1. */
6412 status = cli_posix_open(cli, fname, O_RDWR, 0, &fnum1);
6413 if (!NT_STATUS_IS_OK(status)) {
6414 printf("Third POSIX open of %s failed\n", fname);
6418 /* 60-100 lock should still be there. */
6419 status = cli_posix_lock(cli, fnum1, 60, 100, false, WRITE_LOCK);
6420 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
6421 printf("POSIX lock 60-100 not there %s\n", nt_errstr(status));
6425 /* 0-50 lock should be gone. */
6426 status = cli_posix_lock(cli, fnum1, 0, 50, false, WRITE_LOCK);
6427 if (!NT_STATUS_IS_OK(status)) {
6428 printf("POSIX lock 0-50 failed %s\n", nt_errstr(status));
6432 printf("POSIX OFD lock test passed\n");
6437 if (fnum1 != (uint16_t)-1) {
6438 cli_close(cli, fnum1);
6439 fnum1 = (uint16_t)-1;
6441 if (fnum2 != (uint16_t)-1) {
6442 cli_close(cli, fnum2);
6443 fnum2 = (uint16_t)-1;
6446 cli_setatr(cli, fname, 0, 0);
6447 cli_posix_unlink(cli, fname);
6449 if (!torture_close_connection(cli)) {
6457 static uint32_t open_attrs_table[] = {
6458 FILE_ATTRIBUTE_NORMAL,
6459 FILE_ATTRIBUTE_ARCHIVE,
6460 FILE_ATTRIBUTE_READONLY,
6461 FILE_ATTRIBUTE_HIDDEN,
6462 FILE_ATTRIBUTE_SYSTEM,
6464 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
6465 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
6466 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
6467 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
6468 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
6469 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
6471 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
6472 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
6473 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
6474 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
6477 struct trunc_open_results {
6480 uint32_t trunc_attr;
6481 uint32_t result_attr;
6484 static struct trunc_open_results attr_results[] = {
6485 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
6486 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
6487 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
6488 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
6489 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
6490 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
6491 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6492 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6493 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
6494 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6495 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6496 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
6497 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6498 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6499 { 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 },
6500 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6501 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6502 { 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 },
6503 { 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 },
6504 { 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 },
6505 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6506 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
6507 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
6508 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6509 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
6510 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
6513 static bool run_openattrtest(int dummy)
6515 static struct cli_state *cli1;
6516 const char *fname = "\\openattr.file";
6518 bool correct = True;
6520 unsigned int i, j, k, l;
6523 printf("starting open attr test\n");
6525 if (!torture_open_connection(&cli1, 0)) {
6529 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6531 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32_t); i++) {
6532 cli_setatr(cli1, fname, 0, 0);
6533 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6535 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
6536 open_attrs_table[i], FILE_SHARE_NONE,
6537 FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL);
6538 if (!NT_STATUS_IS_OK(status)) {
6539 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
6543 status = cli_close(cli1, fnum1);
6544 if (!NT_STATUS_IS_OK(status)) {
6545 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
6549 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32_t); j++) {
6550 status = cli_ntcreate(cli1, fname, 0,
6551 FILE_READ_DATA|FILE_WRITE_DATA,
6552 open_attrs_table[j],
6553 FILE_SHARE_NONE, FILE_OVERWRITE,
6554 0, 0, &fnum1, NULL);
6555 if (!NT_STATUS_IS_OK(status)) {
6556 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
6557 if (attr_results[l].num == k) {
6558 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
6559 k, open_attrs_table[i],
6560 open_attrs_table[j],
6561 fname, NT_STATUS_V(status), nt_errstr(status));
6566 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
6567 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
6568 k, open_attrs_table[i], open_attrs_table[j],
6573 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
6579 status = cli_close(cli1, fnum1);
6580 if (!NT_STATUS_IS_OK(status)) {
6581 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
6585 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
6586 if (!NT_STATUS_IS_OK(status)) {
6587 printf("getatr(2) failed (%s)\n", nt_errstr(status));
6592 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
6593 k, open_attrs_table[i], open_attrs_table[j], attr );
6596 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
6597 if (attr_results[l].num == k) {
6598 if (attr != attr_results[l].result_attr ||
6599 open_attrs_table[i] != attr_results[l].init_attr ||
6600 open_attrs_table[j] != attr_results[l].trunc_attr) {
6601 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
6602 open_attrs_table[i],
6603 open_attrs_table[j],
6605 attr_results[l].result_attr);
6615 cli_setatr(cli1, fname, 0, 0);
6616 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6618 printf("open attr test %s.\n", correct ? "passed" : "failed");
6620 if (!torture_close_connection(cli1)) {
6626 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
6627 const char *name, void *state)
6629 int *matched = (int *)state;
6630 if (matched != NULL) {
6633 return NT_STATUS_OK;
6637 test directory listing speed
6639 static bool run_dirtest(int dummy)
6642 static struct cli_state *cli;
6644 struct timeval core_start;
6645 bool correct = True;
6648 printf("starting directory test\n");
6650 if (!torture_open_connection(&cli, 0)) {
6654 smbXcli_conn_set_sockopt(cli->conn, sockops);
6657 for (i=0;i<torture_numops;i++) {
6659 slprintf(fname, sizeof(fname), "\\%x", (int)random());
6660 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
6661 fprintf(stderr,"Failed to open %s\n", fname);
6664 cli_close(cli, fnum);
6667 core_start = timeval_current();
6670 cli_list(cli, "a*.*", 0, list_fn, &matched);
6671 printf("Matched %d\n", matched);
6674 cli_list(cli, "b*.*", 0, list_fn, &matched);
6675 printf("Matched %d\n", matched);
6678 cli_list(cli, "xyzabc", 0, list_fn, &matched);
6679 printf("Matched %d\n", matched);
6681 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
6684 for (i=0;i<torture_numops;i++) {
6686 slprintf(fname, sizeof(fname), "\\%x", (int)random());
6687 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6690 if (!torture_close_connection(cli)) {
6694 printf("finished dirtest\n");
6699 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
6702 struct cli_state *pcli = (struct cli_state *)state;
6704 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
6706 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6707 return NT_STATUS_OK;
6709 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
6710 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6711 printf("del_fn: failed to rmdir %s\n,", fname );
6713 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
6714 printf("del_fn: failed to unlink %s\n,", fname );
6716 return NT_STATUS_OK;
6721 sees what IOCTLs are supported
6723 bool torture_ioctl_test(int dummy)
6725 static struct cli_state *cli;
6726 uint16_t device, function;
6728 const char *fname = "\\ioctl.dat";
6732 if (!torture_open_connection(&cli, 0)) {
6736 printf("starting ioctl test\n");
6738 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6740 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6741 if (!NT_STATUS_IS_OK(status)) {
6742 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
6746 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
6747 printf("ioctl device info: %s\n", nt_errstr(status));
6749 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
6750 printf("ioctl job info: %s\n", nt_errstr(status));
6752 for (device=0;device<0x100;device++) {
6753 printf("ioctl test with device = 0x%x\n", device);
6754 for (function=0;function<0x100;function++) {
6755 uint32_t code = (device<<16) | function;
6757 status = cli_raw_ioctl(cli, fnum, code, &blob);
6759 if (NT_STATUS_IS_OK(status)) {
6760 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
6762 data_blob_free(&blob);
6767 if (!torture_close_connection(cli)) {
6776 tries varients of chkpath
6778 bool torture_chkpath_test(int dummy)
6780 static struct cli_state *cli;
6785 if (!torture_open_connection(&cli, 0)) {
6789 printf("starting chkpath test\n");
6791 /* cleanup from an old run */
6792 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6793 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6794 cli_rmdir(cli, "\\chkpath.dir");
6796 status = cli_mkdir(cli, "\\chkpath.dir");
6797 if (!NT_STATUS_IS_OK(status)) {
6798 printf("mkdir1 failed : %s\n", nt_errstr(status));
6802 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
6803 if (!NT_STATUS_IS_OK(status)) {
6804 printf("mkdir2 failed : %s\n", nt_errstr(status));
6808 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
6810 if (!NT_STATUS_IS_OK(status)) {
6811 printf("open1 failed (%s)\n", nt_errstr(status));
6814 cli_close(cli, fnum);
6816 status = cli_chkpath(cli, "\\chkpath.dir");
6817 if (!NT_STATUS_IS_OK(status)) {
6818 printf("chkpath1 failed: %s\n", nt_errstr(status));
6822 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
6823 if (!NT_STATUS_IS_OK(status)) {
6824 printf("chkpath2 failed: %s\n", nt_errstr(status));
6828 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
6829 if (!NT_STATUS_IS_OK(status)) {
6830 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6831 NT_STATUS_NOT_A_DIRECTORY);
6833 printf("* chkpath on a file should fail\n");
6837 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
6838 if (!NT_STATUS_IS_OK(status)) {
6839 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
6840 NT_STATUS_OBJECT_NAME_NOT_FOUND);
6842 printf("* chkpath on a non existent file should fail\n");
6846 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6847 if (!NT_STATUS_IS_OK(status)) {
6848 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6849 NT_STATUS_OBJECT_PATH_NOT_FOUND);
6851 printf("* chkpath on a non existent component should fail\n");
6855 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6856 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6857 cli_rmdir(cli, "\\chkpath.dir");
6859 if (!torture_close_connection(cli)) {
6866 static bool run_eatest(int dummy)
6868 static struct cli_state *cli;
6869 const char *fname = "\\eatest.txt";
6870 bool correct = True;
6874 struct ea_struct *ea_list = NULL;
6875 TALLOC_CTX *mem_ctx = talloc_init("eatest");
6878 printf("starting eatest\n");
6880 if (!torture_open_connection(&cli, 0)) {
6881 talloc_destroy(mem_ctx);
6885 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6887 status = cli_ntcreate(cli, fname, 0,
6888 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6889 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6890 0x4044, 0, &fnum, NULL);
6891 if (!NT_STATUS_IS_OK(status)) {
6892 printf("open failed - %s\n", nt_errstr(status));
6893 talloc_destroy(mem_ctx);
6897 for (i = 0; i < 10; i++) {
6898 fstring ea_name, ea_val;
6900 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6901 memset(ea_val, (char)i+1, i+1);
6902 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6903 if (!NT_STATUS_IS_OK(status)) {
6904 printf("ea_set of name %s failed - %s\n", ea_name,
6906 talloc_destroy(mem_ctx);
6911 cli_close(cli, fnum);
6912 for (i = 0; i < 10; i++) {
6913 fstring ea_name, ea_val;
6915 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6916 memset(ea_val, (char)i+1, i+1);
6917 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6918 if (!NT_STATUS_IS_OK(status)) {
6919 printf("ea_set of name %s failed - %s\n", ea_name,
6921 talloc_destroy(mem_ctx);
6926 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6927 if (!NT_STATUS_IS_OK(status)) {
6928 printf("ea_get list failed - %s\n", nt_errstr(status));
6932 printf("num_eas = %d\n", (int)num_eas);
6934 if (num_eas != 20) {
6935 printf("Should be 20 EA's stored... failing.\n");
6939 for (i = 0; i < num_eas; i++) {
6940 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6941 dump_data(0, ea_list[i].value.data,
6942 ea_list[i].value.length);
6945 /* Setting EA's to zero length deletes them. Test this */
6946 printf("Now deleting all EA's - case indepenent....\n");
6949 cli_set_ea_path(cli, fname, "", "", 0);
6951 for (i = 0; i < 20; i++) {
6953 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6954 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6955 if (!NT_STATUS_IS_OK(status)) {
6956 printf("ea_set of name %s failed - %s\n", ea_name,
6958 talloc_destroy(mem_ctx);
6964 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6965 if (!NT_STATUS_IS_OK(status)) {
6966 printf("ea_get list failed - %s\n", nt_errstr(status));
6970 printf("num_eas = %d\n", (int)num_eas);
6971 for (i = 0; i < num_eas; i++) {
6972 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6973 dump_data(0, ea_list[i].value.data,
6974 ea_list[i].value.length);
6978 printf("deleting EA's failed.\n");
6982 /* Try and delete a non existent EA. */
6983 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6984 if (!NT_STATUS_IS_OK(status)) {
6985 printf("deleting non-existent EA 'foo' should succeed. %s\n",
6990 talloc_destroy(mem_ctx);
6991 if (!torture_close_connection(cli)) {
6998 static bool run_dirtest1(int dummy)
7001 static struct cli_state *cli;
7004 bool correct = True;
7006 printf("starting directory test\n");
7008 if (!torture_open_connection(&cli, 0)) {
7012 smbXcli_conn_set_sockopt(cli->conn, sockops);
7014 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7015 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7016 cli_rmdir(cli, "\\LISTDIR");
7017 cli_mkdir(cli, "\\LISTDIR");
7019 /* Create 1000 files and 1000 directories. */
7020 for (i=0;i<1000;i++) {
7022 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
7023 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
7024 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF,
7025 0, 0, &fnum, NULL))) {
7026 fprintf(stderr,"Failed to open %s\n", fname);
7029 cli_close(cli, fnum);
7031 for (i=0;i<1000;i++) {
7033 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
7034 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
7035 fprintf(stderr,"Failed to open %s\n", fname);
7040 /* Now ensure that doing an old list sees both files and directories. */
7042 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7043 printf("num_seen = %d\n", num_seen );
7044 /* We should see 100 files + 1000 directories + . and .. */
7045 if (num_seen != 2002)
7048 /* Ensure if we have the "must have" bits we only see the
7052 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7053 printf("num_seen = %d\n", num_seen );
7054 if (num_seen != 1002)
7058 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
7059 printf("num_seen = %d\n", num_seen );
7060 if (num_seen != 1000)
7063 /* Delete everything. */
7064 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
7065 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
7066 cli_rmdir(cli, "\\LISTDIR");
7069 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
7070 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
7071 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
7074 if (!torture_close_connection(cli)) {
7078 printf("finished dirtest1\n");
7083 static bool run_error_map_extract(int dummy) {
7085 static struct cli_state *c_dos;
7086 static struct cli_state *c_nt;
7098 /* NT-Error connection */
7100 disable_spnego = true;
7101 if (!(c_nt = open_nbt_connection())) {
7102 disable_spnego = false;
7105 disable_spnego = false;
7107 status = smbXcli_negprot(c_nt->conn, c_nt->timeout, PROTOCOL_CORE,
7110 if (!NT_STATUS_IS_OK(status)) {
7111 printf("%s rejected the NT-error negprot (%s)\n", host,
7117 status = cli_session_setup_anon(c_nt);
7118 if (!NT_STATUS_IS_OK(status)) {
7119 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
7123 /* DOS-Error connection */
7125 disable_spnego = true;
7126 force_dos_errors = true;
7127 if (!(c_dos = open_nbt_connection())) {
7128 disable_spnego = false;
7129 force_dos_errors = false;
7132 disable_spnego = false;
7133 force_dos_errors = false;
7135 status = smbXcli_negprot(c_dos->conn, c_dos->timeout, PROTOCOL_CORE,
7137 if (!NT_STATUS_IS_OK(status)) {
7138 printf("%s rejected the DOS-error negprot (%s)\n", host,
7140 cli_shutdown(c_dos);
7144 status = cli_session_setup_anon(c_dos);
7145 if (!NT_STATUS_IS_OK(status)) {
7146 printf("%s rejected the DOS-error initial session setup (%s)\n",
7147 host, nt_errstr(status));
7151 c_nt->map_dos_errors = false;
7152 c_dos->map_dos_errors = false;
7154 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
7155 fstr_sprintf(user, "%X", error);
7157 status = cli_session_setup(c_nt, user,
7160 if (NT_STATUS_IS_OK(status)) {
7161 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7164 /* Case #1: 32-bit NT errors */
7165 if (!NT_STATUS_IS_DOS(status)) {
7168 printf("/** Dos error on NT connection! (%s) */\n",
7170 nt_status = NT_STATUS(0xc0000000);
7173 status = cli_session_setup(c_dos, user,
7176 if (NT_STATUS_IS_OK(status)) {
7177 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
7180 /* Case #1: 32-bit NT errors */
7181 if (NT_STATUS_IS_DOS(status)) {
7182 printf("/** NT error on DOS connection! (%s) */\n",
7184 errnum = errclass = 0;
7186 errclass = NT_STATUS_DOS_CLASS(status);
7187 errnum = NT_STATUS_DOS_CODE(status);
7190 if (NT_STATUS_V(nt_status) != error) {
7191 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
7192 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
7193 get_nt_error_c_code(talloc_tos(), nt_status));
7196 printf("\t{%s,\t%s,\t%s},\n",
7197 smb_dos_err_class(errclass),
7198 smb_dos_err_name(errclass, errnum),
7199 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
7204 static bool run_sesssetup_bench(int dummy)
7206 static struct cli_state *c;
7207 const char *fname = "\\file.dat";
7212 if (!torture_open_connection(&c, 0)) {
7216 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7217 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7218 FILE_DELETE_ON_CLOSE, 0, &fnum, NULL);
7219 if (!NT_STATUS_IS_OK(status)) {
7220 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7224 for (i=0; i<torture_numops; i++) {
7225 status = cli_session_setup(
7229 if (!NT_STATUS_IS_OK(status)) {
7230 d_printf("(%s) cli_session_setup failed: %s\n",
7231 __location__, nt_errstr(status));
7235 d_printf("\r%d ", (int)cli_state_get_uid(c));
7237 status = cli_ulogoff(c);
7238 if (!NT_STATUS_IS_OK(status)) {
7239 d_printf("(%s) cli_ulogoff failed: %s\n",
7240 __location__, nt_errstr(status));
7248 static bool subst_test(const char *str, const char *user, const char *domain,
7249 uid_t uid, gid_t gid, const char *expected)
7254 subst = talloc_sub_specified(talloc_tos(), str, user, NULL, domain, uid, gid);
7256 if (strcmp(subst, expected) != 0) {
7257 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
7258 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
7267 static void chain1_open_completion(struct tevent_req *req)
7271 status = cli_openx_recv(req, &fnum);
7274 d_printf("cli_openx_recv returned %s: %d\n",
7276 NT_STATUS_IS_OK(status) ? fnum : -1);
7279 static void chain1_write_completion(struct tevent_req *req)
7283 status = cli_write_andx_recv(req, &written);
7286 d_printf("cli_write_andx_recv returned %s: %d\n",
7288 NT_STATUS_IS_OK(status) ? (int)written : -1);
7291 static void chain1_close_completion(struct tevent_req *req)
7294 bool *done = (bool *)tevent_req_callback_data_void(req);
7296 status = cli_close_recv(req);
7301 d_printf("cli_close returned %s\n", nt_errstr(status));
7304 static bool run_chain1(int dummy)
7306 struct cli_state *cli1;
7307 struct tevent_context *evt = samba_tevent_context_init(NULL);
7308 struct tevent_req *reqs[3], *smbreqs[3];
7310 const char *str = "foobar";
7313 printf("starting chain1 test\n");
7314 if (!torture_open_connection(&cli1, 0)) {
7318 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7320 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
7321 O_CREAT|O_RDWR, 0, &smbreqs[0]);
7322 if (reqs[0] == NULL) return false;
7323 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
7326 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
7327 (const uint8_t *)str, 0, strlen(str)+1,
7328 smbreqs, 1, &smbreqs[1]);
7329 if (reqs[1] == NULL) return false;
7330 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
7332 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
7333 if (reqs[2] == NULL) return false;
7334 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
7336 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7337 if (!NT_STATUS_IS_OK(status)) {
7342 tevent_loop_once(evt);
7345 torture_close_connection(cli1);
7349 static void chain2_sesssetup_completion(struct tevent_req *req)
7352 status = cli_session_setup_guest_recv(req);
7353 d_printf("sesssetup returned %s\n", nt_errstr(status));
7356 static void chain2_tcon_completion(struct tevent_req *req)
7358 bool *done = (bool *)tevent_req_callback_data_void(req);
7360 status = cli_tcon_andx_recv(req);
7361 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
7365 static bool run_chain2(int dummy)
7367 struct cli_state *cli1;
7368 struct tevent_context *evt = samba_tevent_context_init(NULL);
7369 struct tevent_req *reqs[2], *smbreqs[2];
7373 printf("starting chain2 test\n");
7374 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
7375 port_to_use, SMB_SIGNING_DEFAULT, 0);
7376 if (!NT_STATUS_IS_OK(status)) {
7380 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7382 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
7384 if (reqs[0] == NULL) return false;
7385 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
7387 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
7388 "?????", NULL, 0, &smbreqs[1]);
7389 if (reqs[1] == NULL) return false;
7390 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
7392 status = smb1cli_req_chain_submit(smbreqs, ARRAY_SIZE(smbreqs));
7393 if (!NT_STATUS_IS_OK(status)) {
7398 tevent_loop_once(evt);
7401 torture_close_connection(cli1);
7406 struct torture_createdel_state {
7407 struct tevent_context *ev;
7408 struct cli_state *cli;
7411 static void torture_createdel_created(struct tevent_req *subreq);
7412 static void torture_createdel_closed(struct tevent_req *subreq);
7414 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
7415 struct tevent_context *ev,
7416 struct cli_state *cli,
7419 struct tevent_req *req, *subreq;
7420 struct torture_createdel_state *state;
7422 req = tevent_req_create(mem_ctx, &state,
7423 struct torture_createdel_state);
7430 subreq = cli_ntcreate_send(
7431 state, ev, cli, name, 0,
7432 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
7433 FILE_ATTRIBUTE_NORMAL,
7434 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
7435 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
7437 if (tevent_req_nomem(subreq, req)) {
7438 return tevent_req_post(req, ev);
7440 tevent_req_set_callback(subreq, torture_createdel_created, req);
7444 static void torture_createdel_created(struct tevent_req *subreq)
7446 struct tevent_req *req = tevent_req_callback_data(
7447 subreq, struct tevent_req);
7448 struct torture_createdel_state *state = tevent_req_data(
7449 req, struct torture_createdel_state);
7453 status = cli_ntcreate_recv(subreq, &fnum, NULL);
7454 TALLOC_FREE(subreq);
7455 if (tevent_req_nterror(req, status)) {
7456 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
7457 nt_errstr(status)));
7461 subreq = cli_close_send(state, state->ev, state->cli, fnum);
7462 if (tevent_req_nomem(subreq, req)) {
7465 tevent_req_set_callback(subreq, torture_createdel_closed, req);
7468 static void torture_createdel_closed(struct tevent_req *subreq)
7470 struct tevent_req *req = tevent_req_callback_data(
7471 subreq, struct tevent_req);
7474 status = cli_close_recv(subreq);
7475 if (tevent_req_nterror(req, status)) {
7476 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
7479 tevent_req_done(req);
7482 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
7484 return tevent_req_simple_recv_ntstatus(req);
7487 struct torture_createdels_state {
7488 struct tevent_context *ev;
7489 struct cli_state *cli;
7490 const char *base_name;
7494 struct tevent_req **reqs;
7497 static void torture_createdels_done(struct tevent_req *subreq);
7499 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
7500 struct tevent_context *ev,
7501 struct cli_state *cli,
7502 const char *base_name,
7506 struct tevent_req *req;
7507 struct torture_createdels_state *state;
7510 req = tevent_req_create(mem_ctx, &state,
7511 struct torture_createdels_state);
7517 state->base_name = talloc_strdup(state, base_name);
7518 if (tevent_req_nomem(state->base_name, req)) {
7519 return tevent_req_post(req, ev);
7521 state->num_files = MAX(num_parallel, num_files);
7523 state->received = 0;
7525 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
7526 if (tevent_req_nomem(state->reqs, req)) {
7527 return tevent_req_post(req, ev);
7530 for (i=0; i<num_parallel; i++) {
7533 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
7535 if (tevent_req_nomem(name, req)) {
7536 return tevent_req_post(req, ev);
7538 state->reqs[i] = torture_createdel_send(
7539 state->reqs, state->ev, state->cli, name);
7540 if (tevent_req_nomem(state->reqs[i], req)) {
7541 return tevent_req_post(req, ev);
7543 name = talloc_move(state->reqs[i], &name);
7544 tevent_req_set_callback(state->reqs[i],
7545 torture_createdels_done, req);
7551 static void torture_createdels_done(struct tevent_req *subreq)
7553 struct tevent_req *req = tevent_req_callback_data(
7554 subreq, struct tevent_req);
7555 struct torture_createdels_state *state = tevent_req_data(
7556 req, struct torture_createdels_state);
7557 size_t num_parallel = talloc_array_length(state->reqs);
7562 status = torture_createdel_recv(subreq);
7563 if (!NT_STATUS_IS_OK(status)){
7564 DEBUG(10, ("torture_createdel_recv returned %s\n",
7565 nt_errstr(status)));
7566 TALLOC_FREE(subreq);
7567 tevent_req_nterror(req, status);
7571 for (i=0; i<num_parallel; i++) {
7572 if (subreq == state->reqs[i]) {
7576 if (i == num_parallel) {
7577 DEBUG(10, ("received something we did not send\n"));
7578 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
7581 TALLOC_FREE(state->reqs[i]);
7583 if (state->sent >= state->num_files) {
7584 tevent_req_done(req);
7588 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
7590 if (tevent_req_nomem(name, req)) {
7593 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
7595 if (tevent_req_nomem(state->reqs[i], req)) {
7598 name = talloc_move(state->reqs[i], &name);
7599 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
7603 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
7605 return tevent_req_simple_recv_ntstatus(req);
7608 struct swallow_notify_state {
7609 struct tevent_context *ev;
7610 struct cli_state *cli;
7612 uint32_t completion_filter;
7614 bool (*fn)(uint32_t action, const char *name, void *priv);
7618 static void swallow_notify_done(struct tevent_req *subreq);
7620 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
7621 struct tevent_context *ev,
7622 struct cli_state *cli,
7624 uint32_t completion_filter,
7626 bool (*fn)(uint32_t action,
7631 struct tevent_req *req, *subreq;
7632 struct swallow_notify_state *state;
7634 req = tevent_req_create(mem_ctx, &state,
7635 struct swallow_notify_state);
7642 state->completion_filter = completion_filter;
7643 state->recursive = recursive;
7647 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
7648 0xffff, state->completion_filter,
7650 if (tevent_req_nomem(subreq, req)) {
7651 return tevent_req_post(req, ev);
7653 tevent_req_set_callback(subreq, swallow_notify_done, req);
7657 static void swallow_notify_done(struct tevent_req *subreq)
7659 struct tevent_req *req = tevent_req_callback_data(
7660 subreq, struct tevent_req);
7661 struct swallow_notify_state *state = tevent_req_data(
7662 req, struct swallow_notify_state);
7664 uint32_t i, num_changes;
7665 struct notify_change *changes;
7667 status = cli_notify_recv(subreq, state, &num_changes, &changes);
7668 TALLOC_FREE(subreq);
7669 if (!NT_STATUS_IS_OK(status)) {
7670 DEBUG(10, ("cli_notify_recv returned %s\n",
7671 nt_errstr(status)));
7672 tevent_req_nterror(req, status);
7676 for (i=0; i<num_changes; i++) {
7677 state->fn(changes[i].action, changes[i].name, state->priv);
7679 TALLOC_FREE(changes);
7681 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
7682 0xffff, state->completion_filter,
7684 if (tevent_req_nomem(subreq, req)) {
7687 tevent_req_set_callback(subreq, swallow_notify_done, req);
7690 static bool print_notifies(uint32_t action, const char *name, void *priv)
7692 if (DEBUGLEVEL > 5) {
7693 d_printf("%d %s\n", (int)action, name);
7698 static void notify_bench_done(struct tevent_req *req)
7700 int *num_finished = (int *)tevent_req_callback_data_void(req);
7704 static bool run_notify_bench(int dummy)
7706 const char *dname = "\\notify-bench";
7707 struct tevent_context *ev;
7710 struct tevent_req *req1;
7711 struct tevent_req *req2 = NULL;
7712 int i, num_unc_names;
7713 int num_finished = 0;
7715 printf("starting notify-bench test\n");
7717 if (use_multishare_conn) {
7719 unc_list = file_lines_load(multishare_conn_fname,
7720 &num_unc_names, 0, NULL);
7721 if (!unc_list || num_unc_names <= 0) {
7722 d_printf("Failed to load unc names list from '%s'\n",
7723 multishare_conn_fname);
7726 TALLOC_FREE(unc_list);
7731 ev = samba_tevent_context_init(talloc_tos());
7733 d_printf("tevent_context_init failed\n");
7737 for (i=0; i<num_unc_names; i++) {
7738 struct cli_state *cli;
7741 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
7743 if (base_fname == NULL) {
7747 if (!torture_open_connection(&cli, i)) {
7751 status = cli_ntcreate(cli, dname, 0,
7752 MAXIMUM_ALLOWED_ACCESS,
7753 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
7755 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
7758 if (!NT_STATUS_IS_OK(status)) {
7759 d_printf("Could not create %s: %s\n", dname,
7764 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
7765 FILE_NOTIFY_CHANGE_FILE_NAME |
7766 FILE_NOTIFY_CHANGE_DIR_NAME |
7767 FILE_NOTIFY_CHANGE_ATTRIBUTES |
7768 FILE_NOTIFY_CHANGE_LAST_WRITE,
7769 false, print_notifies, NULL);
7771 d_printf("Could not create notify request\n");
7775 req2 = torture_createdels_send(talloc_tos(), ev, cli,
7776 base_fname, 10, torture_numops);
7778 d_printf("Could not create createdels request\n");
7781 TALLOC_FREE(base_fname);
7783 tevent_req_set_callback(req2, notify_bench_done,
7787 while (num_finished < num_unc_names) {
7789 ret = tevent_loop_once(ev);
7791 d_printf("tevent_loop_once failed\n");
7796 if (!tevent_req_poll(req2, ev)) {
7797 d_printf("tevent_req_poll failed\n");
7800 status = torture_createdels_recv(req2);
7801 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
7806 static bool run_mangle1(int dummy)
7808 struct cli_state *cli;
7809 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
7813 time_t change_time, access_time, write_time;
7817 printf("starting mangle1 test\n");
7818 if (!torture_open_connection(&cli, 0)) {
7822 smbXcli_conn_set_sockopt(cli->conn, sockops);
7824 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7825 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7827 if (!NT_STATUS_IS_OK(status)) {
7828 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7831 cli_close(cli, fnum);
7833 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
7834 if (!NT_STATUS_IS_OK(status)) {
7835 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7839 d_printf("alt_name: %s\n", alt_name);
7841 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7842 if (!NT_STATUS_IS_OK(status)) {
7843 d_printf("cli_openx(%s) failed: %s\n", alt_name,
7847 cli_close(cli, fnum);
7849 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7850 &write_time, &size, &mode);
7851 if (!NT_STATUS_IS_OK(status)) {
7852 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7860 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7862 size_t *to_pull = (size_t *)priv;
7863 size_t thistime = *to_pull;
7865 thistime = MIN(thistime, n);
7866 if (thistime == 0) {
7870 memset(buf, 0, thistime);
7871 *to_pull -= thistime;
7875 static bool run_windows_write(int dummy)
7877 struct cli_state *cli1;
7881 const char *fname = "\\writetest.txt";
7882 struct timeval start_time;
7887 printf("starting windows_write test\n");
7888 if (!torture_open_connection(&cli1, 0)) {
7892 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7893 if (!NT_STATUS_IS_OK(status)) {
7894 printf("open failed (%s)\n", nt_errstr(status));
7898 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7900 start_time = timeval_current();
7902 for (i=0; i<torture_numops; i++) {
7904 off_t start = i * torture_blocksize;
7905 size_t to_pull = torture_blocksize - 1;
7907 status = cli_writeall(cli1, fnum, 0, &c,
7908 start + torture_blocksize - 1, 1, NULL);
7909 if (!NT_STATUS_IS_OK(status)) {
7910 printf("cli_write failed: %s\n", nt_errstr(status));
7914 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7915 null_source, &to_pull);
7916 if (!NT_STATUS_IS_OK(status)) {
7917 printf("cli_push returned: %s\n", nt_errstr(status));
7922 seconds = timeval_elapsed(&start_time);
7923 kbytes = (double)torture_blocksize * torture_numops;
7926 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7927 (double)seconds, (int)(kbytes/seconds));
7931 cli_close(cli1, fnum);
7932 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7933 torture_close_connection(cli1);
7937 static size_t calc_expected_return(struct cli_state *cli, size_t len_requested)
7939 size_t max_pdu = 0x1FFFF;
7941 if (cli->server_posix_capabilities & CIFS_UNIX_LARGE_READ_CAP) {
7945 if (smb1cli_conn_signing_is_active(cli->conn)) {
7949 if (smb1cli_conn_encryption_on(cli->conn)) {
7950 max_pdu = CLI_BUFFER_SIZE;
7953 if ((len_requested & 0xFFFF0000) == 0xFFFF0000) {
7954 len_requested &= 0xFFFF;
7957 return MIN(len_requested,
7958 max_pdu - (MIN_SMB_SIZE + VWV(12) + 1 /* padding byte */));
7961 static bool check_read_call(struct cli_state *cli,
7964 size_t len_requested)
7967 struct tevent_req *subreq = NULL;
7968 ssize_t len_read = 0;
7969 size_t len_expected = 0;
7970 struct tevent_context *ev = NULL;
7972 ev = samba_tevent_context_init(talloc_tos());
7977 subreq = cli_read_andx_send(talloc_tos(),
7984 if (!tevent_req_poll_ntstatus(subreq, ev, &status)) {
7988 status = cli_read_andx_recv(subreq, &len_read, &buf);
7989 if (!NT_STATUS_IS_OK(status)) {
7990 d_printf("cli_read_andx_recv failed: %s\n", nt_errstr(status));
7994 TALLOC_FREE(subreq);
7997 len_expected = calc_expected_return(cli, len_requested);
7999 if (len_expected > 0x10000 && len_read == 0x10000) {
8000 /* Windows servers only return a max of 0x10000,
8001 doesn't matter if you set CAP_LARGE_READX in
8002 the client sessionsetupX call or not. */
8003 d_printf("Windows server - returned 0x10000 on a read of 0x%x\n",
8004 (unsigned int)len_requested);
8005 } else if (len_read != len_expected) {
8006 d_printf("read of 0x%x failed: got 0x%x, expected 0x%x\n",
8007 (unsigned int)len_requested,
8008 (unsigned int)len_read,
8009 (unsigned int)len_expected);
8012 d_printf("Correct read reply.\n");
8018 /* Test large readX variants. */
8019 static bool large_readx_tests(struct cli_state *cli,
8023 /* A read of 0xFFFF0001 should *always* return 1 byte. */
8024 if (check_read_call(cli, fnum, buf, 0xFFFF0001) == false) {
8027 /* A read of 0x10000 should return 0x10000 bytes. */
8028 if (check_read_call(cli, fnum, buf, 0x10000) == false) {
8031 /* A read of 0x10000 should return 0x10001 bytes. */
8032 if (check_read_call(cli, fnum, buf, 0x10001) == false) {
8035 /* A read of 0x1FFFF - (MIN_SMB_SIZE + VWV(12) should return
8036 the requested number of bytes. */
8037 if (check_read_call(cli, fnum, buf, 0x1FFFF - (MIN_SMB_SIZE + VWV(12))) == false) {
8040 /* A read of 1MB should return 1MB bytes (on Samba). */
8041 if (check_read_call(cli, fnum, buf, 0x100000) == false) {
8045 if (check_read_call(cli, fnum, buf, 0x20001) == false) {
8048 if (check_read_call(cli, fnum, buf, 0x22000001) == false) {
8051 if (check_read_call(cli, fnum, buf, 0xFFFE0001) == false) {
8057 static bool run_large_readx(int dummy)
8059 uint8_t *buf = NULL;
8060 struct cli_state *cli1 = NULL;
8061 struct cli_state *cli2 = NULL;
8062 bool correct = false;
8063 const char *fname = "\\large_readx.dat";
8065 uint16_t fnum1 = UINT16_MAX;
8066 uint32_t normal_caps = 0;
8067 size_t file_size = 20*1024*1024;
8068 TALLOC_CTX *frame = talloc_stackframe();
8072 enum smb_signing_setting signing_setting;
8073 enum protocol_types protocol;
8077 .signing_setting = SMB_SIGNING_IF_REQUIRED,
8078 .protocol = PROTOCOL_NT1,
8080 .name = "NT1 - SIGNING_REQUIRED",
8081 .signing_setting = SMB_SIGNING_REQUIRED,
8082 .protocol = PROTOCOL_NT1,
8086 printf("starting large_readx test\n");
8088 if (!torture_open_connection(&cli1, 0)) {
8092 normal_caps = smb1cli_conn_capabilities(cli1->conn);
8094 if (!(normal_caps & CAP_LARGE_READX)) {
8095 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8096 (unsigned int)normal_caps);
8100 /* Create a file of size 4MB. */
8101 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
8102 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
8103 0, 0, &fnum1, NULL);
8105 if (!NT_STATUS_IS_OK(status)) {
8106 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
8110 /* Write file_size bytes. */
8111 buf = talloc_zero_array(frame, uint8_t, file_size);
8116 status = cli_writeall(cli1,
8123 if (!NT_STATUS_IS_OK(status)) {
8124 d_printf("cli_writeall failed: %s\n", nt_errstr(status));
8128 status = cli_close(cli1, fnum1);
8129 if (!NT_STATUS_IS_OK(status)) {
8130 d_printf("cli_close failed: %s\n", nt_errstr(status));
8136 for (i=0; i < ARRAY_SIZE(runs); i++) {
8137 enum smb_signing_setting saved_signing_setting = signing_state;
8138 uint16_t fnum2 = -1;
8141 (runs[i].signing_setting == SMB_SIGNING_REQUIRED))
8143 d_printf("skip[%u] - %s\n", (unsigned)i, runs[i].name);
8147 d_printf("run[%u] - %s\n", (unsigned)i, runs[i].name);
8149 signing_state = runs[i].signing_setting;
8150 cli2 = open_nbt_connection();
8151 signing_state = saved_signing_setting;
8156 status = smbXcli_negprot(cli2->conn,
8160 if (!NT_STATUS_IS_OK(status)) {
8164 status = cli_session_setup(cli2,
8168 if (!NT_STATUS_IS_OK(status)) {
8172 status = cli_tree_connect(cli2,
8176 strlen(password)+1);
8177 if (!NT_STATUS_IS_OK(status)) {
8181 cli_set_timeout(cli2, 120000); /* set a really long timeout (2 minutes) */
8183 normal_caps = smb1cli_conn_capabilities(cli2->conn);
8185 if (!(normal_caps & CAP_LARGE_READX)) {
8186 d_printf("Server doesn't have CAP_LARGE_READX 0x%x\n",
8187 (unsigned int)normal_caps);
8192 if (force_cli_encryption(cli2, share) == false) {
8195 } else if (SERVER_HAS_UNIX_CIFS(cli2)) {
8196 uint16_t major, minor;
8197 uint32_t caplow, caphigh;
8199 status = cli_unix_extensions_version(cli2,
8202 if (!NT_STATUS_IS_OK(status)) {
8207 status = cli_ntcreate(cli2, fname, 0, FILE_READ_DATA,
8208 FILE_ATTRIBUTE_NORMAL, 0, FILE_OPEN,
8209 0, 0, &fnum2, NULL);
8210 if (!NT_STATUS_IS_OK(status)) {
8211 d_printf("Second open %s failed: %s\n", fname, nt_errstr(status));
8215 /* All reads must return less than file_size bytes. */
8216 if (!large_readx_tests(cli2, fnum2, buf)) {
8220 status = cli_close(cli2, fnum2);
8221 if (!NT_STATUS_IS_OK(status)) {
8222 d_printf("cli_close failed: %s\n", nt_errstr(status));
8227 if (!torture_close_connection(cli2)) {
8234 printf("Success on large_readx test\n");
8239 if (!torture_close_connection(cli2)) {
8245 if (fnum1 != UINT16_MAX) {
8246 status = cli_close(cli1, fnum1);
8247 if (!NT_STATUS_IS_OK(status)) {
8248 d_printf("cli_close failed: %s\n", nt_errstr(status));
8253 status = cli_unlink(cli1, fname,
8254 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8255 if (!NT_STATUS_IS_OK(status)) {
8256 printf("unlink failed (%s)\n", nt_errstr(status));
8259 if (!torture_close_connection(cli1)) {
8266 printf("finished large_readx test\n");
8270 static bool run_cli_echo(int dummy)
8272 struct cli_state *cli;
8275 printf("starting cli_echo test\n");
8276 if (!torture_open_connection(&cli, 0)) {
8279 smbXcli_conn_set_sockopt(cli->conn, sockops);
8281 status = cli_echo(cli, 5, data_blob_const("hello", 5));
8283 d_printf("cli_echo returned %s\n", nt_errstr(status));
8285 torture_close_connection(cli);
8286 return NT_STATUS_IS_OK(status);
8289 static bool run_uid_regression_test(int dummy)
8291 static struct cli_state *cli;
8294 bool correct = True;
8297 printf("starting uid regression test\n");
8299 if (!torture_open_connection(&cli, 0)) {
8303 smbXcli_conn_set_sockopt(cli->conn, sockops);
8305 /* Ok - now save then logoff our current user. */
8306 old_vuid = cli_state_get_uid(cli);
8308 status = cli_ulogoff(cli);
8309 if (!NT_STATUS_IS_OK(status)) {
8310 d_printf("(%s) cli_ulogoff failed: %s\n",
8311 __location__, nt_errstr(status));
8316 cli_state_set_uid(cli, old_vuid);
8318 /* Try an operation. */
8319 status = cli_mkdir(cli, "\\uid_reg_test");
8320 if (NT_STATUS_IS_OK(status)) {
8321 d_printf("(%s) cli_mkdir succeeded\n",
8326 /* Should be bad uid. */
8327 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
8328 NT_STATUS_USER_SESSION_DELETED)) {
8334 old_cnum = cli_state_get_tid(cli);
8336 /* Now try a SMBtdis with the invald vuid set to zero. */
8337 cli_state_set_uid(cli, 0);
8339 /* This should succeed. */
8340 status = cli_tdis(cli);
8342 if (NT_STATUS_IS_OK(status)) {
8343 d_printf("First tdis with invalid vuid should succeed.\n");
8345 d_printf("First tdis failed (%s)\n", nt_errstr(status));
8350 cli_state_set_uid(cli, old_vuid);
8351 cli_state_set_tid(cli, old_cnum);
8353 /* This should fail. */
8354 status = cli_tdis(cli);
8355 if (NT_STATUS_IS_OK(status)) {
8356 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
8360 /* Should be bad tid. */
8361 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
8362 NT_STATUS_NETWORK_NAME_DELETED)) {
8368 cli_rmdir(cli, "\\uid_reg_test");
8377 static const char *illegal_chars = "*\\/?<>|\":";
8378 static char force_shortname_chars[] = " +,.[];=\177";
8380 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
8381 const char *mask, void *state)
8383 struct cli_state *pcli = (struct cli_state *)state;
8385 NTSTATUS status = NT_STATUS_OK;
8387 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
8389 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
8390 return NT_STATUS_OK;
8392 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
8393 status = cli_rmdir(pcli, fname);
8394 if (!NT_STATUS_IS_OK(status)) {
8395 printf("del_fn: failed to rmdir %s\n,", fname );
8398 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8399 if (!NT_STATUS_IS_OK(status)) {
8400 printf("del_fn: failed to unlink %s\n,", fname );
8412 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
8413 const char *name, void *state)
8415 struct sn_state *s = (struct sn_state *)state;
8419 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
8420 i, finfo->name, finfo->short_name);
8423 if (strchr(force_shortname_chars, i)) {
8424 if (!finfo->short_name) {
8425 /* Shortname not created when it should be. */
8426 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
8427 __location__, finfo->name, i);
8430 } else if (finfo->short_name){
8431 /* Shortname created when it should not be. */
8432 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
8433 __location__, finfo->short_name, finfo->name);
8437 return NT_STATUS_OK;
8440 static bool run_shortname_test(int dummy)
8442 static struct cli_state *cli;
8443 bool correct = True;
8449 printf("starting shortname test\n");
8451 if (!torture_open_connection(&cli, 0)) {
8455 smbXcli_conn_set_sockopt(cli->conn, sockops);
8457 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
8458 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
8459 cli_rmdir(cli, "\\shortname");
8461 status = cli_mkdir(cli, "\\shortname");
8462 if (!NT_STATUS_IS_OK(status)) {
8463 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
8464 __location__, nt_errstr(status));
8469 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
8473 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
8480 for (i = 32; i < 128; i++) {
8481 uint16_t fnum = (uint16_t)-1;
8485 if (strchr(illegal_chars, i)) {
8490 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
8491 FILE_SHARE_READ|FILE_SHARE_WRITE,
8492 FILE_OVERWRITE_IF, 0, 0, &fnum, NULL);
8493 if (!NT_STATUS_IS_OK(status)) {
8494 d_printf("(%s) cli_nt_create of %s failed: %s\n",
8495 __location__, fname, nt_errstr(status));
8499 cli_close(cli, fnum);
8502 status = cli_list(cli, "\\shortname\\test*.*", 0,
8503 shortname_list_fn, &s);
8504 if (s.matched != 1) {
8505 d_printf("(%s) failed to list %s: %s\n",
8506 __location__, fname, nt_errstr(status));
8511 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8512 if (!NT_STATUS_IS_OK(status)) {
8513 d_printf("(%s) failed to delete %s: %s\n",
8514 __location__, fname, nt_errstr(status));
8527 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
8528 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
8529 cli_rmdir(cli, "\\shortname");
8530 torture_close_connection(cli);
8534 static void pagedsearch_cb(struct tevent_req *req)
8537 struct tldap_message *msg;
8540 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
8541 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8542 d_printf("tldap_search_paged_recv failed: %s\n",
8543 tldap_rc2string(rc));
8546 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
8550 if (!tldap_entry_dn(msg, &dn)) {
8551 d_printf("tldap_entry_dn failed\n");
8554 d_printf("%s\n", dn);
8558 static bool run_tldap(int dummy)
8560 struct tldap_context *ld;
8564 struct sockaddr_storage addr;
8565 struct tevent_context *ev;
8566 struct tevent_req *req;
8570 if (!resolve_name(host, &addr, 0, false)) {
8571 d_printf("could not find host %s\n", host);
8574 status = open_socket_out(&addr, 389, 9999, &fd);
8575 if (!NT_STATUS_IS_OK(status)) {
8576 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
8580 ld = tldap_context_create(talloc_tos(), fd);
8583 d_printf("tldap_context_create failed\n");
8587 rc = tldap_fetch_rootdse(ld);
8588 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8589 d_printf("tldap_fetch_rootdse failed: %s\n",
8590 tldap_errstr(talloc_tos(), ld, rc));
8594 basedn = tldap_talloc_single_attribute(
8595 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
8596 if (basedn == NULL) {
8597 d_printf("no defaultNamingContext\n");
8600 d_printf("defaultNamingContext: %s\n", basedn);
8602 ev = samba_tevent_context_init(talloc_tos());
8604 d_printf("tevent_context_init failed\n");
8608 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
8609 TLDAP_SCOPE_SUB, "(objectclass=*)",
8611 NULL, 0, NULL, 0, 0, 0, 0, 5);
8613 d_printf("tldap_search_paged_send failed\n");
8616 tevent_req_set_callback(req, pagedsearch_cb, NULL);
8618 tevent_req_poll(req, ev);
8622 /* test search filters against rootDSE */
8623 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
8624 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
8626 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
8627 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
8628 talloc_tos(), NULL);
8629 if (!TLDAP_RC_IS_SUCCESS(rc)) {
8630 d_printf("tldap_search with complex filter failed: %s\n",
8631 tldap_errstr(talloc_tos(), ld, rc));
8639 /* Torture test to ensure no regression of :
8640 https://bugzilla.samba.org/show_bug.cgi?id=7084
8643 static bool run_dir_createtime(int dummy)
8645 struct cli_state *cli;
8646 const char *dname = "\\testdir";
8647 const char *fname = "\\testdir\\testfile";
8649 struct timespec create_time;
8650 struct timespec create_time1;
8654 if (!torture_open_connection(&cli, 0)) {
8658 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8659 cli_rmdir(cli, dname);
8661 status = cli_mkdir(cli, dname);
8662 if (!NT_STATUS_IS_OK(status)) {
8663 printf("mkdir failed: %s\n", nt_errstr(status));
8667 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
8669 if (!NT_STATUS_IS_OK(status)) {
8670 printf("cli_qpathinfo2 returned %s\n",
8675 /* Sleep 3 seconds, then create a file. */
8678 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
8680 if (!NT_STATUS_IS_OK(status)) {
8681 printf("cli_openx failed: %s\n", nt_errstr(status));
8685 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
8687 if (!NT_STATUS_IS_OK(status)) {
8688 printf("cli_qpathinfo2 (2) returned %s\n",
8693 if (timespec_compare(&create_time1, &create_time)) {
8694 printf("run_dir_createtime: create time was updated (error)\n");
8696 printf("run_dir_createtime: create time was not updated (correct)\n");
8702 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8703 cli_rmdir(cli, dname);
8704 if (!torture_close_connection(cli)) {
8711 static bool run_streamerror(int dummy)
8713 struct cli_state *cli;
8714 const char *dname = "\\testdir";
8715 const char *streamname =
8716 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
8718 time_t change_time, access_time, write_time;
8720 uint16_t mode, fnum;
8723 if (!torture_open_connection(&cli, 0)) {
8727 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
8728 cli_rmdir(cli, dname);
8730 status = cli_mkdir(cli, dname);
8731 if (!NT_STATUS_IS_OK(status)) {
8732 printf("mkdir failed: %s\n", nt_errstr(status));
8736 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
8737 &write_time, &size, &mode);
8738 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
8739 printf("pathinfo returned %s, expected "
8740 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8745 status = cli_ntcreate(cli, streamname, 0x16,
8746 FILE_READ_DATA|FILE_READ_EA|
8747 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
8748 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
8749 FILE_OPEN, 0, 0, &fnum, NULL);
8751 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
8752 printf("ntcreate returned %s, expected "
8753 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
8759 cli_rmdir(cli, dname);
8763 struct pidtest_state {
8769 static void pid_echo_done(struct tevent_req *subreq);
8771 static struct tevent_req *pid_echo_send(TALLOC_CTX *mem_ctx,
8772 struct tevent_context *ev,
8773 struct cli_state *cli)
8775 struct tevent_req *req, *subreq;
8776 struct pidtest_state *state;
8778 req = tevent_req_create(mem_ctx, &state, struct pidtest_state);
8783 SSVAL(state->vwv, 0, 1);
8784 state->data = data_blob_const("hello", 5);
8786 subreq = smb1cli_req_send(state,
8791 0, 0, /* *_flags2 */
8793 0xDEADBEEF, /* pid */
8796 ARRAY_SIZE(state->vwv), state->vwv,
8797 state->data.length, state->data.data);
8799 if (tevent_req_nomem(subreq, req)) {
8800 return tevent_req_post(req, ev);
8802 tevent_req_set_callback(subreq, pid_echo_done, req);
8806 static void pid_echo_done(struct tevent_req *subreq)
8808 struct tevent_req *req = tevent_req_callback_data(
8809 subreq, struct tevent_req);
8810 struct pidtest_state *state = tevent_req_data(
8811 req, struct pidtest_state);
8814 uint8_t *bytes = NULL;
8815 struct iovec *recv_iov = NULL;
8816 uint8_t *phdr = NULL;
8817 uint16_t pidlow = 0;
8818 uint16_t pidhigh = 0;
8819 struct smb1cli_req_expected_response expected[] = {
8821 .status = NT_STATUS_OK,
8826 status = smb1cli_req_recv(subreq, state,
8831 NULL, /* pvwv_offset */
8834 NULL, /* pbytes_offset */
8836 expected, ARRAY_SIZE(expected));
8838 TALLOC_FREE(subreq);
8840 if (!NT_STATUS_IS_OK(status)) {
8841 tevent_req_nterror(req, status);
8845 if (num_bytes != state->data.length) {
8846 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8850 if (memcmp(bytes, state->data.data, num_bytes) != 0) {
8851 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8855 /* Check pid low/high == DEADBEEF */
8856 pidlow = SVAL(phdr, HDR_PID);
8857 if (pidlow != 0xBEEF){
8858 printf("Incorrect pidlow 0x%x, should be 0xBEEF\n",
8859 (unsigned int)pidlow);
8860 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8863 pidhigh = SVAL(phdr, HDR_PIDHIGH);
8864 if (pidhigh != 0xDEAD){
8865 printf("Incorrect pidhigh 0x%x, should be 0xDEAD\n",
8866 (unsigned int)pidhigh);
8867 tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE);
8871 tevent_req_done(req);
8874 static NTSTATUS pid_echo_recv(struct tevent_req *req)
8876 return tevent_req_simple_recv_ntstatus(req);
8879 static bool run_pidhigh(int dummy)
8881 bool success = false;
8882 struct cli_state *cli = NULL;
8884 struct tevent_context *ev = NULL;
8885 struct tevent_req *req = NULL;
8886 TALLOC_CTX *frame = talloc_stackframe();
8888 printf("starting pid high test\n");
8889 if (!torture_open_connection(&cli, 0)) {
8892 smbXcli_conn_set_sockopt(cli->conn, sockops);
8894 ev = samba_tevent_context_init(frame);
8899 req = pid_echo_send(frame, ev, cli);
8904 if (!tevent_req_poll_ntstatus(req, ev, &status)) {
8908 status = pid_echo_recv(req);
8909 if (NT_STATUS_IS_OK(status)) {
8910 printf("pid high test ok\n");
8917 torture_close_connection(cli);
8921 static bool run_local_substitute(int dummy)
8925 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
8926 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
8927 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
8928 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
8929 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
8930 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
8931 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
8932 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
8934 /* Different captialization rules in sub_basic... */
8936 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
8942 static bool run_local_base64(int dummy)
8947 for (i=1; i<2000; i++) {
8948 DATA_BLOB blob1, blob2;
8951 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
8953 generate_random_buffer(blob1.data, blob1.length);
8955 b64 = base64_encode_data_blob(talloc_tos(), blob1);
8957 d_fprintf(stderr, "base64_encode_data_blob failed "
8958 "for %d bytes\n", i);
8961 blob2 = base64_decode_data_blob(b64);
8964 if (data_blob_cmp(&blob1, &blob2)) {
8965 d_fprintf(stderr, "data_blob_cmp failed for %d "
8969 TALLOC_FREE(blob1.data);
8970 data_blob_free(&blob2);
8975 static void parse_fn(time_t timeout, DATA_BLOB blob, void *private_data)
8980 static bool run_local_gencache(int dummy)
8986 struct memcache *mem;
8989 mem = memcache_init(NULL, 0);
8991 d_printf("%s: memcache_init failed\n", __location__);
8994 memcache_set_global(mem);
8996 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
8997 d_printf("%s: gencache_set() failed\n", __location__);
9001 if (!gencache_get("foo", NULL, NULL, NULL)) {
9002 d_printf("%s: gencache_get() failed\n", __location__);
9006 for (i=0; i<1000000; i++) {
9007 gencache_parse("foo", parse_fn, NULL);
9010 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9011 d_printf("%s: gencache_get() failed\n", __location__);
9016 if (!gencache_get("foo", talloc_tos(), &val, &tm)) {
9017 d_printf("%s: gencache_get() failed\n", __location__);
9021 if (strcmp(val, "bar") != 0) {
9022 d_printf("%s: gencache_get() returned %s, expected %s\n",
9023 __location__, val, "bar");
9030 if (!gencache_del("foo")) {
9031 d_printf("%s: gencache_del() failed\n", __location__);
9034 if (gencache_del("foo")) {
9035 d_printf("%s: second gencache_del() succeeded\n",
9040 if (gencache_get("foo", talloc_tos(), &val, &tm)) {
9041 d_printf("%s: gencache_get() on deleted entry "
9042 "succeeded\n", __location__);
9046 blob = data_blob_string_const_null("bar");
9047 tm = time(NULL) + 60;
9049 if (!gencache_set_data_blob("foo", &blob, tm)) {
9050 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
9054 if (!gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
9055 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
9059 if (strcmp((const char *)blob.data, "bar") != 0) {
9060 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
9061 __location__, (const char *)blob.data, "bar");
9062 data_blob_free(&blob);
9066 data_blob_free(&blob);
9068 if (!gencache_del("foo")) {
9069 d_printf("%s: gencache_del() failed\n", __location__);
9072 if (gencache_del("foo")) {
9073 d_printf("%s: second gencache_del() succeeded\n",
9078 if (gencache_get_data_blob("foo", talloc_tos(), &blob, NULL, NULL)) {
9079 d_printf("%s: gencache_get_data_blob() on deleted entry "
9080 "succeeded\n", __location__);
9085 blob.data = (uint8_t *)&v;
9086 blob.length = sizeof(v);
9088 if (!gencache_set_data_blob("blob", &blob, tm)) {
9089 d_printf("%s: gencache_set_data_blob() failed\n",
9093 if (gencache_get("blob", talloc_tos(), &val, &tm)) {
9094 d_printf("%s: gencache_get succeeded\n", __location__);
9101 static bool rbt_testval(struct db_context *db, const char *key,
9104 struct db_record *rec;
9105 TDB_DATA data = string_tdb_data(value);
9110 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
9112 d_fprintf(stderr, "fetch_locked failed\n");
9115 status = dbwrap_record_store(rec, data, 0);
9116 if (!NT_STATUS_IS_OK(status)) {
9117 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
9122 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
9124 d_fprintf(stderr, "second fetch_locked failed\n");
9128 dbvalue = dbwrap_record_get_value(rec);
9129 if ((dbvalue.dsize != data.dsize)
9130 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
9131 d_fprintf(stderr, "Got wrong data back\n");
9141 static int local_rbtree_traverse_read(struct db_record *rec, void *private_data)
9143 int *count2 = (int *)private_data;
9148 static int local_rbtree_traverse_delete(struct db_record *rec, void *private_data)
9150 int *count2 = (int *)private_data;
9152 dbwrap_record_delete(rec);
9156 static bool run_local_rbtree(int dummy)
9158 struct db_context *db;
9165 db = db_open_rbt(NULL);
9168 d_fprintf(stderr, "db_open_rbt failed\n");
9172 for (i=0; i<1000; i++) {
9175 if (asprintf(&key, "key%ld", random()) == -1) {
9178 if (asprintf(&value, "value%ld", random()) == -1) {
9183 if (!rbt_testval(db, key, value)) {
9190 if (asprintf(&value, "value%ld", random()) == -1) {
9195 if (!rbt_testval(db, key, value)) {
9206 count = 0; count2 = 0;
9207 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
9209 printf("%s: read1: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9210 if ((count != count2) || (count != 1000)) {
9213 count = 0; count2 = 0;
9214 status = dbwrap_traverse(db, local_rbtree_traverse_delete,
9216 printf("%s: delete: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9217 if ((count != count2) || (count != 1000)) {
9220 count = 0; count2 = 0;
9221 status = dbwrap_traverse_read(db, local_rbtree_traverse_read,
9223 printf("%s: read2: %d %d, %s\n", __func__, count, count2, nt_errstr(status));
9224 if ((count != count2) || (count != 0)) {
9235 local test for character set functions
9237 This is a very simple test for the functionality in convert_string_error()
9239 static bool run_local_convert_string(int dummy)
9241 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
9242 const char *test_strings[2] = { "March", "M\303\244rz" };
9246 for (i=0; i<2; i++) {
9247 const char *str = test_strings[i];
9248 int len = strlen(str);
9249 size_t converted_size;
9252 memset(dst, 'X', sizeof(dst));
9254 /* first try with real source length */
9255 ret = convert_string_error(CH_UNIX, CH_UTF8,
9260 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
9264 if (converted_size != len) {
9265 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
9266 str, len, (int)converted_size);
9270 if (strncmp(str, dst, converted_size) != 0) {
9271 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
9275 if (strlen(str) != converted_size) {
9276 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
9277 (int)strlen(str), (int)converted_size);
9281 if (dst[converted_size] != 'X') {
9282 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
9286 /* now with srclen==-1, this causes the nul to be
9288 ret = convert_string_error(CH_UNIX, CH_UTF8,
9293 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
9297 if (converted_size != len+1) {
9298 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
9299 str, len, (int)converted_size);
9303 if (strncmp(str, dst, converted_size) != 0) {
9304 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
9308 if (len+1 != converted_size) {
9309 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
9310 len+1, (int)converted_size);
9314 if (dst[converted_size] != 'X') {
9315 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
9322 TALLOC_FREE(tmp_ctx);
9325 TALLOC_FREE(tmp_ctx);
9330 struct talloc_dict_test {
9334 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
9336 int *count = (int *)priv;
9341 static bool run_local_talloc_dict(int dummy)
9343 struct talloc_dict *dict;
9344 struct talloc_dict_test *t;
9345 int key, count, res;
9348 dict = talloc_dict_init(talloc_tos());
9353 t = talloc(talloc_tos(), struct talloc_dict_test);
9360 ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
9366 res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
9384 static bool run_local_string_to_sid(int dummy) {
9387 if (string_to_sid(&sid, "S--1-5-32-545")) {
9388 printf("allowing S--1-5-32-545\n");
9391 if (string_to_sid(&sid, "S-1-5-32-+545")) {
9392 printf("allowing S-1-5-32-+545\n");
9395 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")) {
9396 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
9399 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
9400 printf("allowing S-1-5-32-545-abc\n");
9403 if (string_to_sid(&sid, "S-300-5-32-545")) {
9404 printf("allowing S-300-5-32-545\n");
9407 if (string_to_sid(&sid, "S-1-0xfffffffffffffe-32-545")) {
9408 printf("allowing S-1-0xfffffffffffffe-32-545\n");
9411 if (string_to_sid(&sid, "S-1-0xffffffffffff-5294967297-545")) {
9412 printf("allowing S-1-0xffffffffffff-5294967297-545\n");
9415 if (!string_to_sid(&sid, "S-1-0xfffffffffffe-32-545")) {
9416 printf("could not parse S-1-0xfffffffffffe-32-545\n");
9419 if (!string_to_sid(&sid, "S-1-5-32-545")) {
9420 printf("could not parse S-1-5-32-545\n");
9423 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
9424 printf("mis-parsed S-1-5-32-545 as %s\n",
9425 sid_string_tos(&sid));
9431 static bool sid_to_string_test(const char *expected) {
9436 if (!string_to_sid(&sid, expected)) {
9437 printf("could not parse %s\n", expected);
9441 str = dom_sid_string(NULL, &sid);
9442 if (strcmp(str, expected)) {
9443 printf("Comparison failed (%s != %s)\n", str, expected);
9450 static bool run_local_sid_to_string(int dummy) {
9451 if (!sid_to_string_test("S-1-0xffffffffffff-1-1-1-1-1-1-1-1-1-1-1-1"))
9453 if (!sid_to_string_test("S-1-545"))
9455 if (!sid_to_string_test("S-255-3840-1-1-1-1"))
9460 static bool run_local_binary_to_sid(int dummy) {
9461 struct dom_sid *sid = talloc(NULL, struct dom_sid);
9462 static const uint8_t good_binary_sid[] = {
9463 0x1, /* revision number */
9465 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9466 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9467 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9468 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9469 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9470 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9471 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9472 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9473 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9474 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9475 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9476 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9477 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9478 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9479 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9480 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9483 static const uint8_t long_binary_sid[] = {
9484 0x1, /* revision number */
9486 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9487 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9488 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9489 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9490 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9491 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9492 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9493 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9494 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9495 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9496 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9497 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9498 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9499 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9500 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9501 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9502 0x1, 0x1, 0x1, 0x1, /* auth[15] */
9503 0x1, 0x1, 0x1, 0x1, /* auth[16] */
9504 0x1, 0x1, 0x1, 0x1, /* auth[17] */
9507 static const uint8_t long_binary_sid2[] = {
9508 0x1, /* revision number */
9510 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
9511 0x1, 0x1, 0x1, 0x1, /* auth[0] */
9512 0x1, 0x1, 0x1, 0x1, /* auth[1] */
9513 0x1, 0x1, 0x1, 0x1, /* auth[2] */
9514 0x1, 0x1, 0x1, 0x1, /* auth[3] */
9515 0x1, 0x1, 0x1, 0x1, /* auth[4] */
9516 0x1, 0x1, 0x1, 0x1, /* auth[5] */
9517 0x1, 0x1, 0x1, 0x1, /* auth[6] */
9518 0x1, 0x1, 0x1, 0x1, /* auth[7] */
9519 0x1, 0x1, 0x1, 0x1, /* auth[8] */
9520 0x1, 0x1, 0x1, 0x1, /* auth[9] */
9521 0x1, 0x1, 0x1, 0x1, /* auth[10] */
9522 0x1, 0x1, 0x1, 0x1, /* auth[11] */
9523 0x1, 0x1, 0x1, 0x1, /* auth[12] */
9524 0x1, 0x1, 0x1, 0x1, /* auth[13] */
9525 0x1, 0x1, 0x1, 0x1, /* auth[14] */
9526 0x1, 0x1, 0x1, 0x1, /* auth[15] */
9527 0x1, 0x1, 0x1, 0x1, /* auth[16] */
9528 0x1, 0x1, 0x1, 0x1, /* auth[17] */
9529 0x1, 0x1, 0x1, 0x1, /* auth[18] */
9530 0x1, 0x1, 0x1, 0x1, /* auth[19] */
9531 0x1, 0x1, 0x1, 0x1, /* auth[20] */
9532 0x1, 0x1, 0x1, 0x1, /* auth[21] */
9533 0x1, 0x1, 0x1, 0x1, /* auth[22] */
9534 0x1, 0x1, 0x1, 0x1, /* auth[23] */
9535 0x1, 0x1, 0x1, 0x1, /* auth[24] */
9536 0x1, 0x1, 0x1, 0x1, /* auth[25] */
9537 0x1, 0x1, 0x1, 0x1, /* auth[26] */
9538 0x1, 0x1, 0x1, 0x1, /* auth[27] */
9539 0x1, 0x1, 0x1, 0x1, /* auth[28] */
9540 0x1, 0x1, 0x1, 0x1, /* auth[29] */
9541 0x1, 0x1, 0x1, 0x1, /* auth[30] */
9542 0x1, 0x1, 0x1, 0x1, /* auth[31] */
9545 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
9548 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
9551 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
9557 /* Split a path name into filename and stream name components. Canonicalise
9558 * such that an implicit $DATA token is always explicit.
9560 * The "specification" of this function can be found in the
9561 * run_local_stream_name() function in torture.c, I've tried those
9562 * combinations against a W2k3 server.
9565 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
9566 char **pbase, char **pstream)
9569 char *stream = NULL;
9570 char *sname; /* stream name */
9571 const char *stype; /* stream type */
9573 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
9575 sname = strchr_m(fname, ':');
9577 if (sname == NULL) {
9578 if (pbase != NULL) {
9579 base = talloc_strdup(mem_ctx, fname);
9580 NT_STATUS_HAVE_NO_MEMORY(base);
9585 if (pbase != NULL) {
9586 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
9587 NT_STATUS_HAVE_NO_MEMORY(base);
9592 stype = strchr_m(sname, ':');
9594 if (stype == NULL) {
9595 sname = talloc_strdup(mem_ctx, sname);
9599 if (strcasecmp_m(stype, ":$DATA") != 0) {
9601 * If there is an explicit stream type, so far we only
9602 * allow $DATA. Is there anything else allowed? -- vl
9604 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
9606 return NT_STATUS_OBJECT_NAME_INVALID;
9608 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
9612 if (sname == NULL) {
9614 return NT_STATUS_NO_MEMORY;
9617 if (sname[0] == '\0') {
9619 * no stream name, so no stream
9624 if (pstream != NULL) {
9625 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
9626 if (stream == NULL) {
9629 return NT_STATUS_NO_MEMORY;
9632 * upper-case the type field
9634 (void)strupper_m(strchr_m(stream, ':')+1);
9638 if (pbase != NULL) {
9641 if (pstream != NULL) {
9644 return NT_STATUS_OK;
9647 static bool test_stream_name(const char *fname, const char *expected_base,
9648 const char *expected_stream,
9649 NTSTATUS expected_status)
9653 char *stream = NULL;
9655 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
9656 if (!NT_STATUS_EQUAL(status, expected_status)) {
9660 if (!NT_STATUS_IS_OK(status)) {
9664 if (base == NULL) goto error;
9666 if (strcmp(expected_base, base) != 0) goto error;
9668 if ((expected_stream != NULL) && (stream == NULL)) goto error;
9669 if ((expected_stream == NULL) && (stream != NULL)) goto error;
9671 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
9675 TALLOC_FREE(stream);
9679 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
9680 fname, expected_base ? expected_base : "<NULL>",
9681 expected_stream ? expected_stream : "<NULL>",
9682 nt_errstr(expected_status));
9683 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
9684 base ? base : "<NULL>", stream ? stream : "<NULL>",
9687 TALLOC_FREE(stream);
9691 static bool run_local_stream_name(int dummy)
9695 ret &= test_stream_name(
9696 "bla", "bla", NULL, NT_STATUS_OK);
9697 ret &= test_stream_name(
9698 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
9699 ret &= test_stream_name(
9700 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
9701 ret &= test_stream_name(
9702 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
9703 ret &= test_stream_name(
9704 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
9705 ret &= test_stream_name(
9706 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
9707 ret &= test_stream_name(
9708 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
9709 ret &= test_stream_name(
9710 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
9715 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
9717 if (a.length != b.length) {
9718 printf("a.length=%d != b.length=%d\n",
9719 (int)a.length, (int)b.length);
9722 if (memcmp(a.data, b.data, a.length) != 0) {
9723 printf("a.data and b.data differ\n");
9729 static bool run_local_memcache(int dummy)
9731 struct memcache *cache;
9733 DATA_BLOB d1, d2, d3;
9734 DATA_BLOB v1, v2, v3;
9736 TALLOC_CTX *mem_ctx;
9738 size_t size1, size2;
9741 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
9743 if (cache == NULL) {
9744 printf("memcache_init failed\n");
9748 d1 = data_blob_const("d1", 2);
9749 d2 = data_blob_const("d2", 2);
9750 d3 = data_blob_const("d3", 2);
9752 k1 = data_blob_const("d1", 2);
9753 k2 = data_blob_const("d2", 2);
9755 memcache_add(cache, STAT_CACHE, k1, d1);
9756 memcache_add(cache, GETWD_CACHE, k2, d2);
9758 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
9759 printf("could not find k1\n");
9762 if (!data_blob_equal(d1, v1)) {
9766 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
9767 printf("could not find k2\n");
9770 if (!data_blob_equal(d2, v2)) {
9774 memcache_add(cache, STAT_CACHE, k1, d3);
9776 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
9777 printf("could not find replaced k1\n");
9780 if (!data_blob_equal(d3, v3)) {
9784 memcache_add(cache, GETWD_CACHE, k1, d1);
9786 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
9787 printf("Did find k2, should have been purged\n");
9793 cache = memcache_init(NULL, 0);
9795 mem_ctx = talloc_init("foo");
9797 str1 = talloc_strdup(mem_ctx, "string1");
9798 str2 = talloc_strdup(mem_ctx, "string2");
9800 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
9801 data_blob_string_const("torture"), &str1);
9802 size1 = talloc_total_size(cache);
9804 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
9805 data_blob_string_const("torture"), &str2);
9806 size2 = talloc_total_size(cache);
9808 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
9810 if (size2 > size1) {
9811 printf("memcache leaks memory!\n");
9821 static void wbclient_done(struct tevent_req *req)
9824 struct winbindd_response *wb_resp;
9825 int *i = (int *)tevent_req_callback_data_void(req);
9827 wbc_err = wb_trans_recv(req, req, &wb_resp);
9830 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
9833 static bool run_wbclient_multi_ping(int dummy)
9835 struct tevent_context *ev;
9836 struct wb_context **wb_ctx;
9837 struct winbindd_request wb_req;
9838 bool result = false;
9841 BlockSignals(True, SIGPIPE);
9843 ev = tevent_context_init(talloc_tos());
9848 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
9849 if (wb_ctx == NULL) {
9853 ZERO_STRUCT(wb_req);
9854 wb_req.cmd = WINBINDD_PING;
9856 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
9858 for (i=0; i<torture_nprocs; i++) {
9859 wb_ctx[i] = wb_context_init(ev, NULL);
9860 if (wb_ctx[i] == NULL) {
9863 for (j=0; j<torture_numops; j++) {
9864 struct tevent_req *req;
9865 req = wb_trans_send(ev, ev, wb_ctx[i],
9866 (j % 2) == 0, &wb_req);
9870 tevent_req_set_callback(req, wbclient_done, &i);
9876 while (i < torture_nprocs * torture_numops) {
9877 tevent_loop_once(ev);
9886 static void getaddrinfo_finished(struct tevent_req *req)
9888 char *name = (char *)tevent_req_callback_data_void(req);
9889 struct addrinfo *ainfo;
9892 res = getaddrinfo_recv(req, &ainfo);
9894 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
9897 d_printf("gai(%s) succeeded\n", name);
9898 freeaddrinfo(ainfo);
9901 static bool run_getaddrinfo_send(int dummy)
9903 TALLOC_CTX *frame = talloc_stackframe();
9904 struct fncall_context *ctx;
9905 struct tevent_context *ev;
9906 bool result = false;
9907 const char *names[4] = { "www.samba.org", "notfound.samba.org",
9908 "www.slashdot.org", "heise.de" };
9909 struct tevent_req *reqs[4];
9912 ev = samba_tevent_context_init(frame);
9917 ctx = fncall_context_init(frame, 4);
9919 for (i=0; i<ARRAY_SIZE(names); i++) {
9920 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
9922 if (reqs[i] == NULL) {
9925 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
9926 discard_const_p(void, names[i]));
9929 for (i=0; i<ARRAY_SIZE(reqs); i++) {
9930 tevent_loop_once(ev);
9939 static bool dbtrans_inc(struct db_context *db)
9941 struct db_record *rec;
9947 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
9949 printf(__location__ "fetch_lock failed\n");
9953 value = dbwrap_record_get_value(rec);
9955 if (value.dsize != sizeof(uint32_t)) {
9956 printf(__location__ "value.dsize = %d\n",
9961 memcpy(&val, value.dptr, sizeof(val));
9964 status = dbwrap_record_store(
9965 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
9966 if (!NT_STATUS_IS_OK(status)) {
9967 printf(__location__ "store failed: %s\n",
9978 static bool run_local_dbtrans(int dummy)
9980 struct db_context *db;
9981 struct db_record *rec;
9987 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
9988 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1,
9991 printf("Could not open transtest.db\n");
9995 res = dbwrap_transaction_start(db);
9997 printf(__location__ "transaction_start failed\n");
10001 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
10003 printf(__location__ "fetch_lock failed\n");
10007 value = dbwrap_record_get_value(rec);
10009 if (value.dptr == NULL) {
10011 status = dbwrap_record_store(
10012 rec, make_tdb_data((uint8_t *)&initial,
10015 if (!NT_STATUS_IS_OK(status)) {
10016 printf(__location__ "store returned %s\n",
10017 nt_errstr(status));
10024 res = dbwrap_transaction_commit(db);
10026 printf(__location__ "transaction_commit failed\n");
10031 uint32_t val, val2;
10034 res = dbwrap_transaction_start(db);
10036 printf(__location__ "transaction_start failed\n");
10040 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val);
10041 if (!NT_STATUS_IS_OK(status)) {
10042 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10043 nt_errstr(status));
10047 for (i=0; i<10; i++) {
10048 if (!dbtrans_inc(db)) {
10053 status = dbwrap_fetch_uint32_bystring(db, "transtest", &val2);
10054 if (!NT_STATUS_IS_OK(status)) {
10055 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
10056 nt_errstr(status));
10060 if (val2 != val + 10) {
10061 printf(__location__ "val=%d, val2=%d\n",
10062 (int)val, (int)val2);
10066 printf("val2=%d\r", val2);
10068 res = dbwrap_transaction_commit(db);
10070 printf(__location__ "transaction_commit failed\n");
10080 * Just a dummy test to be run under a debugger. There's no real way
10081 * to inspect the tevent_select specific function from outside of
10085 static bool run_local_tevent_select(int dummy)
10087 struct tevent_context *ev;
10088 struct tevent_fd *fd1, *fd2;
10089 bool result = false;
10091 ev = tevent_context_init_byname(NULL, "select");
10093 d_fprintf(stderr, "tevent_context_init_byname failed\n");
10097 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
10099 d_fprintf(stderr, "tevent_add_fd failed\n");
10102 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
10104 d_fprintf(stderr, "tevent_add_fd failed\n");
10109 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
10111 d_fprintf(stderr, "tevent_add_fd failed\n");
10121 static bool run_local_hex_encode_buf(int dummy)
10127 for (i=0; i<sizeof(src); i++) {
10130 hex_encode_buf(buf, src, sizeof(src));
10131 if (strcmp(buf, "0001020304050607") != 0) {
10134 hex_encode_buf(buf, NULL, 0);
10135 if (buf[0] != '\0') {
10141 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
10163 "1001:1111:1111:1000:0:1111:1111:1111",
10172 static const char *remove_duplicate_addrs2_test_strings_result[] = {
10186 "1001:1111:1111:1000:0:1111:1111:1111"
10189 static bool run_local_remove_duplicate_addrs2(int dummy)
10191 struct ip_service test_vector[28];
10194 /* Construct the sockaddr_storage test vector. */
10195 for (i = 0; i < 28; i++) {
10196 struct addrinfo hints;
10197 struct addrinfo *res = NULL;
10200 memset(&hints, '\0', sizeof(hints));
10201 hints.ai_flags = AI_NUMERICHOST;
10202 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
10207 fprintf(stderr, "getaddrinfo failed on [%s]\n",
10208 remove_duplicate_addrs2_test_strings_vector[i]);
10211 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
10212 memcpy(&test_vector[i].ss,
10218 count = remove_duplicate_addrs2(test_vector, i);
10221 fprintf(stderr, "count wrong (%d) should be 14\n",
10226 for (i = 0; i < count; i++) {
10227 char addr[INET6_ADDRSTRLEN];
10229 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
10231 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
10232 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
10235 remove_duplicate_addrs2_test_strings_result[i]);
10240 printf("run_local_remove_duplicate_addrs2: success\n");
10244 static bool run_local_tdb_opener(int dummy)
10250 t = tdb_open("test.tdb", 1000, TDB_CLEAR_IF_FIRST,
10251 O_RDWR|O_CREAT, 0755);
10253 perror("tdb_open failed");
10264 static bool run_local_tdb_writer(int dummy)
10270 t = tdb_open("test.tdb", 1000, 0, O_RDWR|O_CREAT, 0755);
10272 perror("tdb_open failed");
10276 val.dptr = (uint8_t *)&v;
10277 val.dsize = sizeof(v);
10283 ret = tdb_store(t, val, val, 0);
10285 printf("%s\n", tdb_errorstr(t));
10290 data = tdb_fetch(t, val);
10291 if (data.dptr != NULL) {
10292 SAFE_FREE(data.dptr);
10298 static double create_procs(bool (*fn)(int), bool *result)
10301 volatile pid_t *child_status;
10302 volatile bool *child_status_out;
10305 struct timeval start;
10309 child_status = (volatile pid_t *)anonymous_shared_allocate(sizeof(pid_t)*torture_nprocs);
10310 if (!child_status) {
10311 printf("Failed to setup shared memory\n");
10315 child_status_out = (volatile bool *)anonymous_shared_allocate(sizeof(bool)*torture_nprocs);
10316 if (!child_status_out) {
10317 printf("Failed to setup result status shared memory\n");
10321 for (i = 0; i < torture_nprocs; i++) {
10322 child_status[i] = 0;
10323 child_status_out[i] = True;
10326 start = timeval_current();
10328 for (i=0;i<torture_nprocs;i++) {
10331 pid_t mypid = getpid();
10332 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
10334 slprintf(myname,sizeof(myname),"CLIENT%d", i);
10337 if (torture_open_connection(¤t_cli, i)) break;
10338 if (tries-- == 0) {
10339 printf("pid %d failed to start\n", (int)getpid());
10345 child_status[i] = getpid();
10347 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
10349 child_status_out[i] = fn(i);
10356 for (i=0;i<torture_nprocs;i++) {
10357 if (child_status[i]) synccount++;
10359 if (synccount == torture_nprocs) break;
10361 } while (timeval_elapsed(&start) < 30);
10363 if (synccount != torture_nprocs) {
10364 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
10366 return timeval_elapsed(&start);
10369 /* start the client load */
10370 start = timeval_current();
10372 for (i=0;i<torture_nprocs;i++) {
10373 child_status[i] = 0;
10376 printf("%d clients started\n", torture_nprocs);
10378 for (i=0;i<torture_nprocs;i++) {
10379 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
10384 for (i=0;i<torture_nprocs;i++) {
10385 if (!child_status_out[i]) {
10389 return timeval_elapsed(&start);
10392 #define FLAG_MULTIPROC 1
10398 } torture_ops[] = {
10399 {"FDPASS", run_fdpasstest, 0},
10400 {"LOCK1", run_locktest1, 0},
10401 {"LOCK2", run_locktest2, 0},
10402 {"LOCK3", run_locktest3, 0},
10403 {"LOCK4", run_locktest4, 0},
10404 {"LOCK5", run_locktest5, 0},
10405 {"LOCK6", run_locktest6, 0},
10406 {"LOCK7", run_locktest7, 0},
10407 {"LOCK8", run_locktest8, 0},
10408 {"LOCK9", run_locktest9, 0},
10409 {"UNLINK", run_unlinktest, 0},
10410 {"BROWSE", run_browsetest, 0},
10411 {"ATTR", run_attrtest, 0},
10412 {"TRANS2", run_trans2test, 0},
10413 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
10414 {"TORTURE",run_torture, FLAG_MULTIPROC},
10415 {"RANDOMIPC", run_randomipc, 0},
10416 {"NEGNOWAIT", run_negprot_nowait, 0},
10417 {"NBENCH", run_nbench, 0},
10418 {"NBENCH2", run_nbench2, 0},
10419 {"OPLOCK1", run_oplock1, 0},
10420 {"OPLOCK2", run_oplock2, 0},
10421 {"OPLOCK4", run_oplock4, 0},
10422 {"DIR", run_dirtest, 0},
10423 {"DIR1", run_dirtest1, 0},
10424 {"DIR-CREATETIME", run_dir_createtime, 0},
10425 {"DENY1", torture_denytest1, 0},
10426 {"DENY2", torture_denytest2, 0},
10427 {"TCON", run_tcon_test, 0},
10428 {"TCONDEV", run_tcon_devtype_test, 0},
10429 {"RW1", run_readwritetest, 0},
10430 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
10431 {"RW3", run_readwritelarge, 0},
10432 {"RW-SIGNING", run_readwritelarge_signtest, 0},
10433 {"OPEN", run_opentest, 0},
10434 {"POSIX", run_simple_posix_open_test, 0},
10435 {"POSIX-APPEND", run_posix_append, 0},
10436 {"POSIX-SYMLINK-ACL", run_acl_symlink_test, 0},
10437 {"POSIX-SYMLINK-EA", run_ea_symlink_test, 0},
10438 {"POSIX-STREAM-DELETE", run_posix_stream_delete, 0},
10439 {"POSIX-OFD-LOCK", run_posix_ofd_lock_test, 0},
10440 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
10441 {"ASYNC-ECHO", run_async_echo, 0},
10442 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
10443 { "SHORTNAME-TEST", run_shortname_test, 0},
10444 { "ADDRCHANGE", run_addrchange, 0},
10446 {"OPENATTR", run_openattrtest, 0},
10448 {"XCOPY", run_xcopy, 0},
10449 {"RENAME", run_rename, 0},
10450 {"DELETE", run_deletetest, 0},
10451 {"WILDDELETE", run_wild_deletetest, 0},
10452 {"DELETE-LN", run_deletetest_ln, 0},
10453 {"PROPERTIES", run_properties, 0},
10454 {"MANGLE", torture_mangle, 0},
10455 {"MANGLE1", run_mangle1, 0},
10456 {"W2K", run_w2ktest, 0},
10457 {"TRANS2SCAN", torture_trans2_scan, 0},
10458 {"NTTRANSSCAN", torture_nttrans_scan, 0},
10459 {"UTABLE", torture_utable, 0},
10460 {"CASETABLE", torture_casetable, 0},
10461 {"ERRMAPEXTRACT", run_error_map_extract, 0},
10462 {"PIPE_NUMBER", run_pipe_number, 0},
10463 {"TCON2", run_tcon2_test, 0},
10464 {"IOCTL", torture_ioctl_test, 0},
10465 {"CHKPATH", torture_chkpath_test, 0},
10466 {"FDSESS", run_fdsesstest, 0},
10467 { "EATEST", run_eatest, 0},
10468 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
10469 { "CHAIN1", run_chain1, 0},
10470 { "CHAIN2", run_chain2, 0},
10471 { "CHAIN3", run_chain3, 0},
10472 { "WINDOWS-WRITE", run_windows_write, 0},
10473 { "LARGE_READX", run_large_readx, 0},
10474 { "NTTRANS-CREATE", run_nttrans_create, 0},
10475 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
10476 { "CLI_ECHO", run_cli_echo, 0},
10477 { "GETADDRINFO", run_getaddrinfo_send, 0},
10478 { "TLDAP", run_tldap },
10479 { "STREAMERROR", run_streamerror },
10480 { "NOTIFY-BENCH", run_notify_bench },
10481 { "NOTIFY-BENCH2", run_notify_bench2 },
10482 { "NOTIFY-BENCH3", run_notify_bench3 },
10483 { "BAD-NBT-SESSION", run_bad_nbt_session },
10484 { "SMB-ANY-CONNECT", run_smb_any_connect },
10485 { "NOTIFY-ONLINE", run_notify_online },
10486 { "SMB2-BASIC", run_smb2_basic },
10487 { "SMB2-NEGPROT", run_smb2_negprot },
10488 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
10489 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
10490 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
10491 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
10492 { "CLEANUP1", run_cleanup1 },
10493 { "CLEANUP2", run_cleanup2 },
10494 { "CLEANUP3", run_cleanup3 },
10495 { "CLEANUP4", run_cleanup4 },
10496 { "OPLOCK-CANCEL", run_oplock_cancel },
10497 { "PIDHIGH", run_pidhigh },
10498 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
10499 { "LOCAL-GENCACHE", run_local_gencache, 0},
10500 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
10501 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
10502 { "LOCAL-MESSAGING-READ1", run_messaging_read1, 0 },
10503 { "LOCAL-MESSAGING-READ2", run_messaging_read2, 0 },
10504 { "LOCAL-MESSAGING-READ3", run_messaging_read3, 0 },
10505 { "LOCAL-MESSAGING-READ4", run_messaging_read4, 0 },
10506 { "LOCAL-MESSAGING-FDPASS1", run_messaging_fdpass1, 0 },
10507 { "LOCAL-MESSAGING-FDPASS2", run_messaging_fdpass2, 0 },
10508 { "LOCAL-MESSAGING-FDPASS2a", run_messaging_fdpass2a, 0 },
10509 { "LOCAL-MESSAGING-FDPASS2b", run_messaging_fdpass2b, 0 },
10510 { "LOCAL-BASE64", run_local_base64, 0},
10511 { "LOCAL-RBTREE", run_local_rbtree, 0},
10512 { "LOCAL-MEMCACHE", run_local_memcache, 0},
10513 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
10514 { "WBCLIENT-MULTI-PING", run_wbclient_multi_ping, 0},
10515 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
10516 { "LOCAL-sid_to_string", run_local_sid_to_string, 0},
10517 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
10518 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
10519 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
10520 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
10521 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
10522 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
10523 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
10524 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
10525 { "local-tdb-opener", run_local_tdb_opener, 0 },
10526 { "local-tdb-writer", run_local_tdb_writer, 0 },
10527 { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 },
10528 { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 },
10529 { "LOCAL-PTHREADPOOL-TEVENT", run_pthreadpool_tevent, 0 },
10530 { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 },
10534 * dummy function to satisfy linker dependency
10536 struct tevent_context *winbind_event_context(void);
10537 struct tevent_context *winbind_event_context(void)
10542 /****************************************************************************
10543 run a specified test or "ALL"
10544 ****************************************************************************/
10545 static bool run_test(const char *name)
10548 bool result = True;
10549 bool found = False;
10552 if (strequal(name,"ALL")) {
10553 for (i=0;torture_ops[i].name;i++) {
10554 run_test(torture_ops[i].name);
10559 for (i=0;torture_ops[i].name;i++) {
10560 fstr_sprintf(randomfname, "\\XX%x",
10561 (unsigned)random());
10563 if (strequal(name, torture_ops[i].name)) {
10565 printf("Running %s\n", name);
10566 if (torture_ops[i].flags & FLAG_MULTIPROC) {
10567 t = create_procs(torture_ops[i].fn, &result);
10570 printf("TEST %s FAILED!\n", name);
10573 struct timeval start;
10574 start = timeval_current();
10575 if (!torture_ops[i].fn(0)) {
10577 printf("TEST %s FAILED!\n", name);
10579 t = timeval_elapsed(&start);
10581 printf("%s took %g secs\n\n", name, t);
10586 printf("Did not find a test named %s\n", name);
10594 static void usage(void)
10598 printf("WARNING samba4 test suite is much more complete nowadays.\n");
10599 printf("Please use samba4 torture.\n\n");
10601 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
10603 printf("\t-d debuglevel\n");
10604 printf("\t-U user%%pass\n");
10605 printf("\t-k use kerberos\n");
10606 printf("\t-N numprocs\n");
10607 printf("\t-n my_netbios_name\n");
10608 printf("\t-W workgroup\n");
10609 printf("\t-o num_operations\n");
10610 printf("\t-O socket_options\n");
10611 printf("\t-m maximum protocol\n");
10612 printf("\t-L use oplocks\n");
10613 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
10614 printf("\t-A showall\n");
10615 printf("\t-p port\n");
10616 printf("\t-s seed\n");
10617 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
10618 printf("\t-f filename filename to test\n");
10619 printf("\t-e encrypt\n");
10622 printf("tests are:");
10623 for (i=0;torture_ops[i].name;i++) {
10624 printf(" %s", torture_ops[i].name);
10628 printf("default test is ALL\n");
10633 /****************************************************************************
10635 ****************************************************************************/
10636 int main(int argc,char *argv[])
10642 bool correct = True;
10643 TALLOC_CTX *frame = talloc_stackframe();
10644 int seed = time(NULL);
10646 #ifdef HAVE_SETBUFFER
10647 setbuffer(stdout, NULL, 0);
10650 setup_logging("smbtorture", DEBUG_STDOUT);
10655 if (is_default_dyn_CONFIGFILE()) {
10656 if(getenv("SMB_CONF_PATH")) {
10657 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
10660 lp_load_global(get_dyn_CONFIGFILE());
10667 for(p = argv[1]; *p; p++)
10671 if (strncmp(argv[1], "//", 2)) {
10675 fstrcpy(host, &argv[1][2]);
10676 p = strchr_m(&host[2],'/');
10681 fstrcpy(share, p+1);
10683 fstrcpy(myname, get_myname(talloc_tos()));
10685 fprintf(stderr, "Failed to get my hostname.\n");
10689 if (*username == 0 && getenv("LOGNAME")) {
10690 fstrcpy(username,getenv("LOGNAME"));
10696 fstrcpy(workgroup, lp_workgroup());
10698 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
10702 port_to_use = atoi(optarg);
10705 seed = atoi(optarg);
10708 fstrcpy(workgroup,optarg);
10711 lp_set_cmdline("client max protocol", optarg);
10714 torture_nprocs = atoi(optarg);
10717 torture_numops = atoi(optarg);
10720 lp_set_cmdline("log level", optarg);
10726 use_oplocks = True;
10729 local_path = optarg;
10732 torture_showall = True;
10735 fstrcpy(myname, optarg);
10738 client_txt = optarg;
10745 use_kerberos = True;
10747 d_printf("No kerberos support compiled in\n");
10753 fstrcpy(username,optarg);
10754 p = strchr_m(username,'%');
10757 fstrcpy(password, p+1);
10762 fstrcpy(multishare_conn_fname, optarg);
10763 use_multishare_conn = True;
10766 torture_blocksize = atoi(optarg);
10769 test_filename = SMB_STRDUP(optarg);
10772 printf("Unknown option %c (%d)\n", (char)opt, opt);
10777 d_printf("using seed %d\n", seed);
10781 if(use_kerberos && !gotuser) gotpass = True;
10784 char pwd[256] = {0};
10787 rc = samba_getpass("Password:", pwd, sizeof(pwd), false, false);
10789 fstrcpy(password, pwd);
10794 printf("host=%s share=%s user=%s myname=%s\n",
10795 host, share, username, myname);
10797 torture_creds = cli_session_creds_init(frame,
10803 false, /* fallback_after_kerberos */
10804 false, /* use_ccache */
10805 false); /* password_is_nt_hash */
10806 if (torture_creds == NULL) {
10807 d_printf("cli_session_creds_init() failed.\n");
10811 if (argc == optind) {
10812 correct = run_test("ALL");
10814 for (i=optind;i<argc;i++) {
10815 if (!run_test(argv[i])) {
10821 TALLOC_FREE(frame);