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 "talloc_dict.h"
34 #include "async_smb.h"
35 #include "libsmb/libsmb.h"
36 #include "libsmb/clirap.h"
38 #include "libsmb/nmblib.h"
39 #include "../lib/util/tevent_ntstatus.h"
41 #include "libsmb/read_smb.h"
46 fstring host, workgroup, share, password, username, myname;
47 static int max_protocol = PROTOCOL_NT1;
48 static const char *sockops="TCP_NODELAY";
50 static int port_to_use=0;
51 int torture_numops=100;
52 int torture_blocksize=1024*1024;
53 static int procnum; /* records process count number when forking */
54 static struct cli_state *current_cli;
55 static fstring randomfname;
56 static bool use_oplocks;
57 static bool use_level_II_oplocks;
58 static const char *client_txt = "client_oplocks.txt";
59 static bool disable_spnego;
60 static bool use_kerberos;
61 static bool force_dos_errors;
62 static fstring multishare_conn_fname;
63 static bool use_multishare_conn = False;
64 static bool do_encrypt;
65 static const char *local_path = NULL;
66 static int signing_state = Undefined;
69 bool torture_showall = False;
71 static double create_procs(bool (*fn)(int), bool *result);
74 /* return a pointer to a anonymous shared memory segment of size "size"
75 which will persist across fork() but will disappear when all processes
78 The memory is not zeroed
80 This function uses system5 shared memory. It takes advantage of a property
81 that the memory is not destroyed if it is attached when the id is removed
83 void *shm_setup(int size)
89 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
91 printf("can't get shared memory\n");
94 shm_unlink("private");
95 if (ftruncate(shmid, size) == -1) {
96 printf("can't set shared memory size\n");
99 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
100 if (ret == MAP_FAILED) {
101 printf("can't map shared memory\n");
105 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
107 printf("can't get shared memory\n");
110 ret = (void *)shmat(shmid, 0, 0);
111 if (!ret || ret == (void *)-1) {
112 printf("can't attach to shared memory\n");
115 /* the following releases the ipc, but note that this process
116 and all its children will still have access to the memory, its
117 just that the shmid is no longer valid for other shm calls. This
118 means we don't leave behind lots of shm segments after we exit
120 See Stevens "advanced programming in unix env" for details
122 shmctl(shmid, IPC_RMID, 0);
128 /********************************************************************
129 Ensure a connection is encrypted.
130 ********************************************************************/
132 static bool force_cli_encryption(struct cli_state *c,
133 const char *sharename)
136 uint32 caplow, caphigh;
139 if (!SERVER_HAS_UNIX_CIFS(c)) {
140 d_printf("Encryption required and "
141 "server that doesn't support "
142 "UNIX extensions - failing connect\n");
146 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
148 if (!NT_STATUS_IS_OK(status)) {
149 d_printf("Encryption required and "
150 "can't get UNIX CIFS extensions "
151 "version from server: %s\n", nt_errstr(status));
155 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
156 d_printf("Encryption required and "
157 "share %s doesn't support "
158 "encryption.\n", sharename);
162 if (c->use_kerberos) {
163 status = cli_gss_smb_encryption_start(c);
165 status = cli_raw_ntlm_smb_encryption_start(c,
171 if (!NT_STATUS_IS_OK(status)) {
172 d_printf("Encryption required and "
173 "setup failed with error %s.\n",
182 static struct cli_state *open_nbt_connection(void)
188 if (disable_spnego) {
189 flags |= CLI_FULL_CONNECTION_DONT_SPNEGO;
193 flags |= CLI_FULL_CONNECTION_OPLOCKS;
196 if (use_level_II_oplocks) {
197 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
201 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
204 if (force_dos_errors) {
205 flags |= CLI_FULL_CONNECTION_FORCE_DOS_ERRORS;
208 status = cli_connect_nb(host, NULL, port_to_use, 0x20, myname,
209 signing_state, flags, &c);
210 if (!NT_STATUS_IS_OK(status)) {
211 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
215 cli_set_timeout(c, 120000); /* set a really long timeout (2 minutes) */
220 /****************************************************************************
221 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
222 ****************************************************************************/
224 static bool cli_bad_session_request(int fd,
225 struct nmb_name *calling, struct nmb_name *called)
234 uint8_t message_type;
237 frame = talloc_stackframe();
239 iov[0].iov_base = len_buf;
240 iov[0].iov_len = sizeof(len_buf);
242 /* put in the destination name */
244 iov[1].iov_base = name_mangle(talloc_tos(), called->name,
246 if (iov[1].iov_base == NULL) {
249 iov[1].iov_len = name_len((unsigned char *)iov[1].iov_base,
250 talloc_get_size(iov[1].iov_base));
254 iov[2].iov_base = name_mangle(talloc_tos(), calling->name,
256 if (iov[2].iov_base == NULL) {
259 iov[2].iov_len = name_len((unsigned char *)iov[2].iov_base,
260 talloc_get_size(iov[2].iov_base));
262 /* Deliberately corrupt the name len (first byte) */
263 *((uint8_t *)iov[2].iov_base) = 100;
265 /* send a session request (RFC 1002) */
266 /* setup the packet length
267 * Remove four bytes from the length count, since the length
268 * field in the NBT Session Service header counts the number
269 * of bytes which follow. The cli_send_smb() function knows
270 * about this and accounts for those four bytes.
274 _smb_setlen(len_buf, iov[1].iov_len + iov[2].iov_len);
275 SCVAL(len_buf,0,0x81);
277 len = write_data_iov(fd, iov, 3);
281 len = read_smb(fd, talloc_tos(), &inbuf, &err);
287 message_type = CVAL(inbuf, 0);
288 if (message_type != 0x83) {
289 d_fprintf(stderr, "Expected msg type 0x83, got 0x%2.2x\n",
294 if (smb_len(inbuf) != 1) {
295 d_fprintf(stderr, "Expected smb_len 1, got %d\n",
296 (int)smb_len(inbuf));
300 error = CVAL(inbuf, 4);
302 d_fprintf(stderr, "Expected error 0x82, got %d\n",
313 /* Insert a NULL at the first separator of the given path and return a pointer
314 * to the remainder of the string.
317 terminate_path_at_separator(char * path)
325 if ((p = strchr_m(path, '/'))) {
330 if ((p = strchr_m(path, '\\'))) {
340 parse a //server/share type UNC name
342 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
343 char **hostname, char **sharename)
347 *hostname = *sharename = NULL;
349 if (strncmp(unc_name, "\\\\", 2) &&
350 strncmp(unc_name, "//", 2)) {
354 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
355 p = terminate_path_at_separator(*hostname);
358 *sharename = talloc_strdup(mem_ctx, p);
359 terminate_path_at_separator(*sharename);
362 if (*hostname && *sharename) {
366 TALLOC_FREE(*hostname);
367 TALLOC_FREE(*sharename);
371 static bool torture_open_connection_share(struct cli_state **c,
372 const char *hostname,
373 const char *sharename)
379 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
381 flags |= CLI_FULL_CONNECTION_OPLOCKS;
382 if (use_level_II_oplocks)
383 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
385 status = cli_full_connection(c, myname,
386 hostname, NULL, port_to_use,
389 password, flags, signing_state);
390 if (!NT_STATUS_IS_OK(status)) {
391 printf("failed to open share connection: //%s/%s port:%d - %s\n",
392 hostname, sharename, port_to_use, nt_errstr(status));
396 cli_set_timeout(*c, 120000); /* set a really long timeout (2 minutes) */
399 return force_cli_encryption(*c,
405 bool torture_open_connection(struct cli_state **c, int conn_index)
407 char **unc_list = NULL;
408 int num_unc_names = 0;
411 if (use_multishare_conn==True) {
413 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
414 if (!unc_list || num_unc_names <= 0) {
415 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
419 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
421 printf("Failed to parse UNC name %s\n",
422 unc_list[conn_index % num_unc_names]);
423 TALLOC_FREE(unc_list);
427 result = torture_open_connection_share(c, h, s);
429 /* h, s were copied earlier */
430 TALLOC_FREE(unc_list);
434 return torture_open_connection_share(c, host, share);
437 bool torture_init_connection(struct cli_state **pcli)
439 struct cli_state *cli;
441 cli = open_nbt_connection();
450 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
452 uint16_t old_vuid = cli_state_get_uid(cli);
453 fstring old_user_name;
454 size_t passlen = strlen(password);
458 fstrcpy(old_user_name, cli->user_name);
459 cli_state_set_uid(cli, 0);
460 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
464 *new_vuid = cli_state_get_uid(cli);
465 cli_state_set_uid(cli, old_vuid);
466 status = cli_set_username(cli, old_user_name);
467 if (!NT_STATUS_IS_OK(status)) {
474 bool torture_close_connection(struct cli_state *c)
479 status = cli_tdis(c);
480 if (!NT_STATUS_IS_OK(status)) {
481 printf("tdis failed (%s)\n", nt_errstr(status));
491 /* check if the server produced the expected dos or nt error code */
492 static bool check_both_error(int line, NTSTATUS status,
493 uint8 eclass, uint32 ecode, NTSTATUS nterr)
495 if (NT_STATUS_IS_DOS(status)) {
499 /* Check DOS error */
500 cclass = NT_STATUS_DOS_CLASS(status);
501 num = NT_STATUS_DOS_CODE(status);
503 if (eclass != cclass || ecode != num) {
504 printf("unexpected error code class=%d code=%d\n",
505 (int)cclass, (int)num);
506 printf(" expected %d/%d %s (line=%d)\n",
507 (int)eclass, (int)ecode, nt_errstr(nterr), line);
512 if (!NT_STATUS_EQUAL(nterr, status)) {
513 printf("unexpected error code %s\n",
515 printf(" expected %s (line=%d)\n",
516 nt_errstr(nterr), line);
525 /* check if the server produced the expected error code */
526 static bool check_error(int line, NTSTATUS status,
527 uint8 eclass, uint32 ecode, NTSTATUS nterr)
529 if (NT_STATUS_IS_DOS(status)) {
533 /* Check DOS error */
535 cclass = NT_STATUS_DOS_CLASS(status);
536 num = NT_STATUS_DOS_CODE(status);
538 if (eclass != cclass || ecode != num) {
539 printf("unexpected error code class=%d code=%d\n",
540 (int)cclass, (int)num);
541 printf(" expected %d/%d %s (line=%d)\n",
542 (int)eclass, (int)ecode, nt_errstr(nterr),
550 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
551 printf("unexpected error code %s\n",
553 printf(" expected %s (line=%d)\n", nt_errstr(nterr),
563 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
567 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
569 while (!NT_STATUS_IS_OK(status)) {
570 if (!check_both_error(__LINE__, status, ERRDOS,
571 ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) {
575 status = cli_lock32(c, fnum, offset, len, -1, WRITE_LOCK);
582 static bool rw_torture(struct cli_state *c)
584 const char *lockfname = "\\torture.lck";
588 pid_t pid2, pid = getpid();
595 memset(buf, '\0', sizeof(buf));
597 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
599 if (!NT_STATUS_IS_OK(status)) {
600 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
602 if (!NT_STATUS_IS_OK(status)) {
603 printf("open of %s failed (%s)\n",
604 lockfname, nt_errstr(status));
608 for (i=0;i<torture_numops;i++) {
609 unsigned n = (unsigned)sys_random()%10;
612 printf("%d\r", i); fflush(stdout);
614 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
616 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
620 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
622 if (!NT_STATUS_IS_OK(status)) {
623 printf("open failed (%s)\n", nt_errstr(status));
628 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
630 if (!NT_STATUS_IS_OK(status)) {
631 printf("write failed (%s)\n", nt_errstr(status));
636 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
637 sizeof(pid)+(j*sizeof(buf)),
639 if (!NT_STATUS_IS_OK(status)) {
640 printf("write failed (%s)\n",
648 status = cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid),
650 if (!NT_STATUS_IS_OK(status)) {
651 printf("read failed (%s)\n", nt_errstr(status));
653 } else if (nread != sizeof(pid)) {
654 printf("read/write compare failed: "
655 "recv %ld req %ld\n", (unsigned long)nread,
656 (unsigned long)sizeof(pid));
661 printf("data corruption!\n");
665 status = cli_close(c, fnum);
666 if (!NT_STATUS_IS_OK(status)) {
667 printf("close failed (%s)\n", nt_errstr(status));
671 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
672 if (!NT_STATUS_IS_OK(status)) {
673 printf("unlink failed (%s)\n", nt_errstr(status));
677 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
678 if (!NT_STATUS_IS_OK(status)) {
679 printf("unlock failed (%s)\n", nt_errstr(status));
685 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
692 static bool run_torture(int dummy)
694 struct cli_state *cli;
699 cli_sockopt(cli, sockops);
701 ret = rw_torture(cli);
703 if (!torture_close_connection(cli)) {
710 static bool rw_torture3(struct cli_state *c, char *lockfname)
712 uint16_t fnum = (uint16_t)-1;
717 unsigned countprev = 0;
720 NTSTATUS status = NT_STATUS_OK;
723 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
725 SIVAL(buf, i, sys_random());
732 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
733 if (!NT_STATUS_IS_OK(status)) {
734 printf("unlink failed (%s) (normal, this file should "
735 "not exist)\n", nt_errstr(status));
738 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("first open read/write of %s failed (%s)\n",
742 lockfname, nt_errstr(status));
748 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
750 status = cli_open(c, lockfname, O_RDONLY,
752 if (!NT_STATUS_IS_OK(status)) {
757 if (!NT_STATUS_IS_OK(status)) {
758 printf("second open read-only of %s failed (%s)\n",
759 lockfname, nt_errstr(status));
765 for (count = 0; count < sizeof(buf); count += sent)
767 if (count >= countprev) {
768 printf("%d %8d\r", i, count);
771 countprev += (sizeof(buf) / 20);
776 sent = ((unsigned)sys_random()%(20))+ 1;
777 if (sent > sizeof(buf) - count)
779 sent = sizeof(buf) - count;
782 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
784 if (!NT_STATUS_IS_OK(status)) {
785 printf("write failed (%s)\n",
792 status = cli_read(c, fnum, buf_rd+count, count,
793 sizeof(buf)-count, &sent);
794 if(!NT_STATUS_IS_OK(status)) {
795 printf("read failed offset:%d size:%ld (%s)\n",
796 count, (unsigned long)sizeof(buf)-count,
800 } else if (sent > 0) {
801 if (memcmp(buf_rd+count, buf+count, sent) != 0)
803 printf("read/write compare failed\n");
804 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
813 status = cli_close(c, fnum);
814 if (!NT_STATUS_IS_OK(status)) {
815 printf("close failed (%s)\n", nt_errstr(status));
822 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
824 const char *lockfname = "\\torture2.lck";
834 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
835 if (!NT_STATUS_IS_OK(status)) {
836 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
839 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
841 if (!NT_STATUS_IS_OK(status)) {
842 printf("first open read/write of %s failed (%s)\n",
843 lockfname, nt_errstr(status));
847 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
848 if (!NT_STATUS_IS_OK(status)) {
849 printf("second open read-only of %s failed (%s)\n",
850 lockfname, nt_errstr(status));
851 cli_close(c1, fnum1);
855 for (i = 0; i < torture_numops; i++)
857 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
859 printf("%d\r", i); fflush(stdout);
862 generate_random_buffer((unsigned char *)buf, buf_size);
864 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
866 if (!NT_STATUS_IS_OK(status)) {
867 printf("write failed (%s)\n", nt_errstr(status));
872 status = cli_read(c2, fnum2, buf_rd, 0, buf_size, &bytes_read);
873 if(!NT_STATUS_IS_OK(status)) {
874 printf("read failed (%s)\n", nt_errstr(status));
877 } else if (bytes_read != buf_size) {
878 printf("read failed\n");
879 printf("read %ld, expected %ld\n",
880 (unsigned long)bytes_read,
881 (unsigned long)buf_size);
886 if (memcmp(buf_rd, buf, buf_size) != 0)
888 printf("read/write compare failed\n");
894 status = cli_close(c2, fnum2);
895 if (!NT_STATUS_IS_OK(status)) {
896 printf("close failed (%s)\n", nt_errstr(status));
900 status = cli_close(c1, fnum1);
901 if (!NT_STATUS_IS_OK(status)) {
902 printf("close failed (%s)\n", nt_errstr(status));
906 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
907 if (!NT_STATUS_IS_OK(status)) {
908 printf("unlink failed (%s)\n", nt_errstr(status));
915 static bool run_readwritetest(int dummy)
917 struct cli_state *cli1, *cli2;
918 bool test1, test2 = False;
920 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
923 cli_sockopt(cli1, sockops);
924 cli_sockopt(cli2, sockops);
926 printf("starting readwritetest\n");
928 test1 = rw_torture2(cli1, cli2);
929 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
932 test2 = rw_torture2(cli1, cli1);
933 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
936 if (!torture_close_connection(cli1)) {
940 if (!torture_close_connection(cli2)) {
944 return (test1 && test2);
947 static bool run_readwritemulti(int dummy)
949 struct cli_state *cli;
954 cli_sockopt(cli, sockops);
956 printf("run_readwritemulti: fname %s\n", randomfname);
957 test = rw_torture3(cli, randomfname);
959 if (!torture_close_connection(cli)) {
966 static bool run_readwritelarge_internal(void)
968 static struct cli_state *cli1;
970 const char *lockfname = "\\large.dat";
976 if (!torture_open_connection(&cli1, 0)) {
979 cli_sockopt(cli1, sockops);
980 memset(buf,'\0',sizeof(buf));
982 if (signing_state == Required) {
983 /* Horrible cheat to force
984 multiple signed outstanding
985 packets against a Samba server.
987 cli1->is_samba = false;
990 printf("starting readwritelarge_internal\n");
992 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
994 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
996 if (!NT_STATUS_IS_OK(status)) {
997 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1001 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
1003 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1005 if (!NT_STATUS_IS_OK(status)) {
1006 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1010 if (fsize == sizeof(buf))
1011 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
1012 (unsigned long)fsize);
1014 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
1015 (unsigned long)fsize);
1019 status = cli_close(cli1, fnum1);
1020 if (!NT_STATUS_IS_OK(status)) {
1021 printf("close failed (%s)\n", nt_errstr(status));
1025 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1026 if (!NT_STATUS_IS_OK(status)) {
1027 printf("unlink failed (%s)\n", nt_errstr(status));
1031 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
1033 if (!NT_STATUS_IS_OK(status)) {
1034 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1038 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
1040 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1042 if (!NT_STATUS_IS_OK(status)) {
1043 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1047 if (fsize == sizeof(buf))
1048 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1049 (unsigned long)fsize);
1051 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1052 (unsigned long)fsize);
1057 /* ToDo - set allocation. JRA */
1058 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1059 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1062 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1064 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1068 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1071 status = cli_close(cli1, fnum1);
1072 if (!NT_STATUS_IS_OK(status)) {
1073 printf("close failed (%s)\n", nt_errstr(status));
1077 if (!torture_close_connection(cli1)) {
1083 static bool run_readwritelarge(int dummy)
1085 return run_readwritelarge_internal();
1088 static bool run_readwritelarge_signtest(int dummy)
1091 signing_state = Required;
1092 ret = run_readwritelarge_internal();
1093 signing_state = Undefined;
1100 #define ival(s) strtol(s, NULL, 0)
1102 /* run a test that simulates an approximate netbench client load */
1103 static bool run_netbench(int client)
1105 struct cli_state *cli;
1110 const char *params[20];
1111 bool correct = True;
1117 cli_sockopt(cli, sockops);
1121 slprintf(cname,sizeof(cname)-1, "client%d", client);
1123 f = fopen(client_txt, "r");
1130 while (fgets(line, sizeof(line)-1, f)) {
1134 line[strlen(line)-1] = 0;
1136 /* printf("[%d] %s\n", line_count, line); */
1138 all_string_sub(line,"client1", cname, sizeof(line));
1140 /* parse the command parameters */
1141 params[0] = strtok_r(line, " ", &saveptr);
1143 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1147 if (i < 2) continue;
1149 if (!strncmp(params[0],"SMB", 3)) {
1150 printf("ERROR: You are using a dbench 1 load file\n");
1154 if (!strcmp(params[0],"NTCreateX")) {
1155 nb_createx(params[1], ival(params[2]), ival(params[3]),
1157 } else if (!strcmp(params[0],"Close")) {
1158 nb_close(ival(params[1]));
1159 } else if (!strcmp(params[0],"Rename")) {
1160 nb_rename(params[1], params[2]);
1161 } else if (!strcmp(params[0],"Unlink")) {
1162 nb_unlink(params[1]);
1163 } else if (!strcmp(params[0],"Deltree")) {
1164 nb_deltree(params[1]);
1165 } else if (!strcmp(params[0],"Rmdir")) {
1166 nb_rmdir(params[1]);
1167 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1168 nb_qpathinfo(params[1]);
1169 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1170 nb_qfileinfo(ival(params[1]));
1171 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1172 nb_qfsinfo(ival(params[1]));
1173 } else if (!strcmp(params[0],"FIND_FIRST")) {
1174 nb_findfirst(params[1]);
1175 } else if (!strcmp(params[0],"WriteX")) {
1176 nb_writex(ival(params[1]),
1177 ival(params[2]), ival(params[3]), ival(params[4]));
1178 } else if (!strcmp(params[0],"ReadX")) {
1179 nb_readx(ival(params[1]),
1180 ival(params[2]), ival(params[3]), ival(params[4]));
1181 } else if (!strcmp(params[0],"Flush")) {
1182 nb_flush(ival(params[1]));
1184 printf("Unknown operation %s\n", params[0]);
1192 if (!torture_close_connection(cli)) {
1200 /* run a test that simulates an approximate netbench client load */
1201 static bool run_nbench(int dummy)
1204 bool correct = True;
1210 signal(SIGALRM, nb_alarm);
1212 t = create_procs(run_netbench, &correct);
1215 printf("\nThroughput %g MB/sec\n",
1216 1.0e-6 * nbio_total() / t);
1222 This test checks for two things:
1224 1) correct support for retaining locks over a close (ie. the server
1225 must not use posix semantics)
1226 2) support for lock timeouts
1228 static bool run_locktest1(int dummy)
1230 struct cli_state *cli1, *cli2;
1231 const char *fname = "\\lockt1.lck";
1232 uint16_t fnum1, fnum2, fnum3;
1234 unsigned lock_timeout;
1237 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1240 cli_sockopt(cli1, sockops);
1241 cli_sockopt(cli2, sockops);
1243 printf("starting locktest1\n");
1245 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1247 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1249 if (!NT_STATUS_IS_OK(status)) {
1250 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1254 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1260 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1261 if (!NT_STATUS_IS_OK(status)) {
1262 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1266 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
1267 if (!NT_STATUS_IS_OK(status)) {
1268 printf("lock1 failed (%s)\n", nt_errstr(status));
1272 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1273 if (NT_STATUS_IS_OK(status)) {
1274 printf("lock2 succeeded! This is a locking bug\n");
1277 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1278 NT_STATUS_LOCK_NOT_GRANTED)) {
1283 lock_timeout = (1 + (random() % 20));
1284 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1286 status = cli_lock32(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK);
1287 if (NT_STATUS_IS_OK(status)) {
1288 printf("lock3 succeeded! This is a locking bug\n");
1291 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1292 NT_STATUS_FILE_LOCK_CONFLICT)) {
1298 if (ABS(t2 - t1) < lock_timeout-1) {
1299 printf("error: This server appears not to support timed lock requests\n");
1302 printf("server slept for %u seconds for a %u second timeout\n",
1303 (unsigned int)(t2-t1), lock_timeout);
1305 status = cli_close(cli1, fnum2);
1306 if (!NT_STATUS_IS_OK(status)) {
1307 printf("close1 failed (%s)\n", nt_errstr(status));
1311 status = cli_lock32(cli2, fnum3, 0, 4, 0, WRITE_LOCK);
1312 if (NT_STATUS_IS_OK(status)) {
1313 printf("lock4 succeeded! This is a locking bug\n");
1316 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1317 NT_STATUS_FILE_LOCK_CONFLICT)) {
1322 status = cli_close(cli1, fnum1);
1323 if (!NT_STATUS_IS_OK(status)) {
1324 printf("close2 failed (%s)\n", nt_errstr(status));
1328 status = cli_close(cli2, fnum3);
1329 if (!NT_STATUS_IS_OK(status)) {
1330 printf("close3 failed (%s)\n", nt_errstr(status));
1334 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1335 if (!NT_STATUS_IS_OK(status)) {
1336 printf("unlink failed (%s)\n", nt_errstr(status));
1341 if (!torture_close_connection(cli1)) {
1345 if (!torture_close_connection(cli2)) {
1349 printf("Passed locktest1\n");
1354 this checks to see if a secondary tconx can use open files from an
1357 static bool run_tcon_test(int dummy)
1359 static struct cli_state *cli;
1360 const char *fname = "\\tcontest.tmp";
1362 uint16 cnum1, cnum2, cnum3;
1363 uint16 vuid1, vuid2;
1368 memset(buf, '\0', sizeof(buf));
1370 if (!torture_open_connection(&cli, 0)) {
1373 cli_sockopt(cli, sockops);
1375 printf("starting tcontest\n");
1377 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1379 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1380 if (!NT_STATUS_IS_OK(status)) {
1381 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1385 cnum1 = cli_state_get_tid(cli);
1386 vuid1 = cli_state_get_uid(cli);
1388 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1389 if (!NT_STATUS_IS_OK(status)) {
1390 printf("initial write failed (%s)", nt_errstr(status));
1394 status = cli_tcon_andx(cli, share, "?????",
1395 password, strlen(password)+1);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 printf("%s refused 2nd tree connect (%s)\n", host,
1403 cnum2 = cli_state_get_tid(cli);
1404 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1405 vuid2 = cli_state_get_uid(cli) + 1;
1407 /* try a write with the wrong tid */
1408 cli_state_set_tid(cli, cnum2);
1410 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1411 if (NT_STATUS_IS_OK(status)) {
1412 printf("* server allows write with wrong TID\n");
1415 printf("server fails write with wrong TID : %s\n",
1420 /* try a write with an invalid tid */
1421 cli_state_set_tid(cli, cnum3);
1423 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1424 if (NT_STATUS_IS_OK(status)) {
1425 printf("* server allows write with invalid TID\n");
1428 printf("server fails write with invalid TID : %s\n",
1432 /* try a write with an invalid vuid */
1433 cli_state_set_uid(cli, vuid2);
1434 cli_state_set_tid(cli, cnum1);
1436 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1437 if (NT_STATUS_IS_OK(status)) {
1438 printf("* server allows write with invalid VUID\n");
1441 printf("server fails write with invalid VUID : %s\n",
1445 cli_state_set_tid(cli, cnum1);
1446 cli_state_set_uid(cli, vuid1);
1448 status = cli_close(cli, fnum1);
1449 if (!NT_STATUS_IS_OK(status)) {
1450 printf("close failed (%s)\n", nt_errstr(status));
1454 cli_state_set_tid(cli, cnum2);
1456 status = cli_tdis(cli);
1457 if (!NT_STATUS_IS_OK(status)) {
1458 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1462 cli_state_set_tid(cli, cnum1);
1464 if (!torture_close_connection(cli)) {
1473 checks for old style tcon support
1475 static bool run_tcon2_test(int dummy)
1477 static struct cli_state *cli;
1478 uint16 cnum, max_xmit;
1482 if (!torture_open_connection(&cli, 0)) {
1485 cli_sockopt(cli, sockops);
1487 printf("starting tcon2 test\n");
1489 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1493 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1497 if (!NT_STATUS_IS_OK(status)) {
1498 printf("tcon2 failed : %s\n", nt_errstr(status));
1500 printf("tcon OK : max_xmit=%d cnum=%d\n",
1501 (int)max_xmit, (int)cnum);
1504 if (!torture_close_connection(cli)) {
1508 printf("Passed tcon2 test\n");
1512 static bool tcon_devtest(struct cli_state *cli,
1513 const char *myshare, const char *devtype,
1514 const char *return_devtype,
1515 NTSTATUS expected_error)
1520 status = cli_tcon_andx(cli, myshare, devtype,
1521 password, strlen(password)+1);
1523 if (NT_STATUS_IS_OK(expected_error)) {
1524 if (NT_STATUS_IS_OK(status)) {
1525 if (strcmp(cli->dev, return_devtype) == 0) {
1528 printf("tconX to share %s with type %s "
1529 "succeeded but returned the wrong "
1530 "device type (got [%s] but should have got [%s])\n",
1531 myshare, devtype, cli->dev, return_devtype);
1535 printf("tconX to share %s with type %s "
1536 "should have succeeded but failed\n",
1542 if (NT_STATUS_IS_OK(status)) {
1543 printf("tconx to share %s with type %s "
1544 "should have failed but succeeded\n",
1548 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1552 printf("Returned unexpected error\n");
1561 checks for correct tconX support
1563 static bool run_tcon_devtype_test(int dummy)
1565 static struct cli_state *cli1 = NULL;
1570 status = cli_full_connection(&cli1, myname,
1571 host, NULL, port_to_use,
1573 username, workgroup,
1574 password, flags, signing_state);
1576 if (!NT_STATUS_IS_OK(status)) {
1577 printf("could not open connection\n");
1581 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1584 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1587 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1590 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1593 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1596 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1599 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1602 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1605 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1608 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1614 printf("Passed tcondevtest\n");
1621 This test checks that
1623 1) the server supports multiple locking contexts on the one SMB
1624 connection, distinguished by PID.
1626 2) the server correctly fails overlapping locks made by the same PID (this
1627 goes against POSIX behaviour, which is why it is tricky to implement)
1629 3) the server denies unlock requests by an incorrect client PID
1631 static bool run_locktest2(int dummy)
1633 static struct cli_state *cli;
1634 const char *fname = "\\lockt2.lck";
1635 uint16_t fnum1, fnum2, fnum3;
1636 bool correct = True;
1639 if (!torture_open_connection(&cli, 0)) {
1643 cli_sockopt(cli, sockops);
1645 printf("starting locktest2\n");
1647 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1651 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1652 if (!NT_STATUS_IS_OK(status)) {
1653 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1657 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1658 if (!NT_STATUS_IS_OK(status)) {
1659 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1665 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1666 if (!NT_STATUS_IS_OK(status)) {
1667 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1673 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1674 if (!NT_STATUS_IS_OK(status)) {
1675 printf("lock1 failed (%s)\n", nt_errstr(status));
1679 status = cli_lock32(cli, fnum1, 0, 4, 0, WRITE_LOCK);
1680 if (NT_STATUS_IS_OK(status)) {
1681 printf("WRITE lock1 succeeded! This is a locking bug\n");
1684 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1685 NT_STATUS_LOCK_NOT_GRANTED)) {
1690 status = cli_lock32(cli, fnum2, 0, 4, 0, WRITE_LOCK);
1691 if (NT_STATUS_IS_OK(status)) {
1692 printf("WRITE lock2 succeeded! This is a locking bug\n");
1695 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1696 NT_STATUS_LOCK_NOT_GRANTED)) {
1701 status = cli_lock32(cli, fnum2, 0, 4, 0, READ_LOCK);
1702 if (NT_STATUS_IS_OK(status)) {
1703 printf("READ lock2 succeeded! This is a locking bug\n");
1706 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1707 NT_STATUS_FILE_LOCK_CONFLICT)) {
1712 status = cli_lock32(cli, fnum1, 100, 4, 0, WRITE_LOCK);
1713 if (!NT_STATUS_IS_OK(status)) {
1714 printf("lock at 100 failed (%s)\n", nt_errstr(status));
1717 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1718 printf("unlock at 100 succeeded! This is a locking bug\n");
1722 status = cli_unlock(cli, fnum1, 0, 4);
1723 if (NT_STATUS_IS_OK(status)) {
1724 printf("unlock1 succeeded! This is a locking bug\n");
1727 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1728 NT_STATUS_RANGE_NOT_LOCKED)) {
1733 status = cli_unlock(cli, fnum1, 0, 8);
1734 if (NT_STATUS_IS_OK(status)) {
1735 printf("unlock2 succeeded! This is a locking bug\n");
1738 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1739 NT_STATUS_RANGE_NOT_LOCKED)) {
1744 status = cli_lock32(cli, fnum3, 0, 4, 0, WRITE_LOCK);
1745 if (NT_STATUS_IS_OK(status)) {
1746 printf("lock3 succeeded! This is a locking bug\n");
1749 if (!check_both_error(__LINE__, status, ERRDOS, ERRlock,
1750 NT_STATUS_LOCK_NOT_GRANTED)) {
1757 status = cli_close(cli, fnum1);
1758 if (!NT_STATUS_IS_OK(status)) {
1759 printf("close1 failed (%s)\n", nt_errstr(status));
1763 status = cli_close(cli, fnum2);
1764 if (!NT_STATUS_IS_OK(status)) {
1765 printf("close2 failed (%s)\n", nt_errstr(status));
1769 status = cli_close(cli, fnum3);
1770 if (!NT_STATUS_IS_OK(status)) {
1771 printf("close3 failed (%s)\n", nt_errstr(status));
1775 if (!torture_close_connection(cli)) {
1779 printf("locktest2 finished\n");
1786 This test checks that
1788 1) the server supports the full offset range in lock requests
1790 static bool run_locktest3(int dummy)
1792 static struct cli_state *cli1, *cli2;
1793 const char *fname = "\\lockt3.lck";
1794 uint16_t fnum1, fnum2;
1797 bool correct = True;
1800 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1802 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1805 cli_sockopt(cli1, sockops);
1806 cli_sockopt(cli2, sockops);
1808 printf("starting locktest3\n");
1810 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1812 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1814 if (!NT_STATUS_IS_OK(status)) {
1815 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1819 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1820 if (!NT_STATUS_IS_OK(status)) {
1821 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1825 for (offset=i=0;i<torture_numops;i++) {
1828 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1829 if (!NT_STATUS_IS_OK(status)) {
1830 printf("lock1 %d failed (%s)\n",
1836 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1837 if (!NT_STATUS_IS_OK(status)) {
1838 printf("lock2 %d failed (%s)\n",
1845 for (offset=i=0;i<torture_numops;i++) {
1848 status = cli_lock32(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK);
1849 if (NT_STATUS_IS_OK(status)) {
1850 printf("error: lock1 %d succeeded!\n", i);
1854 status = cli_lock32(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK);
1855 if (NT_STATUS_IS_OK(status)) {
1856 printf("error: lock2 %d succeeded!\n", i);
1860 status = cli_lock32(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK);
1861 if (NT_STATUS_IS_OK(status)) {
1862 printf("error: lock3 %d succeeded!\n", i);
1866 status = cli_lock32(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK);
1867 if (NT_STATUS_IS_OK(status)) {
1868 printf("error: lock4 %d succeeded!\n", i);
1873 for (offset=i=0;i<torture_numops;i++) {
1876 status = cli_unlock(cli1, fnum1, offset-1, 1);
1877 if (!NT_STATUS_IS_OK(status)) {
1878 printf("unlock1 %d failed (%s)\n",
1884 status = cli_unlock(cli2, fnum2, offset-2, 1);
1885 if (!NT_STATUS_IS_OK(status)) {
1886 printf("unlock2 %d failed (%s)\n",
1893 status = cli_close(cli1, fnum1);
1894 if (!NT_STATUS_IS_OK(status)) {
1895 printf("close1 failed (%s)\n", nt_errstr(status));
1899 status = cli_close(cli2, fnum2);
1900 if (!NT_STATUS_IS_OK(status)) {
1901 printf("close2 failed (%s)\n", nt_errstr(status));
1905 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1906 if (!NT_STATUS_IS_OK(status)) {
1907 printf("unlink failed (%s)\n", nt_errstr(status));
1911 if (!torture_close_connection(cli1)) {
1915 if (!torture_close_connection(cli2)) {
1919 printf("finished locktest3\n");
1924 static bool test_cli_read(struct cli_state *cli, uint16_t fnum,
1925 char *buf, off_t offset, size_t size,
1926 size_t *nread, size_t expect)
1931 status = cli_read(cli, fnum, buf, offset, size, &l_nread);
1933 if(!NT_STATUS_IS_OK(status)) {
1935 } else if (l_nread != expect) {
1946 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1947 printf("** "); correct = False; \
1951 looks at overlapping locks
1953 static bool run_locktest4(int dummy)
1955 static struct cli_state *cli1, *cli2;
1956 const char *fname = "\\lockt4.lck";
1957 uint16_t fnum1, fnum2, f;
1960 bool correct = True;
1963 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1967 cli_sockopt(cli1, sockops);
1968 cli_sockopt(cli2, sockops);
1970 printf("starting locktest4\n");
1972 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1974 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1975 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1977 memset(buf, 0, sizeof(buf));
1979 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1981 if (!NT_STATUS_IS_OK(status)) {
1982 printf("Failed to create file: %s\n", nt_errstr(status));
1987 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
1988 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 2, 4, 0, WRITE_LOCK));
1989 EXPECTED(ret, False);
1990 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1992 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 10, 4, 0, READ_LOCK)) &&
1993 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 12, 4, 0, READ_LOCK));
1994 EXPECTED(ret, True);
1995 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1997 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 20, 4, 0, WRITE_LOCK)) &&
1998 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 22, 4, 0, WRITE_LOCK));
1999 EXPECTED(ret, False);
2000 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
2002 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 30, 4, 0, READ_LOCK)) &&
2003 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 32, 4, 0, READ_LOCK));
2004 EXPECTED(ret, True);
2005 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
2007 ret = (cli_setpid(cli1, 1),
2008 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 40, 4, 0, WRITE_LOCK))) &&
2009 (cli_setpid(cli1, 2),
2010 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 42, 4, 0, WRITE_LOCK)));
2011 EXPECTED(ret, False);
2012 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
2014 ret = (cli_setpid(cli1, 1),
2015 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 50, 4, 0, READ_LOCK))) &&
2016 (cli_setpid(cli1, 2),
2017 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 52, 4, 0, READ_LOCK)));
2018 EXPECTED(ret, True);
2019 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
2021 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK)) &&
2022 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 60, 4, 0, READ_LOCK));
2023 EXPECTED(ret, True);
2024 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
2026 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK)) &&
2027 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 70, 4, 0, WRITE_LOCK));
2028 EXPECTED(ret, False);
2029 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
2031 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, READ_LOCK)) &&
2032 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 80, 4, 0, WRITE_LOCK));
2033 EXPECTED(ret, False);
2034 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
2036 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, WRITE_LOCK)) &&
2037 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 90, 4, 0, READ_LOCK));
2038 EXPECTED(ret, True);
2039 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2041 ret = (cli_setpid(cli1, 1),
2042 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, WRITE_LOCK))) &&
2043 (cli_setpid(cli1, 2),
2044 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 100, 4, 0, READ_LOCK)));
2045 EXPECTED(ret, False);
2046 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
2048 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 110, 4, 0, READ_LOCK)) &&
2049 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 112, 4, 0, READ_LOCK)) &&
2050 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
2051 EXPECTED(ret, False);
2052 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
2055 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 120, 4, 0, WRITE_LOCK)) &&
2056 test_cli_read(cli2, fnum2, buf, 120, 4, NULL, 4);
2057 EXPECTED(ret, False);
2058 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
2060 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2061 ret = NT_STATUS_IS_OK(status);
2063 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
2065 ret = NT_STATUS_IS_OK(status);
2067 EXPECTED(ret, False);
2068 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
2071 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2072 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 140, 4, 0, READ_LOCK)) &&
2073 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
2074 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
2075 EXPECTED(ret, True);
2076 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
2079 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, WRITE_LOCK)) &&
2080 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 150, 4, 0, READ_LOCK)) &&
2081 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
2082 test_cli_read(cli2, fnum2, buf, 150, 4, NULL, 4) &&
2083 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2085 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
2086 EXPECTED(ret, True);
2087 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
2089 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 160, 4, 0, READ_LOCK)) &&
2090 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
2091 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2093 test_cli_read(cli2, fnum2, buf, 160, 4, NULL, 4);
2094 EXPECTED(ret, True);
2095 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2097 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 170, 4, 0, WRITE_LOCK)) &&
2098 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2099 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2101 test_cli_read(cli2, fnum2, buf, 170, 4, NULL, 4);
2102 EXPECTED(ret, True);
2103 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2105 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, WRITE_LOCK)) &&
2106 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 190, 4, 0, READ_LOCK)) &&
2107 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2108 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2110 test_cli_read(cli2, fnum2, buf, 190, 4, NULL, 4);
2111 EXPECTED(ret, True);
2112 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2114 cli_close(cli1, fnum1);
2115 cli_close(cli2, fnum2);
2116 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2117 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
2118 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2119 NT_STATUS_IS_OK(cli_lock32(cli1, f, 0, 1, 0, READ_LOCK)) &&
2120 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2121 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2122 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK));
2124 cli_close(cli1, fnum1);
2125 EXPECTED(ret, True);
2126 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2129 cli_close(cli1, fnum1);
2130 cli_close(cli2, fnum2);
2131 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2132 torture_close_connection(cli1);
2133 torture_close_connection(cli2);
2135 printf("finished locktest4\n");
2140 looks at lock upgrade/downgrade.
2142 static bool run_locktest5(int dummy)
2144 static struct cli_state *cli1, *cli2;
2145 const char *fname = "\\lockt5.lck";
2146 uint16_t fnum1, fnum2, fnum3;
2149 bool correct = True;
2152 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2156 cli_sockopt(cli1, sockops);
2157 cli_sockopt(cli2, sockops);
2159 printf("starting locktest5\n");
2161 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2163 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2164 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2165 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2167 memset(buf, 0, sizeof(buf));
2169 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2171 if (!NT_STATUS_IS_OK(status)) {
2172 printf("Failed to create file: %s\n", nt_errstr(status));
2177 /* Check for NT bug... */
2178 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 8, 0, READ_LOCK)) &&
2179 NT_STATUS_IS_OK(cli_lock32(cli1, fnum3, 0, 1, 0, READ_LOCK));
2180 cli_close(cli1, fnum1);
2181 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2182 status = cli_lock32(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2183 ret = NT_STATUS_IS_OK(status);
2184 EXPECTED(ret, True);
2185 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2186 cli_close(cli1, fnum1);
2187 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2188 cli_unlock(cli1, fnum3, 0, 1);
2190 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) &&
2191 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 1, 1, 0, READ_LOCK));
2192 EXPECTED(ret, True);
2193 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2195 status = cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK);
2196 ret = NT_STATUS_IS_OK(status);
2197 EXPECTED(ret, False);
2199 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2201 /* Unlock the process 2 lock. */
2202 cli_unlock(cli2, fnum2, 0, 4);
2204 status = cli_lock32(cli1, fnum3, 0, 4, 0, READ_LOCK);
2205 ret = NT_STATUS_IS_OK(status);
2206 EXPECTED(ret, False);
2208 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2210 /* Unlock the process 1 fnum3 lock. */
2211 cli_unlock(cli1, fnum3, 0, 4);
2213 /* Stack 2 more locks here. */
2214 ret = NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK)) &&
2215 NT_STATUS_IS_OK(cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK));
2217 EXPECTED(ret, True);
2218 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2220 /* Unlock the first process lock, then check this was the WRITE lock that was
2223 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2224 NT_STATUS_IS_OK(cli_lock32(cli2, fnum2, 0, 4, 0, READ_LOCK));
2226 EXPECTED(ret, True);
2227 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2229 /* Unlock the process 2 lock. */
2230 cli_unlock(cli2, fnum2, 0, 4);
2232 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2234 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2235 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2236 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2238 EXPECTED(ret, True);
2239 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2241 /* Ensure the next unlock fails. */
2242 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2243 EXPECTED(ret, False);
2244 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2246 /* Ensure connection 2 can get a write lock. */
2247 status = cli_lock32(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2248 ret = NT_STATUS_IS_OK(status);
2249 EXPECTED(ret, True);
2251 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2255 cli_close(cli1, fnum1);
2256 cli_close(cli2, fnum2);
2257 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2258 if (!torture_close_connection(cli1)) {
2261 if (!torture_close_connection(cli2)) {
2265 printf("finished locktest5\n");
2271 tries the unusual lockingX locktype bits
2273 static bool run_locktest6(int dummy)
2275 static struct cli_state *cli;
2276 const char *fname[1] = { "\\lock6.txt" };
2281 if (!torture_open_connection(&cli, 0)) {
2285 cli_sockopt(cli, sockops);
2287 printf("starting locktest6\n");
2290 printf("Testing %s\n", fname[i]);
2292 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2294 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2295 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2296 cli_close(cli, fnum);
2297 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2299 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2300 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2301 cli_close(cli, fnum);
2302 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2304 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2307 torture_close_connection(cli);
2309 printf("finished locktest6\n");
2313 static bool run_locktest7(int dummy)
2315 struct cli_state *cli1;
2316 const char *fname = "\\lockt7.lck";
2319 bool correct = False;
2323 if (!torture_open_connection(&cli1, 0)) {
2327 cli_sockopt(cli1, sockops);
2329 printf("starting locktest7\n");
2331 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2333 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2335 memset(buf, 0, sizeof(buf));
2337 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2339 if (!NT_STATUS_IS_OK(status)) {
2340 printf("Failed to create file: %s\n", nt_errstr(status));
2344 cli_setpid(cli1, 1);
2346 status = cli_lock32(cli1, fnum1, 130, 4, 0, READ_LOCK);
2347 if (!NT_STATUS_IS_OK(status)) {
2348 printf("Unable to apply read lock on range 130:4, "
2349 "error was %s\n", nt_errstr(status));
2352 printf("pid1 successfully locked range 130:4 for READ\n");
2355 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 printf("pid1 unable to read the range 130:4, error was %s\n",
2360 } else if (nread != 4) {
2361 printf("pid1 unable to read the range 130:4, "
2362 "recv %ld req %d\n", (unsigned long)nread, 4);
2365 printf("pid1 successfully read the range 130:4\n");
2368 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2369 if (!NT_STATUS_IS_OK(status)) {
2370 printf("pid1 unable to write to the range 130:4, error was "
2371 "%s\n", nt_errstr(status));
2372 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2373 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2377 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2381 cli_setpid(cli1, 2);
2383 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2384 if (!NT_STATUS_IS_OK(status)) {
2385 printf("pid2 unable to read the range 130:4, error was %s\n",
2388 } else if (nread != 4) {
2389 printf("pid2 unable to read the range 130:4, "
2390 "recv %ld req %d\n", (unsigned long)nread, 4);
2393 printf("pid2 successfully read the range 130:4\n");
2396 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2397 if (!NT_STATUS_IS_OK(status)) {
2398 printf("pid2 unable to write to the range 130:4, error was "
2399 "%s\n", nt_errstr(status));
2400 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2401 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2405 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2409 cli_setpid(cli1, 1);
2410 cli_unlock(cli1, fnum1, 130, 4);
2412 status = cli_lock32(cli1, fnum1, 130, 4, 0, WRITE_LOCK);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 printf("Unable to apply write lock on range 130:4, error was %s\n", nt_errstr(status));
2417 printf("pid1 successfully locked range 130:4 for WRITE\n");
2420 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2421 if (!NT_STATUS_IS_OK(status)) {
2422 printf("pid1 unable to read the range 130:4, error was %s\n",
2425 } else if (nread != 4) {
2426 printf("pid1 unable to read the range 130:4, "
2427 "recv %ld req %d\n", (unsigned long)nread, 4);
2430 printf("pid1 successfully read the range 130:4\n");
2433 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2434 if (!NT_STATUS_IS_OK(status)) {
2435 printf("pid1 unable to write to the range 130:4, error was "
2436 "%s\n", nt_errstr(status));
2439 printf("pid1 successfully wrote to the range 130:4\n");
2442 cli_setpid(cli1, 2);
2444 status = cli_read(cli1, fnum1, buf, 130, 4, &nread);
2445 if (!NT_STATUS_IS_OK(status)) {
2446 printf("pid2 unable to read the range 130:4, error was "
2447 "%s\n", nt_errstr(status));
2448 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2449 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2453 printf("pid2 successfully read the range 130:4 (should be denied) recv %ld\n",
2454 (unsigned long)nread);
2458 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2459 if (!NT_STATUS_IS_OK(status)) {
2460 printf("pid2 unable to write to the range 130:4, error was "
2461 "%s\n", nt_errstr(status));
2462 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2463 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2467 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2471 cli_unlock(cli1, fnum1, 130, 0);
2475 cli_close(cli1, fnum1);
2476 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2477 torture_close_connection(cli1);
2479 printf("finished locktest7\n");
2484 * This demonstrates a problem with our use of GPFS share modes: A file
2485 * descriptor sitting in the pending close queue holding a GPFS share mode
2486 * blocks opening a file another time. Happens with Word 2007 temp files.
2487 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2488 * open is denied with NT_STATUS_SHARING_VIOLATION.
2491 static bool run_locktest8(int dummy)
2493 struct cli_state *cli1;
2494 const char *fname = "\\lockt8.lck";
2495 uint16_t fnum1, fnum2;
2497 bool correct = False;
2500 if (!torture_open_connection(&cli1, 0)) {
2504 cli_sockopt(cli1, sockops);
2506 printf("starting locktest8\n");
2508 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2510 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2512 if (!NT_STATUS_IS_OK(status)) {
2513 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2517 memset(buf, 0, sizeof(buf));
2519 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2520 if (!NT_STATUS_IS_OK(status)) {
2521 d_fprintf(stderr, "cli_open second time returned %s\n",
2526 status = cli_lock32(cli1, fnum2, 1, 1, 0, READ_LOCK);
2527 if (!NT_STATUS_IS_OK(status)) {
2528 printf("Unable to apply read lock on range 1:1, error was "
2529 "%s\n", nt_errstr(status));
2533 status = cli_close(cli1, fnum1);
2534 if (!NT_STATUS_IS_OK(status)) {
2535 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2539 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2540 if (!NT_STATUS_IS_OK(status)) {
2541 d_fprintf(stderr, "cli_open third time returned %s\n",
2549 cli_close(cli1, fnum1);
2550 cli_close(cli1, fnum2);
2551 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2552 torture_close_connection(cli1);
2554 printf("finished locktest8\n");
2559 * This test is designed to be run in conjunction with
2560 * external NFS or POSIX locks taken in the filesystem.
2561 * It checks that the smbd server will block until the
2562 * lock is released and then acquire it. JRA.
2565 static bool got_alarm;
2566 static struct cli_state *alarm_cli;
2568 static void alarm_handler(int dummy)
2573 static void alarm_handler_parent(int dummy)
2575 cli_state_disconnect(alarm_cli);
2578 static void do_local_lock(int read_fd, int write_fd)
2583 const char *local_pathname = NULL;
2586 local_pathname = talloc_asprintf(talloc_tos(),
2587 "%s/lockt9.lck", local_path);
2588 if (!local_pathname) {
2589 printf("child: alloc fail\n");
2593 unlink(local_pathname);
2594 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2596 printf("child: open of %s failed %s.\n",
2597 local_pathname, strerror(errno));
2601 /* Now take a fcntl lock. */
2602 lock.l_type = F_WRLCK;
2603 lock.l_whence = SEEK_SET;
2606 lock.l_pid = getpid();
2608 ret = fcntl(fd,F_SETLK,&lock);
2610 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2611 local_pathname, strerror(errno));
2614 printf("child: got lock 0:4 on file %s.\n",
2619 CatchSignal(SIGALRM, alarm_handler);
2621 /* Signal the parent. */
2622 if (write(write_fd, &c, 1) != 1) {
2623 printf("child: start signal fail %s.\n",
2630 /* Wait for the parent to be ready. */
2631 if (read(read_fd, &c, 1) != 1) {
2632 printf("child: reply signal fail %s.\n",
2640 printf("child: released lock 0:4 on file %s.\n",
2646 static bool run_locktest9(int dummy)
2648 struct cli_state *cli1;
2649 const char *fname = "\\lockt9.lck";
2651 bool correct = False;
2652 int pipe_in[2], pipe_out[2];
2656 struct timeval start;
2660 printf("starting locktest9\n");
2662 if (local_path == NULL) {
2663 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2667 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2672 if (child_pid == -1) {
2676 if (child_pid == 0) {
2678 do_local_lock(pipe_out[0], pipe_in[1]);
2688 ret = read(pipe_in[0], &c, 1);
2690 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2695 if (!torture_open_connection(&cli1, 0)) {
2699 cli_sockopt(cli1, sockops);
2701 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2703 if (!NT_STATUS_IS_OK(status)) {
2704 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2708 /* Ensure the child has the lock. */
2709 status = cli_lock32(cli1, fnum, 0, 4, 0, WRITE_LOCK);
2710 if (NT_STATUS_IS_OK(status)) {
2711 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2714 d_printf("Child has the lock.\n");
2717 /* Tell the child to wait 5 seconds then exit. */
2718 ret = write(pipe_out[1], &c, 1);
2720 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2725 /* Wait 20 seconds for the lock. */
2727 CatchSignal(SIGALRM, alarm_handler_parent);
2730 start = timeval_current();
2732 status = cli_lock32(cli1, fnum, 0, 4, -1, WRITE_LOCK);
2733 if (!NT_STATUS_IS_OK(status)) {
2734 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2735 "%s\n", nt_errstr(status));
2740 seconds = timeval_elapsed(&start);
2742 printf("Parent got the lock after %.2f seconds.\n",
2745 status = cli_close(cli1, fnum);
2746 if (!NT_STATUS_IS_OK(status)) {
2747 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2754 cli_close(cli1, fnum);
2755 torture_close_connection(cli1);
2759 printf("finished locktest9\n");
2764 test whether fnums and tids open on one VC are available on another (a major
2767 static bool run_fdpasstest(int dummy)
2769 struct cli_state *cli1, *cli2;
2770 const char *fname = "\\fdpass.tst";
2775 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2778 cli_sockopt(cli1, sockops);
2779 cli_sockopt(cli2, sockops);
2781 printf("starting fdpasstest\n");
2783 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2785 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2787 if (!NT_STATUS_IS_OK(status)) {
2788 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2792 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2794 if (!NT_STATUS_IS_OK(status)) {
2795 printf("write failed (%s)\n", nt_errstr(status));
2799 cli_state_set_uid(cli2, cli_state_get_uid(cli1));
2800 cli_state_set_tid(cli2, cli_state_get_tid(cli1));
2801 cli_setpid(cli2, cli_getpid(cli1));
2803 if (test_cli_read(cli2, fnum1, buf, 0, 13, NULL, 13)) {
2804 printf("read succeeded! nasty security hole [%s]\n", buf);
2808 cli_close(cli1, fnum1);
2809 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2811 torture_close_connection(cli1);
2812 torture_close_connection(cli2);
2814 printf("finished fdpasstest\n");
2818 static bool run_fdsesstest(int dummy)
2820 struct cli_state *cli;
2825 const char *fname = "\\fdsess.tst";
2826 const char *fname1 = "\\fdsess1.tst";
2833 if (!torture_open_connection(&cli, 0))
2835 cli_sockopt(cli, sockops);
2837 if (!torture_cli_session_setup2(cli, &new_vuid))
2840 saved_cnum = cli_state_get_tid(cli);
2841 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2843 new_cnum = cli_state_get_tid(cli);
2844 cli_state_set_tid(cli, saved_cnum);
2846 printf("starting fdsesstest\n");
2848 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2849 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2851 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2852 if (!NT_STATUS_IS_OK(status)) {
2853 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2857 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2859 if (!NT_STATUS_IS_OK(status)) {
2860 printf("write failed (%s)\n", nt_errstr(status));
2864 saved_vuid = cli_state_get_uid(cli);
2865 cli_state_set_uid(cli, new_vuid);
2867 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2868 printf("read succeeded with different vuid! "
2869 "nasty security hole [%s]\n", buf);
2872 /* Try to open a file with different vuid, samba cnum. */
2873 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2874 printf("create with different vuid, same cnum succeeded.\n");
2875 cli_close(cli, fnum2);
2876 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2878 printf("create with different vuid, same cnum failed.\n");
2879 printf("This will cause problems with service clients.\n");
2883 cli_state_set_uid(cli, saved_vuid);
2885 /* Try with same vuid, different cnum. */
2886 cli_state_set_tid(cli, new_cnum);
2888 if (test_cli_read(cli, fnum1, buf, 0, 13, NULL, 13)) {
2889 printf("read succeeded with different cnum![%s]\n", buf);
2893 cli_state_set_tid(cli, saved_cnum);
2894 cli_close(cli, fnum1);
2895 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2897 torture_close_connection(cli);
2899 printf("finished fdsesstest\n");
2904 This test checks that
2906 1) the server does not allow an unlink on a file that is open
2908 static bool run_unlinktest(int dummy)
2910 struct cli_state *cli;
2911 const char *fname = "\\unlink.tst";
2913 bool correct = True;
2916 if (!torture_open_connection(&cli, 0)) {
2920 cli_sockopt(cli, sockops);
2922 printf("starting unlink test\n");
2924 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2928 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2929 if (!NT_STATUS_IS_OK(status)) {
2930 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2934 status = cli_unlink(cli, fname,
2935 FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2936 if (NT_STATUS_IS_OK(status)) {
2937 printf("error: server allowed unlink on an open file\n");
2940 correct = check_error(__LINE__, status, ERRDOS, ERRbadshare,
2941 NT_STATUS_SHARING_VIOLATION);
2944 cli_close(cli, fnum);
2945 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2947 if (!torture_close_connection(cli)) {
2951 printf("unlink test finished\n");
2958 test how many open files this server supports on the one socket
2960 static bool run_maxfidtest(int dummy)
2962 struct cli_state *cli;
2964 uint16_t fnums[0x11000];
2967 bool correct = True;
2973 printf("failed to connect\n");
2977 cli_sockopt(cli, sockops);
2979 for (i=0; i<0x11000; i++) {
2980 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2981 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2983 if (!NT_STATUS_IS_OK(status)) {
2984 printf("open of %s failed (%s)\n",
2985 fname, nt_errstr(status));
2986 printf("maximum fnum is %d\n", i);
2994 printf("cleaning up\n");
2996 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2997 cli_close(cli, fnums[i]);
2999 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3000 if (!NT_STATUS_IS_OK(status)) {
3001 printf("unlink of %s failed (%s)\n",
3002 fname, nt_errstr(status));
3009 printf("maxfid test finished\n");
3010 if (!torture_close_connection(cli)) {
3016 /* generate a random buffer */
3017 static void rand_buf(char *buf, int len)
3020 *buf = (char)sys_random();
3025 /* send smb negprot commands, not reading the response */
3026 static bool run_negprot_nowait(int dummy)
3028 struct tevent_context *ev;
3030 struct cli_state *cli;
3031 bool correct = True;
3033 printf("starting negprot nowait test\n");
3035 ev = tevent_context_init(talloc_tos());
3040 if (!(cli = open_nbt_connection())) {
3045 for (i=0;i<50000;i++) {
3046 struct tevent_req *req;
3048 req = cli_negprot_send(ev, ev, cli);
3053 if (!tevent_req_poll(req, ev)) {
3054 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
3062 if (torture_close_connection(cli)) {
3066 printf("finished negprot nowait test\n");
3071 /* send smb negprot commands, not reading the response */
3072 static bool run_bad_nbt_session(int dummy)
3074 struct nmb_name called, calling;
3075 struct sockaddr_storage ss;
3080 printf("starting bad nbt session test\n");
3082 make_nmb_name(&calling, myname, 0x0);
3083 make_nmb_name(&called , host, 0x20);
3085 if (!resolve_name(host, &ss, 0x20, true)) {
3086 d_fprintf(stderr, "Could not resolve name %s\n", host);
3090 status = open_socket_out(&ss, 139, 10000, &fd);
3091 if (!NT_STATUS_IS_OK(status)) {
3092 d_fprintf(stderr, "open_socket_out failed: %s\n",
3097 ret = cli_bad_session_request(fd, &calling, &called);
3100 d_fprintf(stderr, "open_socket_out failed: %s\n",
3105 printf("finished bad nbt session test\n");
3109 /* send random IPC commands */
3110 static bool run_randomipc(int dummy)
3112 char *rparam = NULL;
3114 unsigned int rdrcnt,rprcnt;
3116 int api, param_len, i;
3117 struct cli_state *cli;
3118 bool correct = True;
3121 printf("starting random ipc test\n");
3123 if (!torture_open_connection(&cli, 0)) {
3127 for (i=0;i<count;i++) {
3128 api = sys_random() % 500;
3129 param_len = (sys_random() % 64);
3131 rand_buf(param, param_len);
3136 param, param_len, 8,
3137 NULL, 0, BUFFER_SIZE,
3141 printf("%d/%d\r", i,count);
3144 printf("%d/%d\n", i, count);
3146 if (!torture_close_connection(cli)) {
3150 printf("finished random ipc test\n");
3157 static void browse_callback(const char *sname, uint32 stype,
3158 const char *comment, void *state)
3160 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3166 This test checks the browse list code
3169 static bool run_browsetest(int dummy)
3171 static struct cli_state *cli;
3172 bool correct = True;
3174 printf("starting browse test\n");
3176 if (!torture_open_connection(&cli, 0)) {
3180 printf("domain list:\n");
3181 cli_NetServerEnum(cli, cli->server_domain,
3182 SV_TYPE_DOMAIN_ENUM,
3183 browse_callback, NULL);
3185 printf("machine list:\n");
3186 cli_NetServerEnum(cli, cli->server_domain,
3188 browse_callback, NULL);
3190 if (!torture_close_connection(cli)) {
3194 printf("browse test finished\n");
3202 This checks how the getatr calls works
3204 static bool run_attrtest(int dummy)
3206 struct cli_state *cli;
3209 const char *fname = "\\attrib123456789.tst";
3210 bool correct = True;
3213 printf("starting attrib test\n");
3215 if (!torture_open_connection(&cli, 0)) {
3219 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3220 cli_open(cli, fname,
3221 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3222 cli_close(cli, fnum);
3224 status = cli_getatr(cli, fname, NULL, NULL, &t);
3225 if (!NT_STATUS_IS_OK(status)) {
3226 printf("getatr failed (%s)\n", nt_errstr(status));
3230 if (abs(t - time(NULL)) > 60*60*24*10) {
3231 printf("ERROR: SMBgetatr bug. time is %s",
3237 t2 = t-60*60*24; /* 1 day ago */
3239 status = cli_setatr(cli, fname, 0, t2);
3240 if (!NT_STATUS_IS_OK(status)) {
3241 printf("setatr failed (%s)\n", nt_errstr(status));
3245 status = cli_getatr(cli, fname, NULL, NULL, &t);
3246 if (!NT_STATUS_IS_OK(status)) {
3247 printf("getatr failed (%s)\n", nt_errstr(status));
3252 printf("ERROR: getatr/setatr bug. times are\n%s",
3254 printf("%s", ctime(&t2));
3258 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3260 if (!torture_close_connection(cli)) {
3264 printf("attrib test finished\n");
3271 This checks a couple of trans2 calls
3273 static bool run_trans2test(int dummy)
3275 struct cli_state *cli;
3278 time_t c_time, a_time, m_time;
3279 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3280 const char *fname = "\\trans2.tst";
3281 const char *dname = "\\trans2";
3282 const char *fname2 = "\\trans2\\trans2.tst";
3284 bool correct = True;
3288 printf("starting trans2 test\n");
3290 if (!torture_open_connection(&cli, 0)) {
3294 status = cli_get_fs_attr_info(cli, &fs_attr);
3295 if (!NT_STATUS_IS_OK(status)) {
3296 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3301 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3302 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3303 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3304 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3305 if (!NT_STATUS_IS_OK(status)) {
3306 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3310 status = cli_qfilename(cli, fnum, talloc_tos(), &pname);
3311 if (!NT_STATUS_IS_OK(status)) {
3312 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3316 if (strcmp(pname, fname)) {
3317 printf("qfilename gave different name? [%s] [%s]\n",
3322 cli_close(cli, fnum);
3326 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3327 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3329 if (!NT_STATUS_IS_OK(status)) {
3330 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3333 cli_close(cli, fnum);
3335 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3337 if (!NT_STATUS_IS_OK(status)) {
3338 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3341 time_t t = time(NULL);
3343 if (c_time != m_time) {
3344 printf("create time=%s", ctime(&c_time));
3345 printf("modify time=%s", ctime(&m_time));
3346 printf("This system appears to have sticky create times\n");
3348 if ((abs(a_time - t) > 60) && (a_time % (60*60) == 0)) {
3349 printf("access time=%s", ctime(&a_time));
3350 printf("This system appears to set a midnight access time\n");
3354 if (abs(m_time - t) > 60*60*24*7) {
3355 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3361 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3362 cli_open(cli, fname,
3363 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3364 cli_close(cli, fnum);
3365 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3366 &m_time_ts, &size, NULL, NULL);
3367 if (!NT_STATUS_IS_OK(status)) {
3368 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3371 if (w_time_ts.tv_sec < 60*60*24*2) {
3372 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3373 printf("This system appears to set a initial 0 write time\n");
3378 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3381 /* check if the server updates the directory modification time
3382 when creating a new file */
3383 status = cli_mkdir(cli, dname);
3384 if (!NT_STATUS_IS_OK(status)) {
3385 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3389 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3390 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3391 if (!NT_STATUS_IS_OK(status)) {
3392 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3396 cli_open(cli, fname2,
3397 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3398 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3399 cli_close(cli, fnum);
3400 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3401 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3402 if (!NT_STATUS_IS_OK(status)) {
3403 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3406 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3408 printf("This system does not update directory modification times\n");
3412 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3413 cli_rmdir(cli, dname);
3415 if (!torture_close_connection(cli)) {
3419 printf("trans2 test finished\n");
3425 This checks new W2K calls.
3428 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3430 uint8_t *buf = NULL;
3434 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3435 CLI_BUFFER_SIZE, NULL, &buf, &len);
3436 if (!NT_STATUS_IS_OK(status)) {
3437 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3440 printf("qfileinfo: level %d, len = %u\n", level, len);
3441 dump_data(0, (uint8 *)buf, len);
3448 static bool run_w2ktest(int dummy)
3450 struct cli_state *cli;
3452 const char *fname = "\\w2ktest\\w2k.tst";
3454 bool correct = True;
3456 printf("starting w2k test\n");
3458 if (!torture_open_connection(&cli, 0)) {
3462 cli_open(cli, fname,
3463 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3465 for (level = 1004; level < 1040; level++) {
3466 new_trans(cli, fnum, level);
3469 cli_close(cli, fnum);
3471 if (!torture_close_connection(cli)) {
3475 printf("w2k test finished\n");
3482 this is a harness for some oplock tests
3484 static bool run_oplock1(int dummy)
3486 struct cli_state *cli1;
3487 const char *fname = "\\lockt1.lck";
3489 bool correct = True;
3492 printf("starting oplock test 1\n");
3494 if (!torture_open_connection(&cli1, 0)) {
3498 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3500 cli_sockopt(cli1, sockops);
3502 cli1->use_oplocks = True;
3504 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3506 if (!NT_STATUS_IS_OK(status)) {
3507 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3511 cli1->use_oplocks = False;
3513 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3514 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3516 status = cli_close(cli1, fnum1);
3517 if (!NT_STATUS_IS_OK(status)) {
3518 printf("close2 failed (%s)\n", nt_errstr(status));
3522 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3523 if (!NT_STATUS_IS_OK(status)) {
3524 printf("unlink failed (%s)\n", nt_errstr(status));
3528 if (!torture_close_connection(cli1)) {
3532 printf("finished oplock test 1\n");
3537 static bool run_oplock2(int dummy)
3539 struct cli_state *cli1, *cli2;
3540 const char *fname = "\\lockt2.lck";
3541 uint16_t fnum1, fnum2;
3542 int saved_use_oplocks = use_oplocks;
3544 bool correct = True;
3545 volatile bool *shared_correct;
3549 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3550 *shared_correct = True;
3552 use_level_II_oplocks = True;
3555 printf("starting oplock test 2\n");
3557 if (!torture_open_connection(&cli1, 0)) {
3558 use_level_II_oplocks = False;
3559 use_oplocks = saved_use_oplocks;
3563 if (!torture_open_connection(&cli2, 1)) {
3564 use_level_II_oplocks = False;
3565 use_oplocks = saved_use_oplocks;
3569 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3571 cli_sockopt(cli1, sockops);
3572 cli_sockopt(cli2, sockops);
3574 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3576 if (!NT_STATUS_IS_OK(status)) {
3577 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3581 /* Don't need the globals any more. */
3582 use_level_II_oplocks = False;
3583 use_oplocks = saved_use_oplocks;
3587 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3588 if (!NT_STATUS_IS_OK(status)) {
3589 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3590 *shared_correct = False;
3596 status = cli_close(cli2, fnum2);
3597 if (!NT_STATUS_IS_OK(status)) {
3598 printf("close2 failed (%s)\n", nt_errstr(status));
3599 *shared_correct = False;
3607 /* Ensure cli1 processes the break. Empty file should always return 0
3609 status = cli_read(cli1, fnum1, buf, 0, 4, &nread);
3610 if (!NT_STATUS_IS_OK(status)) {
3611 printf("read on fnum1 failed (%s)\n", nt_errstr(status));
3613 } else if (nread != 0) {
3614 printf("read on empty fnum1 failed. recv %ld expected %d\n",
3615 (unsigned long)nread, 0);
3619 /* Should now be at level II. */
3620 /* Test if sending a write locks causes a break to none. */
3621 status = cli_lock32(cli1, fnum1, 0, 4, 0, READ_LOCK);
3622 if (!NT_STATUS_IS_OK(status)) {
3623 printf("lock failed (%s)\n", nt_errstr(status));
3627 cli_unlock(cli1, fnum1, 0, 4);
3631 status = cli_lock32(cli1, fnum1, 0, 4, 0, WRITE_LOCK);
3632 if (!NT_STATUS_IS_OK(status)) {
3633 printf("lock failed (%s)\n", nt_errstr(status));
3637 cli_unlock(cli1, fnum1, 0, 4);
3641 cli_read(cli1, fnum1, buf, 0, 4, NULL);
3643 status = cli_close(cli1, fnum1);
3644 if (!NT_STATUS_IS_OK(status)) {
3645 printf("close1 failed (%s)\n", nt_errstr(status));
3651 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3652 if (!NT_STATUS_IS_OK(status)) {
3653 printf("unlink failed (%s)\n", nt_errstr(status));
3657 if (!torture_close_connection(cli1)) {
3661 if (!*shared_correct) {
3665 printf("finished oplock test 2\n");
3670 struct oplock4_state {
3671 struct tevent_context *ev;
3672 struct cli_state *cli;
3677 static void oplock4_got_break(struct tevent_req *req);
3678 static void oplock4_got_open(struct tevent_req *req);
3680 static bool run_oplock4(int dummy)
3682 struct tevent_context *ev;
3683 struct cli_state *cli1, *cli2;
3684 struct tevent_req *oplock_req, *open_req;
3685 const char *fname = "\\lockt4.lck";
3686 const char *fname_ln = "\\lockt4_ln.lck";
3687 uint16_t fnum1, fnum2;
3688 int saved_use_oplocks = use_oplocks;
3690 bool correct = true;
3694 struct oplock4_state *state;
3696 printf("starting oplock test 4\n");
3698 if (!torture_open_connection(&cli1, 0)) {
3699 use_level_II_oplocks = false;
3700 use_oplocks = saved_use_oplocks;
3704 if (!torture_open_connection(&cli2, 1)) {
3705 use_level_II_oplocks = false;
3706 use_oplocks = saved_use_oplocks;
3710 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3711 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3713 cli_sockopt(cli1, sockops);
3714 cli_sockopt(cli2, sockops);
3716 /* Create the file. */
3717 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3719 if (!NT_STATUS_IS_OK(status)) {
3720 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3724 status = cli_close(cli1, fnum1);
3725 if (!NT_STATUS_IS_OK(status)) {
3726 printf("close1 failed (%s)\n", nt_errstr(status));
3730 /* Now create a hardlink. */
3731 status = cli_nt_hardlink(cli1, fname, fname_ln);
3732 if (!NT_STATUS_IS_OK(status)) {
3733 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3737 /* Prove that opening hardlinks cause deny modes to conflict. */
3738 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3739 if (!NT_STATUS_IS_OK(status)) {
3740 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3744 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3745 if (NT_STATUS_IS_OK(status)) {
3746 printf("open of %s succeeded - should fail with sharing violation.\n",
3751 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3752 printf("open of %s should fail with sharing violation. Got %s\n",
3753 fname_ln, nt_errstr(status));
3757 status = cli_close(cli1, fnum1);
3758 if (!NT_STATUS_IS_OK(status)) {
3759 printf("close1 failed (%s)\n", nt_errstr(status));
3763 cli1->use_oplocks = true;
3764 cli2->use_oplocks = true;
3766 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3767 if (!NT_STATUS_IS_OK(status)) {
3768 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3772 ev = tevent_context_init(talloc_tos());
3774 printf("tevent_req_create failed\n");
3778 state = talloc(ev, struct oplock4_state);
3779 if (state == NULL) {
3780 printf("talloc failed\n");
3785 state->got_break = &got_break;
3786 state->fnum2 = &fnum2;
3788 oplock_req = cli_smb_oplock_break_waiter_send(
3789 talloc_tos(), ev, cli1);
3790 if (oplock_req == NULL) {
3791 printf("cli_smb_oplock_break_waiter_send failed\n");
3794 tevent_req_set_callback(oplock_req, oplock4_got_break, state);
3796 open_req = cli_open_send(
3797 talloc_tos(), ev, cli2, fname_ln, O_RDWR, DENY_NONE);
3798 if (oplock_req == NULL) {
3799 printf("cli_open_send failed\n");
3802 tevent_req_set_callback(open_req, oplock4_got_open, state);
3807 while (!got_break || fnum2 == 0xffff) {
3809 ret = tevent_loop_once(ev);
3811 printf("tevent_loop_once failed: %s\n",
3817 status = cli_close(cli2, fnum2);
3818 if (!NT_STATUS_IS_OK(status)) {
3819 printf("close2 failed (%s)\n", nt_errstr(status));
3823 status = cli_close(cli1, fnum1);
3824 if (!NT_STATUS_IS_OK(status)) {
3825 printf("close1 failed (%s)\n", nt_errstr(status));
3829 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3830 if (!NT_STATUS_IS_OK(status)) {
3831 printf("unlink failed (%s)\n", nt_errstr(status));
3835 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3836 if (!NT_STATUS_IS_OK(status)) {
3837 printf("unlink failed (%s)\n", nt_errstr(status));
3841 if (!torture_close_connection(cli1)) {
3849 printf("finished oplock test 4\n");
3854 static void oplock4_got_break(struct tevent_req *req)
3856 struct oplock4_state *state = tevent_req_callback_data(
3857 req, struct oplock4_state);
3862 status = cli_smb_oplock_break_waiter_recv(req, &fnum, &level);
3864 if (!NT_STATUS_IS_OK(status)) {
3865 printf("cli_smb_oplock_break_waiter_recv returned %s\n",
3869 *state->got_break = true;
3871 req = cli_oplock_ack_send(state, state->ev, state->cli, fnum,
3874 printf("cli_oplock_ack_send failed\n");
3879 static void oplock4_got_open(struct tevent_req *req)
3881 struct oplock4_state *state = tevent_req_callback_data(
3882 req, struct oplock4_state);
3885 status = cli_open_recv(req, state->fnum2);
3886 if (!NT_STATUS_IS_OK(status)) {
3887 printf("cli_open_recv returned %s\n", nt_errstr(status));
3888 *state->fnum2 = 0xffff;
3893 Test delete on close semantics.
3895 static bool run_deletetest(int dummy)
3897 struct cli_state *cli1 = NULL;
3898 struct cli_state *cli2 = NULL;
3899 const char *fname = "\\delete.file";
3900 uint16_t fnum1 = (uint16_t)-1;
3901 uint16_t fnum2 = (uint16_t)-1;
3902 bool correct = True;
3905 printf("starting delete test\n");
3907 if (!torture_open_connection(&cli1, 0)) {
3911 cli_sockopt(cli1, sockops);
3913 /* Test 1 - this should delete the file on close. */
3915 cli_setatr(cli1, fname, 0, 0);
3916 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3918 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3919 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3920 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3921 if (!NT_STATUS_IS_OK(status)) {
3922 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3927 status = cli_close(cli1, fnum1);
3928 if (!NT_STATUS_IS_OK(status)) {
3929 printf("[1] close failed (%s)\n", nt_errstr(status));
3934 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3935 printf("[1] open of %s succeeded (should fail)\n", fname);
3940 printf("first delete on close test succeeded.\n");
3942 /* Test 2 - this should delete the file on close. */
3944 cli_setatr(cli1, fname, 0, 0);
3945 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3947 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3948 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3949 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3950 if (!NT_STATUS_IS_OK(status)) {
3951 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3956 status = cli_nt_delete_on_close(cli1, fnum1, true);
3957 if (!NT_STATUS_IS_OK(status)) {
3958 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3963 status = cli_close(cli1, fnum1);
3964 if (!NT_STATUS_IS_OK(status)) {
3965 printf("[2] close failed (%s)\n", nt_errstr(status));
3970 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3971 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3972 status = cli_close(cli1, fnum1);
3973 if (!NT_STATUS_IS_OK(status)) {
3974 printf("[2] close failed (%s)\n", nt_errstr(status));
3978 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3980 printf("second delete on close test succeeded.\n");
3983 cli_setatr(cli1, fname, 0, 0);
3984 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3986 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3987 FILE_ATTRIBUTE_NORMAL,
3988 FILE_SHARE_READ|FILE_SHARE_WRITE,
3989 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3990 if (!NT_STATUS_IS_OK(status)) {
3991 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3996 /* This should fail with a sharing violation - open for delete is only compatible
3997 with SHARE_DELETE. */
3999 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4000 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
4001 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
4006 /* This should succeed. */
4007 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4008 FILE_ATTRIBUTE_NORMAL,
4009 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4010 FILE_OPEN, 0, 0, &fnum2);
4011 if (!NT_STATUS_IS_OK(status)) {
4012 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4017 status = cli_nt_delete_on_close(cli1, fnum1, true);
4018 if (!NT_STATUS_IS_OK(status)) {
4019 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
4024 status = cli_close(cli1, fnum1);
4025 if (!NT_STATUS_IS_OK(status)) {
4026 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
4031 status = cli_close(cli1, fnum2);
4032 if (!NT_STATUS_IS_OK(status)) {
4033 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
4038 /* This should fail - file should no longer be there. */
4040 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4041 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
4042 status = cli_close(cli1, fnum1);
4043 if (!NT_STATUS_IS_OK(status)) {
4044 printf("[3] close failed (%s)\n", nt_errstr(status));
4046 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4050 printf("third delete on close test succeeded.\n");
4053 cli_setatr(cli1, fname, 0, 0);
4054 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4056 status = cli_ntcreate(cli1, fname, 0,
4057 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4058 FILE_ATTRIBUTE_NORMAL,
4059 FILE_SHARE_READ|FILE_SHARE_WRITE,
4060 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4061 if (!NT_STATUS_IS_OK(status)) {
4062 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
4067 /* This should succeed. */
4068 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4069 FILE_ATTRIBUTE_NORMAL,
4070 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4071 FILE_OPEN, 0, 0, &fnum2);
4072 if (!NT_STATUS_IS_OK(status)) {
4073 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
4078 status = cli_close(cli1, fnum2);
4079 if (!NT_STATUS_IS_OK(status)) {
4080 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
4085 status = cli_nt_delete_on_close(cli1, fnum1, true);
4086 if (!NT_STATUS_IS_OK(status)) {
4087 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
4092 /* This should fail - no more opens once delete on close set. */
4093 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4094 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4095 FILE_OPEN, 0, 0, &fnum2))) {
4096 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
4100 printf("fourth delete on close test succeeded.\n");
4102 status = cli_close(cli1, fnum1);
4103 if (!NT_STATUS_IS_OK(status)) {
4104 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
4110 cli_setatr(cli1, fname, 0, 0);
4111 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4113 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
4114 if (!NT_STATUS_IS_OK(status)) {
4115 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4120 /* This should fail - only allowed on NT opens with DELETE access. */
4122 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4123 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
4128 status = cli_close(cli1, fnum1);
4129 if (!NT_STATUS_IS_OK(status)) {
4130 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
4135 printf("fifth delete on close test succeeded.\n");
4138 cli_setatr(cli1, fname, 0, 0);
4139 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4141 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4142 FILE_ATTRIBUTE_NORMAL,
4143 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4144 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4145 if (!NT_STATUS_IS_OK(status)) {
4146 printf("[6] open of %s failed (%s)\n", fname,
4152 /* This should fail - only allowed on NT opens with DELETE access. */
4154 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4155 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4160 status = cli_close(cli1, fnum1);
4161 if (!NT_STATUS_IS_OK(status)) {
4162 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4167 printf("sixth delete on close test succeeded.\n");
4170 cli_setatr(cli1, fname, 0, 0);
4171 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4173 status = cli_ntcreate(cli1, fname, 0,
4174 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4175 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4177 if (!NT_STATUS_IS_OK(status)) {
4178 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4183 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4184 printf("[7] setting delete_on_close on file failed !\n");
4189 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4190 printf("[7] unsetting delete_on_close on file failed !\n");
4195 status = cli_close(cli1, fnum1);
4196 if (!NT_STATUS_IS_OK(status)) {
4197 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4202 /* This next open should succeed - we reset the flag. */
4203 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4204 if (!NT_STATUS_IS_OK(status)) {
4205 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4210 status = cli_close(cli1, fnum1);
4211 if (!NT_STATUS_IS_OK(status)) {
4212 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4217 printf("seventh delete on close test succeeded.\n");
4220 cli_setatr(cli1, fname, 0, 0);
4221 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4223 if (!torture_open_connection(&cli2, 1)) {
4224 printf("[8] failed to open second connection.\n");
4229 cli_sockopt(cli1, sockops);
4231 status = cli_ntcreate(cli1, fname, 0,
4232 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4233 FILE_ATTRIBUTE_NORMAL,
4234 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4235 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4236 if (!NT_STATUS_IS_OK(status)) {
4237 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4242 status = cli_ntcreate(cli2, fname, 0,
4243 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4244 FILE_ATTRIBUTE_NORMAL,
4245 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4246 FILE_OPEN, 0, 0, &fnum2);
4247 if (!NT_STATUS_IS_OK(status)) {
4248 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4253 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4254 printf("[8] setting delete_on_close on file failed !\n");
4259 status = cli_close(cli1, fnum1);
4260 if (!NT_STATUS_IS_OK(status)) {
4261 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4266 status = cli_close(cli2, fnum2);
4267 if (!NT_STATUS_IS_OK(status)) {
4268 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4273 /* This should fail.. */
4274 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4275 if (NT_STATUS_IS_OK(status)) {
4276 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4280 printf("eighth delete on close test succeeded.\n");
4282 /* This should fail - we need to set DELETE_ACCESS. */
4283 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4284 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4285 printf("[9] open of %s succeeded should have failed!\n", fname);
4290 printf("ninth delete on close test succeeded.\n");
4292 status = cli_ntcreate(cli1, fname, 0,
4293 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4294 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4295 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4297 if (!NT_STATUS_IS_OK(status)) {
4298 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4303 /* This should delete the file. */
4304 status = cli_close(cli1, fnum1);
4305 if (!NT_STATUS_IS_OK(status)) {
4306 printf("[10] close failed (%s)\n", nt_errstr(status));
4311 /* This should fail.. */
4312 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4313 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4317 printf("tenth delete on close test succeeded.\n");
4319 cli_setatr(cli1, fname, 0, 0);
4320 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4322 /* What error do we get when attempting to open a read-only file with
4325 /* Create a readonly file. */
4326 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4327 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4328 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4329 if (!NT_STATUS_IS_OK(status)) {
4330 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4335 status = cli_close(cli1, fnum1);
4336 if (!NT_STATUS_IS_OK(status)) {
4337 printf("[11] close failed (%s)\n", nt_errstr(status));
4342 /* Now try open for delete access. */
4343 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4344 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4345 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4346 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4347 cli_close(cli1, fnum1);
4351 NTSTATUS nterr = cli_nt_error(cli1);
4352 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4353 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4357 printf("eleventh delete on close test succeeded.\n");
4361 printf("finished delete test\n");
4364 /* FIXME: This will crash if we aborted before cli2 got
4365 * intialized, because these functions don't handle
4366 * uninitialized connections. */
4368 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4369 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4370 cli_setatr(cli1, fname, 0, 0);
4371 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4373 if (cli1 && !torture_close_connection(cli1)) {
4376 if (cli2 && !torture_close_connection(cli2)) {
4382 static bool run_deletetest_ln(int dummy)
4384 struct cli_state *cli;
4385 const char *fname = "\\delete1";
4386 const char *fname_ln = "\\delete1_ln";
4390 bool correct = true;
4393 printf("starting deletetest-ln\n");
4395 if (!torture_open_connection(&cli, 0)) {
4399 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4400 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4402 cli_sockopt(cli, sockops);
4404 /* Create the file. */
4405 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4406 if (!NT_STATUS_IS_OK(status)) {
4407 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4411 status = cli_close(cli, fnum);
4412 if (!NT_STATUS_IS_OK(status)) {
4413 printf("close1 failed (%s)\n", nt_errstr(status));
4417 /* Now create a hardlink. */
4418 status = cli_nt_hardlink(cli, fname, fname_ln);
4419 if (!NT_STATUS_IS_OK(status)) {
4420 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4424 /* Open the original file. */
4425 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4426 FILE_ATTRIBUTE_NORMAL,
4427 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4428 FILE_OPEN_IF, 0, 0, &fnum);
4429 if (!NT_STATUS_IS_OK(status)) {
4430 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4434 /* Unlink the hard link path. */
4435 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4436 FILE_ATTRIBUTE_NORMAL,
4437 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4438 FILE_OPEN_IF, 0, 0, &fnum1);
4439 if (!NT_STATUS_IS_OK(status)) {
4440 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4443 status = cli_nt_delete_on_close(cli, fnum1, true);
4444 if (!NT_STATUS_IS_OK(status)) {
4445 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4446 __location__, fname_ln, nt_errstr(status));
4450 status = cli_close(cli, fnum1);
4451 if (!NT_STATUS_IS_OK(status)) {
4452 printf("close %s failed (%s)\n",
4453 fname_ln, nt_errstr(status));
4457 status = cli_close(cli, fnum);
4458 if (!NT_STATUS_IS_OK(status)) {
4459 printf("close %s failed (%s)\n",
4460 fname, nt_errstr(status));
4464 /* Ensure the original file is still there. */
4465 status = cli_getatr(cli, fname, NULL, NULL, &t);
4466 if (!NT_STATUS_IS_OK(status)) {
4467 printf("%s getatr on file %s failed (%s)\n",
4474 /* Ensure the link path is gone. */
4475 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4476 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4477 printf("%s, getatr for file %s returned wrong error code %s "
4478 "- should have been deleted\n",
4480 fname_ln, nt_errstr(status));
4484 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4485 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4487 if (!torture_close_connection(cli)) {
4491 printf("finished deletetest-ln\n");
4497 print out server properties
4499 static bool run_properties(int dummy)
4501 struct cli_state *cli;
4502 bool correct = True;
4504 printf("starting properties test\n");
4508 if (!torture_open_connection(&cli, 0)) {
4512 cli_sockopt(cli, sockops);
4514 d_printf("Capabilities 0x%08x\n", cli_state_capabilities(cli));
4516 if (!torture_close_connection(cli)) {
4525 /* FIRST_DESIRED_ACCESS 0xf019f */
4526 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4527 FILE_READ_EA| /* 0xf */ \
4528 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4529 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4530 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4531 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4532 /* SECOND_DESIRED_ACCESS 0xe0080 */
4533 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4534 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4535 WRITE_OWNER_ACCESS /* 0xe0000 */
4538 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4539 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4541 WRITE_OWNER_ACCESS /* */
4545 Test ntcreate calls made by xcopy
4547 static bool run_xcopy(int dummy)
4549 static struct cli_state *cli1;
4550 const char *fname = "\\test.txt";
4551 bool correct = True;
4552 uint16_t fnum1, fnum2;
4555 printf("starting xcopy test\n");
4557 if (!torture_open_connection(&cli1, 0)) {
4561 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4562 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4563 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4564 if (!NT_STATUS_IS_OK(status)) {
4565 printf("First open failed - %s\n", nt_errstr(status));
4569 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4570 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4571 FILE_OPEN, 0x200000, 0, &fnum2);
4572 if (!NT_STATUS_IS_OK(status)) {
4573 printf("second open failed - %s\n", nt_errstr(status));
4577 if (!torture_close_connection(cli1)) {
4585 Test rename on files open with share delete and no share delete.
4587 static bool run_rename(int dummy)
4589 static struct cli_state *cli1;
4590 const char *fname = "\\test.txt";
4591 const char *fname1 = "\\test1.txt";
4592 bool correct = True;
4597 printf("starting rename test\n");
4599 if (!torture_open_connection(&cli1, 0)) {
4603 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4604 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4606 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4607 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4608 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4609 if (!NT_STATUS_IS_OK(status)) {
4610 printf("First open failed - %s\n", nt_errstr(status));
4614 status = cli_rename(cli1, fname, fname1);
4615 if (!NT_STATUS_IS_OK(status)) {
4616 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4618 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4622 status = cli_close(cli1, fnum1);
4623 if (!NT_STATUS_IS_OK(status)) {
4624 printf("close - 1 failed (%s)\n", nt_errstr(status));
4628 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4629 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4630 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4632 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4634 FILE_SHARE_DELETE|FILE_SHARE_READ,
4636 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4637 if (!NT_STATUS_IS_OK(status)) {
4638 printf("Second open failed - %s\n", nt_errstr(status));
4642 status = cli_rename(cli1, fname, fname1);
4643 if (!NT_STATUS_IS_OK(status)) {
4644 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4647 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4650 status = cli_close(cli1, fnum1);
4651 if (!NT_STATUS_IS_OK(status)) {
4652 printf("close - 2 failed (%s)\n", nt_errstr(status));
4656 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4657 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4659 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4660 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4661 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4662 if (!NT_STATUS_IS_OK(status)) {
4663 printf("Third open failed - %s\n", nt_errstr(status));
4672 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4673 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4674 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4677 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4678 printf("[8] setting delete_on_close on file failed !\n");
4682 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4683 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4689 status = cli_rename(cli1, fname, fname1);
4690 if (!NT_STATUS_IS_OK(status)) {
4691 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4694 printf("Third rename succeeded (SHARE_NONE)\n");
4697 status = cli_close(cli1, fnum1);
4698 if (!NT_STATUS_IS_OK(status)) {
4699 printf("close - 3 failed (%s)\n", nt_errstr(status));
4703 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4704 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4708 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4709 FILE_ATTRIBUTE_NORMAL,
4710 FILE_SHARE_READ | FILE_SHARE_WRITE,
4711 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4712 if (!NT_STATUS_IS_OK(status)) {
4713 printf("Fourth open failed - %s\n", nt_errstr(status));
4717 status = cli_rename(cli1, fname, fname1);
4718 if (!NT_STATUS_IS_OK(status)) {
4719 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4721 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4725 status = cli_close(cli1, fnum1);
4726 if (!NT_STATUS_IS_OK(status)) {
4727 printf("close - 4 failed (%s)\n", nt_errstr(status));
4731 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4732 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4736 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4737 FILE_ATTRIBUTE_NORMAL,
4738 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4739 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4740 if (!NT_STATUS_IS_OK(status)) {
4741 printf("Fifth open failed - %s\n", nt_errstr(status));
4745 status = cli_rename(cli1, fname, fname1);
4746 if (!NT_STATUS_IS_OK(status)) {
4747 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4750 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4754 * Now check if the first name still exists ...
4757 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4758 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4759 printf("Opening original file after rename of open file fails: %s\n",
4763 printf("Opening original file after rename of open file works ...\n");
4764 (void)cli_close(cli1, fnum2);
4768 status = cli_close(cli1, fnum1);
4769 if (!NT_STATUS_IS_OK(status)) {
4770 printf("close - 5 failed (%s)\n", nt_errstr(status));
4774 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4775 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4776 if (!NT_STATUS_IS_OK(status)) {
4777 printf("getatr on file %s failed - %s ! \n",
4778 fname1, nt_errstr(status));
4781 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4782 printf("Renamed file %s has wrong attr 0x%x "
4783 "(should be 0x%x)\n",
4786 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4789 printf("Renamed file %s has archive bit set\n", fname1);
4793 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4794 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4796 if (!torture_close_connection(cli1)) {
4803 static bool run_pipe_number(int dummy)
4805 struct cli_state *cli1;
4806 const char *pipe_name = "\\SPOOLSS";
4811 printf("starting pipenumber test\n");
4812 if (!torture_open_connection(&cli1, 0)) {
4816 cli_sockopt(cli1, sockops);
4818 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4819 FILE_ATTRIBUTE_NORMAL,
4820 FILE_SHARE_READ|FILE_SHARE_WRITE,
4821 FILE_OPEN_IF, 0, 0, &fnum);
4822 if (!NT_STATUS_IS_OK(status)) {
4823 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4827 printf("\r%6d", num_pipes);
4830 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4831 torture_close_connection(cli1);
4836 Test open mode returns on read-only files.
4838 static bool run_opentest(int dummy)
4840 static struct cli_state *cli1;
4841 static struct cli_state *cli2;
4842 const char *fname = "\\readonly.file";
4843 uint16_t fnum1, fnum2;
4846 bool correct = True;
4850 printf("starting open test\n");
4852 if (!torture_open_connection(&cli1, 0)) {
4856 cli_setatr(cli1, fname, 0, 0);
4857 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4859 cli_sockopt(cli1, sockops);
4861 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4862 if (!NT_STATUS_IS_OK(status)) {
4863 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4867 status = cli_close(cli1, fnum1);
4868 if (!NT_STATUS_IS_OK(status)) {
4869 printf("close2 failed (%s)\n", nt_errstr(status));
4873 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4874 if (!NT_STATUS_IS_OK(status)) {
4875 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4879 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4880 if (!NT_STATUS_IS_OK(status)) {
4881 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4885 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4886 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4888 if (check_error(__LINE__, status, ERRDOS, ERRnoaccess,
4889 NT_STATUS_ACCESS_DENIED)) {
4890 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4893 printf("finished open test 1\n");
4895 cli_close(cli1, fnum1);
4897 /* Now try not readonly and ensure ERRbadshare is returned. */
4899 cli_setatr(cli1, fname, 0, 0);
4901 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4902 if (!NT_STATUS_IS_OK(status)) {
4903 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4907 /* This will fail - but the error should be ERRshare. */
4908 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4910 if (check_error(__LINE__, status, ERRDOS, ERRbadshare,
4911 NT_STATUS_SHARING_VIOLATION)) {
4912 printf("correct error code ERRDOS/ERRbadshare returned\n");
4915 status = cli_close(cli1, fnum1);
4916 if (!NT_STATUS_IS_OK(status)) {
4917 printf("close2 failed (%s)\n", nt_errstr(status));
4921 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4923 printf("finished open test 2\n");
4925 /* Test truncate open disposition on file opened for read. */
4926 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4927 if (!NT_STATUS_IS_OK(status)) {
4928 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4932 /* write 20 bytes. */
4934 memset(buf, '\0', 20);
4936 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4937 if (!NT_STATUS_IS_OK(status)) {
4938 printf("write failed (%s)\n", nt_errstr(status));
4942 status = cli_close(cli1, fnum1);
4943 if (!NT_STATUS_IS_OK(status)) {
4944 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4948 /* Ensure size == 20. */
4949 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4950 if (!NT_STATUS_IS_OK(status)) {
4951 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4956 printf("(3) file size != 20\n");
4960 /* Now test if we can truncate a file opened for readonly. */
4961 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4962 if (!NT_STATUS_IS_OK(status)) {
4963 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4967 status = cli_close(cli1, fnum1);
4968 if (!NT_STATUS_IS_OK(status)) {
4969 printf("close2 failed (%s)\n", nt_errstr(status));
4973 /* Ensure size == 0. */
4974 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4975 if (!NT_STATUS_IS_OK(status)) {
4976 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4981 printf("(3) file size != 0\n");
4984 printf("finished open test 3\n");
4986 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4988 printf("Do ctemp tests\n");
4989 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4990 if (!NT_STATUS_IS_OK(status)) {
4991 printf("ctemp failed (%s)\n", nt_errstr(status));
4995 printf("ctemp gave path %s\n", tmp_path);
4996 status = cli_close(cli1, fnum1);
4997 if (!NT_STATUS_IS_OK(status)) {
4998 printf("close of temp failed (%s)\n", nt_errstr(status));
5001 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5002 if (!NT_STATUS_IS_OK(status)) {
5003 printf("unlink of temp failed (%s)\n", nt_errstr(status));
5006 /* Test the non-io opens... */
5008 if (!torture_open_connection(&cli2, 1)) {
5012 cli_setatr(cli2, fname, 0, 0);
5013 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5015 cli_sockopt(cli2, sockops);
5017 printf("TEST #1 testing 2 non-io opens (no delete)\n");
5018 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5019 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5020 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5021 if (!NT_STATUS_IS_OK(status)) {
5022 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5026 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5027 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5028 FILE_OPEN_IF, 0, 0, &fnum2);
5029 if (!NT_STATUS_IS_OK(status)) {
5030 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5034 status = cli_close(cli1, fnum1);
5035 if (!NT_STATUS_IS_OK(status)) {
5036 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5040 status = cli_close(cli2, fnum2);
5041 if (!NT_STATUS_IS_OK(status)) {
5042 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5046 printf("non-io open test #1 passed.\n");
5048 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5050 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
5052 status = cli_ntcreate(cli1, fname, 0,
5053 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5054 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5055 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5056 if (!NT_STATUS_IS_OK(status)) {
5057 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5061 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5062 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5063 FILE_OPEN_IF, 0, 0, &fnum2);
5064 if (!NT_STATUS_IS_OK(status)) {
5065 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5069 status = cli_close(cli1, fnum1);
5070 if (!NT_STATUS_IS_OK(status)) {
5071 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5075 status = cli_close(cli2, fnum2);
5076 if (!NT_STATUS_IS_OK(status)) {
5077 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5081 printf("non-io open test #2 passed.\n");
5083 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5085 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
5087 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
5088 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5089 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5090 if (!NT_STATUS_IS_OK(status)) {
5091 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5095 status = cli_ntcreate(cli2, fname, 0,
5096 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5097 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5098 FILE_OPEN_IF, 0, 0, &fnum2);
5099 if (!NT_STATUS_IS_OK(status)) {
5100 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5104 status = cli_close(cli1, fnum1);
5105 if (!NT_STATUS_IS_OK(status)) {
5106 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5110 status = cli_close(cli2, fnum2);
5111 if (!NT_STATUS_IS_OK(status)) {
5112 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5116 printf("non-io open test #3 passed.\n");
5118 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5120 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
5122 status = cli_ntcreate(cli1, fname, 0,
5123 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5124 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5125 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5126 if (!NT_STATUS_IS_OK(status)) {
5127 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5131 status = cli_ntcreate(cli2, fname, 0,
5132 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5133 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5134 FILE_OPEN_IF, 0, 0, &fnum2);
5135 if (NT_STATUS_IS_OK(status)) {
5136 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5140 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5142 status = cli_close(cli1, fnum1);
5143 if (!NT_STATUS_IS_OK(status)) {
5144 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5148 printf("non-io open test #4 passed.\n");
5150 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5152 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
5154 status = cli_ntcreate(cli1, fname, 0,
5155 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5156 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5157 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5158 if (!NT_STATUS_IS_OK(status)) {
5159 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5163 status = cli_ntcreate(cli2, fname, 0,
5164 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5165 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5166 FILE_OPEN_IF, 0, 0, &fnum2);
5167 if (!NT_STATUS_IS_OK(status)) {
5168 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5172 status = cli_close(cli1, fnum1);
5173 if (!NT_STATUS_IS_OK(status)) {
5174 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5178 status = cli_close(cli2, fnum2);
5179 if (!NT_STATUS_IS_OK(status)) {
5180 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5184 printf("non-io open test #5 passed.\n");
5186 printf("TEST #6 testing 1 non-io open, one io open\n");
5188 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5190 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5191 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5192 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5193 if (!NT_STATUS_IS_OK(status)) {
5194 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5198 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5199 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5200 FILE_OPEN_IF, 0, 0, &fnum2);
5201 if (!NT_STATUS_IS_OK(status)) {
5202 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5206 status = cli_close(cli1, fnum1);
5207 if (!NT_STATUS_IS_OK(status)) {
5208 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5212 status = cli_close(cli2, fnum2);
5213 if (!NT_STATUS_IS_OK(status)) {
5214 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5218 printf("non-io open test #6 passed.\n");
5220 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5222 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5224 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5225 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5226 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5227 if (!NT_STATUS_IS_OK(status)) {
5228 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5232 status = cli_ntcreate(cli2, fname, 0,
5233 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5234 FILE_ATTRIBUTE_NORMAL,
5235 FILE_SHARE_READ|FILE_SHARE_DELETE,
5236 FILE_OPEN_IF, 0, 0, &fnum2);
5237 if (NT_STATUS_IS_OK(status)) {
5238 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5242 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5244 status = cli_close(cli1, fnum1);
5245 if (!NT_STATUS_IS_OK(status)) {
5246 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5250 printf("non-io open test #7 passed.\n");
5252 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5254 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5255 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5256 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5257 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5258 if (!NT_STATUS_IS_OK(status)) {
5259 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5264 /* Write to ensure we have to update the file time. */
5265 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5267 if (!NT_STATUS_IS_OK(status)) {
5268 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5273 status = cli_close(cli1, fnum1);
5274 if (!NT_STATUS_IS_OK(status)) {
5275 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5281 if (!torture_close_connection(cli1)) {
5284 if (!torture_close_connection(cli2)) {
5291 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5293 uint16 major, minor;
5294 uint32 caplow, caphigh;
5297 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5298 printf("Server doesn't support UNIX CIFS extensions.\n");
5299 return NT_STATUS_NOT_SUPPORTED;
5302 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5304 if (!NT_STATUS_IS_OK(status)) {
5305 printf("Server didn't return UNIX CIFS extensions: %s\n",
5310 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5312 if (!NT_STATUS_IS_OK(status)) {
5313 printf("Server doesn't support setting UNIX CIFS extensions: "
5314 "%s.\n", nt_errstr(status));
5318 return NT_STATUS_OK;
5322 Test POSIX open /mkdir calls.
5324 static bool run_simple_posix_open_test(int dummy)
5326 static struct cli_state *cli1;
5327 const char *fname = "posix:file";
5328 const char *hname = "posix:hlink";
5329 const char *sname = "posix:symlink";
5330 const char *dname = "posix:dir";
5333 uint16_t fnum1 = (uint16_t)-1;
5334 SMB_STRUCT_STAT sbuf;
5335 bool correct = false;
5339 printf("Starting simple POSIX open test\n");
5341 if (!torture_open_connection(&cli1, 0)) {
5345 cli_sockopt(cli1, sockops);
5347 status = torture_setup_unix_extensions(cli1);
5348 if (!NT_STATUS_IS_OK(status)) {
5352 cli_setatr(cli1, fname, 0, 0);
5353 cli_posix_unlink(cli1, fname);
5354 cli_setatr(cli1, dname, 0, 0);
5355 cli_posix_rmdir(cli1, dname);
5356 cli_setatr(cli1, hname, 0, 0);
5357 cli_posix_unlink(cli1, hname);
5358 cli_setatr(cli1, sname, 0, 0);
5359 cli_posix_unlink(cli1, sname);
5361 /* Create a directory. */
5362 status = cli_posix_mkdir(cli1, dname, 0777);
5363 if (!NT_STATUS_IS_OK(status)) {
5364 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5368 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5370 if (!NT_STATUS_IS_OK(status)) {
5371 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5375 /* Test ftruncate - set file size. */
5376 status = cli_ftruncate(cli1, fnum1, 1000);
5377 if (!NT_STATUS_IS_OK(status)) {
5378 printf("ftruncate failed (%s)\n", nt_errstr(status));
5382 /* Ensure st_size == 1000 */
5383 status = cli_posix_stat(cli1, fname, &sbuf);
5384 if (!NT_STATUS_IS_OK(status)) {
5385 printf("stat failed (%s)\n", nt_errstr(status));
5389 if (sbuf.st_ex_size != 1000) {
5390 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5394 /* Test ftruncate - set file size back to zero. */
5395 status = cli_ftruncate(cli1, fnum1, 0);
5396 if (!NT_STATUS_IS_OK(status)) {
5397 printf("ftruncate failed (%s)\n", nt_errstr(status));
5401 status = cli_close(cli1, fnum1);
5402 if (!NT_STATUS_IS_OK(status)) {
5403 printf("close failed (%s)\n", nt_errstr(status));
5407 /* Now open the file again for read only. */
5408 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5409 if (!NT_STATUS_IS_OK(status)) {
5410 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5414 /* Now unlink while open. */
5415 status = cli_posix_unlink(cli1, fname);
5416 if (!NT_STATUS_IS_OK(status)) {
5417 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5421 status = cli_close(cli1, fnum1);
5422 if (!NT_STATUS_IS_OK(status)) {
5423 printf("close(2) failed (%s)\n", nt_errstr(status));
5427 /* Ensure the file has gone. */
5428 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5429 if (NT_STATUS_IS_OK(status)) {
5430 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5434 /* Create again to test open with O_TRUNC. */
5435 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1);
5436 if (!NT_STATUS_IS_OK(status)) {
5437 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5441 /* Test ftruncate - set file size. */
5442 status = cli_ftruncate(cli1, fnum1, 1000);
5443 if (!NT_STATUS_IS_OK(status)) {
5444 printf("ftruncate failed (%s)\n", nt_errstr(status));
5448 /* Ensure st_size == 1000 */
5449 status = cli_posix_stat(cli1, fname, &sbuf);
5450 if (!NT_STATUS_IS_OK(status)) {
5451 printf("stat failed (%s)\n", nt_errstr(status));
5455 if (sbuf.st_ex_size != 1000) {
5456 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5460 status = cli_close(cli1, fnum1);
5461 if (!NT_STATUS_IS_OK(status)) {
5462 printf("close(2) failed (%s)\n", nt_errstr(status));
5466 /* Re-open with O_TRUNC. */
5467 status = cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1);
5468 if (!NT_STATUS_IS_OK(status)) {
5469 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5473 /* Ensure st_size == 0 */
5474 status = cli_posix_stat(cli1, fname, &sbuf);
5475 if (!NT_STATUS_IS_OK(status)) {
5476 printf("stat failed (%s)\n", nt_errstr(status));
5480 if (sbuf.st_ex_size != 0) {
5481 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5485 status = cli_close(cli1, fnum1);
5486 if (!NT_STATUS_IS_OK(status)) {
5487 printf("close failed (%s)\n", nt_errstr(status));
5491 status = cli_posix_unlink(cli1, fname);
5492 if (!NT_STATUS_IS_OK(status)) {
5493 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5497 status = cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1);
5498 if (!NT_STATUS_IS_OK(status)) {
5499 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5500 dname, nt_errstr(status));
5504 cli_close(cli1, fnum1);
5506 /* What happens when we try and POSIX open a directory for write ? */
5507 status = cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1);
5508 if (NT_STATUS_IS_OK(status)) {
5509 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5512 if (!check_both_error(__LINE__, status, ERRDOS, EISDIR,
5513 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5518 /* Create the file. */
5519 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5521 if (!NT_STATUS_IS_OK(status)) {
5522 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5526 /* Write some data into it. */
5527 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5529 if (!NT_STATUS_IS_OK(status)) {
5530 printf("cli_write failed: %s\n", nt_errstr(status));
5534 cli_close(cli1, fnum1);
5536 /* Now create a hardlink. */
5537 status = cli_posix_hardlink(cli1, fname, hname);
5538 if (!NT_STATUS_IS_OK(status)) {
5539 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5543 /* Now create a symlink. */
5544 status = cli_posix_symlink(cli1, fname, sname);
5545 if (!NT_STATUS_IS_OK(status)) {
5546 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5550 /* Open the hardlink for read. */
5551 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5552 if (!NT_STATUS_IS_OK(status)) {
5553 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5557 status = cli_read(cli1, fnum1, buf, 0, 10, &nread);
5558 if (!NT_STATUS_IS_OK(status)) {
5559 printf("POSIX read of %s failed (%s)\n", hname,
5562 } else if (nread != 10) {
5563 printf("POSIX read of %s failed. Received %ld, expected %d\n",
5564 hname, (unsigned long)nread, 10);
5568 if (memcmp(buf, "TEST DATA\n", 10)) {
5569 printf("invalid data read from hardlink\n");
5573 /* Do a POSIX lock/unlock. */
5574 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5575 if (!NT_STATUS_IS_OK(status)) {
5576 printf("POSIX lock failed %s\n", nt_errstr(status));
5580 /* Punch a hole in the locked area. */
5581 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5582 if (!NT_STATUS_IS_OK(status)) {
5583 printf("POSIX unlock failed %s\n", nt_errstr(status));
5587 cli_close(cli1, fnum1);
5589 /* Open the symlink for read - this should fail. A POSIX
5590 client should not be doing opens on a symlink. */
5591 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5592 if (NT_STATUS_IS_OK(status)) {
5593 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5596 if (!check_both_error(__LINE__, status, ERRDOS, ERRbadpath,
5597 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5598 printf("POSIX open of %s should have failed "
5599 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5600 "failed with %s instead.\n",
5601 sname, nt_errstr(status));
5606 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5607 if (!NT_STATUS_IS_OK(status)) {
5608 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5612 if (strcmp(namebuf, fname) != 0) {
5613 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5614 sname, fname, namebuf);
5618 status = cli_posix_rmdir(cli1, dname);
5619 if (!NT_STATUS_IS_OK(status)) {
5620 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5624 printf("Simple POSIX open test passed\n");
5629 if (fnum1 != (uint16_t)-1) {
5630 cli_close(cli1, fnum1);
5631 fnum1 = (uint16_t)-1;
5634 cli_setatr(cli1, sname, 0, 0);
5635 cli_posix_unlink(cli1, sname);
5636 cli_setatr(cli1, hname, 0, 0);
5637 cli_posix_unlink(cli1, hname);
5638 cli_setatr(cli1, fname, 0, 0);
5639 cli_posix_unlink(cli1, fname);
5640 cli_setatr(cli1, dname, 0, 0);
5641 cli_posix_rmdir(cli1, dname);
5643 if (!torture_close_connection(cli1)) {
5651 static uint32 open_attrs_table[] = {
5652 FILE_ATTRIBUTE_NORMAL,
5653 FILE_ATTRIBUTE_ARCHIVE,
5654 FILE_ATTRIBUTE_READONLY,
5655 FILE_ATTRIBUTE_HIDDEN,
5656 FILE_ATTRIBUTE_SYSTEM,
5658 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5659 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5660 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5661 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5662 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5663 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5665 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5666 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5667 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5668 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5671 struct trunc_open_results {
5678 static struct trunc_open_results attr_results[] = {
5679 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5680 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5681 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5682 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5683 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5684 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5685 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5686 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5687 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5688 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5689 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5690 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5691 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5692 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5693 { 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 },
5694 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5695 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5696 { 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 },
5697 { 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 },
5698 { 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 },
5699 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5700 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5701 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5702 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5703 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5704 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5707 static bool run_openattrtest(int dummy)
5709 static struct cli_state *cli1;
5710 const char *fname = "\\openattr.file";
5712 bool correct = True;
5714 unsigned int i, j, k, l;
5717 printf("starting open attr test\n");
5719 if (!torture_open_connection(&cli1, 0)) {
5723 cli_sockopt(cli1, sockops);
5725 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5726 cli_setatr(cli1, fname, 0, 0);
5727 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5729 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5730 open_attrs_table[i], FILE_SHARE_NONE,
5731 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5732 if (!NT_STATUS_IS_OK(status)) {
5733 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5737 status = cli_close(cli1, fnum1);
5738 if (!NT_STATUS_IS_OK(status)) {
5739 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5743 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5744 status = cli_ntcreate(cli1, fname, 0,
5745 FILE_READ_DATA|FILE_WRITE_DATA,
5746 open_attrs_table[j],
5747 FILE_SHARE_NONE, FILE_OVERWRITE,
5749 if (!NT_STATUS_IS_OK(status)) {
5750 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5751 if (attr_results[l].num == k) {
5752 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5753 k, open_attrs_table[i],
5754 open_attrs_table[j],
5755 fname, NT_STATUS_V(status), nt_errstr(status));
5760 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5761 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5762 k, open_attrs_table[i], open_attrs_table[j],
5767 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5773 status = cli_close(cli1, fnum1);
5774 if (!NT_STATUS_IS_OK(status)) {
5775 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5779 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5780 if (!NT_STATUS_IS_OK(status)) {
5781 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5786 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5787 k, open_attrs_table[i], open_attrs_table[j], attr );
5790 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5791 if (attr_results[l].num == k) {
5792 if (attr != attr_results[l].result_attr ||
5793 open_attrs_table[i] != attr_results[l].init_attr ||
5794 open_attrs_table[j] != attr_results[l].trunc_attr) {
5795 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5796 open_attrs_table[i],
5797 open_attrs_table[j],
5799 attr_results[l].result_attr);
5809 cli_setatr(cli1, fname, 0, 0);
5810 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5812 printf("open attr test %s.\n", correct ? "passed" : "failed");
5814 if (!torture_close_connection(cli1)) {
5820 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5821 const char *name, void *state)
5823 int *matched = (int *)state;
5824 if (matched != NULL) {
5827 return NT_STATUS_OK;
5831 test directory listing speed
5833 static bool run_dirtest(int dummy)
5836 static struct cli_state *cli;
5838 struct timeval core_start;
5839 bool correct = True;
5842 printf("starting directory test\n");
5844 if (!torture_open_connection(&cli, 0)) {
5848 cli_sockopt(cli, sockops);
5851 for (i=0;i<torture_numops;i++) {
5853 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5854 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5855 fprintf(stderr,"Failed to open %s\n", fname);
5858 cli_close(cli, fnum);
5861 core_start = timeval_current();
5864 cli_list(cli, "a*.*", 0, list_fn, &matched);
5865 printf("Matched %d\n", matched);
5868 cli_list(cli, "b*.*", 0, list_fn, &matched);
5869 printf("Matched %d\n", matched);
5872 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5873 printf("Matched %d\n", matched);
5875 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5878 for (i=0;i<torture_numops;i++) {
5880 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5881 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5884 if (!torture_close_connection(cli)) {
5888 printf("finished dirtest\n");
5893 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5896 struct cli_state *pcli = (struct cli_state *)state;
5898 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5900 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5901 return NT_STATUS_OK;
5903 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5904 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5905 printf("del_fn: failed to rmdir %s\n,", fname );
5907 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5908 printf("del_fn: failed to unlink %s\n,", fname );
5910 return NT_STATUS_OK;
5915 sees what IOCTLs are supported
5917 bool torture_ioctl_test(int dummy)
5919 static struct cli_state *cli;
5920 uint16_t device, function;
5922 const char *fname = "\\ioctl.dat";
5926 if (!torture_open_connection(&cli, 0)) {
5930 printf("starting ioctl test\n");
5932 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5934 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5935 if (!NT_STATUS_IS_OK(status)) {
5936 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5940 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5941 printf("ioctl device info: %s\n", nt_errstr(status));
5943 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5944 printf("ioctl job info: %s\n", nt_errstr(status));
5946 for (device=0;device<0x100;device++) {
5947 printf("ioctl test with device = 0x%x\n", device);
5948 for (function=0;function<0x100;function++) {
5949 uint32 code = (device<<16) | function;
5951 status = cli_raw_ioctl(cli, fnum, code, &blob);
5953 if (NT_STATUS_IS_OK(status)) {
5954 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5956 data_blob_free(&blob);
5961 if (!torture_close_connection(cli)) {
5970 tries varients of chkpath
5972 bool torture_chkpath_test(int dummy)
5974 static struct cli_state *cli;
5979 if (!torture_open_connection(&cli, 0)) {
5983 printf("starting chkpath test\n");
5985 /* cleanup from an old run */
5986 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5987 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5988 cli_rmdir(cli, "\\chkpath.dir");
5990 status = cli_mkdir(cli, "\\chkpath.dir");
5991 if (!NT_STATUS_IS_OK(status)) {
5992 printf("mkdir1 failed : %s\n", nt_errstr(status));
5996 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5997 if (!NT_STATUS_IS_OK(status)) {
5998 printf("mkdir2 failed : %s\n", nt_errstr(status));
6002 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
6004 if (!NT_STATUS_IS_OK(status)) {
6005 printf("open1 failed (%s)\n", nt_errstr(status));
6008 cli_close(cli, fnum);
6010 status = cli_chkpath(cli, "\\chkpath.dir");
6011 if (!NT_STATUS_IS_OK(status)) {
6012 printf("chkpath1 failed: %s\n", nt_errstr(status));
6016 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
6017 if (!NT_STATUS_IS_OK(status)) {
6018 printf("chkpath2 failed: %s\n", nt_errstr(status));
6022 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
6023 if (!NT_STATUS_IS_OK(status)) {
6024 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6025 NT_STATUS_NOT_A_DIRECTORY);
6027 printf("* chkpath on a file should fail\n");
6031 status = cli_chkpath(cli, "\\chkpath.dir\\bar.txt");
6032 if (!NT_STATUS_IS_OK(status)) {
6033 ret = check_error(__LINE__, status, ERRDOS, ERRbadfile,
6034 NT_STATUS_OBJECT_NAME_NOT_FOUND);
6036 printf("* chkpath on a non existant file should fail\n");
6040 status = cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt");
6041 if (!NT_STATUS_IS_OK(status)) {
6042 ret = check_error(__LINE__, status, ERRDOS, ERRbadpath,
6043 NT_STATUS_OBJECT_PATH_NOT_FOUND);
6045 printf("* chkpath on a non existent component should fail\n");
6049 cli_rmdir(cli, "\\chkpath.dir\\dir2");
6050 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6051 cli_rmdir(cli, "\\chkpath.dir");
6053 if (!torture_close_connection(cli)) {
6060 static bool run_eatest(int dummy)
6062 static struct cli_state *cli;
6063 const char *fname = "\\eatest.txt";
6064 bool correct = True;
6068 struct ea_struct *ea_list = NULL;
6069 TALLOC_CTX *mem_ctx = talloc_init("eatest");
6072 printf("starting eatest\n");
6074 if (!torture_open_connection(&cli, 0)) {
6075 talloc_destroy(mem_ctx);
6079 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6081 status = cli_ntcreate(cli, fname, 0,
6082 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6083 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
6085 if (!NT_STATUS_IS_OK(status)) {
6086 printf("open failed - %s\n", nt_errstr(status));
6087 talloc_destroy(mem_ctx);
6091 for (i = 0; i < 10; i++) {
6092 fstring ea_name, ea_val;
6094 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
6095 memset(ea_val, (char)i+1, i+1);
6096 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
6097 if (!NT_STATUS_IS_OK(status)) {
6098 printf("ea_set of name %s failed - %s\n", ea_name,
6100 talloc_destroy(mem_ctx);
6105 cli_close(cli, fnum);
6106 for (i = 0; i < 10; i++) {
6107 fstring ea_name, ea_val;
6109 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
6110 memset(ea_val, (char)i+1, i+1);
6111 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
6112 if (!NT_STATUS_IS_OK(status)) {
6113 printf("ea_set of name %s failed - %s\n", ea_name,
6115 talloc_destroy(mem_ctx);
6120 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6121 if (!NT_STATUS_IS_OK(status)) {
6122 printf("ea_get list failed - %s\n", nt_errstr(status));
6126 printf("num_eas = %d\n", (int)num_eas);
6128 if (num_eas != 20) {
6129 printf("Should be 20 EA's stored... failing.\n");
6133 for (i = 0; i < num_eas; i++) {
6134 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6135 dump_data(0, ea_list[i].value.data,
6136 ea_list[i].value.length);
6139 /* Setting EA's to zero length deletes them. Test this */
6140 printf("Now deleting all EA's - case indepenent....\n");
6143 cli_set_ea_path(cli, fname, "", "", 0);
6145 for (i = 0; i < 20; i++) {
6147 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
6148 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
6149 if (!NT_STATUS_IS_OK(status)) {
6150 printf("ea_set of name %s failed - %s\n", ea_name,
6152 talloc_destroy(mem_ctx);
6158 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
6159 if (!NT_STATUS_IS_OK(status)) {
6160 printf("ea_get list failed - %s\n", nt_errstr(status));
6164 printf("num_eas = %d\n", (int)num_eas);
6165 for (i = 0; i < num_eas; i++) {
6166 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
6167 dump_data(0, ea_list[i].value.data,
6168 ea_list[i].value.length);
6172 printf("deleting EA's failed.\n");
6176 /* Try and delete a non existant EA. */
6177 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6178 if (!NT_STATUS_IS_OK(status)) {
6179 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6184 talloc_destroy(mem_ctx);
6185 if (!torture_close_connection(cli)) {
6192 static bool run_dirtest1(int dummy)
6195 static struct cli_state *cli;
6198 bool correct = True;
6200 printf("starting directory test\n");
6202 if (!torture_open_connection(&cli, 0)) {
6206 cli_sockopt(cli, sockops);
6208 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6209 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6210 cli_rmdir(cli, "\\LISTDIR");
6211 cli_mkdir(cli, "\\LISTDIR");
6213 /* Create 1000 files and 1000 directories. */
6214 for (i=0;i<1000;i++) {
6216 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6217 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6218 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6219 fprintf(stderr,"Failed to open %s\n", fname);
6222 cli_close(cli, fnum);
6224 for (i=0;i<1000;i++) {
6226 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6227 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6228 fprintf(stderr,"Failed to open %s\n", fname);
6233 /* Now ensure that doing an old list sees both files and directories. */
6235 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6236 printf("num_seen = %d\n", num_seen );
6237 /* We should see 100 files + 1000 directories + . and .. */
6238 if (num_seen != 2002)
6241 /* Ensure if we have the "must have" bits we only see the
6245 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6246 printf("num_seen = %d\n", num_seen );
6247 if (num_seen != 1002)
6251 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6252 printf("num_seen = %d\n", num_seen );
6253 if (num_seen != 1000)
6256 /* Delete everything. */
6257 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6258 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6259 cli_rmdir(cli, "\\LISTDIR");
6262 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6263 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6264 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6267 if (!torture_close_connection(cli)) {
6271 printf("finished dirtest1\n");
6276 static bool run_error_map_extract(int dummy) {
6278 static struct cli_state *c_dos;
6279 static struct cli_state *c_nt;
6291 /* NT-Error connection */
6293 disable_spnego = true;
6294 if (!(c_nt = open_nbt_connection())) {
6295 disable_spnego = false;
6298 disable_spnego = false;
6300 status = cli_negprot(c_nt);
6302 if (!NT_STATUS_IS_OK(status)) {
6303 printf("%s rejected the NT-error negprot (%s)\n", host,
6309 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6310 if (!NT_STATUS_IS_OK(status)) {
6311 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6315 /* DOS-Error connection */
6317 disable_spnego = true;
6318 force_dos_errors = true;
6319 if (!(c_dos = open_nbt_connection())) {
6320 disable_spnego = false;
6321 force_dos_errors = false;
6324 disable_spnego = false;
6325 force_dos_errors = false;
6327 status = cli_negprot(c_dos);
6328 if (!NT_STATUS_IS_OK(status)) {
6329 printf("%s rejected the DOS-error negprot (%s)\n", host,
6331 cli_shutdown(c_dos);
6335 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6336 if (!NT_STATUS_IS_OK(status)) {
6337 printf("%s rejected the DOS-error initial session setup (%s)\n",
6338 host, nt_errstr(status));
6342 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6343 fstr_sprintf(user, "%X", error);
6345 status = cli_session_setup(c_nt, user,
6346 password, strlen(password),
6347 password, strlen(password),
6349 if (NT_STATUS_IS_OK(status)) {
6350 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6353 /* Case #1: 32-bit NT errors */
6354 if (cli_is_nt_error(c_nt)) {
6355 nt_status = cli_nt_error(c_nt);
6357 printf("/** Dos error on NT connection! (%s) */\n",
6359 nt_status = NT_STATUS(0xc0000000);
6362 status = cli_session_setup(c_dos, user,
6363 password, strlen(password),
6364 password, strlen(password),
6366 if (NT_STATUS_IS_OK(status)) {
6367 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6370 /* Case #1: 32-bit NT errors */
6371 if (!cli_is_dos_error(c_dos)) {
6372 printf("/** NT error on DOS connection! (%s) */\n",
6374 errnum = errclass = 0;
6376 cli_dos_error(c_dos, &errclass, &errnum);
6379 if (NT_STATUS_V(nt_status) != error) {
6380 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6381 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6382 get_nt_error_c_code(talloc_tos(), nt_status));
6385 printf("\t{%s,\t%s,\t%s},\n",
6386 smb_dos_err_class(errclass),
6387 smb_dos_err_name(errclass, errnum),
6388 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6393 static bool run_sesssetup_bench(int dummy)
6395 static struct cli_state *c;
6396 const char *fname = "\\file.dat";
6401 if (!torture_open_connection(&c, 0)) {
6405 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6406 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6407 FILE_DELETE_ON_CLOSE, 0, &fnum);
6408 if (!NT_STATUS_IS_OK(status)) {
6409 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6413 for (i=0; i<torture_numops; i++) {
6414 status = cli_session_setup(
6416 password, strlen(password),
6417 password, strlen(password),
6419 if (!NT_STATUS_IS_OK(status)) {
6420 d_printf("(%s) cli_session_setup failed: %s\n",
6421 __location__, nt_errstr(status));
6425 d_printf("\r%d ", (int)cli_state_get_uid(c));
6427 status = cli_ulogoff(c);
6428 if (!NT_STATUS_IS_OK(status)) {
6429 d_printf("(%s) cli_ulogoff failed: %s\n",
6430 __location__, nt_errstr(status));
6438 static bool subst_test(const char *str, const char *user, const char *domain,
6439 uid_t uid, gid_t gid, const char *expected)
6444 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6446 if (strcmp(subst, expected) != 0) {
6447 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6448 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6457 static void chain1_open_completion(struct tevent_req *req)
6461 status = cli_open_recv(req, &fnum);
6464 d_printf("cli_open_recv returned %s: %d\n",
6466 NT_STATUS_IS_OK(status) ? fnum : -1);
6469 static void chain1_write_completion(struct tevent_req *req)
6473 status = cli_write_andx_recv(req, &written);
6476 d_printf("cli_write_andx_recv returned %s: %d\n",
6478 NT_STATUS_IS_OK(status) ? (int)written : -1);
6481 static void chain1_close_completion(struct tevent_req *req)
6484 bool *done = (bool *)tevent_req_callback_data_void(req);
6486 status = cli_close_recv(req);
6491 d_printf("cli_close returned %s\n", nt_errstr(status));
6494 static bool run_chain1(int dummy)
6496 struct cli_state *cli1;
6497 struct event_context *evt = event_context_init(NULL);
6498 struct tevent_req *reqs[3], *smbreqs[3];
6500 const char *str = "foobar";
6503 printf("starting chain1 test\n");
6504 if (!torture_open_connection(&cli1, 0)) {
6508 cli_sockopt(cli1, sockops);
6510 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6511 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6512 if (reqs[0] == NULL) return false;
6513 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6516 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6517 (const uint8_t *)str, 0, strlen(str)+1,
6518 smbreqs, 1, &smbreqs[1]);
6519 if (reqs[1] == NULL) return false;
6520 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6522 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6523 if (reqs[2] == NULL) return false;
6524 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6526 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6527 if (!NT_STATUS_IS_OK(status)) {
6532 tevent_loop_once(evt);
6535 torture_close_connection(cli1);
6539 static void chain2_sesssetup_completion(struct tevent_req *req)
6542 status = cli_session_setup_guest_recv(req);
6543 d_printf("sesssetup returned %s\n", nt_errstr(status));
6546 static void chain2_tcon_completion(struct tevent_req *req)
6548 bool *done = (bool *)tevent_req_callback_data_void(req);
6550 status = cli_tcon_andx_recv(req);
6551 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6555 static bool run_chain2(int dummy)
6557 struct cli_state *cli1;
6558 struct event_context *evt = event_context_init(NULL);
6559 struct tevent_req *reqs[2], *smbreqs[2];
6563 printf("starting chain2 test\n");
6564 status = cli_start_connection(&cli1, lp_netbios_name(), host, NULL,
6565 port_to_use, Undefined, 0);
6566 if (!NT_STATUS_IS_OK(status)) {
6570 cli_sockopt(cli1, sockops);
6572 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6574 if (reqs[0] == NULL) return false;
6575 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6577 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6578 "?????", NULL, 0, &smbreqs[1]);
6579 if (reqs[1] == NULL) return false;
6580 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6582 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6583 if (!NT_STATUS_IS_OK(status)) {
6588 tevent_loop_once(evt);
6591 torture_close_connection(cli1);
6596 struct torture_createdel_state {
6597 struct tevent_context *ev;
6598 struct cli_state *cli;
6601 static void torture_createdel_created(struct tevent_req *subreq);
6602 static void torture_createdel_closed(struct tevent_req *subreq);
6604 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6605 struct tevent_context *ev,
6606 struct cli_state *cli,
6609 struct tevent_req *req, *subreq;
6610 struct torture_createdel_state *state;
6612 req = tevent_req_create(mem_ctx, &state,
6613 struct torture_createdel_state);
6620 subreq = cli_ntcreate_send(
6621 state, ev, cli, name, 0,
6622 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6623 FILE_ATTRIBUTE_NORMAL,
6624 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6625 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6627 if (tevent_req_nomem(subreq, req)) {
6628 return tevent_req_post(req, ev);
6630 tevent_req_set_callback(subreq, torture_createdel_created, req);
6634 static void torture_createdel_created(struct tevent_req *subreq)
6636 struct tevent_req *req = tevent_req_callback_data(
6637 subreq, struct tevent_req);
6638 struct torture_createdel_state *state = tevent_req_data(
6639 req, struct torture_createdel_state);
6643 status = cli_ntcreate_recv(subreq, &fnum);
6644 TALLOC_FREE(subreq);
6645 if (!NT_STATUS_IS_OK(status)) {
6646 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6647 nt_errstr(status)));
6648 tevent_req_nterror(req, status);
6652 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6653 if (tevent_req_nomem(subreq, req)) {
6656 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6659 static void torture_createdel_closed(struct tevent_req *subreq)
6661 struct tevent_req *req = tevent_req_callback_data(
6662 subreq, struct tevent_req);
6665 status = cli_close_recv(subreq);
6666 if (!NT_STATUS_IS_OK(status)) {
6667 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6668 tevent_req_nterror(req, status);
6671 tevent_req_done(req);
6674 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6676 return tevent_req_simple_recv_ntstatus(req);
6679 struct torture_createdels_state {
6680 struct tevent_context *ev;
6681 struct cli_state *cli;
6682 const char *base_name;
6686 struct tevent_req **reqs;
6689 static void torture_createdels_done(struct tevent_req *subreq);
6691 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6692 struct tevent_context *ev,
6693 struct cli_state *cli,
6694 const char *base_name,
6698 struct tevent_req *req;
6699 struct torture_createdels_state *state;
6702 req = tevent_req_create(mem_ctx, &state,
6703 struct torture_createdels_state);
6709 state->base_name = talloc_strdup(state, base_name);
6710 if (tevent_req_nomem(state->base_name, req)) {
6711 return tevent_req_post(req, ev);
6713 state->num_files = MAX(num_parallel, num_files);
6715 state->received = 0;
6717 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6718 if (tevent_req_nomem(state->reqs, req)) {
6719 return tevent_req_post(req, ev);
6722 for (i=0; i<num_parallel; i++) {
6725 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6727 if (tevent_req_nomem(name, req)) {
6728 return tevent_req_post(req, ev);
6730 state->reqs[i] = torture_createdel_send(
6731 state->reqs, state->ev, state->cli, name);
6732 if (tevent_req_nomem(state->reqs[i], req)) {
6733 return tevent_req_post(req, ev);
6735 name = talloc_move(state->reqs[i], &name);
6736 tevent_req_set_callback(state->reqs[i],
6737 torture_createdels_done, req);
6743 static void torture_createdels_done(struct tevent_req *subreq)
6745 struct tevent_req *req = tevent_req_callback_data(
6746 subreq, struct tevent_req);
6747 struct torture_createdels_state *state = tevent_req_data(
6748 req, struct torture_createdels_state);
6749 size_t num_parallel = talloc_array_length(state->reqs);
6754 status = torture_createdel_recv(subreq);
6755 if (!NT_STATUS_IS_OK(status)){
6756 DEBUG(10, ("torture_createdel_recv returned %s\n",
6757 nt_errstr(status)));
6758 TALLOC_FREE(subreq);
6759 tevent_req_nterror(req, status);
6763 for (i=0; i<num_parallel; i++) {
6764 if (subreq == state->reqs[i]) {
6768 if (i == num_parallel) {
6769 DEBUG(10, ("received something we did not send\n"));
6770 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6773 TALLOC_FREE(state->reqs[i]);
6775 if (state->sent >= state->num_files) {
6776 tevent_req_done(req);
6780 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6782 if (tevent_req_nomem(name, req)) {
6785 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6787 if (tevent_req_nomem(state->reqs[i], req)) {
6790 name = talloc_move(state->reqs[i], &name);
6791 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6795 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6797 return tevent_req_simple_recv_ntstatus(req);
6800 struct swallow_notify_state {
6801 struct tevent_context *ev;
6802 struct cli_state *cli;
6804 uint32_t completion_filter;
6806 bool (*fn)(uint32_t action, const char *name, void *priv);
6810 static void swallow_notify_done(struct tevent_req *subreq);
6812 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6813 struct tevent_context *ev,
6814 struct cli_state *cli,
6816 uint32_t completion_filter,
6818 bool (*fn)(uint32_t action,
6823 struct tevent_req *req, *subreq;
6824 struct swallow_notify_state *state;
6826 req = tevent_req_create(mem_ctx, &state,
6827 struct swallow_notify_state);
6834 state->completion_filter = completion_filter;
6835 state->recursive = recursive;
6839 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6840 0xffff, state->completion_filter,
6842 if (tevent_req_nomem(subreq, req)) {
6843 return tevent_req_post(req, ev);
6845 tevent_req_set_callback(subreq, swallow_notify_done, req);
6849 static void swallow_notify_done(struct tevent_req *subreq)
6851 struct tevent_req *req = tevent_req_callback_data(
6852 subreq, struct tevent_req);
6853 struct swallow_notify_state *state = tevent_req_data(
6854 req, struct swallow_notify_state);
6856 uint32_t i, num_changes;
6857 struct notify_change *changes;
6859 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6860 TALLOC_FREE(subreq);
6861 if (!NT_STATUS_IS_OK(status)) {
6862 DEBUG(10, ("cli_notify_recv returned %s\n",
6863 nt_errstr(status)));
6864 tevent_req_nterror(req, status);
6868 for (i=0; i<num_changes; i++) {
6869 state->fn(changes[i].action, changes[i].name, state->priv);
6871 TALLOC_FREE(changes);
6873 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6874 0xffff, state->completion_filter,
6876 if (tevent_req_nomem(subreq, req)) {
6879 tevent_req_set_callback(subreq, swallow_notify_done, req);
6882 static bool print_notifies(uint32_t action, const char *name, void *priv)
6884 if (DEBUGLEVEL > 5) {
6885 d_printf("%d %s\n", (int)action, name);
6890 static void notify_bench_done(struct tevent_req *req)
6892 int *num_finished = (int *)tevent_req_callback_data_void(req);
6896 static bool run_notify_bench(int dummy)
6898 const char *dname = "\\notify-bench";
6899 struct tevent_context *ev;
6902 struct tevent_req *req1;
6903 struct tevent_req *req2 = NULL;
6904 int i, num_unc_names;
6905 int num_finished = 0;
6907 printf("starting notify-bench test\n");
6909 if (use_multishare_conn) {
6911 unc_list = file_lines_load(multishare_conn_fname,
6912 &num_unc_names, 0, NULL);
6913 if (!unc_list || num_unc_names <= 0) {
6914 d_printf("Failed to load unc names list from '%s'\n",
6915 multishare_conn_fname);
6918 TALLOC_FREE(unc_list);
6923 ev = tevent_context_init(talloc_tos());
6925 d_printf("tevent_context_init failed\n");
6929 for (i=0; i<num_unc_names; i++) {
6930 struct cli_state *cli;
6933 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6935 if (base_fname == NULL) {
6939 if (!torture_open_connection(&cli, i)) {
6943 status = cli_ntcreate(cli, dname, 0,
6944 MAXIMUM_ALLOWED_ACCESS,
6945 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6947 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6950 if (!NT_STATUS_IS_OK(status)) {
6951 d_printf("Could not create %s: %s\n", dname,
6956 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6957 FILE_NOTIFY_CHANGE_FILE_NAME |
6958 FILE_NOTIFY_CHANGE_DIR_NAME |
6959 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6960 FILE_NOTIFY_CHANGE_LAST_WRITE,
6961 false, print_notifies, NULL);
6963 d_printf("Could not create notify request\n");
6967 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6968 base_fname, 10, torture_numops);
6970 d_printf("Could not create createdels request\n");
6973 TALLOC_FREE(base_fname);
6975 tevent_req_set_callback(req2, notify_bench_done,
6979 while (num_finished < num_unc_names) {
6981 ret = tevent_loop_once(ev);
6983 d_printf("tevent_loop_once failed\n");
6988 if (!tevent_req_poll(req2, ev)) {
6989 d_printf("tevent_req_poll failed\n");
6992 status = torture_createdels_recv(req2);
6993 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6998 static bool run_mangle1(int dummy)
7000 struct cli_state *cli;
7001 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
7005 time_t change_time, access_time, write_time;
7009 printf("starting mangle1 test\n");
7010 if (!torture_open_connection(&cli, 0)) {
7014 cli_sockopt(cli, sockops);
7016 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
7017 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
7019 if (!NT_STATUS_IS_OK(status)) {
7020 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
7023 cli_close(cli, fnum);
7025 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
7026 if (!NT_STATUS_IS_OK(status)) {
7027 d_printf("cli_qpathinfo_alt_name failed: %s\n",
7031 d_printf("alt_name: %s\n", alt_name);
7033 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
7034 if (!NT_STATUS_IS_OK(status)) {
7035 d_printf("cli_open(%s) failed: %s\n", alt_name,
7039 cli_close(cli, fnum);
7041 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
7042 &write_time, &size, &mode);
7043 if (!NT_STATUS_IS_OK(status)) {
7044 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
7052 static size_t null_source(uint8_t *buf, size_t n, void *priv)
7054 size_t *to_pull = (size_t *)priv;
7055 size_t thistime = *to_pull;
7057 thistime = MIN(thistime, n);
7058 if (thistime == 0) {
7062 memset(buf, 0, thistime);
7063 *to_pull -= thistime;
7067 static bool run_windows_write(int dummy)
7069 struct cli_state *cli1;
7073 const char *fname = "\\writetest.txt";
7074 struct timeval start_time;
7079 printf("starting windows_write test\n");
7080 if (!torture_open_connection(&cli1, 0)) {
7084 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
7085 if (!NT_STATUS_IS_OK(status)) {
7086 printf("open failed (%s)\n", nt_errstr(status));
7090 cli_sockopt(cli1, sockops);
7092 start_time = timeval_current();
7094 for (i=0; i<torture_numops; i++) {
7096 off_t start = i * torture_blocksize;
7097 size_t to_pull = torture_blocksize - 1;
7099 status = cli_writeall(cli1, fnum, 0, &c,
7100 start + torture_blocksize - 1, 1, NULL);
7101 if (!NT_STATUS_IS_OK(status)) {
7102 printf("cli_write failed: %s\n", nt_errstr(status));
7106 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
7107 null_source, &to_pull);
7108 if (!NT_STATUS_IS_OK(status)) {
7109 printf("cli_push returned: %s\n", nt_errstr(status));
7114 seconds = timeval_elapsed(&start_time);
7115 kbytes = (double)torture_blocksize * torture_numops;
7118 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
7119 (double)seconds, (int)(kbytes/seconds));
7123 cli_close(cli1, fnum);
7124 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7125 torture_close_connection(cli1);
7129 static bool run_cli_echo(int dummy)
7131 struct cli_state *cli;
7134 printf("starting cli_echo test\n");
7135 if (!torture_open_connection(&cli, 0)) {
7138 cli_sockopt(cli, sockops);
7140 status = cli_echo(cli, 5, data_blob_const("hello", 5));
7142 d_printf("cli_echo returned %s\n", nt_errstr(status));
7144 torture_close_connection(cli);
7145 return NT_STATUS_IS_OK(status);
7148 static bool run_uid_regression_test(int dummy)
7150 static struct cli_state *cli;
7153 bool correct = True;
7156 printf("starting uid regression test\n");
7158 if (!torture_open_connection(&cli, 0)) {
7162 cli_sockopt(cli, sockops);
7164 /* Ok - now save then logoff our current user. */
7165 old_vuid = cli_state_get_uid(cli);
7167 status = cli_ulogoff(cli);
7168 if (!NT_STATUS_IS_OK(status)) {
7169 d_printf("(%s) cli_ulogoff failed: %s\n",
7170 __location__, nt_errstr(status));
7175 cli_state_set_uid(cli, old_vuid);
7177 /* Try an operation. */
7178 status = cli_mkdir(cli, "\\uid_reg_test");
7179 if (NT_STATUS_IS_OK(status)) {
7180 d_printf("(%s) cli_mkdir succeeded\n",
7185 /* Should be bad uid. */
7186 if (!check_error(__LINE__, status, ERRSRV, ERRbaduid,
7187 NT_STATUS_USER_SESSION_DELETED)) {
7193 old_cnum = cli_state_get_tid(cli);
7195 /* Now try a SMBtdis with the invald vuid set to zero. */
7196 cli_state_set_uid(cli, 0);
7198 /* This should succeed. */
7199 status = cli_tdis(cli);
7201 if (NT_STATUS_IS_OK(status)) {
7202 d_printf("First tdis with invalid vuid should succeed.\n");
7204 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7209 cli_state_set_uid(cli, old_vuid);
7210 cli_state_set_tid(cli, old_cnum);
7212 /* This should fail. */
7213 status = cli_tdis(cli);
7214 if (NT_STATUS_IS_OK(status)) {
7215 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7219 /* Should be bad tid. */
7220 if (!check_error(__LINE__, status, ERRSRV, ERRinvnid,
7221 NT_STATUS_NETWORK_NAME_DELETED)) {
7227 cli_rmdir(cli, "\\uid_reg_test");
7236 static const char *illegal_chars = "*\\/?<>|\":";
7237 static char force_shortname_chars[] = " +,.[];=\177";
7239 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7240 const char *mask, void *state)
7242 struct cli_state *pcli = (struct cli_state *)state;
7244 NTSTATUS status = NT_STATUS_OK;
7246 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7248 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7249 return NT_STATUS_OK;
7251 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7252 status = cli_rmdir(pcli, fname);
7253 if (!NT_STATUS_IS_OK(status)) {
7254 printf("del_fn: failed to rmdir %s\n,", fname );
7257 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7258 if (!NT_STATUS_IS_OK(status)) {
7259 printf("del_fn: failed to unlink %s\n,", fname );
7271 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7272 const char *name, void *state)
7274 struct sn_state *s = (struct sn_state *)state;
7278 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7279 i, finfo->name, finfo->short_name);
7282 if (strchr(force_shortname_chars, i)) {
7283 if (!finfo->short_name) {
7284 /* Shortname not created when it should be. */
7285 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7286 __location__, finfo->name, i);
7289 } else if (finfo->short_name){
7290 /* Shortname created when it should not be. */
7291 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7292 __location__, finfo->short_name, finfo->name);
7296 return NT_STATUS_OK;
7299 static bool run_shortname_test(int dummy)
7301 static struct cli_state *cli;
7302 bool correct = True;
7308 printf("starting shortname test\n");
7310 if (!torture_open_connection(&cli, 0)) {
7314 cli_sockopt(cli, sockops);
7316 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7317 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7318 cli_rmdir(cli, "\\shortname");
7320 status = cli_mkdir(cli, "\\shortname");
7321 if (!NT_STATUS_IS_OK(status)) {
7322 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7323 __location__, nt_errstr(status));
7328 strlcpy(fname, "\\shortname\\", sizeof(fname));
7329 strlcat(fname, "test .txt", sizeof(fname));
7333 for (i = 32; i < 128; i++) {
7334 uint16_t fnum = (uint16_t)-1;
7338 if (strchr(illegal_chars, i)) {
7343 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7344 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7345 if (!NT_STATUS_IS_OK(status)) {
7346 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7347 __location__, fname, nt_errstr(status));
7351 cli_close(cli, fnum);
7354 status = cli_list(cli, "\\shortname\\test*.*", 0,
7355 shortname_list_fn, &s);
7356 if (s.matched != 1) {
7357 d_printf("(%s) failed to list %s: %s\n",
7358 __location__, fname, nt_errstr(status));
7363 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7364 if (!NT_STATUS_IS_OK(status)) {
7365 d_printf("(%s) failed to delete %s: %s\n",
7366 __location__, fname, nt_errstr(status));
7379 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7380 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7381 cli_rmdir(cli, "\\shortname");
7382 torture_close_connection(cli);
7386 static void pagedsearch_cb(struct tevent_req *req)
7389 struct tldap_message *msg;
7392 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7393 if (rc != TLDAP_SUCCESS) {
7394 d_printf("tldap_search_paged_recv failed: %s\n",
7395 tldap_err2string(rc));
7398 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7402 if (!tldap_entry_dn(msg, &dn)) {
7403 d_printf("tldap_entry_dn failed\n");
7406 d_printf("%s\n", dn);
7410 static bool run_tldap(int dummy)
7412 struct tldap_context *ld;
7415 struct sockaddr_storage addr;
7416 struct tevent_context *ev;
7417 struct tevent_req *req;
7421 if (!resolve_name(host, &addr, 0, false)) {
7422 d_printf("could not find host %s\n", host);
7425 status = open_socket_out(&addr, 389, 9999, &fd);
7426 if (!NT_STATUS_IS_OK(status)) {
7427 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7431 ld = tldap_context_create(talloc_tos(), fd);
7434 d_printf("tldap_context_create failed\n");
7438 rc = tldap_fetch_rootdse(ld);
7439 if (rc != TLDAP_SUCCESS) {
7440 d_printf("tldap_fetch_rootdse failed: %s\n",
7441 tldap_errstr(talloc_tos(), ld, rc));
7445 basedn = tldap_talloc_single_attribute(
7446 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7447 if (basedn == NULL) {
7448 d_printf("no defaultNamingContext\n");
7451 d_printf("defaultNamingContext: %s\n", basedn);
7453 ev = tevent_context_init(talloc_tos());
7455 d_printf("tevent_context_init failed\n");
7459 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7460 TLDAP_SCOPE_SUB, "(objectclass=*)",
7462 NULL, 0, NULL, 0, 0, 0, 0, 5);
7464 d_printf("tldap_search_paged_send failed\n");
7467 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7469 tevent_req_poll(req, ev);
7473 /* test search filters against rootDSE */
7474 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7475 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7477 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7478 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7479 talloc_tos(), NULL, NULL);
7480 if (rc != TLDAP_SUCCESS) {
7481 d_printf("tldap_search with complex filter failed: %s\n",
7482 tldap_errstr(talloc_tos(), ld, rc));
7490 /* Torture test to ensure no regression of :
7491 https://bugzilla.samba.org/show_bug.cgi?id=7084
7494 static bool run_dir_createtime(int dummy)
7496 struct cli_state *cli;
7497 const char *dname = "\\testdir";
7498 const char *fname = "\\testdir\\testfile";
7500 struct timespec create_time;
7501 struct timespec create_time1;
7505 if (!torture_open_connection(&cli, 0)) {
7509 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7510 cli_rmdir(cli, dname);
7512 status = cli_mkdir(cli, dname);
7513 if (!NT_STATUS_IS_OK(status)) {
7514 printf("mkdir failed: %s\n", nt_errstr(status));
7518 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7520 if (!NT_STATUS_IS_OK(status)) {
7521 printf("cli_qpathinfo2 returned %s\n",
7526 /* Sleep 3 seconds, then create a file. */
7529 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7531 if (!NT_STATUS_IS_OK(status)) {
7532 printf("cli_open failed: %s\n", nt_errstr(status));
7536 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7538 if (!NT_STATUS_IS_OK(status)) {
7539 printf("cli_qpathinfo2 (2) returned %s\n",
7544 if (timespec_compare(&create_time1, &create_time)) {
7545 printf("run_dir_createtime: create time was updated (error)\n");
7547 printf("run_dir_createtime: create time was not updated (correct)\n");
7553 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7554 cli_rmdir(cli, dname);
7555 if (!torture_close_connection(cli)) {
7562 static bool run_streamerror(int dummy)
7564 struct cli_state *cli;
7565 const char *dname = "\\testdir";
7566 const char *streamname =
7567 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7569 time_t change_time, access_time, write_time;
7571 uint16_t mode, fnum;
7574 if (!torture_open_connection(&cli, 0)) {
7578 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7579 cli_rmdir(cli, dname);
7581 status = cli_mkdir(cli, dname);
7582 if (!NT_STATUS_IS_OK(status)) {
7583 printf("mkdir failed: %s\n", nt_errstr(status));
7587 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7589 status = cli_nt_error(cli);
7591 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7592 printf("pathinfo returned %s, expected "
7593 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7598 status = cli_ntcreate(cli, streamname, 0x16,
7599 FILE_READ_DATA|FILE_READ_EA|
7600 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7601 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7602 FILE_OPEN, 0, 0, &fnum);
7604 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7605 printf("ntcreate returned %s, expected "
7606 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7612 cli_rmdir(cli, dname);
7616 static bool run_local_substitute(int dummy)
7620 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7621 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7622 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7623 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7624 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7625 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7626 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7627 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7629 /* Different captialization rules in sub_basic... */
7631 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7637 static bool run_local_base64(int dummy)
7642 for (i=1; i<2000; i++) {
7643 DATA_BLOB blob1, blob2;
7646 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7648 generate_random_buffer(blob1.data, blob1.length);
7650 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7652 d_fprintf(stderr, "base64_encode_data_blob failed "
7653 "for %d bytes\n", i);
7656 blob2 = base64_decode_data_blob(b64);
7659 if (data_blob_cmp(&blob1, &blob2)) {
7660 d_fprintf(stderr, "data_blob_cmp failed for %d "
7664 TALLOC_FREE(blob1.data);
7665 data_blob_free(&blob2);
7670 static bool run_local_gencache(int dummy)
7676 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7677 d_printf("%s: gencache_set() failed\n", __location__);
7681 if (!gencache_get("foo", NULL, NULL)) {
7682 d_printf("%s: gencache_get() failed\n", __location__);
7686 if (!gencache_get("foo", &val, &tm)) {
7687 d_printf("%s: gencache_get() failed\n", __location__);
7691 if (strcmp(val, "bar") != 0) {
7692 d_printf("%s: gencache_get() returned %s, expected %s\n",
7693 __location__, val, "bar");
7700 if (!gencache_del("foo")) {
7701 d_printf("%s: gencache_del() failed\n", __location__);
7704 if (gencache_del("foo")) {
7705 d_printf("%s: second gencache_del() succeeded\n",
7710 if (gencache_get("foo", &val, &tm)) {
7711 d_printf("%s: gencache_get() on deleted entry "
7712 "succeeded\n", __location__);
7716 blob = data_blob_string_const_null("bar");
7717 tm = time(NULL) + 60;
7719 if (!gencache_set_data_blob("foo", &blob, tm)) {
7720 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7724 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7725 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7729 if (strcmp((const char *)blob.data, "bar") != 0) {
7730 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7731 __location__, (const char *)blob.data, "bar");
7732 data_blob_free(&blob);
7736 data_blob_free(&blob);
7738 if (!gencache_del("foo")) {
7739 d_printf("%s: gencache_del() failed\n", __location__);
7742 if (gencache_del("foo")) {
7743 d_printf("%s: second gencache_del() succeeded\n",
7748 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7749 d_printf("%s: gencache_get_data_blob() on deleted entry "
7750 "succeeded\n", __location__);
7757 static bool rbt_testval(struct db_context *db, const char *key,
7760 struct db_record *rec;
7761 TDB_DATA data = string_tdb_data(value);
7765 rec = db->fetch_locked(db, db, string_tdb_data(key));
7767 d_fprintf(stderr, "fetch_locked failed\n");
7770 status = rec->store(rec, data, 0);
7771 if (!NT_STATUS_IS_OK(status)) {
7772 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7777 rec = db->fetch_locked(db, db, string_tdb_data(key));
7779 d_fprintf(stderr, "second fetch_locked failed\n");
7782 if ((rec->value.dsize != data.dsize)
7783 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7784 d_fprintf(stderr, "Got wrong data back\n");
7794 static bool run_local_rbtree(int dummy)
7796 struct db_context *db;
7800 db = db_open_rbt(NULL);
7803 d_fprintf(stderr, "db_open_rbt failed\n");
7807 for (i=0; i<1000; i++) {
7810 if (asprintf(&key, "key%ld", random()) == -1) {
7813 if (asprintf(&value, "value%ld", random()) == -1) {
7818 if (!rbt_testval(db, key, value)) {
7825 if (asprintf(&value, "value%ld", random()) == -1) {
7830 if (!rbt_testval(db, key, value)) {
7849 local test for character set functions
7851 This is a very simple test for the functionality in convert_string_error()
7853 static bool run_local_convert_string(int dummy)
7855 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7856 const char *test_strings[2] = { "March", "M\303\244rz" };
7860 for (i=0; i<2; i++) {
7861 const char *str = test_strings[i];
7862 int len = strlen(str);
7863 size_t converted_size;
7866 memset(dst, 'X', sizeof(dst));
7868 /* first try with real source length */
7869 ret = convert_string_error(CH_UNIX, CH_UTF8,
7874 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7878 if (converted_size != len) {
7879 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7880 str, len, (int)converted_size);
7884 if (strncmp(str, dst, converted_size) != 0) {
7885 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7889 if (strlen(str) != converted_size) {
7890 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7891 (int)strlen(str), (int)converted_size);
7895 if (dst[converted_size] != 'X') {
7896 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7900 /* now with srclen==-1, this causes the nul to be
7902 ret = convert_string_error(CH_UNIX, CH_UTF8,
7907 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7911 if (converted_size != len+1) {
7912 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7913 str, len, (int)converted_size);
7917 if (strncmp(str, dst, converted_size) != 0) {
7918 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7922 if (len+1 != converted_size) {
7923 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7924 len+1, (int)converted_size);
7928 if (dst[converted_size] != 'X') {
7929 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7936 TALLOC_FREE(tmp_ctx);
7939 TALLOC_FREE(tmp_ctx);
7944 struct talloc_dict_test {
7948 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7950 int *count = (int *)priv;
7955 static bool run_local_talloc_dict(int dummy)
7957 struct talloc_dict *dict;
7958 struct talloc_dict_test *t;
7961 dict = talloc_dict_init(talloc_tos());
7966 t = talloc(talloc_tos(), struct talloc_dict_test);
7973 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7978 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7991 static bool run_local_string_to_sid(int dummy) {
7994 if (string_to_sid(&sid, "S--1-5-32-545")) {
7995 printf("allowing S--1-5-32-545\n");
7998 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7999 printf("allowing S-1-5-32-+545\n");
8002 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")) {
8003 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
8006 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
8007 printf("allowing S-1-5-32-545-abc\n");
8010 if (!string_to_sid(&sid, "S-1-5-32-545")) {
8011 printf("could not parse S-1-5-32-545\n");
8014 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
8015 printf("mis-parsed S-1-5-32-545 as %s\n",
8016 sid_string_tos(&sid));
8022 static bool run_local_binary_to_sid(int dummy) {
8023 struct dom_sid *sid = talloc(NULL, struct dom_sid);
8024 static const char good_binary_sid[] = {
8025 0x1, /* revision number */
8027 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8028 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8029 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8030 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8031 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8032 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8033 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8034 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8035 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8036 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8037 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8038 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8039 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8040 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8041 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8042 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8045 static const char long_binary_sid[] = {
8046 0x1, /* revision number */
8048 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8049 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8050 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8051 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8052 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8053 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8054 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8055 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8056 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8057 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8058 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8059 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8060 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8061 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8062 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8063 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8064 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8065 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8066 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8069 static const char long_binary_sid2[] = {
8070 0x1, /* revision number */
8072 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
8073 0x1, 0x1, 0x1, 0x1, /* auth[0] */
8074 0x1, 0x1, 0x1, 0x1, /* auth[1] */
8075 0x1, 0x1, 0x1, 0x1, /* auth[2] */
8076 0x1, 0x1, 0x1, 0x1, /* auth[3] */
8077 0x1, 0x1, 0x1, 0x1, /* auth[4] */
8078 0x1, 0x1, 0x1, 0x1, /* auth[5] */
8079 0x1, 0x1, 0x1, 0x1, /* auth[6] */
8080 0x1, 0x1, 0x1, 0x1, /* auth[7] */
8081 0x1, 0x1, 0x1, 0x1, /* auth[8] */
8082 0x1, 0x1, 0x1, 0x1, /* auth[9] */
8083 0x1, 0x1, 0x1, 0x1, /* auth[10] */
8084 0x1, 0x1, 0x1, 0x1, /* auth[11] */
8085 0x1, 0x1, 0x1, 0x1, /* auth[12] */
8086 0x1, 0x1, 0x1, 0x1, /* auth[13] */
8087 0x1, 0x1, 0x1, 0x1, /* auth[14] */
8088 0x1, 0x1, 0x1, 0x1, /* auth[15] */
8089 0x1, 0x1, 0x1, 0x1, /* auth[16] */
8090 0x1, 0x1, 0x1, 0x1, /* auth[17] */
8091 0x1, 0x1, 0x1, 0x1, /* auth[18] */
8092 0x1, 0x1, 0x1, 0x1, /* auth[19] */
8093 0x1, 0x1, 0x1, 0x1, /* auth[20] */
8094 0x1, 0x1, 0x1, 0x1, /* auth[21] */
8095 0x1, 0x1, 0x1, 0x1, /* auth[22] */
8096 0x1, 0x1, 0x1, 0x1, /* auth[23] */
8097 0x1, 0x1, 0x1, 0x1, /* auth[24] */
8098 0x1, 0x1, 0x1, 0x1, /* auth[25] */
8099 0x1, 0x1, 0x1, 0x1, /* auth[26] */
8100 0x1, 0x1, 0x1, 0x1, /* auth[27] */
8101 0x1, 0x1, 0x1, 0x1, /* auth[28] */
8102 0x1, 0x1, 0x1, 0x1, /* auth[29] */
8103 0x1, 0x1, 0x1, 0x1, /* auth[30] */
8104 0x1, 0x1, 0x1, 0x1, /* auth[31] */
8107 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
8110 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
8113 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
8119 /* Split a path name into filename and stream name components. Canonicalise
8120 * such that an implicit $DATA token is always explicit.
8122 * The "specification" of this function can be found in the
8123 * run_local_stream_name() function in torture.c, I've tried those
8124 * combinations against a W2k3 server.
8127 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
8128 char **pbase, char **pstream)
8131 char *stream = NULL;
8132 char *sname; /* stream name */
8133 const char *stype; /* stream type */
8135 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
8137 sname = strchr_m(fname, ':');
8139 if (lp_posix_pathnames() || (sname == NULL)) {
8140 if (pbase != NULL) {
8141 base = talloc_strdup(mem_ctx, fname);
8142 NT_STATUS_HAVE_NO_MEMORY(base);
8147 if (pbase != NULL) {
8148 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
8149 NT_STATUS_HAVE_NO_MEMORY(base);
8154 stype = strchr_m(sname, ':');
8156 if (stype == NULL) {
8157 sname = talloc_strdup(mem_ctx, sname);
8161 if (strcasecmp_m(stype, ":$DATA") != 0) {
8163 * If there is an explicit stream type, so far we only
8164 * allow $DATA. Is there anything else allowed? -- vl
8166 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
8168 return NT_STATUS_OBJECT_NAME_INVALID;
8170 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
8174 if (sname == NULL) {
8176 return NT_STATUS_NO_MEMORY;
8179 if (sname[0] == '\0') {
8181 * no stream name, so no stream
8186 if (pstream != NULL) {
8187 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8188 if (stream == NULL) {
8191 return NT_STATUS_NO_MEMORY;
8194 * upper-case the type field
8196 strupper_m(strchr_m(stream, ':')+1);
8200 if (pbase != NULL) {
8203 if (pstream != NULL) {
8206 return NT_STATUS_OK;
8209 static bool test_stream_name(const char *fname, const char *expected_base,
8210 const char *expected_stream,
8211 NTSTATUS expected_status)
8215 char *stream = NULL;
8217 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8218 if (!NT_STATUS_EQUAL(status, expected_status)) {
8222 if (!NT_STATUS_IS_OK(status)) {
8226 if (base == NULL) goto error;
8228 if (strcmp(expected_base, base) != 0) goto error;
8230 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8231 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8233 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8237 TALLOC_FREE(stream);
8241 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8242 fname, expected_base ? expected_base : "<NULL>",
8243 expected_stream ? expected_stream : "<NULL>",
8244 nt_errstr(expected_status));
8245 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8246 base ? base : "<NULL>", stream ? stream : "<NULL>",
8249 TALLOC_FREE(stream);
8253 static bool run_local_stream_name(int dummy)
8257 ret &= test_stream_name(
8258 "bla", "bla", NULL, NT_STATUS_OK);
8259 ret &= test_stream_name(
8260 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8261 ret &= test_stream_name(
8262 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8263 ret &= test_stream_name(
8264 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8265 ret &= test_stream_name(
8266 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8267 ret &= test_stream_name(
8268 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8269 ret &= test_stream_name(
8270 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8271 ret &= test_stream_name(
8272 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8277 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8279 if (a.length != b.length) {
8280 printf("a.length=%d != b.length=%d\n",
8281 (int)a.length, (int)b.length);
8284 if (memcmp(a.data, b.data, a.length) != 0) {
8285 printf("a.data and b.data differ\n");
8291 static bool run_local_memcache(int dummy)
8293 struct memcache *cache;
8295 DATA_BLOB d1, d2, d3;
8296 DATA_BLOB v1, v2, v3;
8298 TALLOC_CTX *mem_ctx;
8300 size_t size1, size2;
8303 cache = memcache_init(NULL, 100);
8305 if (cache == NULL) {
8306 printf("memcache_init failed\n");
8310 d1 = data_blob_const("d1", 2);
8311 d2 = data_blob_const("d2", 2);
8312 d3 = data_blob_const("d3", 2);
8314 k1 = data_blob_const("d1", 2);
8315 k2 = data_blob_const("d2", 2);
8317 memcache_add(cache, STAT_CACHE, k1, d1);
8318 memcache_add(cache, GETWD_CACHE, k2, d2);
8320 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8321 printf("could not find k1\n");
8324 if (!data_blob_equal(d1, v1)) {
8328 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8329 printf("could not find k2\n");
8332 if (!data_blob_equal(d2, v2)) {
8336 memcache_add(cache, STAT_CACHE, k1, d3);
8338 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8339 printf("could not find replaced k1\n");
8342 if (!data_blob_equal(d3, v3)) {
8346 memcache_add(cache, GETWD_CACHE, k1, d1);
8348 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8349 printf("Did find k2, should have been purged\n");
8355 cache = memcache_init(NULL, 0);
8357 mem_ctx = talloc_init("foo");
8359 str1 = talloc_strdup(mem_ctx, "string1");
8360 str2 = talloc_strdup(mem_ctx, "string2");
8362 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8363 data_blob_string_const("torture"), &str1);
8364 size1 = talloc_total_size(cache);
8366 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8367 data_blob_string_const("torture"), &str2);
8368 size2 = talloc_total_size(cache);
8370 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8372 if (size2 > size1) {
8373 printf("memcache leaks memory!\n");
8383 static void wbclient_done(struct tevent_req *req)
8386 struct winbindd_response *wb_resp;
8387 int *i = (int *)tevent_req_callback_data_void(req);
8389 wbc_err = wb_trans_recv(req, req, &wb_resp);
8392 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8395 static bool run_local_wbclient(int dummy)
8397 struct event_context *ev;
8398 struct wb_context **wb_ctx;
8399 struct winbindd_request wb_req;
8400 bool result = false;
8403 BlockSignals(True, SIGPIPE);
8405 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8410 wb_ctx = talloc_array(ev, struct wb_context *, nprocs);
8411 if (wb_ctx == NULL) {
8415 ZERO_STRUCT(wb_req);
8416 wb_req.cmd = WINBINDD_PING;
8418 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8420 for (i=0; i<nprocs; i++) {
8421 wb_ctx[i] = wb_context_init(ev, NULL);
8422 if (wb_ctx[i] == NULL) {
8425 for (j=0; j<torture_numops; j++) {
8426 struct tevent_req *req;
8427 req = wb_trans_send(ev, ev, wb_ctx[i],
8428 (j % 2) == 0, &wb_req);
8432 tevent_req_set_callback(req, wbclient_done, &i);
8438 while (i < nprocs * torture_numops) {
8439 tevent_loop_once(ev);
8448 static void getaddrinfo_finished(struct tevent_req *req)
8450 char *name = (char *)tevent_req_callback_data_void(req);
8451 struct addrinfo *ainfo;
8454 res = getaddrinfo_recv(req, &ainfo);
8456 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8459 d_printf("gai(%s) succeeded\n", name);
8460 freeaddrinfo(ainfo);
8463 static bool run_getaddrinfo_send(int dummy)
8465 TALLOC_CTX *frame = talloc_stackframe();
8466 struct fncall_context *ctx;
8467 struct tevent_context *ev;
8468 bool result = false;
8469 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8470 "www.slashdot.org", "heise.de" };
8471 struct tevent_req *reqs[4];
8474 ev = event_context_init(frame);
8479 ctx = fncall_context_init(frame, 4);
8481 for (i=0; i<ARRAY_SIZE(names); i++) {
8482 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8484 if (reqs[i] == NULL) {
8487 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8488 discard_const_p(void, names[i]));
8491 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8492 tevent_loop_once(ev);
8501 static bool dbtrans_inc(struct db_context *db)
8503 struct db_record *rec;
8508 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8510 printf(__location__ "fetch_lock failed\n");
8514 if (rec->value.dsize != sizeof(uint32_t)) {
8515 printf(__location__ "value.dsize = %d\n",
8516 (int)rec->value.dsize);
8520 val = (uint32_t *)rec->value.dptr;
8523 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8526 if (!NT_STATUS_IS_OK(status)) {
8527 printf(__location__ "store failed: %s\n",
8538 static bool run_local_dbtrans(int dummy)
8540 struct db_context *db;
8541 struct db_record *rec;
8546 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8547 O_RDWR|O_CREAT, 0600);
8549 printf("Could not open transtest.db\n");
8553 res = db->transaction_start(db);
8555 printf(__location__ "transaction_start failed\n");
8559 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8561 printf(__location__ "fetch_lock failed\n");
8565 if (rec->value.dptr == NULL) {
8567 status = rec->store(
8568 rec, make_tdb_data((uint8_t *)&initial,
8571 if (!NT_STATUS_IS_OK(status)) {
8572 printf(__location__ "store returned %s\n",
8580 res = db->transaction_commit(db);
8582 printf(__location__ "transaction_commit failed\n");
8590 res = db->transaction_start(db);
8592 printf(__location__ "transaction_start failed\n");
8596 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8597 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8601 for (i=0; i<10; i++) {
8602 if (!dbtrans_inc(db)) {
8607 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8608 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8612 if (val2 != val + 10) {
8613 printf(__location__ "val=%d, val2=%d\n",
8614 (int)val, (int)val2);
8618 printf("val2=%d\r", val2);
8620 res = db->transaction_commit(db);
8622 printf(__location__ "transaction_commit failed\n");
8632 * Just a dummy test to be run under a debugger. There's no real way
8633 * to inspect the tevent_select specific function from outside of
8637 static bool run_local_tevent_select(int dummy)
8639 struct tevent_context *ev;
8640 struct tevent_fd *fd1, *fd2;
8641 bool result = false;
8643 ev = tevent_context_init_byname(NULL, "select");
8645 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8649 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8651 d_fprintf(stderr, "tevent_add_fd failed\n");
8654 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8656 d_fprintf(stderr, "tevent_add_fd failed\n");
8661 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8663 d_fprintf(stderr, "tevent_add_fd failed\n");
8673 static double create_procs(bool (*fn)(int), bool *result)
8676 volatile pid_t *child_status;
8677 volatile bool *child_status_out;
8680 struct timeval start;
8684 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8685 if (!child_status) {
8686 printf("Failed to setup shared memory\n");
8690 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8691 if (!child_status_out) {
8692 printf("Failed to setup result status shared memory\n");
8696 for (i = 0; i < nprocs; i++) {
8697 child_status[i] = 0;
8698 child_status_out[i] = True;
8701 start = timeval_current();
8703 for (i=0;i<nprocs;i++) {
8706 pid_t mypid = getpid();
8707 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8709 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8712 if (torture_open_connection(¤t_cli, i)) break;
8714 printf("pid %d failed to start\n", (int)getpid());
8720 child_status[i] = getpid();
8722 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8724 child_status_out[i] = fn(i);
8731 for (i=0;i<nprocs;i++) {
8732 if (child_status[i]) synccount++;
8734 if (synccount == nprocs) break;
8736 } while (timeval_elapsed(&start) < 30);
8738 if (synccount != nprocs) {
8739 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8741 return timeval_elapsed(&start);
8744 /* start the client load */
8745 start = timeval_current();
8747 for (i=0;i<nprocs;i++) {
8748 child_status[i] = 0;
8751 printf("%d clients started\n", nprocs);
8753 for (i=0;i<nprocs;i++) {
8754 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8759 for (i=0;i<nprocs;i++) {
8760 if (!child_status_out[i]) {
8764 return timeval_elapsed(&start);
8767 #define FLAG_MULTIPROC 1
8774 {"FDPASS", run_fdpasstest, 0},
8775 {"LOCK1", run_locktest1, 0},
8776 {"LOCK2", run_locktest2, 0},
8777 {"LOCK3", run_locktest3, 0},
8778 {"LOCK4", run_locktest4, 0},
8779 {"LOCK5", run_locktest5, 0},
8780 {"LOCK6", run_locktest6, 0},
8781 {"LOCK7", run_locktest7, 0},
8782 {"LOCK8", run_locktest8, 0},
8783 {"LOCK9", run_locktest9, 0},
8784 {"UNLINK", run_unlinktest, 0},
8785 {"BROWSE", run_browsetest, 0},
8786 {"ATTR", run_attrtest, 0},
8787 {"TRANS2", run_trans2test, 0},
8788 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8789 {"TORTURE",run_torture, FLAG_MULTIPROC},
8790 {"RANDOMIPC", run_randomipc, 0},
8791 {"NEGNOWAIT", run_negprot_nowait, 0},
8792 {"NBENCH", run_nbench, 0},
8793 {"NBENCH2", run_nbench2, 0},
8794 {"OPLOCK1", run_oplock1, 0},
8795 {"OPLOCK2", run_oplock2, 0},
8796 {"OPLOCK4", run_oplock4, 0},
8797 {"DIR", run_dirtest, 0},
8798 {"DIR1", run_dirtest1, 0},
8799 {"DIR-CREATETIME", run_dir_createtime, 0},
8800 {"DENY1", torture_denytest1, 0},
8801 {"DENY2", torture_denytest2, 0},
8802 {"TCON", run_tcon_test, 0},
8803 {"TCONDEV", run_tcon_devtype_test, 0},
8804 {"RW1", run_readwritetest, 0},
8805 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8806 {"RW3", run_readwritelarge, 0},
8807 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8808 {"OPEN", run_opentest, 0},
8809 {"POSIX", run_simple_posix_open_test, 0},
8810 {"POSIX-APPEND", run_posix_append, 0},
8811 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8812 {"ASYNC-ECHO", run_async_echo, 0},
8813 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8814 { "SHORTNAME-TEST", run_shortname_test, 0},
8815 { "ADDRCHANGE", run_addrchange, 0},
8817 {"OPENATTR", run_openattrtest, 0},
8819 {"XCOPY", run_xcopy, 0},
8820 {"RENAME", run_rename, 0},
8821 {"DELETE", run_deletetest, 0},
8822 {"DELETE-LN", run_deletetest_ln, 0},
8823 {"PROPERTIES", run_properties, 0},
8824 {"MANGLE", torture_mangle, 0},
8825 {"MANGLE1", run_mangle1, 0},
8826 {"W2K", run_w2ktest, 0},
8827 {"TRANS2SCAN", torture_trans2_scan, 0},
8828 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8829 {"UTABLE", torture_utable, 0},
8830 {"CASETABLE", torture_casetable, 0},
8831 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8832 {"PIPE_NUMBER", run_pipe_number, 0},
8833 {"TCON2", run_tcon2_test, 0},
8834 {"IOCTL", torture_ioctl_test, 0},
8835 {"CHKPATH", torture_chkpath_test, 0},
8836 {"FDSESS", run_fdsesstest, 0},
8837 { "EATEST", run_eatest, 0},
8838 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8839 { "CHAIN1", run_chain1, 0},
8840 { "CHAIN2", run_chain2, 0},
8841 { "WINDOWS-WRITE", run_windows_write, 0},
8842 { "NTTRANS-CREATE", run_nttrans_create, 0},
8843 { "CLI_ECHO", run_cli_echo, 0},
8844 { "GETADDRINFO", run_getaddrinfo_send, 0},
8845 { "TLDAP", run_tldap },
8846 { "STREAMERROR", run_streamerror },
8847 { "NOTIFY-BENCH", run_notify_bench },
8848 { "BAD-NBT-SESSION", run_bad_nbt_session },
8849 { "SMB-ANY-CONNECT", run_smb_any_connect },
8850 { "NOTIFY-ONLINE", run_notify_online },
8851 { "SMB2-BASIC", run_smb2_basic },
8852 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8853 { "LOCAL-GENCACHE", run_local_gencache, 0},
8854 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8855 { "LOCAL-BASE64", run_local_base64, 0},
8856 { "LOCAL-RBTREE", run_local_rbtree, 0},
8857 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8858 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8859 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8860 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8861 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8862 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8863 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8864 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8865 { "LOCAL-CONV-AUTH-INFO", run_local_conv_auth_info, 0},
8870 /****************************************************************************
8871 run a specified test or "ALL"
8872 ****************************************************************************/
8873 static bool run_test(const char *name)
8880 if (strequal(name,"ALL")) {
8881 for (i=0;torture_ops[i].name;i++) {
8882 run_test(torture_ops[i].name);
8887 for (i=0;torture_ops[i].name;i++) {
8888 fstr_sprintf(randomfname, "\\XX%x",
8889 (unsigned)random());
8891 if (strequal(name, torture_ops[i].name)) {
8893 printf("Running %s\n", name);
8894 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8895 t = create_procs(torture_ops[i].fn, &result);
8898 printf("TEST %s FAILED!\n", name);
8901 struct timeval start;
8902 start = timeval_current();
8903 if (!torture_ops[i].fn(0)) {
8905 printf("TEST %s FAILED!\n", name);
8907 t = timeval_elapsed(&start);
8909 printf("%s took %g secs\n\n", name, t);
8914 printf("Did not find a test named %s\n", name);
8922 static void usage(void)
8926 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8927 printf("Please use samba4 torture.\n\n");
8929 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8931 printf("\t-d debuglevel\n");
8932 printf("\t-U user%%pass\n");
8933 printf("\t-k use kerberos\n");
8934 printf("\t-N numprocs\n");
8935 printf("\t-n my_netbios_name\n");
8936 printf("\t-W workgroup\n");
8937 printf("\t-o num_operations\n");
8938 printf("\t-O socket_options\n");
8939 printf("\t-m maximum protocol\n");
8940 printf("\t-L use oplocks\n");
8941 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8942 printf("\t-A showall\n");
8943 printf("\t-p port\n");
8944 printf("\t-s seed\n");
8945 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8946 printf("\t-f filename filename to test\n");
8949 printf("tests are:");
8950 for (i=0;torture_ops[i].name;i++) {
8951 printf(" %s", torture_ops[i].name);
8955 printf("default test is ALL\n");
8960 /****************************************************************************
8962 ****************************************************************************/
8963 int main(int argc,char *argv[])
8969 bool correct = True;
8970 TALLOC_CTX *frame = talloc_stackframe();
8971 int seed = time(NULL);
8973 #ifdef HAVE_SETBUFFER
8974 setbuffer(stdout, NULL, 0);
8977 setup_logging("smbtorture", DEBUG_STDOUT);
8981 if (is_default_dyn_CONFIGFILE()) {
8982 if(getenv("SMB_CONF_PATH")) {
8983 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8986 lp_load_global(get_dyn_CONFIGFILE());
8993 for(p = argv[1]; *p; p++)
8997 if (strncmp(argv[1], "//", 2)) {
9001 fstrcpy(host, &argv[1][2]);
9002 p = strchr_m(&host[2],'/');
9007 fstrcpy(share, p+1);
9009 fstrcpy(myname, get_myname(talloc_tos()));
9011 fprintf(stderr, "Failed to get my hostname.\n");
9015 if (*username == 0 && getenv("LOGNAME")) {
9016 fstrcpy(username,getenv("LOGNAME"));
9022 fstrcpy(workgroup, lp_workgroup());
9024 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
9028 port_to_use = atoi(optarg);
9031 seed = atoi(optarg);
9034 fstrcpy(workgroup,optarg);
9037 max_protocol = interpret_protocol(optarg, max_protocol);
9040 nprocs = atoi(optarg);
9043 torture_numops = atoi(optarg);
9046 lp_set_cmdline("log level", optarg);
9055 local_path = optarg;
9058 torture_showall = True;
9061 fstrcpy(myname, optarg);
9064 client_txt = optarg;
9071 use_kerberos = True;
9073 d_printf("No kerberos support compiled in\n");
9079 fstrcpy(username,optarg);
9080 p = strchr_m(username,'%');
9083 fstrcpy(password, p+1);
9088 fstrcpy(multishare_conn_fname, optarg);
9089 use_multishare_conn = True;
9092 torture_blocksize = atoi(optarg);
9095 test_filename = SMB_STRDUP(optarg);
9098 printf("Unknown option %c (%d)\n", (char)opt, opt);
9103 d_printf("using seed %d\n", seed);
9107 if(use_kerberos && !gotuser) gotpass = True;
9110 p = getpass("Password:");
9112 fstrcpy(password, p);
9117 printf("host=%s share=%s user=%s myname=%s\n",
9118 host, share, username, myname);
9120 if (argc == optind) {
9121 correct = run_test("ALL");
9123 for (i=optind;i<argc;i++) {
9124 if (!run_test(argv[i])) {