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"
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"
48 fstring host, workgroup, share, password, username, myname;
49 static int max_protocol = PROTOCOL_NT1;
50 static const char *sockops="TCP_NODELAY";
52 static int port_to_use=0;
53 int torture_numops=100;
54 int torture_blocksize=1024*1024;
55 static int procnum; /* records process count number when forking */
56 static struct cli_state *current_cli;
57 static fstring randomfname;
58 static bool use_oplocks;
59 static bool use_level_II_oplocks;
60 static const char *client_txt = "client_oplocks.txt";
61 static bool disable_spnego;
62 static bool use_kerberos;
63 static bool force_dos_errors;
64 static fstring multishare_conn_fname;
65 static bool use_multishare_conn = False;
66 static bool do_encrypt;
67 static const char *local_path = NULL;
68 static int signing_state = SMB_SIGNING_DEFAULT;
71 bool torture_showall = False;
73 static double create_procs(bool (*fn)(int), bool *result);
76 /* return a pointer to a anonymous shared memory segment of size "size"
77 which will persist across fork() but will disappear when all processes
80 The memory is not zeroed
82 This function uses system5 shared memory. It takes advantage of a property
83 that the memory is not destroyed if it is attached when the id is removed
85 void *shm_setup(int size)
91 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
93 printf("can't get shared memory\n");
96 shm_unlink("private");
97 if (ftruncate(shmid, size) == -1) {
98 printf("can't set shared memory size\n");
101 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
102 if (ret == MAP_FAILED) {
103 printf("can't map shared memory\n");
107 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
109 printf("can't get shared memory\n");
112 ret = (void *)shmat(shmid, 0, 0);
113 if (!ret || ret == (void *)-1) {
114 printf("can't attach to shared memory\n");
117 /* the following releases the ipc, but note that this process
118 and all its children will still have access to the memory, its
119 just that the shmid is no longer valid for other shm calls. This
120 means we don't leave behind lots of shm segments after we exit
122 See Stevens "advanced programming in unix env" for details
124 shmctl(shmid, IPC_RMID, 0);
130 /********************************************************************
131 Ensure a connection is encrypted.
132 ********************************************************************/
134 static bool force_cli_encryption(struct cli_state *c,
135 const char *sharename)
138 uint32 caplow, caphigh;
141 if (!SERVER_HAS_UNIX_CIFS(c)) {
142 d_printf("Encryption required and "
143 "server that doesn't support "
144 "UNIX extensions - failing connect\n");
148 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
150 if (!NT_STATUS_IS_OK(status)) {
151 d_printf("Encryption required and "
152 "can't get UNIX CIFS extensions "
153 "version from server: %s\n", nt_errstr(status));
157 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
158 d_printf("Encryption required and "
159 "share %s doesn't support "
160 "encryption.\n", sharename);
164 if (c->use_kerberos) {
165 status = cli_gss_smb_encryption_start(c);
167 status = cli_raw_ntlm_smb_encryption_start(c,
173 if (!NT_STATUS_IS_OK(status)) {
174 d_printf("Encryption required and "
175 "setup failed with error %s.\n",
184 static struct cli_state *open_nbt_connection(void)
190 if (disable_spnego) {
191 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
195 flags |= CLI_FULL_CONNECTION_OPLOCKS;
198 if (use_level_II_oplocks) {
199 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
203 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
206 if (force_dos_errors) {
207 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
210 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
211 signing_state, flags, &c);
212 if (!NT_STATUS_IS_OK(status)) {
213 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
217 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
222 /****************************************************************************
223 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
224 ****************************************************************************/
226 static bool cli_bad_session_request(int fd,
227 struct nmb_name *calling, struct nmb_name *called)
236 uint8_t message_type;
238 struct event_context *ev;
239 struct tevent_req *req;
241 frame = talloc_stackframe();
243 iov[0].iov_base = len_buf;
244 iov[0].iov_len = sizeof(len_buf);
246 /* put in the destination name */
248 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
250 if (iov[1].iov_base == NULL) {
253 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
254 talloc_get_size(iov[1].iov_base));
258 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
260 if (iov[2].iov_base == NULL) {
263 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
264 talloc_get_size(iov[2].iov_base));
266 /* Deliberately corrupt the name len (first byte) */
267 *((uint8_t *)iov[2].iov_base) = 100;
269 /* send a session request (RFC 1002) */
270 /* setup the packet length
271 * Remove four bytes from the length count, since the length
272 * field in the NBT Session Service header counts the number
273 * of bytes which follow. The cli_send_smb() function knows
274 * about this and accounts for those four bytes.
278 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
279 SCVAL(len_buf,0,0x81);
281 len = write_data_iov(fd, iov, 3);
286 ev = event_context_init(frame);
290 req = read_smb_send(frame, ev, fd);
294 if (!tevent_req_poll(req, ev)) {
297 len = read_smb_recv(req, talloc_tos(), &inbuf, &err);
304 message_type = CVAL(inbuf, 0);
305 if (message_type != 0x83) {
306 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
311 if (smb_len(inbuf) != 1) {
312 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
313 (int)smb_len(inbuf));
317 error = CVAL(inbuf, 4);
319 d_fprintf(stderr, "Expected error 0x82, got %d\n",
330 /* Insert a NULL at the first separator of the given path and return a pointer
331 * to the remainder of the string.
334 terminate_path_at_separator(char * path)
342 if ((p = strchr_m(path, '/'))) {
347 if ((p = strchr_m(path, '\\'))) {
357 parse a //server/share type UNC name
359 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
360 char **hostname, char **sharename)
364 *hostname = *sharename = NULL;
366 if (strncmp(unc_name, "\\\\", 2) &&
367 strncmp(unc_name, "//", 2)) {
371 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
372 p = terminate_path_at_separator(*hostname);
375 *sharename = talloc_strdup(mem_ctx, p);
376 terminate_path_at_separator(*sharename);
379 if (*hostname && *sharename) {
383 TALLOC_FREE(*hostname);
384 TALLOC_FREE(*sharename);
388 static bool torture_open_connection_share(struct cli_state **c,
389 const char *hostname,
390 const char *sharename)
396 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
398 flags |= CLI_FULL_CONNECTION_OPLOCKS;
399 if (use_level_II_oplocks)
400 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
402 status = cli_full_connection(c, myname,
403 hostname, NULL, port_to_use,
406 password, flags, signing_state);
407 if (!NT_STATUS_IS_OK(status)) {
408 printf("failed to open share connection: //%s/%s port:%d - %s\n",
409 hostname, sharename, port_to_use, nt_errstr(status));
413 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
416 return force_cli_encryption(*c,
422 bool torture_open_connection(struct cli_state **c, int conn_index)
424 char **unc_list = NULL;
425 int num_unc_names = 0;
428 if (use_multishare_conn==True) {
430 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
431 if (!unc_list || num_unc_names <= 0) {
432 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
436 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
438 printf("Failed to parse UNC name %s\n",
439 unc_list[conn_index % num_unc_names]);
440 TALLOC_FREE(unc_list);
444 result = torture_open_connection_share(c, h, s);
446 /* h, s were copied earlier */
447 TALLOC_FREE(unc_list);
451 return torture_open_connection_share(c, host, share);
454 bool torture_init_connection(struct cli_state **pcli)
456 struct cli_state *cli;
458 cli = open_nbt_connection();
467 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
469 uint16_t old_vuid = cli_state_get_uid(cli);
470 fstring old_user_name;
471 size_t passlen = strlen(password);
475 fstrcpy(old_user_name, cli->user_name);
476 cli_state_set_uid(cli, 0);
477 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
481 *new_vuid = cli_state_get_uid(cli);
482 cli_state_set_uid(cli, old_vuid);
483 status = cli_set_username(cli, old_user_name);
484 if (!NT_STATUS_IS_OK(status)) {
491 bool torture_close_connection(struct cli_state *c)
496 status = cli_tdis(c);
497 if (!NT_STATUS_IS_OK(status)) {
498 printf("tdis failed (%s)\n", nt_errstr(status));
508 /* check if the server produced the expected dos or nt error code */
509 static bool check_both_error(int line, NTSTATUS status,
510 uint8 eclass, uint32 ecode, NTSTATUS nterr)
512 if (NT_STATUS_IS_DOS(status)) {
516 /* Check DOS error */
517 cclass = NT_STATUS_DOS_CLASS(status);
518 num = NT_STATUS_DOS_CODE(status);
520 if (eclass != cclass || ecode != num) {
521 printf("unexpected error code class=%d code=%d\n",
522 (int)cclass, (int)num);
523 printf(" expected %d/%d %s (line=%d)\n",
524 (int)eclass, (int)ecode, nt_errstr(nterr), line);
529 if (!NT_STATUS_EQUAL(nterr, status)) {
530 printf("unexpected error code %s\n",
532 printf(" expected %s (line=%d)\n",
533 nt_errstr(nterr), line);
542 /* check if the server produced the expected error code */
543 static bool check_error(int line, NTSTATUS status,
544 uint8 eclass, uint32 ecode, NTSTATUS nterr)
546 if (NT_STATUS_IS_DOS(status)) {
550 /* Check DOS error */
552 cclass = NT_STATUS_DOS_CLASS(status);
553 num = NT_STATUS_DOS_CODE(status);
555 if (eclass != cclass || ecode != num) {
556 printf("unexpected error code class=%d code=%d\n",
557 (int)cclass, (int)num);
558 printf(" expected %d/%d %s (line=%d)\n",
559 (int)eclass, (int)ecode, nt_errstr(nterr),
567 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
568 printf("unexpected error code %s\n",
570 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
580 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
584 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
586 while (!NT_STATUS_IS_OK(status)) {
587 if (!check_both_error(__LINE__, status, ERRDOS,
588 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
592 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
599 static bool rw_torture(struct cli_state *c)
601 const char *lockfname = "\\torture.lck";
605 pid_t pid2, pid = getpid();
612 memset(buf, '\0', sizeof(buf));
614 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
616 if (!NT_STATUS_IS_OK(status)) {
617 status = cli_openx(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
619 if (!NT_STATUS_IS_OK(status)) {
620 printf("open of %s failed (%s)\n",
621 lockfname, nt_errstr(status));
625 for (i=0;i<torture_numops;i++) {
626 unsigned n = (unsigned)sys_random()%10;
629 printf("%d\r", i); fflush(stdout);
631 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
633 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
637 status = cli_openx(c, fname, O_RDWR | O_CREAT | O_TRUNC,
639 if (!NT_STATUS_IS_OK(status)) {
640 printf("open failed (%s)\n", nt_errstr(status));
645 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
647 if (!NT_STATUS_IS_OK(status)) {
648 printf("write failed (%s)\n", nt_errstr(status));
653 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
654 sizeof(pid)+(j*sizeof(buf)),
656 if (!NT_STATUS_IS_OK(status)) {
657 printf("write failed (%s)\n",
665 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
667 if (!NT_STATUS_IS_OK(status)) {
668 printf("read failed (%s)\n", nt_errstr(status));
670 } else if (nread != sizeof(pid)) {
671 printf("read/write compare failed: "
672 "recv %ld req %ld\n", (unsigned long)nread,
673 (unsigned long)sizeof(pid));
678 printf("data corruption!\n");
682 status = cli_close(c, fnum);
683 if (!NT_STATUS_IS_OK(status)) {
684 printf("close failed (%s)\n", nt_errstr(status));
688 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
689 if (!NT_STATUS_IS_OK(status)) {
690 printf("unlink failed (%s)\n", nt_errstr(status));
694 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
695 if (!NT_STATUS_IS_OK(status)) {
696 printf("unlock failed (%s)\n", nt_errstr(status));
702 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
709 static bool run_torture(int dummy)
711 struct cli_state *cli;
716 smbXcli_conn_set_sockopt(cli->conn, sockops);
718 ret = rw_torture(cli);
720 if (!torture_close_connection(cli)) {
727 static bool rw_torture3(struct cli_state *c, char *lockfname)
729 uint16_t fnum = (uint16_t)-1;
734 unsigned countprev = 0;
737 NTSTATUS status = NT_STATUS_OK;
740 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
742 SIVAL(buf, i, sys_random());
749 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
750 if (!NT_STATUS_IS_OK(status)) {
751 printf("unlink failed (%s) (normal, this file should "
752 "not exist)\n", nt_errstr(status));
755 status = cli_openx(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
757 if (!NT_STATUS_IS_OK(status)) {
758 printf("first open read/write of %s failed (%s)\n",
759 lockfname, nt_errstr(status));
765 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
767 status = cli_openx(c, lockfname, O_RDONLY,
769 if (!NT_STATUS_IS_OK(status)) {
774 if (!NT_STATUS_IS_OK(status)) {
775 printf("second open read-only of %s failed (%s)\n",
776 lockfname, nt_errstr(status));
782 for (count = 0; count < sizeof(buf); count += sent)
784 if (count >= countprev) {
785 printf("%d %8d\r", i, count);
788 countprev += (sizeof(buf) / 20);
793 sent = ((unsigned)sys_random()%(20))+ 1;
794 if (sent > sizeof(buf) - count)
796 sent = sizeof(buf) - count;
799 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
801 if (!NT_STATUS_IS_OK(status)) {
802 printf("write failed (%s)\n",
809 status = cli_read(c, fnum, buf_rd+count, count,
810 sizeof(buf)-count, &sent);
811 if(!NT_STATUS_IS_OK(status)) {
812 printf("read failed offset:%d size:%ld (%s)\n",
813 count, (unsigned long)sizeof(buf)-count,
817 } else if (sent > 0) {
818 if (memcmp(buf_rd+count, buf+count, sent) != 0)
820 printf("read/write compare failed\n");
821 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
830 status = cli_close(c, fnum);
831 if (!NT_STATUS_IS_OK(status)) {
832 printf("close failed (%s)\n", nt_errstr(status));
839 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
841 const char *lockfname = "\\torture2.lck";
851 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
852 if (!NT_STATUS_IS_OK(status)) {
853 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
856 status = cli_openx(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
858 if (!NT_STATUS_IS_OK(status)) {
859 printf("first open read/write of %s failed (%s)\n",
860 lockfname, nt_errstr(status));
864 status = cli_openx(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
865 if (!NT_STATUS_IS_OK(status)) {
866 printf("second open read-only of %s failed (%s)\n",
867 lockfname, nt_errstr(status));
868 cli_close(c1, fnum1);
872 for (i = 0; i < torture_numops; i++)
874 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
876 printf("%d\r", i); fflush(stdout);
879 generate_random_buffer((unsigned char *)buf, buf_size);
881 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
883 if (!NT_STATUS_IS_OK(status)) {
884 printf("write failed (%s)\n", nt_errstr(status));
889 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
890 if(!NT_STATUS_IS_OK(status)) {
891 printf("read failed (%s)\n", nt_errstr(status));
894 } else if (bytes_read != buf_size) {
895 printf("read failed\n");
896 printf("read %ld, expected %ld\n",
897 (unsigned long)bytes_read,
898 (unsigned long)buf_size);
903 if (memcmp(buf_rd, buf, buf_size) != 0)
905 printf("read/write compare failed\n");
911 status = cli_close(c2, fnum2);
912 if (!NT_STATUS_IS_OK(status)) {
913 printf("close failed (%s)\n", nt_errstr(status));
917 status = cli_close(c1, fnum1);
918 if (!NT_STATUS_IS_OK(status)) {
919 printf("close failed (%s)\n", nt_errstr(status));
923 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
924 if (!NT_STATUS_IS_OK(status)) {
925 printf("unlink failed (%s)\n", nt_errstr(status));
932 static bool run_readwritetest(int dummy)
934 struct cli_state *cli1, *cli2;
935 bool test1, test2 = False;
937 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
940 smbXcli_conn_set_sockopt(cli1->conn, sockops);
941 smbXcli_conn_set_sockopt(cli2->conn, sockops);
943 printf("starting readwritetest\n");
945 test1 = rw_torture2(cli1, cli2);
946 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
949 test2 = rw_torture2(cli1, cli1);
950 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
953 if (!torture_close_connection(cli1)) {
957 if (!torture_close_connection(cli2)) {
961 return (test1 && test2);
964 static bool run_readwritemulti(int dummy)
966 struct cli_state *cli;
971 smbXcli_conn_set_sockopt(cli->conn, sockops);
973 printf("run_readwritemulti: fname %s\n", randomfname);
974 test = rw_torture3(cli, randomfname);
976 if (!torture_close_connection(cli)) {
983 static bool run_readwritelarge_internal(void)
985 static struct cli_state *cli1;
987 const char *lockfname = "\\large.dat";
993 if (!torture_open_connection(&cli1, 0)) {
996 smbXcli_conn_set_sockopt(cli1->conn, sockops);
997 memset(buf,'\0',sizeof(buf));
999 printf("starting readwritelarge_internal\n");
1001 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1003 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
1005 if (!NT_STATUS_IS_OK(status)) {
1006 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1010 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
1012 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1014 if (!NT_STATUS_IS_OK(status)) {
1015 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1019 if (fsize == sizeof(buf))
1020 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
1021 (unsigned long)fsize);
1023 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
1024 (unsigned long)fsize);
1028 status = cli_close(cli1, fnum1);
1029 if (!NT_STATUS_IS_OK(status)) {
1030 printf("close failed (%s)\n", nt_errstr(status));
1034 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1035 if (!NT_STATUS_IS_OK(status)) {
1036 printf("unlink failed (%s)\n", nt_errstr(status));
1040 status = cli_openx(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
1042 if (!NT_STATUS_IS_OK(status)) {
1043 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1047 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
1049 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1051 if (!NT_STATUS_IS_OK(status)) {
1052 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1056 if (fsize == sizeof(buf))
1057 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1058 (unsigned long)fsize);
1060 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1061 (unsigned long)fsize);
1066 /* ToDo - set allocation. JRA */
1067 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1068 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1071 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1073 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1077 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1080 status = cli_close(cli1, fnum1);
1081 if (!NT_STATUS_IS_OK(status)) {
1082 printf("close failed (%s)\n", nt_errstr(status));
1086 if (!torture_close_connection(cli1)) {
1092 static bool run_readwritelarge(int dummy)
1094 return run_readwritelarge_internal();
1097 static bool run_readwritelarge_signtest(int dummy)
1100 signing_state = SMB_SIGNING_REQUIRED;
1101 ret = run_readwritelarge_internal();
1102 signing_state = SMB_SIGNING_DEFAULT;
1109 #define ival(s) strtol(s, NULL, 0)
1111 /* run a test that simulates an approximate netbench client load */
1112 static bool run_netbench(int client)
1114 struct cli_state *cli;
1119 const char *params[20];
1120 bool correct = True;
1126 smbXcli_conn_set_sockopt(cli->conn, sockops);
1130 slprintf(cname,sizeof(cname)-1, "client%d", client);
1132 f = fopen(client_txt, "r");
1139 while (fgets(line, sizeof(line)-1, f)) {
1143 line[strlen(line)-1] = 0;
1145 /* printf("[%d] %s\n", line_count, line); */
1147 all_string_sub(line,"client1", cname, sizeof(line));
1149 /* parse the command parameters */
1150 params[0] = strtok_r(line, " ", &saveptr);
1152 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1156 if (i < 2) continue;
1158 if (!strncmp(params[0],"SMB", 3)) {
1159 printf("ERROR: You are using a dbench 1 load file\n");
1163 if (!strcmp(params[0],"NTCreateX")) {
1164 nb_createx(params[1], ival(params[2]), ival(params[3]),
1166 } else if (!strcmp(params[0],"Close")) {
1167 nb_close(ival(params[1]));
1168 } else if (!strcmp(params[0],"Rename")) {
1169 nb_rename(params[1], params[2]);
1170 } else if (!strcmp(params[0],"Unlink")) {
1171 nb_unlink(params[1]);
1172 } else if (!strcmp(params[0],"Deltree")) {
1173 nb_deltree(params[1]);
1174 } else if (!strcmp(params[0],"Rmdir")) {
1175 nb_rmdir(params[1]);
1176 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1177 nb_qpathinfo(params[1]);
1178 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1179 nb_qfileinfo(ival(params[1]));
1180 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1181 nb_qfsinfo(ival(params[1]));
1182 } else if (!strcmp(params[0],"FIND_FIRST")) {
1183 nb_findfirst(params[1]);
1184 } else if (!strcmp(params[0],"WriteX")) {
1185 nb_writex(ival(params[1]),
1186 ival(params[2]), ival(params[3]), ival(params[4]));
1187 } else if (!strcmp(params[0],"ReadX")) {
1188 nb_readx(ival(params[1]),
1189 ival(params[2]), ival(params[3]), ival(params[4]));
1190 } else if (!strcmp(params[0],"Flush")) {
1191 nb_flush(ival(params[1]));
1193 printf("Unknown operation %s\n", params[0]);
1201 if (!torture_close_connection(cli)) {
1209 /* run a test that simulates an approximate netbench client load */
1210 static bool run_nbench(int dummy)
1213 bool correct = True;
1215 nbio_shmem(torture_nprocs);
1219 signal(SIGALRM, nb_alarm);
1221 t = create_procs(run_netbench, &correct);
1224 printf("\nThroughput %g MB/sec\n",
1225 1.0e-6 * nbio_total() / t);
1231 This test checks for two things:
1233 1) correct support for retaining locks over a close (ie. the server
1234 must not use posix semantics)
1235 2) support for lock timeouts
1237 static bool run_locktest1(int dummy)
1239 struct cli_state *cli1, *cli2;
1240 const char *fname = "\\lockt1.lck";
1241 uint16_t fnum1, fnum2, fnum3;
1243 unsigned lock_timeout;
1246 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1249 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1250 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1252 printf("starting locktest1\n");
1254 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1256 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1258 if (!NT_STATUS_IS_OK(status)) {
1259 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1263 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1264 if (!NT_STATUS_IS_OK(status)) {
1265 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1269 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1270 if (!NT_STATUS_IS_OK(status)) {
1271 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1275 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1276 if (!NT_STATUS_IS_OK(status)) {
1277 printf("lock1 failed (%s)\n", nt_errstr(status));
1281 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1282 if (NT_STATUS_IS_OK(status)) {
1283 printf("lock2 succeeded! This is a locking bug\n");
1286 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1287 NT_STATUS_LOCK_NOT_GRANTED)) {
1292 lock_timeout = (1 + (random() % 20));
1293 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1295 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1296 if (NT_STATUS_IS_OK(status)) {
1297 printf("lock3 succeeded! This is a locking bug\n");
1300 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1301 NT_STATUS_FILE_LOCK_CONFLICT)) {
1307 if (ABS(t2 - t1) < lock_timeout-1) {
1308 printf("error: This server appears not to support timed lock requests\n");
1311 printf("server slept for %u seconds for a %u second timeout\n",
1312 (unsigned int)(t2-t1), lock_timeout);
1314 status = cli_close(cli1, fnum2);
1315 if (!NT_STATUS_IS_OK(status)) {
1316 printf("close1 failed (%s)\n", nt_errstr(status));
1320 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1321 if (NT_STATUS_IS_OK(status)) {
1322 printf("lock4 succeeded! This is a locking bug\n");
1325 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1326 NT_STATUS_FILE_LOCK_CONFLICT)) {
1331 status = cli_close(cli1, fnum1);
1332 if (!NT_STATUS_IS_OK(status)) {
1333 printf("close2 failed (%s)\n", nt_errstr(status));
1337 status = cli_close(cli2, fnum3);
1338 if (!NT_STATUS_IS_OK(status)) {
1339 printf("close3 failed (%s)\n", nt_errstr(status));
1343 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1344 if (!NT_STATUS_IS_OK(status)) {
1345 printf("unlink failed (%s)\n", nt_errstr(status));
1350 if (!torture_close_connection(cli1)) {
1354 if (!torture_close_connection(cli2)) {
1358 printf("Passed locktest1\n");
1363 this checks to see if a secondary tconx can use open files from an
1366 static bool run_tcon_test(int dummy)
1368 static struct cli_state *cli;
1369 const char *fname = "\\tcontest.tmp";
1371 uint16 cnum1, cnum2, cnum3;
1372 uint16 vuid1, vuid2;
1377 memset(buf, '\0', sizeof(buf));
1379 if (!torture_open_connection(&cli, 0)) {
1382 smbXcli_conn_set_sockopt(cli->conn, sockops);
1384 printf("starting tcontest\n");
1386 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1388 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1389 if (!NT_STATUS_IS_OK(status)) {
1390 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1394 cnum1 = cli_state_get_tid(cli);
1395 vuid1 = cli_state_get_uid(cli);
1397 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1398 if (!NT_STATUS_IS_OK(status)) {
1399 printf("initial write failed (%s)", nt_errstr(status));
1403 status = cli_tree_connect(cli, share, "?????",
1404 password, strlen(password)+1);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 printf("%s refused 2nd tree connect (%s)\n", host,
1412 cnum2 = cli_state_get_tid(cli);
1413 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1414 vuid2 = cli_state_get_uid(cli) + 1;
1416 /* try a write with the wrong tid */
1417 cli_state_set_tid(cli, cnum2);
1419 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1420 if (NT_STATUS_IS_OK(status)) {
1421 printf("* server allows write with wrong TID\n");
1424 printf("server fails write with wrong TID : %s\n",
1429 /* try a write with an invalid tid */
1430 cli_state_set_tid(cli, cnum3);
1432 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1433 if (NT_STATUS_IS_OK(status)) {
1434 printf("* server allows write with invalid TID\n");
1437 printf("server fails write with invalid TID : %s\n",
1441 /* try a write with an invalid vuid */
1442 cli_state_set_uid(cli, vuid2);
1443 cli_state_set_tid(cli, cnum1);
1445 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1446 if (NT_STATUS_IS_OK(status)) {
1447 printf("* server allows write with invalid VUID\n");
1450 printf("server fails write with invalid VUID : %s\n",
1454 cli_state_set_tid(cli, cnum1);
1455 cli_state_set_uid(cli, vuid1);
1457 status = cli_close(cli, fnum1);
1458 if (!NT_STATUS_IS_OK(status)) {
1459 printf("close failed (%s)\n", nt_errstr(status));
1463 cli_state_set_tid(cli, cnum2);
1465 status = cli_tdis(cli);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1471 cli_state_set_tid(cli, cnum1);
1473 if (!torture_close_connection(cli)) {
1482 checks for old style tcon support
1484 static bool run_tcon2_test(int dummy)
1486 static struct cli_state *cli;
1487 uint16 cnum, max_xmit;
1491 if (!torture_open_connection(&cli, 0)) {
1494 smbXcli_conn_set_sockopt(cli->conn, sockops);
1496 printf("starting tcon2 test\n");
1498 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1502 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1506 if (!NT_STATUS_IS_OK(status)) {
1507 printf("tcon2 failed : %s\n", nt_errstr(status));
1509 printf("tcon OK : max_xmit=%d cnum=%d\n",
1510 (int)max_xmit, (int)cnum);
1513 if (!torture_close_connection(cli)) {
1517 printf("Passed tcon2 test\n");
1521 static bool tcon_devtest(struct cli_state *cli,
1522 const char *myshare, const char *devtype,
1523 const char *return_devtype,
1524 NTSTATUS expected_error)
1529 status = cli_tree_connect(cli, myshare, devtype,
1530 password, strlen(password)+1);
1532 if (NT_STATUS_IS_OK(expected_error)) {
1533 if (NT_STATUS_IS_OK(status)) {
1534 if (strcmp(cli->dev, return_devtype) == 0) {
1537 printf("tconX to share %s with type %s "
1538 "succeeded but returned the wrong "
1539 "device type (got [%s] but should have got [%s])\n",
1540 myshare, devtype, cli->dev, return_devtype);
1544 printf("tconX to share %s with type %s "
1545 "should have succeeded but failed\n",
1551 if (NT_STATUS_IS_OK(status)) {
1552 printf("tconx to share %s with type %s "
1553 "should have failed but succeeded\n",
1557 if (NT_STATUS_EQUAL(status, expected_error)) {
1560 printf("Returned unexpected error\n");
1569 checks for correct tconX support
1571 static bool run_tcon_devtype_test(int dummy)
1573 static struct cli_state *cli1 = NULL;
1578 status = cli_full_connection(&cli1, myname,
1579 host, NULL, port_to_use,
1581 username, workgroup,
1582 password, flags, signing_state);
1584 if (!NT_STATUS_IS_OK(status)) {
1585 printf("could not open connection\n");
1589 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1592 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1595 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1598 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1601 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1604 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1607 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1610 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1613 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1616 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1622 printf("Passed tcondevtest\n");
1629 This test checks that
1631 1) the server supports multiple locking contexts on the one SMB
1632 connection, distinguished by PID.
1634 2) the server correctly fails overlapping locks made by the same PID (this
1635 goes against POSIX behaviour, which is why it is tricky to implement)
1637 3) the server denies unlock requests by an incorrect client PID
1639 static bool run_locktest2(int dummy)
1641 static struct cli_state *cli;
1642 const char *fname = "\\lockt2.lck";
1643 uint16_t fnum1, fnum2, fnum3;
1644 bool correct = True;
1647 if (!torture_open_connection(&cli, 0)) {
1651 smbXcli_conn_set_sockopt(cli->conn, sockops);
1653 printf("starting locktest2\n");
1655 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1659 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1660 if (!NT_STATUS_IS_OK(status)) {
1661 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1665 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1666 if (!NT_STATUS_IS_OK(status)) {
1667 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1673 status = cli_openx(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1674 if (!NT_STATUS_IS_OK(status)) {
1675 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1681 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1682 if (!NT_STATUS_IS_OK(status)) {
1683 printf("lock1 failed (%s)\n", nt_errstr(status));
1687 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1688 if (NT_STATUS_IS_OK(status)) {
1689 printf("WRITE lock1 succeeded! This is a locking bug\n");
1692 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1693 NT_STATUS_LOCK_NOT_GRANTED)) {
1698 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1699 if (NT_STATUS_IS_OK(status)) {
1700 printf("WRITE lock2 succeeded! This is a locking bug\n");
1703 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1704 NT_STATUS_LOCK_NOT_GRANTED)) {
1709 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1710 if (NT_STATUS_IS_OK(status)) {
1711 printf("READ lock2 succeeded! This is a locking bug\n");
1714 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1715 NT_STATUS_FILE_LOCK_CONFLICT)) {
1720 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1721 if (!NT_STATUS_IS_OK(status)) {
1722 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1725 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1726 printf("unlock at 100 succeeded! This is a locking bug\n");
1730 status = cli_unlock(cli, fnum1, 0, 4);
1731 if (NT_STATUS_IS_OK(status)) {
1732 printf("unlock1 succeeded! This is a locking bug\n");
1735 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1736 NT_STATUS_RANGE_NOT_LOCKED)) {
1741 status = cli_unlock(cli, fnum1, 0, 8);
1742 if (NT_STATUS_IS_OK(status)) {
1743 printf("unlock2 succeeded! This is a locking bug\n");
1746 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1747 NT_STATUS_RANGE_NOT_LOCKED)) {
1752 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1753 if (NT_STATUS_IS_OK(status)) {
1754 printf("lock3 succeeded! This is a locking bug\n");
1757 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1758 NT_STATUS_LOCK_NOT_GRANTED)) {
1765 status = cli_close(cli, fnum1);
1766 if (!NT_STATUS_IS_OK(status)) {
1767 printf("close1 failed (%s)\n", nt_errstr(status));
1771 status = cli_close(cli, fnum2);
1772 if (!NT_STATUS_IS_OK(status)) {
1773 printf("close2 failed (%s)\n", nt_errstr(status));
1777 status = cli_close(cli, fnum3);
1778 if (!NT_STATUS_IS_OK(status)) {
1779 printf("close3 failed (%s)\n", nt_errstr(status));
1783 if (!torture_close_connection(cli)) {
1787 printf("locktest2 finished\n");
1794 This test checks that
1796 1) the server supports the full offset range in lock requests
1798 static bool run_locktest3(int dummy)
1800 static struct cli_state *cli1, *cli2;
1801 const char *fname = "\\lockt3.lck";
1802 uint16_t fnum1, fnum2;
1805 bool correct = True;
1808 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1810 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1813 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1814 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1816 printf("starting locktest3\n");
1818 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1820 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1822 if (!NT_STATUS_IS_OK(status)) {
1823 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1827 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1828 if (!NT_STATUS_IS_OK(status)) {
1829 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1833 for (offset=i=0;i<torture_numops;i++) {
1836 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1837 if (!NT_STATUS_IS_OK(status)) {
1838 printf("lock1 %d failed (%s)\n",
1844 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1845 if (!NT_STATUS_IS_OK(status)) {
1846 printf("lock2 %d failed (%s)\n",
1853 for (offset=i=0;i<torture_numops;i++) {
1856 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1857 if (NT_STATUS_IS_OK(status)) {
1858 printf("error: lock1 %d succeeded!\n", i);
1862 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1863 if (NT_STATUS_IS_OK(status)) {
1864 printf("error: lock2 %d succeeded!\n", i);
1868 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1869 if (NT_STATUS_IS_OK(status)) {
1870 printf("error: lock3 %d succeeded!\n", i);
1874 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1875 if (NT_STATUS_IS_OK(status)) {
1876 printf("error: lock4 %d succeeded!\n", i);
1881 for (offset=i=0;i<torture_numops;i++) {
1884 status = cli_unlock(cli1, fnum1, offset-1, 1);
1885 if (!NT_STATUS_IS_OK(status)) {
1886 printf("unlock1 %d failed (%s)\n",
1892 status = cli_unlock(cli2, fnum2, offset-2, 1);
1893 if (!NT_STATUS_IS_OK(status)) {
1894 printf("unlock2 %d failed (%s)\n",
1901 status = cli_close(cli1, fnum1);
1902 if (!NT_STATUS_IS_OK(status)) {
1903 printf("close1 failed (%s)\n", nt_errstr(status));
1907 status = cli_close(cli2, fnum2);
1908 if (!NT_STATUS_IS_OK(status)) {
1909 printf("close2 failed (%s)\n", nt_errstr(status));
1913 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1914 if (!NT_STATUS_IS_OK(status)) {
1915 printf("unlink failed (%s)\n", nt_errstr(status));
1919 if (!torture_close_connection(cli1)) {
1923 if (!torture_close_connection(cli2)) {
1927 printf("finished locktest3\n");
1932 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1933 char *buf, off_t offset, size_t size,
1934 size_t *nread, size_t expect)
1939 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1941 if(!NT_STATUS_IS_OK(status)) {
1943 } else if (l_nread != expect) {
1954 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1955 printf("** "); correct = False; \
1959 looks at overlapping locks
1961 static bool run_locktest4(int dummy)
1963 static struct cli_state *cli1, *cli2;
1964 const char *fname = "\\lockt4.lck";
1965 uint16_t fnum1, fnum2, f;
1968 bool correct = True;
1971 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1975 smbXcli_conn_set_sockopt(cli1->conn, sockops);
1976 smbXcli_conn_set_sockopt(cli2->conn, sockops);
1978 printf("starting locktest4\n");
1980 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1982 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1983 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1985 memset(buf, 0, sizeof(buf));
1987 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1989 if (!NT_STATUS_IS_OK(status)) {
1990 printf("Failed to create file: %s\n", nt_errstr(status));
1995 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1996 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1997 EXPECTED(ret, False);
1998 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
2000 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
2001 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
2002 EXPECTED(ret, True);
2003 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
2005 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
2006 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
2007 EXPECTED(ret, False);
2008 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
2010 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
2011 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
2012 EXPECTED(ret, True);
2013 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
2015 ret = (cli_setpid(cli1, 1),
2016 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
2017 (cli_setpid(cli1, 2),
2018 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
2019 EXPECTED(ret, False);
2020 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
2022 ret = (cli_setpid(cli1, 1),
2023 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
2024 (cli_setpid(cli1, 2),
2025 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
2026 EXPECTED(ret, True);
2027 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
2029 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
2030 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
2031 EXPECTED(ret, True);
2032 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
2034 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
2035 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
2036 EXPECTED(ret, False);
2037 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
2039 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
2040 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
2041 EXPECTED(ret, False);
2042 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
2044 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
2045 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2046 EXPECTED(ret, True);
2047 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2049 ret = (cli_setpid(cli1, 1),
2050 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2051 (cli_setpid(cli1, 2),
2052 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2053 EXPECTED(ret, False);
2054 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2056 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2057 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2058 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2059 EXPECTED(ret, False);
2060 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2063 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2064 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2065 EXPECTED(ret, False);
2066 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2068 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2069 ret = NT_STATUS_IS_OK(status);
2071 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2073 ret = NT_STATUS_IS_OK(status);
2075 EXPECTED(ret, False);
2076 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2079 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2080 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2081 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2082 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2083 EXPECTED(ret, True);
2084 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2087 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2088 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2089 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2090 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2091 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2093 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2094 EXPECTED(ret, True);
2095 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2097 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2098 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2099 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2101 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2102 EXPECTED(ret, True);
2103 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2105 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2106 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2107 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2109 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2110 EXPECTED(ret, True);
2111 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2113 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2114 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2115 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2116 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2118 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2119 EXPECTED(ret, True);
2120 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2122 cli_close(cli1, fnum1);
2123 cli_close(cli2, fnum2);
2124 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2125 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &f);
2126 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2127 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2128 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2129 NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2130 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2132 cli_close(cli1, fnum1);
2133 EXPECTED(ret, True);
2134 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2137 cli_close(cli1, fnum1);
2138 cli_close(cli2, fnum2);
2139 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2140 torture_close_connection(cli1);
2141 torture_close_connection(cli2);
2143 printf("finished locktest4\n");
2148 looks at lock upgrade/downgrade.
2150 static bool run_locktest5(int dummy)
2152 static struct cli_state *cli1, *cli2;
2153 const char *fname = "\\lockt5.lck";
2154 uint16_t fnum1, fnum2, fnum3;
2157 bool correct = True;
2160 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2164 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2165 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2167 printf("starting locktest5\n");
2169 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2171 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2172 cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2173 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2175 memset(buf, 0, sizeof(buf));
2177 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2179 if (!NT_STATUS_IS_OK(status)) {
2180 printf("Failed to create file: %s\n", nt_errstr(status));
2185 /* Check for NT bug... */
2186 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2187 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2188 cli_close(cli1, fnum1);
2189 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2190 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2191 ret = NT_STATUS_IS_OK(status);
2192 EXPECTED(ret, True);
2193 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2194 cli_close(cli1, fnum1);
2195 cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2196 cli_unlock(cli1, fnum3, 0, 1);
2198 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2199 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2200 EXPECTED(ret, True);
2201 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2203 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2204 ret = NT_STATUS_IS_OK(status);
2205 EXPECTED(ret, False);
2207 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2209 /* Unlock the process 2 lock. */
2210 cli_unlock(cli2, fnum2, 0, 4);
2212 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2213 ret = NT_STATUS_IS_OK(status);
2214 EXPECTED(ret, False);
2216 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2218 /* Unlock the process 1 fnum3 lock. */
2219 cli_unlock(cli1, fnum3, 0, 4);
2221 /* Stack 2 more locks here. */
2222 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2223 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2225 EXPECTED(ret, True);
2226 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2228 /* Unlock the first process lock, then check this was the WRITE lock that was
2231 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2232 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2234 EXPECTED(ret, True);
2235 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2237 /* Unlock the process 2 lock. */
2238 cli_unlock(cli2, fnum2, 0, 4);
2240 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2242 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2243 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2244 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2246 EXPECTED(ret, True);
2247 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2249 /* Ensure the next unlock fails. */
2250 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2251 EXPECTED(ret, False);
2252 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2254 /* Ensure connection 2 can get a write lock. */
2255 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2256 ret = NT_STATUS_IS_OK(status);
2257 EXPECTED(ret, True);
2259 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2263 cli_close(cli1, fnum1);
2264 cli_close(cli2, fnum2);
2265 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2266 if (!torture_close_connection(cli1)) {
2269 if (!torture_close_connection(cli2)) {
2273 printf("finished locktest5\n");
2279 tries the unusual lockingX locktype bits
2281 static bool run_locktest6(int dummy)
2283 static struct cli_state *cli;
2284 const char *fname[1] = { "\\lock6.txt" };
2289 if (!torture_open_connection(&cli, 0)) {
2293 smbXcli_conn_set_sockopt(cli->conn, sockops);
2295 printf("starting locktest6\n");
2298 printf("Testing %s\n", fname[i]);
2300 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2302 cli_openx(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2303 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2304 cli_close(cli, fnum);
2305 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2307 cli_openx(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2308 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2309 cli_close(cli, fnum);
2310 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2312 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2315 torture_close_connection(cli);
2317 printf("finished locktest6\n");
2321 static bool run_locktest7(int dummy)
2323 struct cli_state *cli1;
2324 const char *fname = "\\lockt7.lck";
2327 bool correct = False;
2331 if (!torture_open_connection(&cli1, 0)) {
2335 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2337 printf("starting locktest7\n");
2339 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2341 cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2343 memset(buf, 0, sizeof(buf));
2345 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2347 if (!NT_STATUS_IS_OK(status)) {
2348 printf("Failed to create file: %s\n", nt_errstr(status));
2352 cli_setpid(cli1, 1);
2354 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2355 if (!NT_STATUS_IS_OK(status)) {
2356 printf("Unable to apply read lock on range 130:4, "
2357 "error was %s\n", nt_errstr(status));
2360 printf("pid1 successfully locked range 130:4 for READ\n");
2363 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2364 if (!NT_STATUS_IS_OK(status)) {
2365 printf("pid1 unable to read the range 130:4, error was %s\n",
2368 } else if (nread != 4) {
2369 printf("pid1 unable to read the range 130:4, "
2370 "recv %ld req %d\n", (unsigned long)nread, 4);
2373 printf("pid1 successfully read the range 130:4\n");
2376 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 printf("pid1 unable to write to the range 130:4, error was "
2379 "%s\n", nt_errstr(status));
2380 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2381 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2385 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2389 cli_setpid(cli1, 2);
2391 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2392 if (!NT_STATUS_IS_OK(status)) {
2393 printf("pid2 unable to read the range 130:4, error was %s\n",
2396 } else if (nread != 4) {
2397 printf("pid2 unable to read the range 130:4, "
2398 "recv %ld req %d\n", (unsigned long)nread, 4);
2401 printf("pid2 successfully read the range 130:4\n");
2404 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2405 if (!NT_STATUS_IS_OK(status)) {
2406 printf("pid2 unable to write to the range 130:4, error was "
2407 "%s\n", nt_errstr(status));
2408 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2409 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2413 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2417 cli_setpid(cli1, 1);
2418 cli_unlock(cli1, fnum1, 130, 4);
2420 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2421 if (!NT_STATUS_IS_OK(status)) {
2422 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2425 printf("pid1 successfully locked range 130:4 for WRITE\n");
2428 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2429 if (!NT_STATUS_IS_OK(status)) {
2430 printf("pid1 unable to read the range 130:4, error was %s\n",
2433 } else if (nread != 4) {
2434 printf("pid1 unable to read the range 130:4, "
2435 "recv %ld req %d\n", (unsigned long)nread, 4);
2438 printf("pid1 successfully read the range 130:4\n");
2441 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2442 if (!NT_STATUS_IS_OK(status)) {
2443 printf("pid1 unable to write to the range 130:4, error was "
2444 "%s\n", nt_errstr(status));
2447 printf("pid1 successfully wrote to the range 130:4\n");
2450 cli_setpid(cli1, 2);
2452 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2453 if (!NT_STATUS_IS_OK(status)) {
2454 printf("pid2 unable to read the range 130:4, error was "
2455 "%s\n", nt_errstr(status));
2456 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2457 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2461 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2462 (unsigned long)nread);
2466 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2467 if (!NT_STATUS_IS_OK(status)) {
2468 printf("pid2 unable to write to the range 130:4, error was "
2469 "%s\n", nt_errstr(status));
2470 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2471 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2475 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2479 cli_unlock(cli1, fnum1, 130, 0);
2483 cli_close(cli1, fnum1);
2484 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2485 torture_close_connection(cli1);
2487 printf("finished locktest7\n");
2492 * This demonstrates a problem with our use of GPFS share modes: A file
2493 * descriptor sitting in the pending close queue holding a GPFS share mode
2494 * blocks opening a file another time. Happens with Word 2007 temp files.
2495 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2496 * open is denied with NT_STATUS_SHARING_VIOLATION.
2499 static bool run_locktest8(int dummy)
2501 struct cli_state *cli1;
2502 const char *fname = "\\lockt8.lck";
2503 uint16_t fnum1, fnum2;
2505 bool correct = False;
2508 if (!torture_open_connection(&cli1, 0)) {
2512 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2514 printf("starting locktest8\n");
2516 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2518 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2520 if (!NT_STATUS_IS_OK(status)) {
2521 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2525 memset(buf, 0, sizeof(buf));
2527 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2528 if (!NT_STATUS_IS_OK(status)) {
2529 d_fprintf(stderr, "cli_openx second time returned %s\n",
2534 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2535 if (!NT_STATUS_IS_OK(status)) {
2536 printf("Unable to apply read lock on range 1:1, error was "
2537 "%s\n", nt_errstr(status));
2541 status = cli_close(cli1, fnum1);
2542 if (!NT_STATUS_IS_OK(status)) {
2543 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2547 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2548 if (!NT_STATUS_IS_OK(status)) {
2549 d_fprintf(stderr, "cli_openx third time returned %s\n",
2557 cli_close(cli1, fnum1);
2558 cli_close(cli1, fnum2);
2559 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2560 torture_close_connection(cli1);
2562 printf("finished locktest8\n");
2567 * This test is designed to be run in conjunction with
2568 * external NFS or POSIX locks taken in the filesystem.
2569 * It checks that the smbd server will block until the
2570 * lock is released and then acquire it. JRA.
2573 static bool got_alarm;
2574 static struct cli_state *alarm_cli;
2576 static void alarm_handler(int dummy)
2581 static void alarm_handler_parent(int dummy)
2583 cli_state_disconnect(alarm_cli);
2586 static void do_local_lock(int read_fd, int write_fd)
2591 const char *local_pathname = NULL;
2594 local_pathname = talloc_asprintf(talloc_tos(),
2595 "%s/lockt9.lck", local_path);
2596 if (!local_pathname) {
2597 printf("child: alloc fail\n");
2601 unlink(local_pathname);
2602 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2604 printf("child: open of %s failed %s.\n",
2605 local_pathname, strerror(errno));
2609 /* Now take a fcntl lock. */
2610 lock.l_type = F_WRLCK;
2611 lock.l_whence = SEEK_SET;
2614 lock.l_pid = getpid();
2616 ret = fcntl(fd,F_SETLK,&lock);
2618 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2619 local_pathname, strerror(errno));
2622 printf("child: got lock 0:4 on file %s.\n",
2627 CatchSignal(SIGALRM, alarm_handler);
2629 /* Signal the parent. */
2630 if (write(write_fd, &c, 1) != 1) {
2631 printf("child: start signal fail %s.\n",
2638 /* Wait for the parent to be ready. */
2639 if (read(read_fd, &c, 1) != 1) {
2640 printf("child: reply signal fail %s.\n",
2648 printf("child: released lock 0:4 on file %s.\n",
2654 static bool run_locktest9(int dummy)
2656 struct cli_state *cli1;
2657 const char *fname = "\\lockt9.lck";
2659 bool correct = False;
2660 int pipe_in[2], pipe_out[2];
2664 struct timeval start;
2668 printf("starting locktest9\n");
2670 if (local_path == NULL) {
2671 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2675 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2680 if (child_pid == -1) {
2684 if (child_pid == 0) {
2686 do_local_lock(pipe_out[0], pipe_in[1]);
2696 ret = read(pipe_in[0], &c, 1);
2698 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2703 if (!torture_open_connection(&cli1, 0)) {
2707 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2709 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE,
2711 if (!NT_STATUS_IS_OK(status)) {
2712 d_fprintf(stderr, "cli_openx returned %s\n", nt_errstr(status));
2716 /* Ensure the child has the lock. */
2717 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2718 if (NT_STATUS_IS_OK(status)) {
2719 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2722 d_printf("Child has the lock.\n");
2725 /* Tell the child to wait 5 seconds then exit. */
2726 ret = write(pipe_out[1], &c, 1);
2728 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2733 /* Wait 20 seconds for the lock. */
2735 CatchSignal(SIGALRM, alarm_handler_parent);
2738 start = timeval_current();
2740 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2741 if (!NT_STATUS_IS_OK(status)) {
2742 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2743 "%s\n", nt_errstr(status));
2748 seconds = timeval_elapsed(&start);
2750 printf("Parent got the lock after %.2f seconds.\n",
2753 status = cli_close(cli1, fnum);
2754 if (!NT_STATUS_IS_OK(status)) {
2755 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2762 cli_close(cli1, fnum);
2763 torture_close_connection(cli1);
2767 printf("finished locktest9\n");
2772 test whether fnums and tids open on one VC are available on another (a major
2775 static bool run_fdpasstest(int dummy)
2777 struct cli_state *cli1, *cli2;
2778 const char *fname = "\\fdpass.tst";
2783 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2786 smbXcli_conn_set_sockopt(cli1->conn, sockops);
2787 smbXcli_conn_set_sockopt(cli2->conn, sockops);
2789 printf("starting fdpasstest\n");
2791 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2793 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2795 if (!NT_STATUS_IS_OK(status)) {
2796 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2800 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2802 if (!NT_STATUS_IS_OK(status)) {
2803 printf("write failed (%s)\n", nt_errstr(status));
2807 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2808 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2809 cli_setpid(cli2, cli_getpid(cli1));
2811 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2812 printf("read succeeded! nasty security hole [%s]\n", buf);
2816 cli_close(cli1, fnum1);
2817 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2819 torture_close_connection(cli1);
2820 torture_close_connection(cli2);
2822 printf("finished fdpasstest\n");
2826 static bool run_fdsesstest(int dummy)
2828 struct cli_state *cli;
2833 const char *fname = "\\fdsess.tst";
2834 const char *fname1 = "\\fdsess1.tst";
2841 if (!torture_open_connection(&cli, 0))
2843 smbXcli_conn_set_sockopt(cli->conn, sockops);
2845 if (!torture_cli_session_setup2(cli, &new_vuid))
2848 saved_cnum = cli_state_get_tid(cli);
2849 if (!NT_STATUS_IS_OK(cli_tree_connect(cli, share, "?????", "", 1)))
2851 new_cnum = cli_state_get_tid(cli);
2852 cli_state_set_tid(cli, saved_cnum);
2854 printf("starting fdsesstest\n");
2856 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2857 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2859 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2860 if (!NT_STATUS_IS_OK(status)) {
2861 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2865 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2867 if (!NT_STATUS_IS_OK(status)) {
2868 printf("write failed (%s)\n", nt_errstr(status));
2872 saved_vuid = cli_state_get_uid(cli);
2873 cli_state_set_uid(cli, new_vuid);
2875 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2876 printf("read succeeded with different vuid! "
2877 "nasty security hole [%s]\n", buf);
2880 /* Try to open a file with different vuid, samba cnum. */
2881 if (NT_STATUS_IS_OK(cli_openx(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2882 printf("create with different vuid, same cnum succeeded.\n");
2883 cli_close(cli, fnum2);
2884 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2886 printf("create with different vuid, same cnum failed.\n");
2887 printf("This will cause problems with service clients.\n");
2891 cli_state_set_uid(cli, saved_vuid);
2893 /* Try with same vuid, different cnum. */
2894 cli_state_set_tid(cli, new_cnum);
2896 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2897 printf("read succeeded with different cnum![%s]\n", buf);
2901 cli_state_set_tid(cli, saved_cnum);
2902 cli_close(cli, fnum1);
2903 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2905 torture_close_connection(cli);
2907 printf("finished fdsesstest\n");
2912 This test checks that
2914 1) the server does not allow an unlink on a file that is open
2916 static bool run_unlinktest(int dummy)
2918 struct cli_state *cli;
2919 const char *fname = "\\unlink.tst";
2921 bool correct = True;
2924 if (!torture_open_connection(&cli, 0)) {
2928 smbXcli_conn_set_sockopt(cli->conn, sockops);
2930 printf("starting unlink test\n");
2932 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2936 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2937 if (!NT_STATUS_IS_OK(status)) {
2938 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2942 status = cli_unlink(cli, fname,
2943 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2944 if (NT_STATUS_IS_OK(status)) {
2945 printf("error: server allowed unlink on an open file\n");
2948 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2949 NT_STATUS_SHARING_VIOLATION);
2952 cli_close(cli, fnum);
2953 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2955 if (!torture_close_connection(cli)) {
2959 printf("unlink test finished\n");
2966 test how many open files this server supports on the one socket
2968 static bool run_maxfidtest(int dummy)
2970 struct cli_state *cli;
2972 uint16_t fnums[0x11000];
2975 bool correct = True;
2981 printf("failed to connect\n");
2985 smbXcli_conn_set_sockopt(cli->conn, sockops);
2987 for (i=0; i<0x11000; i++) {
2988 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2989 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2991 if (!NT_STATUS_IS_OK(status)) {
2992 printf("open of %s failed (%s)\n",
2993 fname, nt_errstr(status));
2994 printf("maximum fnum is %d\n", i);
3002 printf("cleaning up\n");
3004 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
3005 cli_close(cli, fnums[i]);
3007 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3008 if (!NT_STATUS_IS_OK(status)) {
3009 printf("unlink of %s failed (%s)\n",
3010 fname, nt_errstr(status));
3017 printf("maxfid test finished\n");
3018 if (!torture_close_connection(cli)) {
3024 /* generate a random buffer */
3025 static void rand_buf(char *buf, int len)
3028 *buf = (char)sys_random();
3033 /* send smb negprot commands, not reading the response */
3034 static bool run_negprot_nowait(int dummy)
3036 struct tevent_context *ev;
3038 struct cli_state *cli;
3039 bool correct = True;
3041 printf("starting negprot nowait test\n");
3043 ev = tevent_context_init(talloc_tos());
3048 if (!(cli = open_nbt_connection())) {
3053 for (i=0;i<50000;i++) {
3054 struct tevent_req *req;
3056 req = cli_negprot_send(ev, ev, cli, PROTOCOL_NT1);
3061 if (!tevent_req_poll(req, ev)) {
3062 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3070 if (torture_close_connection(cli)) {
3074 printf("finished negprot nowait test\n");
3079 /* send smb negprot commands, not reading the response */
3080 static bool run_bad_nbt_session(int dummy)
3082 struct nmb_name called, calling;
3083 struct sockaddr_storage ss;
3088 printf("starting bad nbt session test\n");
3090 make_nmb_name(&calling, myname, 0x0);
3091 make_nmb_name(&called , host, 0x20);
3093 if (!resolve_name(host, &ss, 0x20, true)) {
3094 d_fprintf(stderr, "Could not resolve name %s\n", host);
3098 status = open_socket_out(&ss, NBT_SMB_PORT, 10000, &fd);
3099 if (!NT_STATUS_IS_OK(status)) {
3100 d_fprintf(stderr, "open_socket_out failed: %s\n",
3105 ret = cli_bad_session_request(fd, &calling, &called);
3108 d_fprintf(stderr, "open_socket_out failed: %s\n",
3113 printf("finished bad nbt session test\n");
3117 /* send random IPC commands */
3118 static bool run_randomipc(int dummy)
3120 char *rparam = NULL;
3122 unsigned int rdrcnt,rprcnt;
3124 int api, param_len, i;
3125 struct cli_state *cli;
3126 bool correct = True;
3129 printf("starting random ipc test\n");
3131 if (!torture_open_connection(&cli, 0)) {
3135 for (i=0;i<count;i++) {
3136 api = sys_random() % 500;
3137 param_len = (sys_random() % 64);
3139 rand_buf(param, param_len);
3144 param, param_len, 8,
3145 NULL, 0, BUFFER_SIZE,
3149 printf("%d/%d\r", i,count);
3152 printf("%d/%d\n", i, count);
3154 if (!torture_close_connection(cli)) {
3158 printf("finished random ipc test\n");
3165 static void browse_callback(const char *sname, uint32 stype,
3166 const char *comment, void *state)
3168 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3174 This test checks the browse list code
3177 static bool run_browsetest(int dummy)
3179 static struct cli_state *cli;
3180 bool correct = True;
3182 printf("starting browse test\n");
3184 if (!torture_open_connection(&cli, 0)) {
3188 printf("domain list:\n");
3189 cli_NetServerEnum(cli, cli->server_domain,
3190 SV_TYPE_DOMAIN_ENUM,
3191 browse_callback, NULL);
3193 printf("machine list:\n");
3194 cli_NetServerEnum(cli, cli->server_domain,
3196 browse_callback, NULL);
3198 if (!torture_close_connection(cli)) {
3202 printf("browse test finished\n");
3210 This checks how the getatr calls works
3212 static bool run_attrtest(int dummy)
3214 struct cli_state *cli;
3217 const char *fname = "\\attrib123456789.tst";
3218 bool correct = True;
3221 printf("starting attrib test\n");
3223 if (!torture_open_connection(&cli, 0)) {
3227 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3228 cli_openx(cli, fname,
3229 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3230 cli_close(cli, fnum);
3232 status = cli_getatr(cli, fname, NULL, NULL, &t);
3233 if (!NT_STATUS_IS_OK(status)) {
3234 printf("getatr failed (%s)\n", nt_errstr(status));
3238 if (abs(t - time(NULL)) > 60*60*24*10) {
3239 printf("ERROR: SMBgetatr bug. time is %s",
3245 t2 = t-60*60*24; /* 1 day ago */
3247 status = cli_setatr(cli, fname, 0, t2);
3248 if (!NT_STATUS_IS_OK(status)) {
3249 printf("setatr failed (%s)\n", nt_errstr(status));
3253 status = cli_getatr(cli, fname, NULL, NULL, &t);
3254 if (!NT_STATUS_IS_OK(status)) {
3255 printf("getatr failed (%s)\n", nt_errstr(status));
3260 printf("ERROR: getatr/setatr bug. times are\n%s",
3262 printf("%s", ctime(&t2));
3266 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3268 if (!torture_close_connection(cli)) {
3272 printf("attrib test finished\n");
3279 This checks a couple of trans2 calls
3281 static bool run_trans2test(int dummy)
3283 struct cli_state *cli;
3286 time_t c_time, a_time, m_time;
3287 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3288 const char *fname = "\\trans2.tst";
3289 const char *dname = "\\trans2";
3290 const char *fname2 = "\\trans2\\trans2.tst";
3292 bool correct = True;
3296 printf("starting trans2 test\n");
3298 if (!torture_open_connection(&cli, 0)) {
3302 status = cli_get_fs_attr_info(cli, &fs_attr);
3303 if (!NT_STATUS_IS_OK(status)) {
3304 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3309 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3310 cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3311 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3312 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3313 if (!NT_STATUS_IS_OK(status)) {
3314 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3318 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3319 if (!NT_STATUS_IS_OK(status)) {
3320 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3324 if (strcmp(pname, fname)) {
3325 printf("qfilename gave different name? [%s] [%s]\n",
3330 cli_close(cli, fnum);
3334 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3335 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3337 if (!NT_STATUS_IS_OK(status)) {
3338 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3341 cli_close(cli, fnum);
3343 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3345 if (!NT_STATUS_IS_OK(status)) {
3346 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3349 time_t t = time(NULL);
3351 if (c_time != m_time) {
3352 printf("create time=%s", ctime(&c_time));
3353 printf("modify time=%s", ctime(&m_time));
3354 printf("This system appears to have sticky create times\n");
3356 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3357 printf("access time=%s", ctime(&a_time));
3358 printf("This system appears to set a midnight access time\n");
3362 if (abs(m_time - t) > 60*60*24*7) {
3363 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3369 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3370 cli_openx(cli, fname,
3371 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3372 cli_close(cli, fnum);
3373 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3374 &m_time_ts, &size, NULL, NULL);
3375 if (!NT_STATUS_IS_OK(status)) {
3376 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3379 if (w_time_ts.tv_sec < 60*60*24*2) {
3380 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3381 printf("This system appears to set a initial 0 write time\n");
3386 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3389 /* check if the server updates the directory modification time
3390 when creating a new file */
3391 status = cli_mkdir(cli, dname);
3392 if (!NT_STATUS_IS_OK(status)) {
3393 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3397 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3398 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3399 if (!NT_STATUS_IS_OK(status)) {
3400 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3404 cli_openx(cli, fname2,
3405 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3406 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3407 cli_close(cli, fnum);
3408 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3409 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3410 if (!NT_STATUS_IS_OK(status)) {
3411 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3414 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3416 printf("This system does not update directory modification times\n");
3420 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3421 cli_rmdir(cli, dname);
3423 if (!torture_close_connection(cli)) {
3427 printf("trans2 test finished\n");
3433 This checks new W2K calls.
3436 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3438 uint8_t *buf = NULL;
3442 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3443 CLI_BUFFER_SIZE, NULL, &buf, &len);
3444 if (!NT_STATUS_IS_OK(status)) {
3445 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3448 printf("qfileinfo: level %d, len = %u\n", level, len);
3449 dump_data(0, (uint8 *)buf, len);
3456 static bool run_w2ktest(int dummy)
3458 struct cli_state *cli;
3460 const char *fname = "\\w2ktest\\w2k.tst";
3462 bool correct = True;
3464 printf("starting w2k test\n");
3466 if (!torture_open_connection(&cli, 0)) {
3470 cli_openx(cli, fname,
3471 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3473 for (level = 1004; level < 1040; level++) {
3474 new_trans(cli, fnum, level);
3477 cli_close(cli, fnum);
3479 if (!torture_close_connection(cli)) {
3483 printf("w2k test finished\n");
3490 this is a harness for some oplock tests
3492 static bool run_oplock1(int dummy)
3494 struct cli_state *cli1;
3495 const char *fname = "\\lockt1.lck";
3497 bool correct = True;
3500 printf("starting oplock test 1\n");
3502 if (!torture_open_connection(&cli1, 0)) {
3506 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3508 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3510 cli1->use_oplocks = True;
3512 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3514 if (!NT_STATUS_IS_OK(status)) {
3515 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3519 cli1->use_oplocks = False;
3521 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3522 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3524 status = cli_close(cli1, fnum1);
3525 if (!NT_STATUS_IS_OK(status)) {
3526 printf("close2 failed (%s)\n", nt_errstr(status));
3530 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3531 if (!NT_STATUS_IS_OK(status)) {
3532 printf("unlink failed (%s)\n", nt_errstr(status));
3536 if (!torture_close_connection(cli1)) {
3540 printf("finished oplock test 1\n");
3545 static bool run_oplock2(int dummy)
3547 struct cli_state *cli1, *cli2;
3548 const char *fname = "\\lockt2.lck";
3549 uint16_t fnum1, fnum2;
3550 int saved_use_oplocks = use_oplocks;
3552 bool correct = True;
3553 volatile bool *shared_correct;
3557 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3558 *shared_correct = True;
3560 use_level_II_oplocks = True;
3563 printf("starting oplock test 2\n");
3565 if (!torture_open_connection(&cli1, 0)) {
3566 use_level_II_oplocks = False;
3567 use_oplocks = saved_use_oplocks;
3571 if (!torture_open_connection(&cli2, 1)) {
3572 use_level_II_oplocks = False;
3573 use_oplocks = saved_use_oplocks;
3577 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3579 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3580 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3582 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3584 if (!NT_STATUS_IS_OK(status)) {
3585 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3589 /* Don't need the globals any more. */
3590 use_level_II_oplocks = False;
3591 use_oplocks = saved_use_oplocks;
3595 status = cli_openx(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3596 if (!NT_STATUS_IS_OK(status)) {
3597 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3598 *shared_correct = False;
3604 status = cli_close(cli2, fnum2);
3605 if (!NT_STATUS_IS_OK(status)) {
3606 printf("close2 failed (%s)\n", nt_errstr(status));
3607 *shared_correct = False;
3615 /* Ensure cli1 processes the break. Empty file should always return 0
3617 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3618 if (!NT_STATUS_IS_OK(status)) {
3619 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3621 } else if (nread != 0) {
3622 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3623 (unsigned long)nread, 0);
3627 /* Should now be at level II. */
3628 /* Test if sending a write locks causes a break to none. */
3629 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3630 if (!NT_STATUS_IS_OK(status)) {
3631 printf("lock failed (%s)\n", nt_errstr(status));
3635 cli_unlock(cli1, fnum1, 0, 4);
3639 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3640 if (!NT_STATUS_IS_OK(status)) {
3641 printf("lock failed (%s)\n", nt_errstr(status));
3645 cli_unlock(cli1, fnum1, 0, 4);
3649 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3651 status = cli_close(cli1, fnum1);
3652 if (!NT_STATUS_IS_OK(status)) {
3653 printf("close1 failed (%s)\n", nt_errstr(status));
3659 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3660 if (!NT_STATUS_IS_OK(status)) {
3661 printf("unlink failed (%s)\n", nt_errstr(status));
3665 if (!torture_close_connection(cli1)) {
3669 if (!*shared_correct) {
3673 printf("finished oplock test 2\n");
3678 struct oplock4_state {
3679 struct tevent_context *ev;
3680 struct cli_state *cli;
3685 static void oplock4_got_break(struct tevent_req *req);
3686 static void oplock4_got_open(struct tevent_req *req);
3688 static bool run_oplock4(int dummy)
3690 struct tevent_context *ev;
3691 struct cli_state *cli1, *cli2;
3692 struct tevent_req *oplock_req, *open_req;
3693 const char *fname = "\\lockt4.lck";
3694 const char *fname_ln = "\\lockt4_ln.lck";
3695 uint16_t fnum1, fnum2;
3696 int saved_use_oplocks = use_oplocks;
3698 bool correct = true;
3702 struct oplock4_state *state;
3704 printf("starting oplock test 4\n");
3706 if (!torture_open_connection(&cli1, 0)) {
3707 use_level_II_oplocks = false;
3708 use_oplocks = saved_use_oplocks;
3712 if (!torture_open_connection(&cli2, 1)) {
3713 use_level_II_oplocks = false;
3714 use_oplocks = saved_use_oplocks;
3718 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3719 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3721 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3722 smbXcli_conn_set_sockopt(cli2->conn, sockops);
3724 /* Create the file. */
3725 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3727 if (!NT_STATUS_IS_OK(status)) {
3728 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3732 status = cli_close(cli1, fnum1);
3733 if (!NT_STATUS_IS_OK(status)) {
3734 printf("close1 failed (%s)\n", nt_errstr(status));
3738 /* Now create a hardlink. */
3739 status = cli_nt_hardlink(cli1, fname, fname_ln);
3740 if (!NT_STATUS_IS_OK(status)) {
3741 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3745 /* Prove that opening hardlinks cause deny modes to conflict. */
3746 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3747 if (!NT_STATUS_IS_OK(status)) {
3748 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3752 status = cli_openx(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3753 if (NT_STATUS_IS_OK(status)) {
3754 printf("open of %s succeeded - should fail with sharing violation.\n",
3759 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3760 printf("open of %s should fail with sharing violation. Got %s\n",
3761 fname_ln, nt_errstr(status));
3765 status = cli_close(cli1, fnum1);
3766 if (!NT_STATUS_IS_OK(status)) {
3767 printf("close1 failed (%s)\n", nt_errstr(status));
3771 cli1->use_oplocks = true;
3772 cli2->use_oplocks = true;
3774 status = cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3775 if (!NT_STATUS_IS_OK(status)) {
3776 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3780 ev = tevent_context_init(talloc_tos());
3782 printf("tevent_context_init failed\n");
3786 state = talloc(ev, struct oplock4_state);
3787 if (state == NULL) {
3788 printf("talloc failed\n");
3793 state->got_break = &got_break;
3794 state->fnum2 = &fnum2;
3796 oplock_req = cli_smb_oplock_break_waiter_send(
3797 talloc_tos(), ev, cli1);
3798 if (oplock_req == NULL) {
3799 printf("cli_smb_oplock_break_waiter_send failed\n");
3802 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3804 open_req = cli_openx_send(
3805 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3806 if (open_req == NULL) {
3807 printf("cli_openx_send failed\n");
3810 tevent_req_set_callback(open_req, oplock4_got_open, state);
3815 while (!got_break || fnum2 == 0xffff) {
3817 ret = tevent_loop_once(ev);
3819 printf("tevent_loop_once failed: %s\n",
3825 status = cli_close(cli2, fnum2);
3826 if (!NT_STATUS_IS_OK(status)) {
3827 printf("close2 failed (%s)\n", nt_errstr(status));
3831 status = cli_close(cli1, fnum1);
3832 if (!NT_STATUS_IS_OK(status)) {
3833 printf("close1 failed (%s)\n", nt_errstr(status));
3837 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3838 if (!NT_STATUS_IS_OK(status)) {
3839 printf("unlink failed (%s)\n", nt_errstr(status));
3843 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3844 if (!NT_STATUS_IS_OK(status)) {
3845 printf("unlink failed (%s)\n", nt_errstr(status));
3849 if (!torture_close_connection(cli1)) {
3857 printf("finished oplock test 4\n");
3862 static void oplock4_got_break(struct tevent_req *req)
3864 struct oplock4_state *state = tevent_req_callback_data(
3865 req, struct oplock4_state);
3870 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3872 if (!NT_STATUS_IS_OK(status)) {
3873 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3877 *state->got_break = true;
3879 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3882 printf("cli_oplock_ack_send failed\n");
3887 static void oplock4_got_open(struct tevent_req *req)
3889 struct oplock4_state *state = tevent_req_callback_data(
3890 req, struct oplock4_state);
3893 status = cli_openx_recv(req, state->fnum2);
3894 if (!NT_STATUS_IS_OK(status)) {
3895 printf("cli_openx_recv returned %s\n", nt_errstr(status));
3896 *state->fnum2 = 0xffff;
3901 Test delete on close semantics.
3903 static bool run_deletetest(int dummy)
3905 struct cli_state *cli1 = NULL;
3906 struct cli_state *cli2 = NULL;
3907 const char *fname = "\\delete.file";
3908 uint16_t fnum1 = (uint16_t)-1;
3909 uint16_t fnum2 = (uint16_t)-1;
3910 bool correct = True;
3913 printf("starting delete test\n");
3915 if (!torture_open_connection(&cli1, 0)) {
3919 smbXcli_conn_set_sockopt(cli1->conn, sockops);
3921 /* Test 1 - this should delete the file on close. */
3923 cli_setatr(cli1, fname, 0, 0);
3924 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3926 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3927 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3928 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3929 if (!NT_STATUS_IS_OK(status)) {
3930 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3935 status = cli_close(cli1, fnum1);
3936 if (!NT_STATUS_IS_OK(status)) {
3937 printf("[1] close failed (%s)\n", nt_errstr(status));
3942 if (NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3943 printf("[1] open of %s succeeded (should fail)\n", fname);
3948 printf("first delete on close test succeeded.\n");
3950 /* Test 2 - this should delete the file on close. */
3952 cli_setatr(cli1, fname, 0, 0);
3953 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3955 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3956 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3957 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3958 if (!NT_STATUS_IS_OK(status)) {
3959 printf("[2] open 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("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3971 status = cli_close(cli1, fnum1);
3972 if (!NT_STATUS_IS_OK(status)) {
3973 printf("[2] close failed (%s)\n", nt_errstr(status));
3978 if (NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3979 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3980 status = cli_close(cli1, fnum1);
3981 if (!NT_STATUS_IS_OK(status)) {
3982 printf("[2] close failed (%s)\n", nt_errstr(status));
3986 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3988 printf("second delete on close test succeeded.\n");
3991 cli_setatr(cli1, fname, 0, 0);
3992 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3994 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3995 FILE_ATTRIBUTE_NORMAL,
3996 FILE_SHARE_READ|FILE_SHARE_WRITE,
3997 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3998 if (!NT_STATUS_IS_OK(status)) {
3999 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
4004 /* This should fail with a sharing violation - open for delete is only compatible
4005 with SHARE_DELETE. */
4007 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4008 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
4009 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4014 /* This should succeed. */
4015 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4016 FILE_ATTRIBUTE_NORMAL,
4017 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4018 FILE_OPEN, 0, 0, &fnum2);
4019 if (!NT_STATUS_IS_OK(status)) {
4020 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4025 status = cli_nt_delete_on_close(cli1, fnum1, true);
4026 if (!NT_STATUS_IS_OK(status)) {
4027 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4032 status = cli_close(cli1, fnum1);
4033 if (!NT_STATUS_IS_OK(status)) {
4034 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4039 status = cli_close(cli1, fnum2);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4046 /* This should fail - file should no longer be there. */
4048 if (NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4049 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4050 status = cli_close(cli1, fnum1);
4051 if (!NT_STATUS_IS_OK(status)) {
4052 printf("[3] close failed (%s)\n", nt_errstr(status));
4054 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4058 printf("third delete on close test succeeded.\n");
4061 cli_setatr(cli1, fname, 0, 0);
4062 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4064 status = cli_ntcreate(cli1, fname, 0,
4065 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4066 FILE_ATTRIBUTE_NORMAL,
4067 FILE_SHARE_READ|FILE_SHARE_WRITE,
4068 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4069 if (!NT_STATUS_IS_OK(status)) {
4070 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4075 /* This should succeed. */
4076 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4077 FILE_ATTRIBUTE_NORMAL,
4078 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4079 FILE_OPEN, 0, 0, &fnum2);
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4086 status = cli_close(cli1, fnum2);
4087 if (!NT_STATUS_IS_OK(status)) {
4088 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4093 status = cli_nt_delete_on_close(cli1, fnum1, true);
4094 if (!NT_STATUS_IS_OK(status)) {
4095 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4100 /* This should fail - no more opens once delete on close set. */
4101 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4102 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4103 FILE_OPEN, 0, 0, &fnum2))) {
4104 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4108 printf("fourth delete on close test succeeded.\n");
4110 status = cli_close(cli1, fnum1);
4111 if (!NT_STATUS_IS_OK(status)) {
4112 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4118 cli_setatr(cli1, fname, 0, 0);
4119 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4121 status = cli_openx(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4122 if (!NT_STATUS_IS_OK(status)) {
4123 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4128 /* This should fail - only allowed on NT opens with DELETE access. */
4130 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4131 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4136 status = cli_close(cli1, fnum1);
4137 if (!NT_STATUS_IS_OK(status)) {
4138 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
4143 printf("fifth delete on close test succeeded.\n");
4146 cli_setatr(cli1, fname, 0, 0);
4147 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4149 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4150 FILE_ATTRIBUTE_NORMAL,
4151 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4152 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4153 if (!NT_STATUS_IS_OK(status)) {
4154 printf("[6] open of %s failed (%s)\n", fname,
4160 /* This should fail - only allowed on NT opens with DELETE access. */
4162 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4163 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4168 status = cli_close(cli1, fnum1);
4169 if (!NT_STATUS_IS_OK(status)) {
4170 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4175 printf("sixth delete on close test succeeded.\n");
4178 cli_setatr(cli1, fname, 0, 0);
4179 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4181 status = cli_ntcreate(cli1, fname, 0,
4182 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4183 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4185 if (!NT_STATUS_IS_OK(status)) {
4186 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4191 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4192 printf("[7] setting delete_on_close on file failed !\n");
4197 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4198 printf("[7] unsetting delete_on_close on file failed !\n");
4203 status = cli_close(cli1, fnum1);
4204 if (!NT_STATUS_IS_OK(status)) {
4205 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4210 /* This next open should succeed - we reset the flag. */
4211 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4212 if (!NT_STATUS_IS_OK(status)) {
4213 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4218 status = cli_close(cli1, fnum1);
4219 if (!NT_STATUS_IS_OK(status)) {
4220 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4225 printf("seventh delete on close test succeeded.\n");
4228 cli_setatr(cli1, fname, 0, 0);
4229 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4231 if (!torture_open_connection(&cli2, 1)) {
4232 printf("[8] failed to open second connection.\n");
4237 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4239 status = cli_ntcreate(cli1, fname, 0,
4240 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4241 FILE_ATTRIBUTE_NORMAL,
4242 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4243 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4244 if (!NT_STATUS_IS_OK(status)) {
4245 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4250 status = cli_ntcreate(cli2, fname, 0,
4251 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4252 FILE_ATTRIBUTE_NORMAL,
4253 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4254 FILE_OPEN, 0, 0, &fnum2);
4255 if (!NT_STATUS_IS_OK(status)) {
4256 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4261 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4262 printf("[8] setting delete_on_close on file failed !\n");
4267 status = cli_close(cli1, fnum1);
4268 if (!NT_STATUS_IS_OK(status)) {
4269 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4274 status = cli_close(cli2, fnum2);
4275 if (!NT_STATUS_IS_OK(status)) {
4276 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4281 /* This should fail.. */
4282 status = cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4283 if (NT_STATUS_IS_OK(status)) {
4284 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4288 printf("eighth delete on close test succeeded.\n");
4290 /* This should fail - we need to set DELETE_ACCESS. */
4291 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4292 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4293 printf("[9] open of %s succeeded should have failed!\n", fname);
4298 printf("ninth delete on close test succeeded.\n");
4300 status = cli_ntcreate(cli1, fname, 0,
4301 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4302 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4303 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4305 if (!NT_STATUS_IS_OK(status)) {
4306 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4311 /* This should delete the file. */
4312 status = cli_close(cli1, fnum1);
4313 if (!NT_STATUS_IS_OK(status)) {
4314 printf("[10] close failed (%s)\n", nt_errstr(status));
4319 /* This should fail.. */
4320 if (NT_STATUS_IS_OK(cli_openx(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4321 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4325 printf("tenth delete on close test succeeded.\n");
4327 cli_setatr(cli1, fname, 0, 0);
4328 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4330 /* What error do we get when attempting to open a read-only file with
4333 /* Create a readonly file. */
4334 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4335 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4336 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4337 if (!NT_STATUS_IS_OK(status)) {
4338 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4343 status = cli_close(cli1, fnum1);
4344 if (!NT_STATUS_IS_OK(status)) {
4345 printf("[11] close failed (%s)\n", nt_errstr(status));
4350 /* Now try open for delete access. */
4351 status = cli_ntcreate(cli1, fname, 0,
4352 FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4354 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4355 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4356 if (NT_STATUS_IS_OK(status)) {
4357 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4358 cli_close(cli1, fnum1);
4362 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
4363 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(status));
4367 printf("eleventh delete on close test succeeded.\n");
4371 printf("finished delete test\n");
4374 /* FIXME: This will crash if we aborted before cli2 got
4375 * intialized, because these functions don't handle
4376 * uninitialized connections. */
4378 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4379 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4380 cli_setatr(cli1, fname, 0, 0);
4381 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4383 if (cli1 && !torture_close_connection(cli1)) {
4386 if (cli2 && !torture_close_connection(cli2)) {
4392 static bool run_deletetest_ln(int dummy)
4394 struct cli_state *cli;
4395 const char *fname = "\\delete1";
4396 const char *fname_ln = "\\delete1_ln";
4400 bool correct = true;
4403 printf("starting deletetest-ln\n");
4405 if (!torture_open_connection(&cli, 0)) {
4409 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4410 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4412 smbXcli_conn_set_sockopt(cli->conn, sockops);
4414 /* Create the file. */
4415 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4416 if (!NT_STATUS_IS_OK(status)) {
4417 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4421 status = cli_close(cli, fnum);
4422 if (!NT_STATUS_IS_OK(status)) {
4423 printf("close1 failed (%s)\n", nt_errstr(status));
4427 /* Now create a hardlink. */
4428 status = cli_nt_hardlink(cli, fname, fname_ln);
4429 if (!NT_STATUS_IS_OK(status)) {
4430 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4434 /* Open the original file. */
4435 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4436 FILE_ATTRIBUTE_NORMAL,
4437 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4438 FILE_OPEN_IF, 0, 0, &fnum);
4439 if (!NT_STATUS_IS_OK(status)) {
4440 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4444 /* Unlink the hard link path. */
4445 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4446 FILE_ATTRIBUTE_NORMAL,
4447 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4448 FILE_OPEN_IF, 0, 0, &fnum1);
4449 if (!NT_STATUS_IS_OK(status)) {
4450 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4453 status = cli_nt_delete_on_close(cli, fnum1, true);
4454 if (!NT_STATUS_IS_OK(status)) {
4455 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4456 __location__, fname_ln, nt_errstr(status));
4460 status = cli_close(cli, fnum1);
4461 if (!NT_STATUS_IS_OK(status)) {
4462 printf("close %s failed (%s)\n",
4463 fname_ln, nt_errstr(status));
4467 status = cli_close(cli, fnum);
4468 if (!NT_STATUS_IS_OK(status)) {
4469 printf("close %s failed (%s)\n",
4470 fname, nt_errstr(status));
4474 /* Ensure the original file is still there. */
4475 status = cli_getatr(cli, fname, NULL, NULL, &t);
4476 if (!NT_STATUS_IS_OK(status)) {
4477 printf("%s getatr on file %s failed (%s)\n",
4484 /* Ensure the link path is gone. */
4485 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4486 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4487 printf("%s, getatr for file %s returned wrong error code %s "
4488 "- should have been deleted\n",
4490 fname_ln, nt_errstr(status));
4494 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4495 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4497 if (!torture_close_connection(cli)) {
4501 printf("finished deletetest-ln\n");
4507 print out server properties
4509 static bool run_properties(int dummy)
4511 struct cli_state *cli;
4512 bool correct = True;
4514 printf("starting properties test\n");
4518 if (!torture_open_connection(&cli, 0)) {
4522 smbXcli_conn_set_sockopt(cli->conn, sockops);
4524 d_printf("Capabilities 0x%08x\n", cli_state_capabilities(cli));
4526 if (!torture_close_connection(cli)) {
4535 /* FIRST_DESIRED_ACCESS 0xf019f */
4536 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4537 FILE_READ_EA| /* 0xf */ \
4538 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4539 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4540 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4541 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4542 /* SECOND_DESIRED_ACCESS 0xe0080 */
4543 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4544 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4545 WRITE_OWNER_ACCESS /* 0xe0000 */
4548 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4549 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4551 WRITE_OWNER_ACCESS /* */
4555 Test ntcreate calls made by xcopy
4557 static bool run_xcopy(int dummy)
4559 static struct cli_state *cli1;
4560 const char *fname = "\\test.txt";
4561 bool correct = True;
4562 uint16_t fnum1, fnum2;
4565 printf("starting xcopy test\n");
4567 if (!torture_open_connection(&cli1, 0)) {
4571 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4572 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4573 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4574 if (!NT_STATUS_IS_OK(status)) {
4575 printf("First open failed - %s\n", nt_errstr(status));
4579 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4580 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4581 FILE_OPEN, 0x200000, 0, &fnum2);
4582 if (!NT_STATUS_IS_OK(status)) {
4583 printf("second open failed - %s\n", nt_errstr(status));
4587 if (!torture_close_connection(cli1)) {
4595 Test rename on files open with share delete and no share delete.
4597 static bool run_rename(int dummy)
4599 static struct cli_state *cli1;
4600 const char *fname = "\\test.txt";
4601 const char *fname1 = "\\test1.txt";
4602 bool correct = True;
4607 printf("starting rename test\n");
4609 if (!torture_open_connection(&cli1, 0)) {
4613 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4614 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4616 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4617 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4618 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4619 if (!NT_STATUS_IS_OK(status)) {
4620 printf("First open failed - %s\n", nt_errstr(status));
4624 status = cli_rename(cli1, fname, fname1);
4625 if (!NT_STATUS_IS_OK(status)) {
4626 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4628 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4632 status = cli_close(cli1, fnum1);
4633 if (!NT_STATUS_IS_OK(status)) {
4634 printf("close - 1 failed (%s)\n", nt_errstr(status));
4638 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4639 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4640 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4642 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4644 FILE_SHARE_DELETE|FILE_SHARE_READ,
4646 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4647 if (!NT_STATUS_IS_OK(status)) {
4648 printf("Second open failed - %s\n", nt_errstr(status));
4652 status = cli_rename(cli1, fname, fname1);
4653 if (!NT_STATUS_IS_OK(status)) {
4654 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4657 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4660 status = cli_close(cli1, fnum1);
4661 if (!NT_STATUS_IS_OK(status)) {
4662 printf("close - 2 failed (%s)\n", nt_errstr(status));
4666 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4667 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4669 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4670 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4671 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4672 if (!NT_STATUS_IS_OK(status)) {
4673 printf("Third open failed - %s\n", nt_errstr(status));
4682 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4683 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4684 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4687 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4688 printf("[8] setting delete_on_close on file failed !\n");
4692 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4693 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4699 status = cli_rename(cli1, fname, fname1);
4700 if (!NT_STATUS_IS_OK(status)) {
4701 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4704 printf("Third rename succeeded (SHARE_NONE)\n");
4707 status = cli_close(cli1, fnum1);
4708 if (!NT_STATUS_IS_OK(status)) {
4709 printf("close - 3 failed (%s)\n", nt_errstr(status));
4713 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4714 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4718 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4719 FILE_ATTRIBUTE_NORMAL,
4720 FILE_SHARE_READ | FILE_SHARE_WRITE,
4721 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4722 if (!NT_STATUS_IS_OK(status)) {
4723 printf("Fourth open failed - %s\n", nt_errstr(status));
4727 status = cli_rename(cli1, fname, fname1);
4728 if (!NT_STATUS_IS_OK(status)) {
4729 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4731 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4735 status = cli_close(cli1, fnum1);
4736 if (!NT_STATUS_IS_OK(status)) {
4737 printf("close - 4 failed (%s)\n", nt_errstr(status));
4741 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4742 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4746 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4747 FILE_ATTRIBUTE_NORMAL,
4748 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4749 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4750 if (!NT_STATUS_IS_OK(status)) {
4751 printf("Fifth open failed - %s\n", nt_errstr(status));
4755 status = cli_rename(cli1, fname, fname1);
4756 if (!NT_STATUS_IS_OK(status)) {
4757 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4760 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4764 * Now check if the first name still exists ...
4767 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4768 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4769 printf("Opening original file after rename of open file fails: %s\n",
4773 printf("Opening original file after rename of open file works ...\n");
4774 (void)cli_close(cli1, fnum2);
4778 status = cli_close(cli1, fnum1);
4779 if (!NT_STATUS_IS_OK(status)) {
4780 printf("close - 5 failed (%s)\n", nt_errstr(status));
4784 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4785 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4786 if (!NT_STATUS_IS_OK(status)) {
4787 printf("getatr on file %s failed - %s ! \n",
4788 fname1, nt_errstr(status));
4791 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4792 printf("Renamed file %s has wrong attr 0x%x "
4793 "(should be 0x%x)\n",
4796 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4799 printf("Renamed file %s has archive bit set\n", fname1);
4803 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4804 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4806 if (!torture_close_connection(cli1)) {
4813 static bool run_pipe_number(int dummy)
4815 struct cli_state *cli1;
4816 const char *pipe_name = "\\SPOOLSS";
4821 printf("starting pipenumber test\n");
4822 if (!torture_open_connection(&cli1, 0)) {
4826 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4828 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4829 FILE_ATTRIBUTE_NORMAL,
4830 FILE_SHARE_READ|FILE_SHARE_WRITE,
4831 FILE_OPEN_IF, 0, 0, &fnum);
4832 if (!NT_STATUS_IS_OK(status)) {
4833 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4837 printf("\r%6d", num_pipes);
4840 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4841 torture_close_connection(cli1);
4846 Test open mode returns on read-only files.
4848 static bool run_opentest(int dummy)
4850 static struct cli_state *cli1;
4851 static struct cli_state *cli2;
4852 const char *fname = "\\readonly.file";
4853 uint16_t fnum1, fnum2;
4856 bool correct = True;
4860 printf("starting open test\n");
4862 if (!torture_open_connection(&cli1, 0)) {
4866 cli_setatr(cli1, fname, 0, 0);
4867 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4869 smbXcli_conn_set_sockopt(cli1->conn, sockops);
4871 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4872 if (!NT_STATUS_IS_OK(status)) {
4873 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4877 status = cli_close(cli1, fnum1);
4878 if (!NT_STATUS_IS_OK(status)) {
4879 printf("close2 failed (%s)\n", nt_errstr(status));
4883 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4884 if (!NT_STATUS_IS_OK(status)) {
4885 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4889 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4890 if (!NT_STATUS_IS_OK(status)) {
4891 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4895 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4896 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4898 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4899 NT_STATUS_ACCESS_DENIED)) {
4900 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4903 printf("finished open test 1\n");
4905 cli_close(cli1, fnum1);
4907 /* Now try not readonly and ensure ERRbadshare is returned. */
4909 cli_setatr(cli1, fname, 0, 0);
4911 status = cli_openx(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4912 if (!NT_STATUS_IS_OK(status)) {
4913 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4917 /* This will fail - but the error should be ERRshare. */
4918 status = cli_openx(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4920 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
4921 NT_STATUS_SHARING_VIOLATION)) {
4922 printf("correct error code ERRDOS/ERRbadshare returned\n");
4925 status = cli_close(cli1, fnum1);
4926 if (!NT_STATUS_IS_OK(status)) {
4927 printf("close2 failed (%s)\n", nt_errstr(status));
4931 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4933 printf("finished open test 2\n");
4935 /* Test truncate open disposition on file opened for read. */
4936 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4937 if (!NT_STATUS_IS_OK(status)) {
4938 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4942 /* write 20 bytes. */
4944 memset(buf, '\0', 20);
4946 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4947 if (!NT_STATUS_IS_OK(status)) {
4948 printf("write failed (%s)\n", nt_errstr(status));
4952 status = cli_close(cli1, fnum1);
4953 if (!NT_STATUS_IS_OK(status)) {
4954 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4958 /* Ensure size == 20. */
4959 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4960 if (!NT_STATUS_IS_OK(status)) {
4961 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4966 printf("(3) file size != 20\n");
4970 /* Now test if we can truncate a file opened for readonly. */
4971 status = cli_openx(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4972 if (!NT_STATUS_IS_OK(status)) {
4973 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4977 status = cli_close(cli1, fnum1);
4978 if (!NT_STATUS_IS_OK(status)) {
4979 printf("close2 failed (%s)\n", nt_errstr(status));
4983 /* Ensure size == 0. */
4984 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4985 if (!NT_STATUS_IS_OK(status)) {
4986 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4991 printf("(3) file size != 0\n");
4994 printf("finished open test 3\n");
4996 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4998 printf("Do ctemp tests\n");
4999 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
5000 if (!NT_STATUS_IS_OK(status)) {
5001 printf("ctemp failed (%s)\n", nt_errstr(status));
5005 printf("ctemp gave path %s\n", tmp_path);
5006 status = cli_close(cli1, fnum1);
5007 if (!NT_STATUS_IS_OK(status)) {
5008 printf("close of temp failed (%s)\n", nt_errstr(status));
5011 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5012 if (!NT_STATUS_IS_OK(status)) {
5013 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5016 /* Test the non-io opens... */
5018 if (!torture_open_connection(&cli2, 1)) {
5022 cli_setatr(cli2, fname, 0, 0);
5023 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5025 smbXcli_conn_set_sockopt(cli2->conn, sockops);
5027 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5028 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5029 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5030 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5031 if (!NT_STATUS_IS_OK(status)) {
5032 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5036 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5037 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5038 FILE_OPEN_IF, 0, 0, &fnum2);
5039 if (!NT_STATUS_IS_OK(status)) {
5040 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5044 status = cli_close(cli1, fnum1);
5045 if (!NT_STATUS_IS_OK(status)) {
5046 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5050 status = cli_close(cli2, fnum2);
5051 if (!NT_STATUS_IS_OK(status)) {
5052 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5056 printf("non-io open test #1 passed.\n");
5058 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5060 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5062 status = cli_ntcreate(cli1, fname, 0,
5063 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5064 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5065 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5066 if (!NT_STATUS_IS_OK(status)) {
5067 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5071 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5072 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5073 FILE_OPEN_IF, 0, 0, &fnum2);
5074 if (!NT_STATUS_IS_OK(status)) {
5075 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5079 status = cli_close(cli1, fnum1);
5080 if (!NT_STATUS_IS_OK(status)) {
5081 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5085 status = cli_close(cli2, fnum2);
5086 if (!NT_STATUS_IS_OK(status)) {
5087 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5091 printf("non-io open test #2 passed.\n");
5093 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5095 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5097 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5098 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5099 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5100 if (!NT_STATUS_IS_OK(status)) {
5101 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5105 status = cli_ntcreate(cli2, fname, 0,
5106 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5107 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5108 FILE_OPEN_IF, 0, 0, &fnum2);
5109 if (!NT_STATUS_IS_OK(status)) {
5110 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5114 status = cli_close(cli1, fnum1);
5115 if (!NT_STATUS_IS_OK(status)) {
5116 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5120 status = cli_close(cli2, fnum2);
5121 if (!NT_STATUS_IS_OK(status)) {
5122 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5126 printf("non-io open test #3 passed.\n");
5128 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5130 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5132 status = cli_ntcreate(cli1, fname, 0,
5133 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5134 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5135 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5136 if (!NT_STATUS_IS_OK(status)) {
5137 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5141 status = cli_ntcreate(cli2, fname, 0,
5142 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5143 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5144 FILE_OPEN_IF, 0, 0, &fnum2);
5145 if (NT_STATUS_IS_OK(status)) {
5146 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5150 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5152 status = cli_close(cli1, fnum1);
5153 if (!NT_STATUS_IS_OK(status)) {
5154 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5158 printf("non-io open test #4 passed.\n");
5160 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5162 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5164 status = cli_ntcreate(cli1, fname, 0,
5165 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5166 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5167 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5168 if (!NT_STATUS_IS_OK(status)) {
5169 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5173 status = cli_ntcreate(cli2, fname, 0,
5174 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5175 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5176 FILE_OPEN_IF, 0, 0, &fnum2);
5177 if (!NT_STATUS_IS_OK(status)) {
5178 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5182 status = cli_close(cli1, fnum1);
5183 if (!NT_STATUS_IS_OK(status)) {
5184 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5188 status = cli_close(cli2, fnum2);
5189 if (!NT_STATUS_IS_OK(status)) {
5190 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5194 printf("non-io open test #5 passed.\n");
5196 printf("TEST #6 testing 1 non-io open, one io open\n");
5198 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5200 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5201 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5202 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5203 if (!NT_STATUS_IS_OK(status)) {
5204 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5208 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5209 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5210 FILE_OPEN_IF, 0, 0, &fnum2);
5211 if (!NT_STATUS_IS_OK(status)) {
5212 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5216 status = cli_close(cli1, fnum1);
5217 if (!NT_STATUS_IS_OK(status)) {
5218 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5222 status = cli_close(cli2, fnum2);
5223 if (!NT_STATUS_IS_OK(status)) {
5224 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5228 printf("non-io open test #6 passed.\n");
5230 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5232 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5234 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5235 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5236 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5237 if (!NT_STATUS_IS_OK(status)) {
5238 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5242 status = cli_ntcreate(cli2, fname, 0,
5243 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5244 FILE_ATTRIBUTE_NORMAL,
5245 FILE_SHARE_READ|FILE_SHARE_DELETE,
5246 FILE_OPEN_IF, 0, 0, &fnum2);
5247 if (NT_STATUS_IS_OK(status)) {
5248 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5252 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5254 status = cli_close(cli1, fnum1);
5255 if (!NT_STATUS_IS_OK(status)) {
5256 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5260 printf("non-io open test #7 passed.\n");
5262 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5264 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5265 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5266 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5267 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5268 if (!NT_STATUS_IS_OK(status)) {
5269 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5274 /* Write to ensure we have to update the file time. */
5275 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5277 if (!NT_STATUS_IS_OK(status)) {
5278 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5283 status = cli_close(cli1, fnum1);
5284 if (!NT_STATUS_IS_OK(status)) {
5285 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5291 if (!torture_close_connection(cli1)) {
5294 if (!torture_close_connection(cli2)) {
5301 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5303 uint16 major, minor;
5304 uint32 caplow, caphigh;
5307 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5308 printf("Server doesn't support UNIX CIFS extensions.\n");
5309 return NT_STATUS_NOT_SUPPORTED;
5312 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5314 if (!NT_STATUS_IS_OK(status)) {
5315 printf("Server didn't return UNIX CIFS extensions: %s\n",
5320 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5322 if (!NT_STATUS_IS_OK(status)) {
5323 printf("Server doesn't support setting UNIX CIFS extensions: "
5324 "%s.\n", nt_errstr(status));
5328 return NT_STATUS_OK;
5332 Test POSIX open /mkdir calls.
5334 static bool run_simple_posix_open_test(int dummy)
5336 static struct cli_state *cli1;
5337 const char *fname = "posix:file";
5338 const char *hname = "posix:hlink";
5339 const char *sname = "posix:symlink";
5340 const char *dname = "posix:dir";
5343 uint16_t fnum1 = (uint16_t)-1;
5344 SMB_STRUCT_STAT sbuf;
5345 bool correct = false;
5349 printf("Starting simple POSIX open test\n");
5351 if (!torture_open_connection(&cli1, 0)) {
5355 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5357 status = torture_setup_unix_extensions(cli1);
5358 if (!NT_STATUS_IS_OK(status)) {
5362 cli_setatr(cli1, fname, 0, 0);
5363 cli_posix_unlink(cli1, fname);
5364 cli_setatr(cli1, dname, 0, 0);
5365 cli_posix_rmdir(cli1, dname);
5366 cli_setatr(cli1, hname, 0, 0);
5367 cli_posix_unlink(cli1, hname);
5368 cli_setatr(cli1, sname, 0, 0);
5369 cli_posix_unlink(cli1, sname);
5371 /* Create a directory. */
5372 status = cli_posix_mkdir(cli1, dname, 0777);
5373 if (!NT_STATUS_IS_OK(status)) {
5374 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5378 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5380 if (!NT_STATUS_IS_OK(status)) {
5381 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5385 /* Test ftruncate - set file size. */
5386 status = cli_ftruncate(cli1, fnum1, 1000);
5387 if (!NT_STATUS_IS_OK(status)) {
5388 printf("ftruncate failed (%s)\n", nt_errstr(status));
5392 /* Ensure st_size == 1000 */
5393 status = cli_posix_stat(cli1, fname, &sbuf);
5394 if (!NT_STATUS_IS_OK(status)) {
5395 printf("stat failed (%s)\n", nt_errstr(status));
5399 if (sbuf.st_ex_size != 1000) {
5400 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5404 /* Test ftruncate - set file size back to zero. */
5405 status = cli_ftruncate(cli1, fnum1, 0);
5406 if (!NT_STATUS_IS_OK(status)) {
5407 printf("ftruncate failed (%s)\n", nt_errstr(status));
5411 status = cli_close(cli1, fnum1);
5412 if (!NT_STATUS_IS_OK(status)) {
5413 printf("close failed (%s)\n", nt_errstr(status));
5417 /* Now open the file again for read only. */
5418 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5419 if (!NT_STATUS_IS_OK(status)) {
5420 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5424 /* Now unlink while open. */
5425 status = cli_posix_unlink(cli1, fname);
5426 if (!NT_STATUS_IS_OK(status)) {
5427 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5431 status = cli_close(cli1, fnum1);
5432 if (!NT_STATUS_IS_OK(status)) {
5433 printf("close(2) failed (%s)\n", nt_errstr(status));
5437 /* Ensure the file has gone. */
5438 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5439 if (NT_STATUS_IS_OK(status)) {
5440 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5444 /* Create again to test open with O_TRUNC. */
5445 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5446 if (!NT_STATUS_IS_OK(status)) {
5447 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5451 /* Test ftruncate - set file size. */
5452 status = cli_ftruncate(cli1, fnum1, 1000);
5453 if (!NT_STATUS_IS_OK(status)) {
5454 printf("ftruncate failed (%s)\n", nt_errstr(status));
5458 /* Ensure st_size == 1000 */
5459 status = cli_posix_stat(cli1, fname, &sbuf);
5460 if (!NT_STATUS_IS_OK(status)) {
5461 printf("stat failed (%s)\n", nt_errstr(status));
5465 if (sbuf.st_ex_size != 1000) {
5466 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5470 status = cli_close(cli1, fnum1);
5471 if (!NT_STATUS_IS_OK(status)) {
5472 printf("close(2) failed (%s)\n", nt_errstr(status));
5476 /* Re-open with O_TRUNC. */
5477 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5478 if (!NT_STATUS_IS_OK(status)) {
5479 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5483 /* Ensure st_size == 0 */
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 != 0) {
5491 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5495 status = cli_close(cli1, fnum1);
5496 if (!NT_STATUS_IS_OK(status)) {
5497 printf("close failed (%s)\n", nt_errstr(status));
5501 status = cli_posix_unlink(cli1, fname);
5502 if (!NT_STATUS_IS_OK(status)) {
5503 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5507 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5508 if (!NT_STATUS_IS_OK(status)) {
5509 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5510 dname, nt_errstr(status));
5514 cli_close(cli1, fnum1);
5516 /* What happens when we try and POSIX open a directory for write ? */
5517 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5518 if (NT_STATUS_IS_OK(status)) {
5519 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5522 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5523 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5528 /* Create the file. */
5529 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5531 if (!NT_STATUS_IS_OK(status)) {
5532 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5536 /* Write some data into it. */
5537 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5539 if (!NT_STATUS_IS_OK(status)) {
5540 printf("cli_write failed: %s\n", nt_errstr(status));
5544 cli_close(cli1, fnum1);
5546 /* Now create a hardlink. */
5547 status = cli_posix_hardlink(cli1, fname, hname);
5548 if (!NT_STATUS_IS_OK(status)) {
5549 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5553 /* Now create a symlink. */
5554 status = cli_posix_symlink(cli1, fname, sname);
5555 if (!NT_STATUS_IS_OK(status)) {
5556 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5560 /* Open the hardlink for read. */
5561 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5562 if (!NT_STATUS_IS_OK(status)) {
5563 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5567 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5568 if (!NT_STATUS_IS_OK(status)) {
5569 printf("POSIX read of %s failed (%s)\n", hname,
5572 } else if (nread != 10) {
5573 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5574 hname, (unsigned long)nread, 10);
5578 if (memcmp(buf, "TEST DATA\n", 10)) {
5579 printf("invalid data read from hardlink\n");
5583 /* Do a POSIX lock/unlock. */
5584 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5585 if (!NT_STATUS_IS_OK(status)) {
5586 printf("POSIX lock failed %s\n", nt_errstr(status));
5590 /* Punch a hole in the locked area. */
5591 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5592 if (!NT_STATUS_IS_OK(status)) {
5593 printf("POSIX unlock failed %s\n", nt_errstr(status));
5597 cli_close(cli1, fnum1);
5599 /* Open the symlink for read - this should fail. A POSIX
5600 client should not be doing opens on a symlink. */
5601 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5602 if (NT_STATUS_IS_OK(status)) {
5603 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5606 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5607 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5608 printf("POSIX open of %s should have failed "
5609 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5610 "failed with %s instead.\n",
5611 sname, nt_errstr(status));
5616 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5617 if (!NT_STATUS_IS_OK(status)) {
5618 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5622 if (strcmp(namebuf, fname) != 0) {
5623 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5624 sname, fname, namebuf);
5628 status = cli_posix_rmdir(cli1, dname);
5629 if (!NT_STATUS_IS_OK(status)) {
5630 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5634 printf("Simple POSIX open test passed\n");
5639 if (fnum1 != (uint16_t)-1) {
5640 cli_close(cli1, fnum1);
5641 fnum1 = (uint16_t)-1;
5644 cli_setatr(cli1, sname, 0, 0);
5645 cli_posix_unlink(cli1, sname);
5646 cli_setatr(cli1, hname, 0, 0);
5647 cli_posix_unlink(cli1, hname);
5648 cli_setatr(cli1, fname, 0, 0);
5649 cli_posix_unlink(cli1, fname);
5650 cli_setatr(cli1, dname, 0, 0);
5651 cli_posix_rmdir(cli1, dname);
5653 if (!torture_close_connection(cli1)) {
5661 static uint32 open_attrs_table[] = {
5662 FILE_ATTRIBUTE_NORMAL,
5663 FILE_ATTRIBUTE_ARCHIVE,
5664 FILE_ATTRIBUTE_READONLY,
5665 FILE_ATTRIBUTE_HIDDEN,
5666 FILE_ATTRIBUTE_SYSTEM,
5668 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5669 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5670 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5671 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5672 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5673 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5675 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5676 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5677 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5678 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5681 struct trunc_open_results {
5688 static struct trunc_open_results attr_results[] = {
5689 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5690 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5691 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5692 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5693 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5694 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5695 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5696 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5697 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5698 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5699 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5700 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5701 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5702 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5703 { 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 },
5704 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5705 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5706 { 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 },
5707 { 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 },
5708 { 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 },
5709 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5710 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5711 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5712 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5713 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5714 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5717 static bool run_openattrtest(int dummy)
5719 static struct cli_state *cli1;
5720 const char *fname = "\\openattr.file";
5722 bool correct = True;
5724 unsigned int i, j, k, l;
5727 printf("starting open attr test\n");
5729 if (!torture_open_connection(&cli1, 0)) {
5733 smbXcli_conn_set_sockopt(cli1->conn, sockops);
5735 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5736 cli_setatr(cli1, fname, 0, 0);
5737 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5739 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5740 open_attrs_table[i], FILE_SHARE_NONE,
5741 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5742 if (!NT_STATUS_IS_OK(status)) {
5743 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5747 status = cli_close(cli1, fnum1);
5748 if (!NT_STATUS_IS_OK(status)) {
5749 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5753 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5754 status = cli_ntcreate(cli1, fname, 0,
5755 FILE_READ_DATA|FILE_WRITE_DATA,
5756 open_attrs_table[j],
5757 FILE_SHARE_NONE, FILE_OVERWRITE,
5759 if (!NT_STATUS_IS_OK(status)) {
5760 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5761 if (attr_results[l].num == k) {
5762 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5763 k, open_attrs_table[i],
5764 open_attrs_table[j],
5765 fname, NT_STATUS_V(status), nt_errstr(status));
5770 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5771 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5772 k, open_attrs_table[i], open_attrs_table[j],
5777 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5783 status = cli_close(cli1, fnum1);
5784 if (!NT_STATUS_IS_OK(status)) {
5785 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5789 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5790 if (!NT_STATUS_IS_OK(status)) {
5791 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5796 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5797 k, open_attrs_table[i], open_attrs_table[j], attr );
5800 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5801 if (attr_results[l].num == k) {
5802 if (attr != attr_results[l].result_attr ||
5803 open_attrs_table[i] != attr_results[l].init_attr ||
5804 open_attrs_table[j] != attr_results[l].trunc_attr) {
5805 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5806 open_attrs_table[i],
5807 open_attrs_table[j],
5809 attr_results[l].result_attr);
5819 cli_setatr(cli1, fname, 0, 0);
5820 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5822 printf("open attr test %s.\n", correct ? "passed" : "failed");
5824 if (!torture_close_connection(cli1)) {
5830 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5831 const char *name, void *state)
5833 int *matched = (int *)state;
5834 if (matched != NULL) {
5837 return NT_STATUS_OK;
5841 test directory listing speed
5843 static bool run_dirtest(int dummy)
5846 static struct cli_state *cli;
5848 struct timeval core_start;
5849 bool correct = True;
5852 printf("starting directory test\n");
5854 if (!torture_open_connection(&cli, 0)) {
5858 smbXcli_conn_set_sockopt(cli->conn, sockops);
5861 for (i=0;i<torture_numops;i++) {
5863 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5864 if (!NT_STATUS_IS_OK(cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5865 fprintf(stderr,"Failed to open %s\n", fname);
5868 cli_close(cli, fnum);
5871 core_start = timeval_current();
5874 cli_list(cli, "a*.*", 0, list_fn, &matched);
5875 printf("Matched %d\n", matched);
5878 cli_list(cli, "b*.*", 0, list_fn, &matched);
5879 printf("Matched %d\n", matched);
5882 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5883 printf("Matched %d\n", matched);
5885 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5888 for (i=0;i<torture_numops;i++) {
5890 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5891 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5894 if (!torture_close_connection(cli)) {
5898 printf("finished dirtest\n");
5903 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5906 struct cli_state *pcli = (struct cli_state *)state;
5908 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5910 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5911 return NT_STATUS_OK;
5913 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5914 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5915 printf("del_fn: failed to rmdir %s\n,", fname );
5917 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5918 printf("del_fn: failed to unlink %s\n,", fname );
5920 return NT_STATUS_OK;
5925 sees what IOCTLs are supported
5927 bool torture_ioctl_test(int dummy)
5929 static struct cli_state *cli;
5930 uint16_t device, function;
5932 const char *fname = "\\ioctl.dat";
5936 if (!torture_open_connection(&cli, 0)) {
5940 printf("starting ioctl test\n");
5942 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5944 status = cli_openx(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5945 if (!NT_STATUS_IS_OK(status)) {
5946 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5950 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5951 printf("ioctl device info: %s\n", nt_errstr(status));
5953 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5954 printf("ioctl job info: %s\n", nt_errstr(status));
5956 for (device=0;device<0x100;device++) {
5957 printf("ioctl test with device = 0x%x\n", device);
5958 for (function=0;function<0x100;function++) {
5959 uint32 code = (device<<16) | function;
5961 status = cli_raw_ioctl(cli, fnum, code, &blob);
5963 if (NT_STATUS_IS_OK(status)) {
5964 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5966 data_blob_free(&blob);
5971 if (!torture_close_connection(cli)) {
5980 tries varients of chkpath
5982 bool torture_chkpath_test(int dummy)
5984 static struct cli_state *cli;
5989 if (!torture_open_connection(&cli, 0)) {
5993 printf("starting chkpath test\n");
5995 /* cleanup from an old run */
5996 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5997 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5998 cli_rmdir(cli, "\\chkpath.dir");
6000 status = cli_mkdir(cli, "\\chkpath.dir");
6001 if (!NT_STATUS_IS_OK(status)) {
6002 printf("mkdir1 failed : %s\n", nt_errstr(status));
6006 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
6007 if (!NT_STATUS_IS_OK(status)) {
6008 printf("mkdir2 failed : %s\n", nt_errstr(status));
6012 status = cli_openx(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
6014 if (!NT_STATUS_IS_OK(status)) {
6015 printf("open1 failed (%s)\n", nt_errstr(status));
6018 cli_close(cli, fnum);
6020 status = cli_chkpath(cli, "\\chkpath.dir");
6021 if (!NT_STATUS_IS_OK(status)) {
6022 printf("chkpath1 failed: %s\n", nt_errstr(status));
6026 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
6027 if (!NT_STATUS_IS_OK(status)) {
6028 printf("chkpath2 failed: %s\n", nt_errstr(status));
6032 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
6033 if (!NT_STATUS_IS_OK(status)) {
6034 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6035 NT_STATUS_NOT_A_DIRECTORY);
6037 printf("* chkpath on a file should fail\n");
6041 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
6042 if (!NT_STATUS_IS_OK(status)) {
6043 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
6044 NT_STATUS_OBJECT_NAME_NOT_FOUND);
6046 printf("* chkpath on a non existant file should fail\n");
6050 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6051 if (!NT_STATUS_IS_OK(status)) {
6052 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6053 NT_STATUS_OBJECT_PATH_NOT_FOUND);
6055 printf("* chkpath on a non existent component should fail\n");
6059 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6060 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6061 cli_rmdir(cli, "\\chkpath.dir");
6063 if (!torture_close_connection(cli)) {
6070 static bool run_eatest(int dummy)
6072 static struct cli_state *cli;
6073 const char *fname = "\\eatest.txt";
6074 bool correct = True;
6078 struct ea_struct *ea_list = NULL;
6079 TALLOC_CTX *mem_ctx = talloc_init("eatest");
6082 printf("starting eatest\n");
6084 if (!torture_open_connection(&cli, 0)) {
6085 talloc_destroy(mem_ctx);
6089 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6091 status = cli_ntcreate(cli, fname, 0,
6092 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6093 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6095 if (!NT_STATUS_IS_OK(status)) {
6096 printf("open failed - %s\n", nt_errstr(status));
6097 talloc_destroy(mem_ctx);
6101 for (i = 0; i < 10; i++) {
6102 fstring ea_name, ea_val;
6104 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6105 memset(ea_val, (char)i+1, i+1);
6106 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6107 if (!NT_STATUS_IS_OK(status)) {
6108 printf("ea_set of name %s failed - %s\n", ea_name,
6110 talloc_destroy(mem_ctx);
6115 cli_close(cli, fnum);
6116 for (i = 0; i < 10; i++) {
6117 fstring ea_name, ea_val;
6119 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6120 memset(ea_val, (char)i+1, i+1);
6121 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6122 if (!NT_STATUS_IS_OK(status)) {
6123 printf("ea_set of name %s failed - %s\n", ea_name,
6125 talloc_destroy(mem_ctx);
6130 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6131 if (!NT_STATUS_IS_OK(status)) {
6132 printf("ea_get list failed - %s\n", nt_errstr(status));
6136 printf("num_eas = %d\n", (int)num_eas);
6138 if (num_eas != 20) {
6139 printf("Should be 20 EA's stored... failing.\n");
6143 for (i = 0; i < num_eas; i++) {
6144 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6145 dump_data(0, ea_list[i].value.data,
6146 ea_list[i].value.length);
6149 /* Setting EA's to zero length deletes them. Test this */
6150 printf("Now deleting all EA's - case indepenent....\n");
6153 cli_set_ea_path(cli, fname, "", "", 0);
6155 for (i = 0; i < 20; i++) {
6157 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6158 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6159 if (!NT_STATUS_IS_OK(status)) {
6160 printf("ea_set of name %s failed - %s\n", ea_name,
6162 talloc_destroy(mem_ctx);
6168 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6169 if (!NT_STATUS_IS_OK(status)) {
6170 printf("ea_get list failed - %s\n", nt_errstr(status));
6174 printf("num_eas = %d\n", (int)num_eas);
6175 for (i = 0; i < num_eas; i++) {
6176 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6177 dump_data(0, ea_list[i].value.data,
6178 ea_list[i].value.length);
6182 printf("deleting EA's failed.\n");
6186 /* Try and delete a non existant EA. */
6187 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6188 if (!NT_STATUS_IS_OK(status)) {
6189 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6194 talloc_destroy(mem_ctx);
6195 if (!torture_close_connection(cli)) {
6202 static bool run_dirtest1(int dummy)
6205 static struct cli_state *cli;
6208 bool correct = True;
6210 printf("starting directory test\n");
6212 if (!torture_open_connection(&cli, 0)) {
6216 smbXcli_conn_set_sockopt(cli->conn, sockops);
6218 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6219 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6220 cli_rmdir(cli, "\\LISTDIR");
6221 cli_mkdir(cli, "\\LISTDIR");
6223 /* Create 1000 files and 1000 directories. */
6224 for (i=0;i<1000;i++) {
6226 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6227 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6228 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6229 fprintf(stderr,"Failed to open %s\n", fname);
6232 cli_close(cli, fnum);
6234 for (i=0;i<1000;i++) {
6236 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6237 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6238 fprintf(stderr,"Failed to open %s\n", fname);
6243 /* Now ensure that doing an old list sees both files and directories. */
6245 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6246 printf("num_seen = %d\n", num_seen );
6247 /* We should see 100 files + 1000 directories + . and .. */
6248 if (num_seen != 2002)
6251 /* Ensure if we have the "must have" bits we only see the
6255 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6256 printf("num_seen = %d\n", num_seen );
6257 if (num_seen != 1002)
6261 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6262 printf("num_seen = %d\n", num_seen );
6263 if (num_seen != 1000)
6266 /* Delete everything. */
6267 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6268 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6269 cli_rmdir(cli, "\\LISTDIR");
6272 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6273 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6274 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6277 if (!torture_close_connection(cli)) {
6281 printf("finished dirtest1\n");
6286 static bool run_error_map_extract(int dummy) {
6288 static struct cli_state *c_dos;
6289 static struct cli_state *c_nt;
6301 /* NT-Error connection */
6303 disable_spnego = true;
6304 if (!(c_nt = open_nbt_connection())) {
6305 disable_spnego = false;
6308 disable_spnego = false;
6310 status = cli_negprot(c_nt, PROTOCOL_NT1);
6312 if (!NT_STATUS_IS_OK(status)) {
6313 printf("%s rejected the NT-error negprot (%s)\n", host,
6319 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6320 if (!NT_STATUS_IS_OK(status)) {
6321 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6325 /* DOS-Error connection */
6327 disable_spnego = true;
6328 force_dos_errors = true;
6329 if (!(c_dos = open_nbt_connection())) {
6330 disable_spnego = false;
6331 force_dos_errors = false;
6334 disable_spnego = false;
6335 force_dos_errors = false;
6337 status = cli_negprot(c_dos, PROTOCOL_NT1);
6338 if (!NT_STATUS_IS_OK(status)) {
6339 printf("%s rejected the DOS-error negprot (%s)\n", host,
6341 cli_shutdown(c_dos);
6345 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6346 if (!NT_STATUS_IS_OK(status)) {
6347 printf("%s rejected the DOS-error initial session setup (%s)\n",
6348 host, nt_errstr(status));
6352 c_nt->map_dos_errors = false;
6353 c_dos->map_dos_errors = false;
6355 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6356 fstr_sprintf(user, "%X", error);
6358 status = cli_session_setup(c_nt, user,
6359 password, strlen(password),
6360 password, strlen(password),
6362 if (NT_STATUS_IS_OK(status)) {
6363 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6366 /* Case #1: 32-bit NT errors */
6367 if (!NT_STATUS_IS_DOS(status)) {
6370 printf("/** Dos error on NT connection! (%s) */\n",
6372 nt_status = NT_STATUS(0xc0000000);
6375 status = cli_session_setup(c_dos, user,
6376 password, strlen(password),
6377 password, strlen(password),
6379 if (NT_STATUS_IS_OK(status)) {
6380 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6383 /* Case #1: 32-bit NT errors */
6384 if (NT_STATUS_IS_DOS(status)) {
6385 printf("/** NT error on DOS connection! (%s) */\n",
6387 errnum = errclass = 0;
6389 errclass = NT_STATUS_DOS_CLASS(status);
6390 errnum = NT_STATUS_DOS_CODE(status);
6393 if (NT_STATUS_V(nt_status) != error) {
6394 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6395 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6396 get_nt_error_c_code(talloc_tos(), nt_status));
6399 printf("\t{%s,\t%s,\t%s},\n",
6400 smb_dos_err_class(errclass),
6401 smb_dos_err_name(errclass, errnum),
6402 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6407 static bool run_sesssetup_bench(int dummy)
6409 static struct cli_state *c;
6410 const char *fname = "\\file.dat";
6415 if (!torture_open_connection(&c, 0)) {
6419 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6420 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6421 FILE_DELETE_ON_CLOSE, 0, &fnum);
6422 if (!NT_STATUS_IS_OK(status)) {
6423 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6427 for (i=0; i<torture_numops; i++) {
6428 status = cli_session_setup(
6430 password, strlen(password),
6431 password, strlen(password),
6433 if (!NT_STATUS_IS_OK(status)) {
6434 d_printf("(%s) cli_session_setup failed: %s\n",
6435 __location__, nt_errstr(status));
6439 d_printf("\r%d ", (int)cli_state_get_uid(c));
6441 status = cli_ulogoff(c);
6442 if (!NT_STATUS_IS_OK(status)) {
6443 d_printf("(%s) cli_ulogoff failed: %s\n",
6444 __location__, nt_errstr(status));
6452 static bool subst_test(const char *str, const char *user, const char *domain,
6453 uid_t uid, gid_t gid, const char *expected)
6458 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6460 if (strcmp(subst, expected) != 0) {
6461 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6462 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6471 static void chain1_open_completion(struct tevent_req *req)
6475 status = cli_openx_recv(req, &fnum);
6478 d_printf("cli_openx_recv returned %s: %d\n",
6480 NT_STATUS_IS_OK(status) ? fnum : -1);
6483 static void chain1_write_completion(struct tevent_req *req)
6487 status = cli_write_andx_recv(req, &written);
6490 d_printf("cli_write_andx_recv returned %s: %d\n",
6492 NT_STATUS_IS_OK(status) ? (int)written : -1);
6495 static void chain1_close_completion(struct tevent_req *req)
6498 bool *done = (bool *)tevent_req_callback_data_void(req);
6500 status = cli_close_recv(req);
6505 d_printf("cli_close returned %s\n", nt_errstr(status));
6508 static bool run_chain1(int dummy)
6510 struct cli_state *cli1;
6511 struct event_context *evt = event_context_init(NULL);
6512 struct tevent_req *reqs[3], *smbreqs[3];
6514 const char *str = "foobar";
6517 printf("starting chain1 test\n");
6518 if (!torture_open_connection(&cli1, 0)) {
6522 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6524 reqs[0] = cli_openx_create(talloc_tos(), evt, cli1, "\\test",
6525 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6526 if (reqs[0] == NULL) return false;
6527 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6530 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6531 (const uint8_t *)str, 0, strlen(str)+1,
6532 smbreqs, 1, &smbreqs[1]);
6533 if (reqs[1] == NULL) return false;
6534 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6536 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6537 if (reqs[2] == NULL) return false;
6538 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6540 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6541 if (!NT_STATUS_IS_OK(status)) {
6546 tevent_loop_once(evt);
6549 torture_close_connection(cli1);
6553 static void chain2_sesssetup_completion(struct tevent_req *req)
6556 status = cli_session_setup_guest_recv(req);
6557 d_printf("sesssetup returned %s\n", nt_errstr(status));
6560 static void chain2_tcon_completion(struct tevent_req *req)
6562 bool *done = (bool *)tevent_req_callback_data_void(req);
6564 status = cli_tcon_andx_recv(req);
6565 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6569 static bool run_chain2(int dummy)
6571 struct cli_state *cli1;
6572 struct event_context *evt = event_context_init(NULL);
6573 struct tevent_req *reqs[2], *smbreqs[2];
6577 printf("starting chain2 test\n");
6578 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6579 port_to_use, SMB_SIGNING_DEFAULT, 0);
6580 if (!NT_STATUS_IS_OK(status)) {
6584 smbXcli_conn_set_sockopt(cli1->conn, sockops);
6586 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6588 if (reqs[0] == NULL) return false;
6589 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6591 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6592 "?????", NULL, 0, &smbreqs[1]);
6593 if (reqs[1] == NULL) return false;
6594 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6596 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6597 if (!NT_STATUS_IS_OK(status)) {
6602 tevent_loop_once(evt);
6605 torture_close_connection(cli1);
6610 struct torture_createdel_state {
6611 struct tevent_context *ev;
6612 struct cli_state *cli;
6615 static void torture_createdel_created(struct tevent_req *subreq);
6616 static void torture_createdel_closed(struct tevent_req *subreq);
6618 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6619 struct tevent_context *ev,
6620 struct cli_state *cli,
6623 struct tevent_req *req, *subreq;
6624 struct torture_createdel_state *state;
6626 req = tevent_req_create(mem_ctx, &state,
6627 struct torture_createdel_state);
6634 subreq = cli_ntcreate_send(
6635 state, ev, cli, name, 0,
6636 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6637 FILE_ATTRIBUTE_NORMAL,
6638 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6639 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6641 if (tevent_req_nomem(subreq, req)) {
6642 return tevent_req_post(req, ev);
6644 tevent_req_set_callback(subreq, torture_createdel_created, req);
6648 static void torture_createdel_created(struct tevent_req *subreq)
6650 struct tevent_req *req = tevent_req_callback_data(
6651 subreq, struct tevent_req);
6652 struct torture_createdel_state *state = tevent_req_data(
6653 req, struct torture_createdel_state);
6657 status = cli_ntcreate_recv(subreq, &fnum);
6658 TALLOC_FREE(subreq);
6659 if (!NT_STATUS_IS_OK(status)) {
6660 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6661 nt_errstr(status)));
6662 tevent_req_nterror(req, status);
6666 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6667 if (tevent_req_nomem(subreq, req)) {
6670 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6673 static void torture_createdel_closed(struct tevent_req *subreq)
6675 struct tevent_req *req = tevent_req_callback_data(
6676 subreq, struct tevent_req);
6679 status = cli_close_recv(subreq);
6680 if (!NT_STATUS_IS_OK(status)) {
6681 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6682 tevent_req_nterror(req, status);
6685 tevent_req_done(req);
6688 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6690 return tevent_req_simple_recv_ntstatus(req);
6693 struct torture_createdels_state {
6694 struct tevent_context *ev;
6695 struct cli_state *cli;
6696 const char *base_name;
6700 struct tevent_req **reqs;
6703 static void torture_createdels_done(struct tevent_req *subreq);
6705 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6706 struct tevent_context *ev,
6707 struct cli_state *cli,
6708 const char *base_name,
6712 struct tevent_req *req;
6713 struct torture_createdels_state *state;
6716 req = tevent_req_create(mem_ctx, &state,
6717 struct torture_createdels_state);
6723 state->base_name = talloc_strdup(state, base_name);
6724 if (tevent_req_nomem(state->base_name, req)) {
6725 return tevent_req_post(req, ev);
6727 state->num_files = MAX(num_parallel, num_files);
6729 state->received = 0;
6731 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6732 if (tevent_req_nomem(state->reqs, req)) {
6733 return tevent_req_post(req, ev);
6736 for (i=0; i<num_parallel; i++) {
6739 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6741 if (tevent_req_nomem(name, req)) {
6742 return tevent_req_post(req, ev);
6744 state->reqs[i] = torture_createdel_send(
6745 state->reqs, state->ev, state->cli, name);
6746 if (tevent_req_nomem(state->reqs[i], req)) {
6747 return tevent_req_post(req, ev);
6749 name = talloc_move(state->reqs[i], &name);
6750 tevent_req_set_callback(state->reqs[i],
6751 torture_createdels_done, req);
6757 static void torture_createdels_done(struct tevent_req *subreq)
6759 struct tevent_req *req = tevent_req_callback_data(
6760 subreq, struct tevent_req);
6761 struct torture_createdels_state *state = tevent_req_data(
6762 req, struct torture_createdels_state);
6763 size_t num_parallel = talloc_array_length(state->reqs);
6768 status = torture_createdel_recv(subreq);
6769 if (!NT_STATUS_IS_OK(status)){
6770 DEBUG(10, ("torture_createdel_recv returned %s\n",
6771 nt_errstr(status)));
6772 TALLOC_FREE(subreq);
6773 tevent_req_nterror(req, status);
6777 for (i=0; i<num_parallel; i++) {
6778 if (subreq == state->reqs[i]) {
6782 if (i == num_parallel) {
6783 DEBUG(10, ("received something we did not send\n"));
6784 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6787 TALLOC_FREE(state->reqs[i]);
6789 if (state->sent >= state->num_files) {
6790 tevent_req_done(req);
6794 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6796 if (tevent_req_nomem(name, req)) {
6799 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6801 if (tevent_req_nomem(state->reqs[i], req)) {
6804 name = talloc_move(state->reqs[i], &name);
6805 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6809 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6811 return tevent_req_simple_recv_ntstatus(req);
6814 struct swallow_notify_state {
6815 struct tevent_context *ev;
6816 struct cli_state *cli;
6818 uint32_t completion_filter;
6820 bool (*fn)(uint32_t action, const char *name, void *priv);
6824 static void swallow_notify_done(struct tevent_req *subreq);
6826 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6827 struct tevent_context *ev,
6828 struct cli_state *cli,
6830 uint32_t completion_filter,
6832 bool (*fn)(uint32_t action,
6837 struct tevent_req *req, *subreq;
6838 struct swallow_notify_state *state;
6840 req = tevent_req_create(mem_ctx, &state,
6841 struct swallow_notify_state);
6848 state->completion_filter = completion_filter;
6849 state->recursive = recursive;
6853 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6854 0xffff, state->completion_filter,
6856 if (tevent_req_nomem(subreq, req)) {
6857 return tevent_req_post(req, ev);
6859 tevent_req_set_callback(subreq, swallow_notify_done, req);
6863 static void swallow_notify_done(struct tevent_req *subreq)
6865 struct tevent_req *req = tevent_req_callback_data(
6866 subreq, struct tevent_req);
6867 struct swallow_notify_state *state = tevent_req_data(
6868 req, struct swallow_notify_state);
6870 uint32_t i, num_changes;
6871 struct notify_change *changes;
6873 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6874 TALLOC_FREE(subreq);
6875 if (!NT_STATUS_IS_OK(status)) {
6876 DEBUG(10, ("cli_notify_recv returned %s\n",
6877 nt_errstr(status)));
6878 tevent_req_nterror(req, status);
6882 for (i=0; i<num_changes; i++) {
6883 state->fn(changes[i].action, changes[i].name, state->priv);
6885 TALLOC_FREE(changes);
6887 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6888 0xffff, state->completion_filter,
6890 if (tevent_req_nomem(subreq, req)) {
6893 tevent_req_set_callback(subreq, swallow_notify_done, req);
6896 static bool print_notifies(uint32_t action, const char *name, void *priv)
6898 if (DEBUGLEVEL > 5) {
6899 d_printf("%d %s\n", (int)action, name);
6904 static void notify_bench_done(struct tevent_req *req)
6906 int *num_finished = (int *)tevent_req_callback_data_void(req);
6910 static bool run_notify_bench(int dummy)
6912 const char *dname = "\\notify-bench";
6913 struct tevent_context *ev;
6916 struct tevent_req *req1;
6917 struct tevent_req *req2 = NULL;
6918 int i, num_unc_names;
6919 int num_finished = 0;
6921 printf("starting notify-bench test\n");
6923 if (use_multishare_conn) {
6925 unc_list = file_lines_load(multishare_conn_fname,
6926 &num_unc_names, 0, NULL);
6927 if (!unc_list || num_unc_names <= 0) {
6928 d_printf("Failed to load unc names list from '%s'\n",
6929 multishare_conn_fname);
6932 TALLOC_FREE(unc_list);
6937 ev = tevent_context_init(talloc_tos());
6939 d_printf("tevent_context_init failed\n");
6943 for (i=0; i<num_unc_names; i++) {
6944 struct cli_state *cli;
6947 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6949 if (base_fname == NULL) {
6953 if (!torture_open_connection(&cli, i)) {
6957 status = cli_ntcreate(cli, dname, 0,
6958 MAXIMUM_ALLOWED_ACCESS,
6959 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6961 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6964 if (!NT_STATUS_IS_OK(status)) {
6965 d_printf("Could not create %s: %s\n", dname,
6970 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6971 FILE_NOTIFY_CHANGE_FILE_NAME |
6972 FILE_NOTIFY_CHANGE_DIR_NAME |
6973 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6974 FILE_NOTIFY_CHANGE_LAST_WRITE,
6975 false, print_notifies, NULL);
6977 d_printf("Could not create notify request\n");
6981 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6982 base_fname, 10, torture_numops);
6984 d_printf("Could not create createdels request\n");
6987 TALLOC_FREE(base_fname);
6989 tevent_req_set_callback(req2, notify_bench_done,
6993 while (num_finished < num_unc_names) {
6995 ret = tevent_loop_once(ev);
6997 d_printf("tevent_loop_once failed\n");
7002 if (!tevent_req_poll(req2, ev)) {
7003 d_printf("tevent_req_poll failed\n");
7006 status = torture_createdels_recv(req2);
7007 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
7012 static bool run_mangle1(int dummy)
7014 struct cli_state *cli;
7015 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
7019 time_t change_time, access_time, write_time;
7023 printf("starting mangle1 test\n");
7024 if (!torture_open_connection(&cli, 0)) {
7028 smbXcli_conn_set_sockopt(cli->conn, sockops);
7030 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7031 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7033 if (!NT_STATUS_IS_OK(status)) {
7034 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7037 cli_close(cli, fnum);
7039 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
7040 if (!NT_STATUS_IS_OK(status)) {
7041 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7045 d_printf("alt_name: %s\n", alt_name);
7047 status = cli_openx(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7048 if (!NT_STATUS_IS_OK(status)) {
7049 d_printf("cli_openx(%s) failed: %s\n", alt_name,
7053 cli_close(cli, fnum);
7055 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7056 &write_time, &size, &mode);
7057 if (!NT_STATUS_IS_OK(status)) {
7058 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7066 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7068 size_t *to_pull = (size_t *)priv;
7069 size_t thistime = *to_pull;
7071 thistime = MIN(thistime, n);
7072 if (thistime == 0) {
7076 memset(buf, 0, thistime);
7077 *to_pull -= thistime;
7081 static bool run_windows_write(int dummy)
7083 struct cli_state *cli1;
7087 const char *fname = "\\writetest.txt";
7088 struct timeval start_time;
7093 printf("starting windows_write test\n");
7094 if (!torture_open_connection(&cli1, 0)) {
7098 status = cli_openx(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7099 if (!NT_STATUS_IS_OK(status)) {
7100 printf("open failed (%s)\n", nt_errstr(status));
7104 smbXcli_conn_set_sockopt(cli1->conn, sockops);
7106 start_time = timeval_current();
7108 for (i=0; i<torture_numops; i++) {
7110 off_t start = i * torture_blocksize;
7111 size_t to_pull = torture_blocksize - 1;
7113 status = cli_writeall(cli1, fnum, 0, &c,
7114 start + torture_blocksize - 1, 1, NULL);
7115 if (!NT_STATUS_IS_OK(status)) {
7116 printf("cli_write failed: %s\n", nt_errstr(status));
7120 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7121 null_source, &to_pull);
7122 if (!NT_STATUS_IS_OK(status)) {
7123 printf("cli_push returned: %s\n", nt_errstr(status));
7128 seconds = timeval_elapsed(&start_time);
7129 kbytes = (double)torture_blocksize * torture_numops;
7132 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7133 (double)seconds, (int)(kbytes/seconds));
7137 cli_close(cli1, fnum);
7138 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7139 torture_close_connection(cli1);
7143 static bool run_cli_echo(int dummy)
7145 struct cli_state *cli;
7148 printf("starting cli_echo test\n");
7149 if (!torture_open_connection(&cli, 0)) {
7152 smbXcli_conn_set_sockopt(cli->conn, sockops);
7154 status = cli_echo(cli, 5, data_blob_const("hello", 5));
7156 d_printf("cli_echo returned %s\n", nt_errstr(status));
7158 torture_close_connection(cli);
7159 return NT_STATUS_IS_OK(status);
7162 static bool run_uid_regression_test(int dummy)
7164 static struct cli_state *cli;
7167 bool correct = True;
7170 printf("starting uid regression test\n");
7172 if (!torture_open_connection(&cli, 0)) {
7176 smbXcli_conn_set_sockopt(cli->conn, sockops);
7178 /* Ok - now save then logoff our current user. */
7179 old_vuid = cli_state_get_uid(cli);
7181 status = cli_ulogoff(cli);
7182 if (!NT_STATUS_IS_OK(status)) {
7183 d_printf("(%s) cli_ulogoff failed: %s\n",
7184 __location__, nt_errstr(status));
7189 cli_state_set_uid(cli, old_vuid);
7191 /* Try an operation. */
7192 status = cli_mkdir(cli, "\\uid_reg_test");
7193 if (NT_STATUS_IS_OK(status)) {
7194 d_printf("(%s) cli_mkdir succeeded\n",
7199 /* Should be bad uid. */
7200 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
7201 NT_STATUS_USER_SESSION_DELETED)) {
7207 old_cnum = cli_state_get_tid(cli);
7209 /* Now try a SMBtdis with the invald vuid set to zero. */
7210 cli_state_set_uid(cli, 0);
7212 /* This should succeed. */
7213 status = cli_tdis(cli);
7215 if (NT_STATUS_IS_OK(status)) {
7216 d_printf("First tdis with invalid vuid should succeed.\n");
7218 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7223 cli_state_set_uid(cli, old_vuid);
7224 cli_state_set_tid(cli, old_cnum);
7226 /* This should fail. */
7227 status = cli_tdis(cli);
7228 if (NT_STATUS_IS_OK(status)) {
7229 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7233 /* Should be bad tid. */
7234 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
7235 NT_STATUS_NETWORK_NAME_DELETED)) {
7241 cli_rmdir(cli, "\\uid_reg_test");
7250 static const char *illegal_chars = "*\\/?<>|\":";
7251 static char force_shortname_chars[] = " +,.[];=\177";
7253 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7254 const char *mask, void *state)
7256 struct cli_state *pcli = (struct cli_state *)state;
7258 NTSTATUS status = NT_STATUS_OK;
7260 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7262 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7263 return NT_STATUS_OK;
7265 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7266 status = cli_rmdir(pcli, fname);
7267 if (!NT_STATUS_IS_OK(status)) {
7268 printf("del_fn: failed to rmdir %s\n,", fname );
7271 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7272 if (!NT_STATUS_IS_OK(status)) {
7273 printf("del_fn: failed to unlink %s\n,", fname );
7285 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7286 const char *name, void *state)
7288 struct sn_state *s = (struct sn_state *)state;
7292 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7293 i, finfo->name, finfo->short_name);
7296 if (strchr(force_shortname_chars, i)) {
7297 if (!finfo->short_name) {
7298 /* Shortname not created when it should be. */
7299 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7300 __location__, finfo->name, i);
7303 } else if (finfo->short_name){
7304 /* Shortname created when it should not be. */
7305 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7306 __location__, finfo->short_name, finfo->name);
7310 return NT_STATUS_OK;
7313 static bool run_shortname_test(int dummy)
7315 static struct cli_state *cli;
7316 bool correct = True;
7322 printf("starting shortname test\n");
7324 if (!torture_open_connection(&cli, 0)) {
7328 smbXcli_conn_set_sockopt(cli->conn, sockops);
7330 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7331 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7332 cli_rmdir(cli, "\\shortname");
7334 status = cli_mkdir(cli, "\\shortname");
7335 if (!NT_STATUS_IS_OK(status)) {
7336 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7337 __location__, nt_errstr(status));
7342 if (strlcpy(fname, "\\shortname\\", sizeof(fname)) >= sizeof(fname)) {
7346 if (strlcat(fname, "test .txt", sizeof(fname)) >= sizeof(fname)) {
7353 for (i = 32; i < 128; i++) {
7354 uint16_t fnum = (uint16_t)-1;
7358 if (strchr(illegal_chars, i)) {
7363 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7364 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7365 if (!NT_STATUS_IS_OK(status)) {
7366 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7367 __location__, fname, nt_errstr(status));
7371 cli_close(cli, fnum);
7374 status = cli_list(cli, "\\shortname\\test*.*", 0,
7375 shortname_list_fn, &s);
7376 if (s.matched != 1) {
7377 d_printf("(%s) failed to list %s: %s\n",
7378 __location__, fname, nt_errstr(status));
7383 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7384 if (!NT_STATUS_IS_OK(status)) {
7385 d_printf("(%s) failed to delete %s: %s\n",
7386 __location__, fname, nt_errstr(status));
7399 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7400 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7401 cli_rmdir(cli, "\\shortname");
7402 torture_close_connection(cli);
7406 static void pagedsearch_cb(struct tevent_req *req)
7409 struct tldap_message *msg;
7412 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7413 if (rc != TLDAP_SUCCESS) {
7414 d_printf("tldap_search_paged_recv failed: %s\n",
7415 tldap_err2string(rc));
7418 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7422 if (!tldap_entry_dn(msg, &dn)) {
7423 d_printf("tldap_entry_dn failed\n");
7426 d_printf("%s\n", dn);
7430 static bool run_tldap(int dummy)
7432 struct tldap_context *ld;
7435 struct sockaddr_storage addr;
7436 struct tevent_context *ev;
7437 struct tevent_req *req;
7441 if (!resolve_name(host, &addr, 0, false)) {
7442 d_printf("could not find host %s\n", host);
7445 status = open_socket_out(&addr, 389, 9999, &fd);
7446 if (!NT_STATUS_IS_OK(status)) {
7447 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7451 ld = tldap_context_create(talloc_tos(), fd);
7454 d_printf("tldap_context_create failed\n");
7458 rc = tldap_fetch_rootdse(ld);
7459 if (rc != TLDAP_SUCCESS) {
7460 d_printf("tldap_fetch_rootdse failed: %s\n",
7461 tldap_errstr(talloc_tos(), ld, rc));
7465 basedn = tldap_talloc_single_attribute(
7466 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7467 if (basedn == NULL) {
7468 d_printf("no defaultNamingContext\n");
7471 d_printf("defaultNamingContext: %s\n", basedn);
7473 ev = tevent_context_init(talloc_tos());
7475 d_printf("tevent_context_init failed\n");
7479 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7480 TLDAP_SCOPE_SUB, "(objectclass=*)",
7482 NULL, 0, NULL, 0, 0, 0, 0, 5);
7484 d_printf("tldap_search_paged_send failed\n");
7487 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7489 tevent_req_poll(req, ev);
7493 /* test search filters against rootDSE */
7494 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7495 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7497 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7498 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7499 talloc_tos(), NULL, NULL);
7500 if (rc != TLDAP_SUCCESS) {
7501 d_printf("tldap_search with complex filter failed: %s\n",
7502 tldap_errstr(talloc_tos(), ld, rc));
7510 /* Torture test to ensure no regression of :
7511 https://bugzilla.samba.org/show_bug.cgi?id=7084
7514 static bool run_dir_createtime(int dummy)
7516 struct cli_state *cli;
7517 const char *dname = "\\testdir";
7518 const char *fname = "\\testdir\\testfile";
7520 struct timespec create_time;
7521 struct timespec create_time1;
7525 if (!torture_open_connection(&cli, 0)) {
7529 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7530 cli_rmdir(cli, dname);
7532 status = cli_mkdir(cli, dname);
7533 if (!NT_STATUS_IS_OK(status)) {
7534 printf("mkdir failed: %s\n", nt_errstr(status));
7538 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7540 if (!NT_STATUS_IS_OK(status)) {
7541 printf("cli_qpathinfo2 returned %s\n",
7546 /* Sleep 3 seconds, then create a file. */
7549 status = cli_openx(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7551 if (!NT_STATUS_IS_OK(status)) {
7552 printf("cli_openx failed: %s\n", nt_errstr(status));
7556 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7558 if (!NT_STATUS_IS_OK(status)) {
7559 printf("cli_qpathinfo2 (2) returned %s\n",
7564 if (timespec_compare(&create_time1, &create_time)) {
7565 printf("run_dir_createtime: create time was updated (error)\n");
7567 printf("run_dir_createtime: create time was not updated (correct)\n");
7573 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7574 cli_rmdir(cli, dname);
7575 if (!torture_close_connection(cli)) {
7582 static bool run_streamerror(int dummy)
7584 struct cli_state *cli;
7585 const char *dname = "\\testdir";
7586 const char *streamname =
7587 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7589 time_t change_time, access_time, write_time;
7591 uint16_t mode, fnum;
7594 if (!torture_open_connection(&cli, 0)) {
7598 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7599 cli_rmdir(cli, dname);
7601 status = cli_mkdir(cli, dname);
7602 if (!NT_STATUS_IS_OK(status)) {
7603 printf("mkdir failed: %s\n", nt_errstr(status));
7607 status = cli_qpathinfo1(cli, streamname, &change_time, &access_time,
7608 &write_time, &size, &mode);
7609 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7610 printf("pathinfo returned %s, expected "
7611 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7616 status = cli_ntcreate(cli, streamname, 0x16,
7617 FILE_READ_DATA|FILE_READ_EA|
7618 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7619 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7620 FILE_OPEN, 0, 0, &fnum);
7622 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7623 printf("ntcreate returned %s, expected "
7624 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7630 cli_rmdir(cli, dname);
7634 static bool run_local_substitute(int dummy)
7638 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7639 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7640 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7641 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7642 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7643 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7644 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7645 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7647 /* Different captialization rules in sub_basic... */
7649 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7655 static bool run_local_base64(int dummy)
7660 for (i=1; i<2000; i++) {
7661 DATA_BLOB blob1, blob2;
7664 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7666 generate_random_buffer(blob1.data, blob1.length);
7668 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7670 d_fprintf(stderr, "base64_encode_data_blob failed "
7671 "for %d bytes\n", i);
7674 blob2 = base64_decode_data_blob(b64);
7677 if (data_blob_cmp(&blob1, &blob2)) {
7678 d_fprintf(stderr, "data_blob_cmp failed for %d "
7682 TALLOC_FREE(blob1.data);
7683 data_blob_free(&blob2);
7688 static bool run_local_gencache(int dummy)
7694 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7695 d_printf("%s: gencache_set() failed\n", __location__);
7699 if (!gencache_get("foo", NULL, NULL)) {
7700 d_printf("%s: gencache_get() failed\n", __location__);
7704 if (!gencache_get("foo", &val, &tm)) {
7705 d_printf("%s: gencache_get() failed\n", __location__);
7709 if (strcmp(val, "bar") != 0) {
7710 d_printf("%s: gencache_get() returned %s, expected %s\n",
7711 __location__, val, "bar");
7718 if (!gencache_del("foo")) {
7719 d_printf("%s: gencache_del() failed\n", __location__);
7722 if (gencache_del("foo")) {
7723 d_printf("%s: second gencache_del() succeeded\n",
7728 if (gencache_get("foo", &val, &tm)) {
7729 d_printf("%s: gencache_get() on deleted entry "
7730 "succeeded\n", __location__);
7734 blob = data_blob_string_const_null("bar");
7735 tm = time(NULL) + 60;
7737 if (!gencache_set_data_blob("foo", &blob, tm)) {
7738 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7742 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7743 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7747 if (strcmp((const char *)blob.data, "bar") != 0) {
7748 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7749 __location__, (const char *)blob.data, "bar");
7750 data_blob_free(&blob);
7754 data_blob_free(&blob);
7756 if (!gencache_del("foo")) {
7757 d_printf("%s: gencache_del() failed\n", __location__);
7760 if (gencache_del("foo")) {
7761 d_printf("%s: second gencache_del() succeeded\n",
7766 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7767 d_printf("%s: gencache_get_data_blob() on deleted entry "
7768 "succeeded\n", __location__);
7775 static bool rbt_testval(struct db_context *db, const char *key,
7778 struct db_record *rec;
7779 TDB_DATA data = string_tdb_data(value);
7784 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
7786 d_fprintf(stderr, "fetch_locked failed\n");
7789 status = dbwrap_record_store(rec, data, 0);
7790 if (!NT_STATUS_IS_OK(status)) {
7791 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7796 rec = dbwrap_fetch_locked(db, db, string_tdb_data(key));
7798 d_fprintf(stderr, "second fetch_locked failed\n");
7802 dbvalue = dbwrap_record_get_value(rec);
7803 if ((dbvalue.dsize != data.dsize)
7804 || (memcmp(dbvalue.dptr, data.dptr, data.dsize) != 0)) {
7805 d_fprintf(stderr, "Got wrong data back\n");
7815 static bool run_local_rbtree(int dummy)
7817 struct db_context *db;
7821 db = db_open_rbt(NULL);
7824 d_fprintf(stderr, "db_open_rbt failed\n");
7828 for (i=0; i<1000; i++) {
7831 if (asprintf(&key, "key%ld", random()) == -1) {
7834 if (asprintf(&value, "value%ld", random()) == -1) {
7839 if (!rbt_testval(db, key, value)) {
7846 if (asprintf(&value, "value%ld", random()) == -1) {
7851 if (!rbt_testval(db, key, value)) {
7870 local test for character set functions
7872 This is a very simple test for the functionality in convert_string_error()
7874 static bool run_local_convert_string(int dummy)
7876 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7877 const char *test_strings[2] = { "March", "M\303\244rz" };
7881 for (i=0; i<2; i++) {
7882 const char *str = test_strings[i];
7883 int len = strlen(str);
7884 size_t converted_size;
7887 memset(dst, 'X', sizeof(dst));
7889 /* first try with real source length */
7890 ret = convert_string_error(CH_UNIX, CH_UTF8,
7895 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7899 if (converted_size != len) {
7900 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7901 str, len, (int)converted_size);
7905 if (strncmp(str, dst, converted_size) != 0) {
7906 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7910 if (strlen(str) != converted_size) {
7911 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7912 (int)strlen(str), (int)converted_size);
7916 if (dst[converted_size] != 'X') {
7917 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7921 /* now with srclen==-1, this causes the nul to be
7923 ret = convert_string_error(CH_UNIX, CH_UTF8,
7928 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7932 if (converted_size != len+1) {
7933 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7934 str, len, (int)converted_size);
7938 if (strncmp(str, dst, converted_size) != 0) {
7939 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7943 if (len+1 != converted_size) {
7944 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7945 len+1, (int)converted_size);
7949 if (dst[converted_size] != 'X') {
7950 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7957 TALLOC_FREE(tmp_ctx);
7960 TALLOC_FREE(tmp_ctx);
7965 struct talloc_dict_test {
7969 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7971 int *count = (int *)priv;
7976 static bool run_local_talloc_dict(int dummy)
7978 struct talloc_dict *dict;
7979 struct talloc_dict_test *t;
7980 int key, count, res;
7983 dict = talloc_dict_init(talloc_tos());
7988 t = talloc(talloc_tos(), struct talloc_dict_test);
7995 ok = talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), &t);
8001 res = talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count);
8019 static bool run_local_string_to_sid(int dummy) {
8022 if (string_to_sid(&sid, "S--1-5-32-545")) {
8023 printf("allowing S--1-5-32-545\n");
8026 if (string_to_sid(&sid, "S-1-5-32-+545")) {
8027 printf("allowing S-1-5-32-+545\n");
8030 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")) {
8031 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8034 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
8035 printf("allowing S-1-5-32-545-abc\n");
8038 if (!string_to_sid(&sid, "S-1-5-32-545")) {
8039 printf("could not parse S-1-5-32-545\n");
8042 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
8043 printf("mis-parsed S-1-5-32-545 as %s\n",
8044 sid_string_tos(&sid));
8050 static bool run_local_binary_to_sid(int dummy) {
8051 struct dom_sid *sid = talloc(NULL, struct dom_sid);
8052 static const char good_binary_sid[] = {
8053 0x1, /* revision number */
8055 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8056 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8057 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8058 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8059 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8060 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8061 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8062 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8063 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8064 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8065 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8066 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8067 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8068 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8069 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8070 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8073 static const char long_binary_sid[] = {
8074 0x1, /* revision number */
8076 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8077 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8078 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8079 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8080 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8081 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8082 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8083 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8084 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8085 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8086 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8087 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8088 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8089 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8090 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8091 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8092 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8093 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8094 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8097 static const char long_binary_sid2[] = {
8098 0x1, /* revision number */
8100 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8101 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8102 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8103 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8104 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8105 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8106 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8107 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8108 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8109 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8110 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8111 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8112 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8113 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8114 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8115 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8116 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8117 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8118 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8119 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8120 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8121 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8122 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8123 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8124 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8125 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8126 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8127 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8128 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8129 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8130 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8131 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8132 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8135 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
8138 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
8141 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
8147 /* Split a path name into filename and stream name components. Canonicalise
8148 * such that an implicit $DATA token is always explicit.
8150 * The "specification" of this function can be found in the
8151 * run_local_stream_name() function in torture.c, I've tried those
8152 * combinations against a W2k3 server.
8155 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
8156 char **pbase, char **pstream)
8159 char *stream = NULL;
8160 char *sname; /* stream name */
8161 const char *stype; /* stream type */
8163 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
8165 sname = strchr_m(fname, ':');
8167 if (lp_posix_pathnames() || (sname == NULL)) {
8168 if (pbase != NULL) {
8169 base = talloc_strdup(mem_ctx, fname);
8170 NT_STATUS_HAVE_NO_MEMORY(base);
8175 if (pbase != NULL) {
8176 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
8177 NT_STATUS_HAVE_NO_MEMORY(base);
8182 stype = strchr_m(sname, ':');
8184 if (stype == NULL) {
8185 sname = talloc_strdup(mem_ctx, sname);
8189 if (strcasecmp_m(stype, ":$DATA") != 0) {
8191 * If there is an explicit stream type, so far we only
8192 * allow $DATA. Is there anything else allowed? -- vl
8194 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8196 return NT_STATUS_OBJECT_NAME_INVALID;
8198 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8202 if (sname == NULL) {
8204 return NT_STATUS_NO_MEMORY;
8207 if (sname[0] == '\0') {
8209 * no stream name, so no stream
8214 if (pstream != NULL) {
8215 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8216 if (stream == NULL) {
8219 return NT_STATUS_NO_MEMORY;
8222 * upper-case the type field
8224 strupper_m(strchr_m(stream, ':')+1);
8228 if (pbase != NULL) {
8231 if (pstream != NULL) {
8234 return NT_STATUS_OK;
8237 static bool test_stream_name(const char *fname, const char *expected_base,
8238 const char *expected_stream,
8239 NTSTATUS expected_status)
8243 char *stream = NULL;
8245 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8246 if (!NT_STATUS_EQUAL(status, expected_status)) {
8250 if (!NT_STATUS_IS_OK(status)) {
8254 if (base == NULL) goto error;
8256 if (strcmp(expected_base, base) != 0) goto error;
8258 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8259 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8261 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8265 TALLOC_FREE(stream);
8269 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8270 fname, expected_base ? expected_base : "<NULL>",
8271 expected_stream ? expected_stream : "<NULL>",
8272 nt_errstr(expected_status));
8273 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8274 base ? base : "<NULL>", stream ? stream : "<NULL>",
8277 TALLOC_FREE(stream);
8281 static bool run_local_stream_name(int dummy)
8285 ret &= test_stream_name(
8286 "bla", "bla", NULL, NT_STATUS_OK);
8287 ret &= test_stream_name(
8288 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8289 ret &= test_stream_name(
8290 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8291 ret &= test_stream_name(
8292 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8293 ret &= test_stream_name(
8294 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8295 ret &= test_stream_name(
8296 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8297 ret &= test_stream_name(
8298 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8299 ret &= test_stream_name(
8300 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8305 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8307 if (a.length != b.length) {
8308 printf("a.length=%d != b.length=%d\n",
8309 (int)a.length, (int)b.length);
8312 if (memcmp(a.data, b.data, a.length) != 0) {
8313 printf("a.data and b.data differ\n");
8319 static bool run_local_memcache(int dummy)
8321 struct memcache *cache;
8323 DATA_BLOB d1, d2, d3;
8324 DATA_BLOB v1, v2, v3;
8326 TALLOC_CTX *mem_ctx;
8328 size_t size1, size2;
8331 cache = memcache_init(NULL, sizeof(void *) == 8 ? 200 : 100);
8333 if (cache == NULL) {
8334 printf("memcache_init failed\n");
8338 d1 = data_blob_const("d1", 2);
8339 d2 = data_blob_const("d2", 2);
8340 d3 = data_blob_const("d3", 2);
8342 k1 = data_blob_const("d1", 2);
8343 k2 = data_blob_const("d2", 2);
8345 memcache_add(cache, STAT_CACHE, k1, d1);
8346 memcache_add(cache, GETWD_CACHE, k2, d2);
8348 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8349 printf("could not find k1\n");
8352 if (!data_blob_equal(d1, v1)) {
8356 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8357 printf("could not find k2\n");
8360 if (!data_blob_equal(d2, v2)) {
8364 memcache_add(cache, STAT_CACHE, k1, d3);
8366 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8367 printf("could not find replaced k1\n");
8370 if (!data_blob_equal(d3, v3)) {
8374 memcache_add(cache, GETWD_CACHE, k1, d1);
8376 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8377 printf("Did find k2, should have been purged\n");
8383 cache = memcache_init(NULL, 0);
8385 mem_ctx = talloc_init("foo");
8387 str1 = talloc_strdup(mem_ctx, "string1");
8388 str2 = talloc_strdup(mem_ctx, "string2");
8390 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8391 data_blob_string_const("torture"), &str1);
8392 size1 = talloc_total_size(cache);
8394 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8395 data_blob_string_const("torture"), &str2);
8396 size2 = talloc_total_size(cache);
8398 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8400 if (size2 > size1) {
8401 printf("memcache leaks memory!\n");
8411 static void wbclient_done(struct tevent_req *req)
8414 struct winbindd_response *wb_resp;
8415 int *i = (int *)tevent_req_callback_data_void(req);
8417 wbc_err = wb_trans_recv(req, req, &wb_resp);
8420 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8423 static bool run_local_wbclient(int dummy)
8425 struct event_context *ev;
8426 struct wb_context **wb_ctx;
8427 struct winbindd_request wb_req;
8428 bool result = false;
8431 BlockSignals(True, SIGPIPE);
8433 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8438 wb_ctx = talloc_array(ev, struct wb_context *, torture_nprocs);
8439 if (wb_ctx == NULL) {
8443 ZERO_STRUCT(wb_req);
8444 wb_req.cmd = WINBINDD_PING;
8446 d_printf("torture_nprocs=%d, numops=%d\n", (int)torture_nprocs, (int)torture_numops);
8448 for (i=0; i<torture_nprocs; i++) {
8449 wb_ctx[i] = wb_context_init(ev, NULL);
8450 if (wb_ctx[i] == NULL) {
8453 for (j=0; j<torture_numops; j++) {
8454 struct tevent_req *req;
8455 req = wb_trans_send(ev, ev, wb_ctx[i],
8456 (j % 2) == 0, &wb_req);
8460 tevent_req_set_callback(req, wbclient_done, &i);
8466 while (i < torture_nprocs * torture_numops) {
8467 tevent_loop_once(ev);
8476 static void getaddrinfo_finished(struct tevent_req *req)
8478 char *name = (char *)tevent_req_callback_data_void(req);
8479 struct addrinfo *ainfo;
8482 res = getaddrinfo_recv(req, &ainfo);
8484 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8487 d_printf("gai(%s) succeeded\n", name);
8488 freeaddrinfo(ainfo);
8491 static bool run_getaddrinfo_send(int dummy)
8493 TALLOC_CTX *frame = talloc_stackframe();
8494 struct fncall_context *ctx;
8495 struct tevent_context *ev;
8496 bool result = false;
8497 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8498 "www.slashdot.org", "heise.de" };
8499 struct tevent_req *reqs[4];
8502 ev = event_context_init(frame);
8507 ctx = fncall_context_init(frame, 4);
8509 for (i=0; i<ARRAY_SIZE(names); i++) {
8510 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8512 if (reqs[i] == NULL) {
8515 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8516 discard_const_p(void, names[i]));
8519 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8520 tevent_loop_once(ev);
8529 static bool dbtrans_inc(struct db_context *db)
8531 struct db_record *rec;
8537 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
8539 printf(__location__ "fetch_lock failed\n");
8543 value = dbwrap_record_get_value(rec);
8545 if (value.dsize != sizeof(uint32_t)) {
8546 printf(__location__ "value.dsize = %d\n",
8551 memcpy(&val, value.dptr, sizeof(val));
8554 status = dbwrap_record_store(
8555 rec, make_tdb_data((uint8_t *)&val, sizeof(val)), 0);
8556 if (!NT_STATUS_IS_OK(status)) {
8557 printf(__location__ "store failed: %s\n",
8568 static bool run_local_dbtrans(int dummy)
8570 struct db_context *db;
8571 struct db_record *rec;
8577 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8578 O_RDWR|O_CREAT, 0600, DBWRAP_LOCK_ORDER_1);
8580 printf("Could not open transtest.db\n");
8584 res = dbwrap_transaction_start(db);
8586 printf(__location__ "transaction_start failed\n");
8590 rec = dbwrap_fetch_locked(db, db, string_term_tdb_data("transtest"));
8592 printf(__location__ "fetch_lock failed\n");
8596 value = dbwrap_record_get_value(rec);
8598 if (value.dptr == NULL) {
8600 status = dbwrap_record_store(
8601 rec, make_tdb_data((uint8_t *)&initial,
8604 if (!NT_STATUS_IS_OK(status)) {
8605 printf(__location__ "store returned %s\n",
8613 res = dbwrap_transaction_commit(db);
8615 printf(__location__ "transaction_commit failed\n");
8623 res = dbwrap_transaction_start(db);
8625 printf(__location__ "transaction_start failed\n");
8629 status = dbwrap_fetch_uint32(db, "transtest", &val);
8630 if (!NT_STATUS_IS_OK(status)) {
8631 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
8636 for (i=0; i<10; i++) {
8637 if (!dbtrans_inc(db)) {
8642 status = dbwrap_fetch_uint32(db, "transtest", &val2);
8643 if (!NT_STATUS_IS_OK(status)) {
8644 printf(__location__ "dbwrap_fetch_uint32 failed: %s\n",
8649 if (val2 != val + 10) {
8650 printf(__location__ "val=%d, val2=%d\n",
8651 (int)val, (int)val2);
8655 printf("val2=%d\r", val2);
8657 res = dbwrap_transaction_commit(db);
8659 printf(__location__ "transaction_commit failed\n");
8669 * Just a dummy test to be run under a debugger. There's no real way
8670 * to inspect the tevent_select specific function from outside of
8674 static bool run_local_tevent_select(int dummy)
8676 struct tevent_context *ev;
8677 struct tevent_fd *fd1, *fd2;
8678 bool result = false;
8680 ev = tevent_context_init_byname(NULL, "select");
8682 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8686 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8688 d_fprintf(stderr, "tevent_add_fd failed\n");
8691 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8693 d_fprintf(stderr, "tevent_add_fd failed\n");
8698 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8700 d_fprintf(stderr, "tevent_add_fd failed\n");
8710 static bool run_local_hex_encode_buf(int dummy)
8716 for (i=0; i<sizeof(src); i++) {
8719 hex_encode_buf(buf, src, sizeof(src));
8720 if (strcmp(buf, "0001020304050607") != 0) {
8723 hex_encode_buf(buf, NULL, 0);
8724 if (buf[0] != '\0') {
8730 static const char *remove_duplicate_addrs2_test_strings_vector[] = {
8752 "1001:1111:1111:1000:0:1111:1111:1111",
8761 static const char *remove_duplicate_addrs2_test_strings_result[] = {
8775 "1001:1111:1111:1000:0:1111:1111:1111"
8778 static bool run_local_remove_duplicate_addrs2(int dummy)
8780 struct ip_service test_vector[28];
8783 /* Construct the sockaddr_storage test vector. */
8784 for (i = 0; i < 28; i++) {
8785 struct addrinfo hints;
8786 struct addrinfo *res = NULL;
8789 memset(&hints, '\0', sizeof(hints));
8790 hints.ai_flags = AI_NUMERICHOST;
8791 ret = getaddrinfo(remove_duplicate_addrs2_test_strings_vector[i],
8796 fprintf(stderr, "getaddrinfo failed on [%s]\n",
8797 remove_duplicate_addrs2_test_strings_vector[i]);
8800 memset(&test_vector[i], '\0', sizeof(test_vector[i]));
8801 memcpy(&test_vector[i].ss,
8807 count = remove_duplicate_addrs2(test_vector, i);
8810 fprintf(stderr, "count wrong (%d) should be 14\n",
8815 for (i = 0; i < count; i++) {
8816 char addr[INET6_ADDRSTRLEN];
8818 print_sockaddr(addr, sizeof(addr), &test_vector[i].ss);
8820 if (strcmp(addr, remove_duplicate_addrs2_test_strings_result[i]) != 0) {
8821 fprintf(stderr, "mismatch on [%d] [%s] [%s]\n",
8824 remove_duplicate_addrs2_test_strings_result[i]);
8829 printf("run_local_remove_duplicate_addrs2: success\n");
8833 static double create_procs(bool (*fn)(int), bool *result)
8836 volatile pid_t *child_status;
8837 volatile bool *child_status_out;
8840 struct timeval start;
8844 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*torture_nprocs);
8845 if (!child_status) {
8846 printf("Failed to setup shared memory\n");
8850 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*torture_nprocs);
8851 if (!child_status_out) {
8852 printf("Failed to setup result status shared memory\n");
8856 for (i = 0; i < torture_nprocs; i++) {
8857 child_status[i] = 0;
8858 child_status_out[i] = True;
8861 start = timeval_current();
8863 for (i=0;i<torture_nprocs;i++) {
8866 pid_t mypid = getpid();
8867 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8869 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8872 if (torture_open_connection(¤t_cli, i)) break;
8874 printf("pid %d failed to start\n", (int)getpid());
8880 child_status[i] = getpid();
8882 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8884 child_status_out[i] = fn(i);
8891 for (i=0;i<torture_nprocs;i++) {
8892 if (child_status[i]) synccount++;
8894 if (synccount == torture_nprocs) break;
8896 } while (timeval_elapsed(&start) < 30);
8898 if (synccount != torture_nprocs) {
8899 printf("FAILED TO START %d CLIENTS (started %d)\n", torture_nprocs, synccount);
8901 return timeval_elapsed(&start);
8904 /* start the client load */
8905 start = timeval_current();
8907 for (i=0;i<torture_nprocs;i++) {
8908 child_status[i] = 0;
8911 printf("%d clients started\n", torture_nprocs);
8913 for (i=0;i<torture_nprocs;i++) {
8914 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8919 for (i=0;i<torture_nprocs;i++) {
8920 if (!child_status_out[i]) {
8924 return timeval_elapsed(&start);
8927 #define FLAG_MULTIPROC 1
8934 {"FDPASS", run_fdpasstest, 0},
8935 {"LOCK1", run_locktest1, 0},
8936 {"LOCK2", run_locktest2, 0},
8937 {"LOCK3", run_locktest3, 0},
8938 {"LOCK4", run_locktest4, 0},
8939 {"LOCK5", run_locktest5, 0},
8940 {"LOCK6", run_locktest6, 0},
8941 {"LOCK7", run_locktest7, 0},
8942 {"LOCK8", run_locktest8, 0},
8943 {"LOCK9", run_locktest9, 0},
8944 {"UNLINK", run_unlinktest, 0},
8945 {"BROWSE", run_browsetest, 0},
8946 {"ATTR", run_attrtest, 0},
8947 {"TRANS2", run_trans2test, 0},
8948 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8949 {"TORTURE",run_torture, FLAG_MULTIPROC},
8950 {"RANDOMIPC", run_randomipc, 0},
8951 {"NEGNOWAIT", run_negprot_nowait, 0},
8952 {"NBENCH", run_nbench, 0},
8953 {"NBENCH2", run_nbench2, 0},
8954 {"OPLOCK1", run_oplock1, 0},
8955 {"OPLOCK2", run_oplock2, 0},
8956 {"OPLOCK4", run_oplock4, 0},
8957 {"DIR", run_dirtest, 0},
8958 {"DIR1", run_dirtest1, 0},
8959 {"DIR-CREATETIME", run_dir_createtime, 0},
8960 {"DENY1", torture_denytest1, 0},
8961 {"DENY2", torture_denytest2, 0},
8962 {"TCON", run_tcon_test, 0},
8963 {"TCONDEV", run_tcon_devtype_test, 0},
8964 {"RW1", run_readwritetest, 0},
8965 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8966 {"RW3", run_readwritelarge, 0},
8967 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8968 {"OPEN", run_opentest, 0},
8969 {"POSIX", run_simple_posix_open_test, 0},
8970 {"POSIX-APPEND", run_posix_append, 0},
8971 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8972 {"ASYNC-ECHO", run_async_echo, 0},
8973 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8974 { "SHORTNAME-TEST", run_shortname_test, 0},
8975 { "ADDRCHANGE", run_addrchange, 0},
8977 {"OPENATTR", run_openattrtest, 0},
8979 {"XCOPY", run_xcopy, 0},
8980 {"RENAME", run_rename, 0},
8981 {"DELETE", run_deletetest, 0},
8982 {"DELETE-LN", run_deletetest_ln, 0},
8983 {"PROPERTIES", run_properties, 0},
8984 {"MANGLE", torture_mangle, 0},
8985 {"MANGLE1", run_mangle1, 0},
8986 {"W2K", run_w2ktest, 0},
8987 {"TRANS2SCAN", torture_trans2_scan, 0},
8988 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8989 {"UTABLE", torture_utable, 0},
8990 {"CASETABLE", torture_casetable, 0},
8991 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8992 {"PIPE_NUMBER", run_pipe_number, 0},
8993 {"TCON2", run_tcon2_test, 0},
8994 {"IOCTL", torture_ioctl_test, 0},
8995 {"CHKPATH", torture_chkpath_test, 0},
8996 {"FDSESS", run_fdsesstest, 0},
8997 { "EATEST", run_eatest, 0},
8998 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8999 { "CHAIN1", run_chain1, 0},
9000 { "CHAIN2", run_chain2, 0},
9001 { "CHAIN3", run_chain3, 0},
9002 { "WINDOWS-WRITE", run_windows_write, 0},
9003 { "NTTRANS-CREATE", run_nttrans_create, 0},
9004 { "NTTRANS-FSCTL", run_nttrans_fsctl, 0},
9005 { "CLI_ECHO", run_cli_echo, 0},
9006 { "GETADDRINFO", run_getaddrinfo_send, 0},
9007 { "TLDAP", run_tldap },
9008 { "STREAMERROR", run_streamerror },
9009 { "NOTIFY-BENCH", run_notify_bench },
9010 { "NOTIFY-BENCH2", run_notify_bench2 },
9011 { "NOTIFY-BENCH3", run_notify_bench3 },
9012 { "BAD-NBT-SESSION", run_bad_nbt_session },
9013 { "SMB-ANY-CONNECT", run_smb_any_connect },
9014 { "NOTIFY-ONLINE", run_notify_online },
9015 { "SMB2-BASIC", run_smb2_basic },
9016 { "SMB2-NEGPROT", run_smb2_negprot },
9017 { "SMB2-SESSION-RECONNECT", run_smb2_session_reconnect },
9018 { "SMB2-TCON-DEPENDENCE", run_smb2_tcon_dependence },
9019 { "SMB2-MULTI-CHANNEL", run_smb2_multi_channel },
9020 { "SMB2-SESSION-REAUTH", run_smb2_session_reauth },
9021 { "CLEANUP1", run_cleanup1 },
9022 { "CLEANUP2", run_cleanup2 },
9023 { "CLEANUP3", run_cleanup3 },
9024 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
9025 { "LOCAL-GENCACHE", run_local_gencache, 0},
9026 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
9027 { "LOCAL-CTDB-CONN", run_ctdb_conn, 0},
9028 { "LOCAL-MSG", run_msg_test, 0},
9029 { "LOCAL-DBWRAP-WATCH1", run_dbwrap_watch1, 0 },
9030 { "LOCAL-BASE64", run_local_base64, 0},
9031 { "LOCAL-RBTREE", run_local_rbtree, 0},
9032 { "LOCAL-MEMCACHE", run_local_memcache, 0},
9033 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
9034 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
9035 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
9036 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
9037 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
9038 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
9039 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
9040 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
9041 { "LOCAL-sprintf_append", run_local_sprintf_append, 0},
9042 { "LOCAL-hex_encode_buf", run_local_hex_encode_buf, 0},
9043 { "LOCAL-IDMAP-TDB-COMMON", run_idmap_tdb_common_test, 0},
9044 { "LOCAL-remove_duplicate_addrs2", run_local_remove_duplicate_addrs2, 0},
9049 /****************************************************************************
9050 run a specified test or "ALL"
9051 ****************************************************************************/
9052 static bool run_test(const char *name)
9059 if (strequal(name,"ALL")) {
9060 for (i=0;torture_ops[i].name;i++) {
9061 run_test(torture_ops[i].name);
9066 for (i=0;torture_ops[i].name;i++) {
9067 fstr_sprintf(randomfname, "\\XX%x",
9068 (unsigned)random());
9070 if (strequal(name, torture_ops[i].name)) {
9072 printf("Running %s\n", name);
9073 if (torture_ops[i].flags & FLAG_MULTIPROC) {
9074 t = create_procs(torture_ops[i].fn, &result);
9077 printf("TEST %s FAILED!\n", name);
9080 struct timeval start;
9081 start = timeval_current();
9082 if (!torture_ops[i].fn(0)) {
9084 printf("TEST %s FAILED!\n", name);
9086 t = timeval_elapsed(&start);
9088 printf("%s took %g secs\n\n", name, t);
9093 printf("Did not find a test named %s\n", name);
9101 static void usage(void)
9105 printf("WARNING samba4 test suite is much more complete nowadays.\n");
9106 printf("Please use samba4 torture.\n\n");
9108 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
9110 printf("\t-d debuglevel\n");
9111 printf("\t-U user%%pass\n");
9112 printf("\t-k use kerberos\n");
9113 printf("\t-N numprocs\n");
9114 printf("\t-n my_netbios_name\n");
9115 printf("\t-W workgroup\n");
9116 printf("\t-o num_operations\n");
9117 printf("\t-O socket_options\n");
9118 printf("\t-m maximum protocol\n");
9119 printf("\t-L use oplocks\n");
9120 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
9121 printf("\t-A showall\n");
9122 printf("\t-p port\n");
9123 printf("\t-s seed\n");
9124 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
9125 printf("\t-f filename filename to test\n");
9128 printf("tests are:");
9129 for (i=0;torture_ops[i].name;i++) {
9130 printf(" %s", torture_ops[i].name);
9134 printf("default test is ALL\n");
9139 /****************************************************************************
9141 ****************************************************************************/
9142 int main(int argc,char *argv[])
9148 bool correct = True;
9149 TALLOC_CTX *frame = talloc_stackframe();
9150 int seed = time(NULL);
9152 #ifdef HAVE_SETBUFFER
9153 setbuffer(stdout, NULL, 0);
9156 setup_logging("smbtorture", DEBUG_STDOUT);
9160 if (is_default_dyn_CONFIGFILE()) {
9161 if(getenv("SMB_CONF_PATH")) {
9162 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
9165 lp_load_global(get_dyn_CONFIGFILE());
9172 for(p = argv[1]; *p; p++)
9176 if (strncmp(argv[1], "//", 2)) {
9180 fstrcpy(host, &argv[1][2]);
9181 p = strchr_m(&host[2],'/');
9186 fstrcpy(share, p+1);
9188 fstrcpy(myname, get_myname(talloc_tos()));
9190 fprintf(stderr, "Failed to get my hostname.\n");
9194 if (*username == 0 && getenv("LOGNAME")) {
9195 fstrcpy(username,getenv("LOGNAME"));
9201 fstrcpy(workgroup, lp_workgroup());
9203 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9207 port_to_use = atoi(optarg);
9210 seed = atoi(optarg);
9213 fstrcpy(workgroup,optarg);
9216 max_protocol = interpret_protocol(optarg, max_protocol);
9219 torture_nprocs = atoi(optarg);
9222 torture_numops = atoi(optarg);
9225 lp_set_cmdline("log level", optarg);
9234 local_path = optarg;
9237 torture_showall = True;
9240 fstrcpy(myname, optarg);
9243 client_txt = optarg;
9250 use_kerberos = True;
9252 d_printf("No kerberos support compiled in\n");
9258 fstrcpy(username,optarg);
9259 p = strchr_m(username,'%');
9262 fstrcpy(password, p+1);
9267 fstrcpy(multishare_conn_fname, optarg);
9268 use_multishare_conn = True;
9271 torture_blocksize = atoi(optarg);
9274 test_filename = SMB_STRDUP(optarg);
9277 printf("Unknown option %c (%d)\n", (char)opt, opt);
9282 d_printf("using seed %d\n", seed);
9286 if(use_kerberos && !gotuser) gotpass = True;
9289 p = getpass("Password:");
9291 fstrcpy(password, p);
9296 printf("host=%s share=%s user=%s myname=%s\n",
9297 host, share, username, myname);
9299 if (argc == optind) {
9300 correct = run_test("ALL");
9302 for (i=optind;i<argc;i++) {
9303 if (!run_test(argv[i])) {