s3-debug Remove last direct assignements to DEBUGLEVEL
[Samba/gebeck_regimport.git] / source3 / torture / torture.c
blob161c6f9a6489a62c544c229f99da9c6cb9b4e52e
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
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/>.
21 #include "includes.h"
22 #include "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/security.h"
25 #include "tldap.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
28 #include "memcache.h"
29 #include "nsswitch/winbind_client.h"
30 #include "dbwrap.h"
31 #include "talloc_dict.h"
32 #include "async_smb.h"
34 extern char *optarg;
35 extern int optind;
37 static fstring host, workgroup, share, password, username, myname;
38 static int max_protocol = PROTOCOL_NT1;
39 static const char *sockops="TCP_NODELAY";
40 static int nprocs=1;
41 static int port_to_use=0;
42 int torture_numops=100;
43 int torture_blocksize=1024*1024;
44 static int procnum; /* records process count number when forking */
45 static struct cli_state *current_cli;
46 static fstring randomfname;
47 static bool use_oplocks;
48 static bool use_level_II_oplocks;
49 static const char *client_txt = "client_oplocks.txt";
50 static bool use_kerberos;
51 static fstring multishare_conn_fname;
52 static bool use_multishare_conn = False;
53 static bool do_encrypt;
54 static const char *local_path = NULL;
56 bool torture_showall = False;
58 static double create_procs(bool (*fn)(int), bool *result);
61 /* return a pointer to a anonymous shared memory segment of size "size"
62 which will persist across fork() but will disappear when all processes
63 exit
65 The memory is not zeroed
67 This function uses system5 shared memory. It takes advantage of a property
68 that the memory is not destroyed if it is attached when the id is removed
70 void *shm_setup(int size)
72 int shmid;
73 void *ret;
75 #ifdef __QNXNTO__
76 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
77 if (shmid == -1) {
78 printf("can't get shared memory\n");
79 exit(1);
81 shm_unlink("private");
82 if (ftruncate(shmid, size) == -1) {
83 printf("can't set shared memory size\n");
84 exit(1);
86 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
87 if (ret == MAP_FAILED) {
88 printf("can't map shared memory\n");
89 exit(1);
91 #else
92 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
93 if (shmid == -1) {
94 printf("can't get shared memory\n");
95 exit(1);
97 ret = (void *)shmat(shmid, 0, 0);
98 if (!ret || ret == (void *)-1) {
99 printf("can't attach to shared memory\n");
100 return NULL;
102 /* the following releases the ipc, but note that this process
103 and all its children will still have access to the memory, its
104 just that the shmid is no longer valid for other shm calls. This
105 means we don't leave behind lots of shm segments after we exit
107 See Stevens "advanced programming in unix env" for details
109 shmctl(shmid, IPC_RMID, 0);
110 #endif
112 return ret;
115 /********************************************************************
116 Ensure a connection is encrypted.
117 ********************************************************************/
119 static bool force_cli_encryption(struct cli_state *c,
120 const char *sharename)
122 uint16 major, minor;
123 uint32 caplow, caphigh;
124 NTSTATUS status;
126 if (!SERVER_HAS_UNIX_CIFS(c)) {
127 d_printf("Encryption required and "
128 "server that doesn't support "
129 "UNIX extensions - failing connect\n");
130 return false;
133 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
134 &caphigh);
135 if (!NT_STATUS_IS_OK(status)) {
136 d_printf("Encryption required and "
137 "can't get UNIX CIFS extensions "
138 "version from server: %s\n", nt_errstr(status));
139 return false;
142 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
143 d_printf("Encryption required and "
144 "share %s doesn't support "
145 "encryption.\n", sharename);
146 return false;
149 if (c->use_kerberos) {
150 status = cli_gss_smb_encryption_start(c);
151 } else {
152 status = cli_raw_ntlm_smb_encryption_start(c,
153 username,
154 password,
155 workgroup);
158 if (!NT_STATUS_IS_OK(status)) {
159 d_printf("Encryption required and "
160 "setup failed with error %s.\n",
161 nt_errstr(status));
162 return false;
165 return true;
169 static struct cli_state *open_nbt_connection(void)
171 struct nmb_name called, calling;
172 struct sockaddr_storage ss;
173 struct cli_state *c;
174 NTSTATUS status;
176 make_nmb_name(&calling, myname, 0x0);
177 make_nmb_name(&called , host, 0x20);
179 zero_sockaddr(&ss);
181 if (!(c = cli_initialise())) {
182 printf("Failed initialize cli_struct to connect with %s\n", host);
183 return NULL;
186 c->port = port_to_use;
188 status = cli_connect(c, host, &ss);
189 if (!NT_STATUS_IS_OK(status)) {
190 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
191 return NULL;
194 c->use_kerberos = use_kerberos;
196 c->timeout = 120000; /* set a really long timeout (2 minutes) */
197 if (use_oplocks) c->use_oplocks = True;
198 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
200 if (!cli_session_request(c, &calling, &called)) {
202 * Well, that failed, try *SMBSERVER ...
203 * However, we must reconnect as well ...
205 status = cli_connect(c, host, &ss);
206 if (!NT_STATUS_IS_OK(status)) {
207 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
208 return NULL;
211 make_nmb_name(&called, "*SMBSERVER", 0x20);
212 if (!cli_session_request(c, &calling, &called)) {
213 printf("%s rejected the session\n",host);
214 printf("We tried with a called name of %s & %s\n",
215 host, "*SMBSERVER");
216 cli_shutdown(c);
217 return NULL;
221 return c;
224 /****************************************************************************
225 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
226 ****************************************************************************/
228 static bool cli_bad_session_request(struct cli_state *cli,
229 struct nmb_name *calling, struct nmb_name *called)
231 char *p;
232 int len = 4;
233 int namelen = 0;
234 char *tmp;
236 memcpy(&(cli->calling), calling, sizeof(*calling));
237 memcpy(&(cli->called ), called , sizeof(*called ));
239 /* put in the destination name */
241 tmp = name_mangle(talloc_tos(), cli->called.name,
242 cli->called.name_type);
243 if (tmp == NULL) {
244 return false;
247 p = cli->outbuf+len;
248 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
249 if (namelen > 0) {
250 memcpy(p, tmp, namelen);
251 len += namelen;
253 TALLOC_FREE(tmp);
255 /* Deliberately corrupt the name len (first byte) */
256 *p = 100;
258 /* and my name */
260 tmp = name_mangle(talloc_tos(), cli->calling.name,
261 cli->calling.name_type);
262 if (tmp == NULL) {
263 return false;
266 p = cli->outbuf+len;
267 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
268 if (namelen > 0) {
269 memcpy(p, tmp, namelen);
270 len += namelen;
272 TALLOC_FREE(tmp);
273 /* Deliberately corrupt the name len (first byte) */
274 *p = 100;
276 /* send a session request (RFC 1002) */
277 /* setup the packet length
278 * Remove four bytes from the length count, since the length
279 * field in the NBT Session Service header counts the number
280 * of bytes which follow. The cli_send_smb() function knows
281 * about this and accounts for those four bytes.
282 * CRH.
284 len -= 4;
285 _smb_setlen(cli->outbuf,len);
286 SCVAL(cli->outbuf,0,0x81);
288 cli_send_smb(cli);
289 DEBUG(5,("Sent session request\n"));
291 if (!cli_receive_smb(cli))
292 return False;
294 if (CVAL(cli->inbuf,0) != 0x82) {
295 /* This is the wrong place to put the error... JRA. */
296 cli->rap_error = CVAL(cli->inbuf,4);
297 return False;
299 return(True);
302 static struct cli_state *open_bad_nbt_connection(void)
304 struct nmb_name called, calling;
305 struct sockaddr_storage ss;
306 struct cli_state *c;
307 NTSTATUS status;
309 make_nmb_name(&calling, myname, 0x0);
310 make_nmb_name(&called , host, 0x20);
312 zero_sockaddr(&ss);
314 if (!(c = cli_initialise())) {
315 printf("Failed initialize cli_struct to connect with %s\n", host);
316 return NULL;
319 c->port = 139;
321 status = cli_connect(c, host, &ss);
322 if (!NT_STATUS_IS_OK(status)) {
323 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
324 return NULL;
327 c->timeout = 4000; /* set a short timeout (4 seconds) */
329 if (!cli_bad_session_request(c, &calling, &called)) {
330 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
331 return NULL;
334 return c;
338 /* Insert a NULL at the first separator of the given path and return a pointer
339 * to the remainder of the string.
341 static char *
342 terminate_path_at_separator(char * path)
344 char * p;
346 if (!path) {
347 return NULL;
350 if ((p = strchr_m(path, '/'))) {
351 *p = '\0';
352 return p + 1;
355 if ((p = strchr_m(path, '\\'))) {
356 *p = '\0';
357 return p + 1;
360 /* No separator. */
361 return NULL;
365 parse a //server/share type UNC name
367 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
368 char **hostname, char **sharename)
370 char *p;
372 *hostname = *sharename = NULL;
374 if (strncmp(unc_name, "\\\\", 2) &&
375 strncmp(unc_name, "//", 2)) {
376 return False;
379 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
380 p = terminate_path_at_separator(*hostname);
382 if (p && *p) {
383 *sharename = talloc_strdup(mem_ctx, p);
384 terminate_path_at_separator(*sharename);
387 if (*hostname && *sharename) {
388 return True;
391 TALLOC_FREE(*hostname);
392 TALLOC_FREE(*sharename);
393 return False;
396 static bool torture_open_connection_share(struct cli_state **c,
397 const char *hostname,
398 const char *sharename)
400 bool retry;
401 int flags = 0;
402 NTSTATUS status;
404 if (use_kerberos)
405 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
406 if (use_oplocks)
407 flags |= CLI_FULL_CONNECTION_OPLOCKS;
408 if (use_level_II_oplocks)
409 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
411 status = cli_full_connection(c, myname,
412 hostname, NULL, port_to_use,
413 sharename, "?????",
414 username, workgroup,
415 password, flags, Undefined, &retry);
416 if (!NT_STATUS_IS_OK(status)) {
417 printf("failed to open share connection: //%s/%s port:%d - %s\n",
418 hostname, sharename, port_to_use, nt_errstr(status));
419 return False;
422 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
424 if (do_encrypt) {
425 return force_cli_encryption(*c,
426 sharename);
428 return True;
431 bool torture_open_connection(struct cli_state **c, int conn_index)
433 char **unc_list = NULL;
434 int num_unc_names = 0;
435 bool result;
437 if (use_multishare_conn==True) {
438 char *h, *s;
439 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
440 if (!unc_list || num_unc_names <= 0) {
441 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
442 exit(1);
445 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
446 NULL, &h, &s)) {
447 printf("Failed to parse UNC name %s\n",
448 unc_list[conn_index % num_unc_names]);
449 TALLOC_FREE(unc_list);
450 exit(1);
453 result = torture_open_connection_share(c, h, s);
455 /* h, s were copied earlier */
456 TALLOC_FREE(unc_list);
457 return result;
460 return torture_open_connection_share(c, host, share);
463 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
465 uint16 old_vuid = cli->vuid;
466 fstring old_user_name;
467 size_t passlen = strlen(password);
468 NTSTATUS status;
469 bool ret;
471 fstrcpy(old_user_name, cli->user_name);
472 cli->vuid = 0;
473 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
474 password, passlen,
475 password, passlen,
476 workgroup));
477 *new_vuid = cli->vuid;
478 cli->vuid = old_vuid;
479 status = cli_set_username(cli, old_user_name);
480 if (!NT_STATUS_IS_OK(status)) {
481 return false;
483 return ret;
487 bool torture_close_connection(struct cli_state *c)
489 bool ret = True;
490 NTSTATUS status;
492 status = cli_tdis(c);
493 if (!NT_STATUS_IS_OK(status)) {
494 printf("tdis failed (%s)\n", nt_errstr(status));
495 ret = False;
498 cli_shutdown(c);
500 return ret;
504 /* check if the server produced the expected error code */
505 static bool check_error(int line, struct cli_state *c,
506 uint8 eclass, uint32 ecode, NTSTATUS nterr)
508 if (cli_is_dos_error(c)) {
509 uint8 cclass;
510 uint32 num;
512 /* Check DOS error */
514 cli_dos_error(c, &cclass, &num);
516 if (eclass != cclass || ecode != num) {
517 printf("unexpected error code class=%d code=%d\n",
518 (int)cclass, (int)num);
519 printf(" expected %d/%d %s (line=%d)\n",
520 (int)eclass, (int)ecode, nt_errstr(nterr), line);
521 return False;
524 } else {
525 NTSTATUS status;
527 /* Check NT error */
529 status = cli_nt_error(c);
531 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
532 printf("unexpected error code %s\n", nt_errstr(status));
533 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
534 return False;
538 return True;
542 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
544 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
545 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
547 return True;
551 static bool rw_torture(struct cli_state *c)
553 const char *lockfname = "\\torture.lck";
554 fstring fname;
555 uint16_t fnum;
556 uint16_t fnum2;
557 pid_t pid2, pid = getpid();
558 int i, j;
559 char buf[1024];
560 bool correct = True;
561 NTSTATUS status;
563 memset(buf, '\0', sizeof(buf));
565 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
566 DENY_NONE, &fnum2);
567 if (!NT_STATUS_IS_OK(status)) {
568 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
570 if (!NT_STATUS_IS_OK(status)) {
571 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
572 return False;
575 for (i=0;i<torture_numops;i++) {
576 unsigned n = (unsigned)sys_random()%10;
577 if (i % 10 == 0) {
578 printf("%d\r", i); fflush(stdout);
580 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
582 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
583 return False;
586 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
587 printf("open failed (%s)\n", cli_errstr(c));
588 correct = False;
589 break;
592 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
593 printf("write failed (%s)\n", cli_errstr(c));
594 correct = False;
597 for (j=0;j<50;j++) {
598 if (cli_write(c, fnum, 0, (char *)buf,
599 sizeof(pid)+(j*sizeof(buf)),
600 sizeof(buf)) != sizeof(buf)) {
601 printf("write failed (%s)\n", cli_errstr(c));
602 correct = False;
606 pid2 = 0;
608 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
609 printf("read failed (%s)\n", cli_errstr(c));
610 correct = False;
613 if (pid2 != pid) {
614 printf("data corruption!\n");
615 correct = False;
618 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
619 printf("close failed (%s)\n", cli_errstr(c));
620 correct = False;
623 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
624 printf("unlink failed (%s)\n", cli_errstr(c));
625 correct = False;
628 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
629 printf("unlock failed (%s)\n", cli_errstr(c));
630 correct = False;
634 cli_close(c, fnum2);
635 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
637 printf("%d\n", i);
639 return correct;
642 static bool run_torture(int dummy)
644 struct cli_state *cli;
645 bool ret;
647 cli = current_cli;
649 cli_sockopt(cli, sockops);
651 ret = rw_torture(cli);
653 if (!torture_close_connection(cli)) {
654 ret = False;
657 return ret;
660 static bool rw_torture3(struct cli_state *c, char *lockfname)
662 uint16_t fnum = (uint16_t)-1;
663 unsigned int i = 0;
664 char buf[131072];
665 char buf_rd[131072];
666 unsigned count;
667 unsigned countprev = 0;
668 ssize_t sent = 0;
669 bool correct = True;
670 NTSTATUS status;
672 srandom(1);
673 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
675 SIVAL(buf, i, sys_random());
678 if (procnum == 0)
680 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
681 DENY_NONE, &fnum))) {
682 printf("first open read/write of %s failed (%s)\n",
683 lockfname, cli_errstr(c));
684 return False;
687 else
689 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
691 status = cli_open(c, lockfname, O_RDONLY,
692 DENY_NONE, &fnum);
693 if (!NT_STATUS_IS_OK(status)) {
694 break;
696 smb_msleep(10);
698 if (!NT_STATUS_IS_OK(status)) {
699 printf("second open read-only of %s failed (%s)\n",
700 lockfname, cli_errstr(c));
701 return False;
705 i = 0;
706 for (count = 0; count < sizeof(buf); count += sent)
708 if (count >= countprev) {
709 printf("%d %8d\r", i, count);
710 fflush(stdout);
711 i++;
712 countprev += (sizeof(buf) / 20);
715 if (procnum == 0)
717 sent = ((unsigned)sys_random()%(20))+ 1;
718 if (sent > sizeof(buf) - count)
720 sent = sizeof(buf) - count;
723 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
724 printf("write failed (%s)\n", cli_errstr(c));
725 correct = False;
728 else
730 sent = cli_read(c, fnum, buf_rd+count, count,
731 sizeof(buf)-count);
732 if (sent < 0)
734 printf("read failed offset:%d size:%ld (%s)\n",
735 count, (unsigned long)sizeof(buf)-count,
736 cli_errstr(c));
737 correct = False;
738 sent = 0;
740 if (sent > 0)
742 if (memcmp(buf_rd+count, buf+count, sent) != 0)
744 printf("read/write compare failed\n");
745 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
746 correct = False;
747 break;
754 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
755 printf("close failed (%s)\n", cli_errstr(c));
756 correct = False;
759 return correct;
762 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
764 const char *lockfname = "\\torture2.lck";
765 uint16_t fnum1;
766 uint16_t fnum2;
767 int i;
768 char buf[131072];
769 char buf_rd[131072];
770 bool correct = True;
771 ssize_t bytes_read;
773 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
774 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
777 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
778 DENY_NONE, &fnum1))) {
779 printf("first open read/write of %s failed (%s)\n",
780 lockfname, cli_errstr(c1));
781 return False;
783 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
784 DENY_NONE, &fnum2))) {
785 printf("second open read-only of %s failed (%s)\n",
786 lockfname, cli_errstr(c2));
787 cli_close(c1, fnum1);
788 return False;
791 for (i=0;i<torture_numops;i++)
793 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
794 if (i % 10 == 0) {
795 printf("%d\r", i); fflush(stdout);
798 generate_random_buffer((unsigned char *)buf, buf_size);
800 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
801 printf("write failed (%s)\n", cli_errstr(c1));
802 correct = False;
803 break;
806 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
807 printf("read failed (%s)\n", cli_errstr(c2));
808 printf("read %d, expected %ld\n", (int)bytes_read,
809 (unsigned long)buf_size);
810 correct = False;
811 break;
814 if (memcmp(buf_rd, buf, buf_size) != 0)
816 printf("read/write compare failed\n");
817 correct = False;
818 break;
822 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
823 printf("close failed (%s)\n", cli_errstr(c2));
824 correct = False;
826 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
827 printf("close failed (%s)\n", cli_errstr(c1));
828 correct = False;
831 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
832 printf("unlink failed (%s)\n", cli_errstr(c1));
833 correct = False;
836 return correct;
839 static bool run_readwritetest(int dummy)
841 struct cli_state *cli1, *cli2;
842 bool test1, test2 = False;
844 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
845 return False;
847 cli_sockopt(cli1, sockops);
848 cli_sockopt(cli2, sockops);
850 printf("starting readwritetest\n");
852 test1 = rw_torture2(cli1, cli2);
853 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
855 if (test1) {
856 test2 = rw_torture2(cli1, cli1);
857 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
860 if (!torture_close_connection(cli1)) {
861 test1 = False;
864 if (!torture_close_connection(cli2)) {
865 test2 = False;
868 return (test1 && test2);
871 static bool run_readwritemulti(int dummy)
873 struct cli_state *cli;
874 bool test;
876 cli = current_cli;
878 cli_sockopt(cli, sockops);
880 printf("run_readwritemulti: fname %s\n", randomfname);
881 test = rw_torture3(cli, randomfname);
883 if (!torture_close_connection(cli)) {
884 test = False;
887 return test;
890 static bool run_readwritelarge(int dummy)
892 static struct cli_state *cli1;
893 uint16_t fnum1;
894 const char *lockfname = "\\large.dat";
895 SMB_OFF_T fsize;
896 char buf[126*1024];
897 bool correct = True;
899 if (!torture_open_connection(&cli1, 0)) {
900 return False;
902 cli_sockopt(cli1, sockops);
903 memset(buf,'\0',sizeof(buf));
905 cli1->max_xmit = 128*1024;
907 printf("starting readwritelarge\n");
909 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
911 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
912 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
913 return False;
916 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
918 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
919 cli1, fnum1, NULL, &fsize, NULL, NULL,
920 NULL, NULL, NULL))) {
921 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
922 correct = False;
925 if (fsize == sizeof(buf))
926 printf("readwritelarge test 1 succeeded (size = %lx)\n",
927 (unsigned long)fsize);
928 else {
929 printf("readwritelarge test 1 failed (size = %lx)\n",
930 (unsigned long)fsize);
931 correct = False;
934 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
935 printf("close failed (%s)\n", cli_errstr(cli1));
936 correct = False;
939 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
940 printf("unlink failed (%s)\n", cli_errstr(cli1));
941 correct = False;
944 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
945 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
946 return False;
949 cli1->max_xmit = 4*1024;
951 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
953 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
954 cli1, fnum1, NULL, &fsize, NULL, NULL,
955 NULL, NULL, NULL))) {
956 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
957 correct = False;
960 if (fsize == sizeof(buf))
961 printf("readwritelarge test 2 succeeded (size = %lx)\n",
962 (unsigned long)fsize);
963 else {
964 printf("readwritelarge test 2 failed (size = %lx)\n",
965 (unsigned long)fsize);
966 correct = False;
969 #if 0
970 /* ToDo - set allocation. JRA */
971 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
972 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
973 return False;
975 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
976 NULL, NULL)) {
977 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
978 correct = False;
980 if (fsize != 0)
981 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
982 #endif
984 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
985 printf("close failed (%s)\n", cli_errstr(cli1));
986 correct = False;
989 if (!torture_close_connection(cli1)) {
990 correct = False;
992 return correct;
995 int line_count = 0;
996 int nbio_id;
998 #define ival(s) strtol(s, NULL, 0)
1000 /* run a test that simulates an approximate netbench client load */
1001 static bool run_netbench(int client)
1003 struct cli_state *cli;
1004 int i;
1005 char line[1024];
1006 char cname[20];
1007 FILE *f;
1008 const char *params[20];
1009 bool correct = True;
1011 cli = current_cli;
1013 nbio_id = client;
1015 cli_sockopt(cli, sockops);
1017 nb_setup(cli);
1019 slprintf(cname,sizeof(cname)-1, "client%d", client);
1021 f = fopen(client_txt, "r");
1023 if (!f) {
1024 perror(client_txt);
1025 return False;
1028 while (fgets(line, sizeof(line)-1, f)) {
1029 char *saveptr;
1030 line_count++;
1032 line[strlen(line)-1] = 0;
1034 /* printf("[%d] %s\n", line_count, line); */
1036 all_string_sub(line,"client1", cname, sizeof(line));
1038 /* parse the command parameters */
1039 params[0] = strtok_r(line, " ", &saveptr);
1040 i = 0;
1041 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1043 params[i] = "";
1045 if (i < 2) continue;
1047 if (!strncmp(params[0],"SMB", 3)) {
1048 printf("ERROR: You are using a dbench 1 load file\n");
1049 exit(1);
1052 if (!strcmp(params[0],"NTCreateX")) {
1053 nb_createx(params[1], ival(params[2]), ival(params[3]),
1054 ival(params[4]));
1055 } else if (!strcmp(params[0],"Close")) {
1056 nb_close(ival(params[1]));
1057 } else if (!strcmp(params[0],"Rename")) {
1058 nb_rename(params[1], params[2]);
1059 } else if (!strcmp(params[0],"Unlink")) {
1060 nb_unlink(params[1]);
1061 } else if (!strcmp(params[0],"Deltree")) {
1062 nb_deltree(params[1]);
1063 } else if (!strcmp(params[0],"Rmdir")) {
1064 nb_rmdir(params[1]);
1065 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1066 nb_qpathinfo(params[1]);
1067 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1068 nb_qfileinfo(ival(params[1]));
1069 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1070 nb_qfsinfo(ival(params[1]));
1071 } else if (!strcmp(params[0],"FIND_FIRST")) {
1072 nb_findfirst(params[1]);
1073 } else if (!strcmp(params[0],"WriteX")) {
1074 nb_writex(ival(params[1]),
1075 ival(params[2]), ival(params[3]), ival(params[4]));
1076 } else if (!strcmp(params[0],"ReadX")) {
1077 nb_readx(ival(params[1]),
1078 ival(params[2]), ival(params[3]), ival(params[4]));
1079 } else if (!strcmp(params[0],"Flush")) {
1080 nb_flush(ival(params[1]));
1081 } else {
1082 printf("Unknown operation %s\n", params[0]);
1083 exit(1);
1086 fclose(f);
1088 nb_cleanup();
1090 if (!torture_close_connection(cli)) {
1091 correct = False;
1094 return correct;
1098 /* run a test that simulates an approximate netbench client load */
1099 static bool run_nbench(int dummy)
1101 double t;
1102 bool correct = True;
1104 nbio_shmem(nprocs);
1106 nbio_id = -1;
1108 signal(SIGALRM, nb_alarm);
1109 alarm(1);
1110 t = create_procs(run_netbench, &correct);
1111 alarm(0);
1113 printf("\nThroughput %g MB/sec\n",
1114 1.0e-6 * nbio_total() / t);
1115 return correct;
1120 This test checks for two things:
1122 1) correct support for retaining locks over a close (ie. the server
1123 must not use posix semantics)
1124 2) support for lock timeouts
1126 static bool run_locktest1(int dummy)
1128 struct cli_state *cli1, *cli2;
1129 const char *fname = "\\lockt1.lck";
1130 uint16_t fnum1, fnum2, fnum3;
1131 time_t t1, t2;
1132 unsigned lock_timeout;
1134 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1135 return False;
1137 cli_sockopt(cli1, sockops);
1138 cli_sockopt(cli2, sockops);
1140 printf("starting locktest1\n");
1142 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1144 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1145 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1146 return False;
1148 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1149 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1150 return False;
1152 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1153 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1154 return False;
1157 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1158 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1159 return False;
1163 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1164 printf("lock2 succeeded! This is a locking bug\n");
1165 return False;
1166 } else {
1167 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1168 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1172 lock_timeout = (1 + (random() % 20));
1173 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1174 t1 = time(NULL);
1175 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1176 printf("lock3 succeeded! This is a locking bug\n");
1177 return False;
1178 } else {
1179 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1180 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1182 t2 = time(NULL);
1184 if (ABS(t2 - t1) < lock_timeout-1) {
1185 printf("error: This server appears not to support timed lock requests\n");
1188 printf("server slept for %u seconds for a %u second timeout\n",
1189 (unsigned int)(t2-t1), lock_timeout);
1191 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1192 printf("close1 failed (%s)\n", cli_errstr(cli1));
1193 return False;
1196 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1197 printf("lock4 succeeded! This is a locking bug\n");
1198 return False;
1199 } else {
1200 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1201 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1204 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1205 printf("close2 failed (%s)\n", cli_errstr(cli1));
1206 return False;
1209 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1210 printf("close3 failed (%s)\n", cli_errstr(cli2));
1211 return False;
1214 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1215 printf("unlink failed (%s)\n", cli_errstr(cli1));
1216 return False;
1220 if (!torture_close_connection(cli1)) {
1221 return False;
1224 if (!torture_close_connection(cli2)) {
1225 return False;
1228 printf("Passed locktest1\n");
1229 return True;
1233 this checks to see if a secondary tconx can use open files from an
1234 earlier tconx
1236 static bool run_tcon_test(int dummy)
1238 static struct cli_state *cli;
1239 const char *fname = "\\tcontest.tmp";
1240 uint16 fnum1;
1241 uint16 cnum1, cnum2, cnum3;
1242 uint16 vuid1, vuid2;
1243 char buf[4];
1244 bool ret = True;
1245 NTSTATUS status;
1247 memset(buf, '\0', sizeof(buf));
1249 if (!torture_open_connection(&cli, 0)) {
1250 return False;
1252 cli_sockopt(cli, sockops);
1254 printf("starting tcontest\n");
1256 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1258 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1259 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1260 return False;
1263 cnum1 = cli->cnum;
1264 vuid1 = cli->vuid;
1266 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1267 printf("initial write failed (%s)", cli_errstr(cli));
1268 return False;
1271 status = cli_tcon_andx(cli, share, "?????",
1272 password, strlen(password)+1);
1273 if (!NT_STATUS_IS_OK(status)) {
1274 printf("%s refused 2nd tree connect (%s)\n", host,
1275 nt_errstr(status));
1276 cli_shutdown(cli);
1277 return False;
1280 cnum2 = cli->cnum;
1281 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1282 vuid2 = cli->vuid + 1;
1284 /* try a write with the wrong tid */
1285 cli->cnum = cnum2;
1287 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1288 printf("* server allows write with wrong TID\n");
1289 ret = False;
1290 } else {
1291 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1295 /* try a write with an invalid tid */
1296 cli->cnum = cnum3;
1298 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1299 printf("* server allows write with invalid TID\n");
1300 ret = False;
1301 } else {
1302 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1305 /* try a write with an invalid vuid */
1306 cli->vuid = vuid2;
1307 cli->cnum = cnum1;
1309 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1310 printf("* server allows write with invalid VUID\n");
1311 ret = False;
1312 } else {
1313 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1316 cli->cnum = cnum1;
1317 cli->vuid = vuid1;
1319 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1320 printf("close failed (%s)\n", cli_errstr(cli));
1321 return False;
1324 cli->cnum = cnum2;
1326 status = cli_tdis(cli);
1327 if (!NT_STATUS_IS_OK(status)) {
1328 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1329 return False;
1332 cli->cnum = cnum1;
1334 if (!torture_close_connection(cli)) {
1335 return False;
1338 return ret;
1343 checks for old style tcon support
1345 static bool run_tcon2_test(int dummy)
1347 static struct cli_state *cli;
1348 uint16 cnum, max_xmit;
1349 char *service;
1350 NTSTATUS status;
1352 if (!torture_open_connection(&cli, 0)) {
1353 return False;
1355 cli_sockopt(cli, sockops);
1357 printf("starting tcon2 test\n");
1359 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1360 return false;
1363 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1365 if (!NT_STATUS_IS_OK(status)) {
1366 printf("tcon2 failed : %s\n", cli_errstr(cli));
1367 } else {
1368 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1369 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1372 if (!torture_close_connection(cli)) {
1373 return False;
1376 printf("Passed tcon2 test\n");
1377 return True;
1380 static bool tcon_devtest(struct cli_state *cli,
1381 const char *myshare, const char *devtype,
1382 const char *return_devtype,
1383 NTSTATUS expected_error)
1385 NTSTATUS status;
1386 bool ret;
1388 status = cli_tcon_andx(cli, myshare, devtype,
1389 password, strlen(password)+1);
1391 if (NT_STATUS_IS_OK(expected_error)) {
1392 if (NT_STATUS_IS_OK(status)) {
1393 if (strcmp(cli->dev, return_devtype) == 0) {
1394 ret = True;
1395 } else {
1396 printf("tconX to share %s with type %s "
1397 "succeeded but returned the wrong "
1398 "device type (got [%s] but should have got [%s])\n",
1399 myshare, devtype, cli->dev, return_devtype);
1400 ret = False;
1402 } else {
1403 printf("tconX to share %s with type %s "
1404 "should have succeeded but failed\n",
1405 myshare, devtype);
1406 ret = False;
1408 cli_tdis(cli);
1409 } else {
1410 if (NT_STATUS_IS_OK(status)) {
1411 printf("tconx to share %s with type %s "
1412 "should have failed but succeeded\n",
1413 myshare, devtype);
1414 ret = False;
1415 } else {
1416 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1417 expected_error)) {
1418 ret = True;
1419 } else {
1420 printf("Returned unexpected error\n");
1421 ret = False;
1425 return ret;
1429 checks for correct tconX support
1431 static bool run_tcon_devtype_test(int dummy)
1433 static struct cli_state *cli1 = NULL;
1434 bool retry;
1435 int flags = 0;
1436 NTSTATUS status;
1437 bool ret = True;
1439 status = cli_full_connection(&cli1, myname,
1440 host, NULL, port_to_use,
1441 NULL, NULL,
1442 username, workgroup,
1443 password, flags, Undefined, &retry);
1445 if (!NT_STATUS_IS_OK(status)) {
1446 printf("could not open connection\n");
1447 return False;
1450 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1451 ret = False;
1453 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1454 ret = False;
1456 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1457 ret = False;
1459 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1460 ret = False;
1462 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1463 ret = False;
1465 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1466 ret = False;
1468 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1469 ret = False;
1471 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1472 ret = False;
1474 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1475 ret = False;
1477 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1478 ret = False;
1480 cli_shutdown(cli1);
1482 if (ret)
1483 printf("Passed tcondevtest\n");
1485 return ret;
1490 This test checks that
1492 1) the server supports multiple locking contexts on the one SMB
1493 connection, distinguished by PID.
1495 2) the server correctly fails overlapping locks made by the same PID (this
1496 goes against POSIX behaviour, which is why it is tricky to implement)
1498 3) the server denies unlock requests by an incorrect client PID
1500 static bool run_locktest2(int dummy)
1502 static struct cli_state *cli;
1503 const char *fname = "\\lockt2.lck";
1504 uint16_t fnum1, fnum2, fnum3;
1505 bool correct = True;
1507 if (!torture_open_connection(&cli, 0)) {
1508 return False;
1511 cli_sockopt(cli, sockops);
1513 printf("starting locktest2\n");
1515 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1517 cli_setpid(cli, 1);
1519 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1520 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1521 return False;
1524 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1525 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1526 return False;
1529 cli_setpid(cli, 2);
1531 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1532 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1533 return False;
1536 cli_setpid(cli, 1);
1538 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1539 printf("lock1 failed (%s)\n", cli_errstr(cli));
1540 return False;
1543 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1544 printf("WRITE lock1 succeeded! This is a locking bug\n");
1545 correct = False;
1546 } else {
1547 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1548 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1551 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1552 printf("WRITE lock2 succeeded! This is a locking bug\n");
1553 correct = False;
1554 } else {
1555 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1556 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1559 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1560 printf("READ lock2 succeeded! This is a locking bug\n");
1561 correct = False;
1562 } else {
1563 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1564 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1567 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1568 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1570 cli_setpid(cli, 2);
1571 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1572 printf("unlock at 100 succeeded! This is a locking bug\n");
1573 correct = False;
1576 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1577 printf("unlock1 succeeded! This is a locking bug\n");
1578 correct = False;
1579 } else {
1580 if (!check_error(__LINE__, cli,
1581 ERRDOS, ERRlock,
1582 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1585 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1586 printf("unlock2 succeeded! This is a locking bug\n");
1587 correct = False;
1588 } else {
1589 if (!check_error(__LINE__, cli,
1590 ERRDOS, ERRlock,
1591 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1594 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1595 printf("lock3 succeeded! This is a locking bug\n");
1596 correct = False;
1597 } else {
1598 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1601 cli_setpid(cli, 1);
1603 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1604 printf("close1 failed (%s)\n", cli_errstr(cli));
1605 return False;
1608 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1609 printf("close2 failed (%s)\n", cli_errstr(cli));
1610 return False;
1613 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1614 printf("close3 failed (%s)\n", cli_errstr(cli));
1615 return False;
1618 if (!torture_close_connection(cli)) {
1619 correct = False;
1622 printf("locktest2 finished\n");
1624 return correct;
1629 This test checks that
1631 1) the server supports the full offset range in lock requests
1633 static bool run_locktest3(int dummy)
1635 static struct cli_state *cli1, *cli2;
1636 const char *fname = "\\lockt3.lck";
1637 uint16_t fnum1, fnum2;
1638 int i;
1639 uint32 offset;
1640 bool correct = True;
1642 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1644 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1645 return False;
1647 cli_sockopt(cli1, sockops);
1648 cli_sockopt(cli2, sockops);
1650 printf("starting locktest3\n");
1652 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1654 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1655 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1656 return False;
1658 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1659 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1660 return False;
1663 for (offset=i=0;i<torture_numops;i++) {
1664 NEXT_OFFSET;
1665 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1666 printf("lock1 %d failed (%s)\n",
1668 cli_errstr(cli1));
1669 return False;
1672 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1673 printf("lock2 %d failed (%s)\n",
1675 cli_errstr(cli1));
1676 return False;
1680 for (offset=i=0;i<torture_numops;i++) {
1681 NEXT_OFFSET;
1683 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1684 printf("error: lock1 %d succeeded!\n", i);
1685 return False;
1688 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1689 printf("error: lock2 %d succeeded!\n", i);
1690 return False;
1693 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1694 printf("error: lock3 %d succeeded!\n", i);
1695 return False;
1698 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1699 printf("error: lock4 %d succeeded!\n", i);
1700 return False;
1704 for (offset=i=0;i<torture_numops;i++) {
1705 NEXT_OFFSET;
1707 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1708 printf("unlock1 %d failed (%s)\n",
1710 cli_errstr(cli1));
1711 return False;
1714 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1715 printf("unlock2 %d failed (%s)\n",
1717 cli_errstr(cli1));
1718 return False;
1722 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1723 printf("close1 failed (%s)\n", cli_errstr(cli1));
1724 return False;
1727 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1728 printf("close2 failed (%s)\n", cli_errstr(cli2));
1729 return False;
1732 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1733 printf("unlink failed (%s)\n", cli_errstr(cli1));
1734 return False;
1737 if (!torture_close_connection(cli1)) {
1738 correct = False;
1741 if (!torture_close_connection(cli2)) {
1742 correct = False;
1745 printf("finished locktest3\n");
1747 return correct;
1750 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1751 printf("** "); correct = False; \
1755 looks at overlapping locks
1757 static bool run_locktest4(int dummy)
1759 static struct cli_state *cli1, *cli2;
1760 const char *fname = "\\lockt4.lck";
1761 uint16_t fnum1, fnum2, f;
1762 bool ret;
1763 char buf[1000];
1764 bool correct = True;
1766 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1767 return False;
1770 cli_sockopt(cli1, sockops);
1771 cli_sockopt(cli2, sockops);
1773 printf("starting locktest4\n");
1775 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1777 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1778 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1780 memset(buf, 0, sizeof(buf));
1782 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1783 printf("Failed to create file\n");
1784 correct = False;
1785 goto fail;
1788 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1789 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1790 EXPECTED(ret, False);
1791 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1793 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1794 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1795 EXPECTED(ret, True);
1796 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1798 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1799 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1800 EXPECTED(ret, False);
1801 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1803 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1804 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1805 EXPECTED(ret, True);
1806 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1808 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1809 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1810 EXPECTED(ret, False);
1811 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1813 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1814 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1815 EXPECTED(ret, True);
1816 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1818 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1819 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1820 EXPECTED(ret, True);
1821 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1823 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1824 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1825 EXPECTED(ret, False);
1826 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1828 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1829 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1830 EXPECTED(ret, False);
1831 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1833 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1834 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1835 EXPECTED(ret, True);
1836 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1838 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1839 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1840 EXPECTED(ret, False);
1841 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1843 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1844 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1845 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1846 EXPECTED(ret, False);
1847 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1850 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1851 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1852 EXPECTED(ret, False);
1853 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1855 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1856 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1857 EXPECTED(ret, False);
1858 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1861 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1862 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1863 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1864 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1865 EXPECTED(ret, True);
1866 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1869 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1870 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1871 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1872 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1873 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1874 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1875 EXPECTED(ret, True);
1876 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1878 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1879 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1880 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1881 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1882 EXPECTED(ret, True);
1883 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1885 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1886 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1887 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1888 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1889 EXPECTED(ret, True);
1890 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1892 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1893 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1894 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1895 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1896 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1897 EXPECTED(ret, True);
1898 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1900 cli_close(cli1, fnum1);
1901 cli_close(cli2, fnum2);
1902 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1903 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1904 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1905 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1906 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1907 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1908 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1909 cli_close(cli1, f);
1910 cli_close(cli1, fnum1);
1911 EXPECTED(ret, True);
1912 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1914 fail:
1915 cli_close(cli1, fnum1);
1916 cli_close(cli2, fnum2);
1917 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1918 torture_close_connection(cli1);
1919 torture_close_connection(cli2);
1921 printf("finished locktest4\n");
1922 return correct;
1926 looks at lock upgrade/downgrade.
1928 static bool run_locktest5(int dummy)
1930 static struct cli_state *cli1, *cli2;
1931 const char *fname = "\\lockt5.lck";
1932 uint16_t fnum1, fnum2, fnum3;
1933 bool ret;
1934 char buf[1000];
1935 bool correct = True;
1937 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1938 return False;
1941 cli_sockopt(cli1, sockops);
1942 cli_sockopt(cli2, sockops);
1944 printf("starting locktest5\n");
1946 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1948 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1949 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1950 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1952 memset(buf, 0, sizeof(buf));
1954 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1955 printf("Failed to create file\n");
1956 correct = False;
1957 goto fail;
1960 /* Check for NT bug... */
1961 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1962 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1963 cli_close(cli1, fnum1);
1964 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1965 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1966 EXPECTED(ret, True);
1967 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1968 cli_close(cli1, fnum1);
1969 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1970 cli_unlock(cli1, fnum3, 0, 1);
1972 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1973 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1974 EXPECTED(ret, True);
1975 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1977 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1978 EXPECTED(ret, False);
1980 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1982 /* Unlock the process 2 lock. */
1983 cli_unlock(cli2, fnum2, 0, 4);
1985 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1986 EXPECTED(ret, False);
1988 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1990 /* Unlock the process 1 fnum3 lock. */
1991 cli_unlock(cli1, fnum3, 0, 4);
1993 /* Stack 2 more locks here. */
1994 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1995 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1997 EXPECTED(ret, True);
1998 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2000 /* Unlock the first process lock, then check this was the WRITE lock that was
2001 removed. */
2003 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2004 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2006 EXPECTED(ret, True);
2007 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2009 /* Unlock the process 2 lock. */
2010 cli_unlock(cli2, fnum2, 0, 4);
2012 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2014 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2015 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2016 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2018 EXPECTED(ret, True);
2019 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2021 /* Ensure the next unlock fails. */
2022 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2023 EXPECTED(ret, False);
2024 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2026 /* Ensure connection 2 can get a write lock. */
2027 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2028 EXPECTED(ret, True);
2030 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2033 fail:
2034 cli_close(cli1, fnum1);
2035 cli_close(cli2, fnum2);
2036 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2037 if (!torture_close_connection(cli1)) {
2038 correct = False;
2040 if (!torture_close_connection(cli2)) {
2041 correct = False;
2044 printf("finished locktest5\n");
2046 return correct;
2050 tries the unusual lockingX locktype bits
2052 static bool run_locktest6(int dummy)
2054 static struct cli_state *cli;
2055 const char *fname[1] = { "\\lock6.txt" };
2056 int i;
2057 uint16_t fnum;
2058 NTSTATUS status;
2060 if (!torture_open_connection(&cli, 0)) {
2061 return False;
2064 cli_sockopt(cli, sockops);
2066 printf("starting locktest6\n");
2068 for (i=0;i<1;i++) {
2069 printf("Testing %s\n", fname[i]);
2071 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2073 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2074 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2075 cli_close(cli, fnum);
2076 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2078 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2079 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2080 cli_close(cli, fnum);
2081 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2083 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2086 torture_close_connection(cli);
2088 printf("finished locktest6\n");
2089 return True;
2092 static bool run_locktest7(int dummy)
2094 struct cli_state *cli1;
2095 const char *fname = "\\lockt7.lck";
2096 uint16_t fnum1;
2097 char buf[200];
2098 bool correct = False;
2100 if (!torture_open_connection(&cli1, 0)) {
2101 return False;
2104 cli_sockopt(cli1, sockops);
2106 printf("starting locktest7\n");
2108 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2110 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2112 memset(buf, 0, sizeof(buf));
2114 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2115 printf("Failed to create file\n");
2116 goto fail;
2119 cli_setpid(cli1, 1);
2121 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2122 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2123 goto fail;
2124 } else {
2125 printf("pid1 successfully locked range 130:4 for READ\n");
2128 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2129 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2130 goto fail;
2131 } else {
2132 printf("pid1 successfully read the range 130:4\n");
2135 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2136 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2137 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2138 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2139 goto fail;
2141 } else {
2142 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2143 goto fail;
2146 cli_setpid(cli1, 2);
2148 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2149 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2150 } else {
2151 printf("pid2 successfully read the range 130:4\n");
2154 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2155 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2156 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2157 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2158 goto fail;
2160 } else {
2161 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2162 goto fail;
2165 cli_setpid(cli1, 1);
2166 cli_unlock(cli1, fnum1, 130, 4);
2168 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2169 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2170 goto fail;
2171 } else {
2172 printf("pid1 successfully locked range 130:4 for WRITE\n");
2175 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2176 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2177 goto fail;
2178 } else {
2179 printf("pid1 successfully read the range 130:4\n");
2182 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2183 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2184 goto fail;
2185 } else {
2186 printf("pid1 successfully wrote to the range 130:4\n");
2189 cli_setpid(cli1, 2);
2191 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2192 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2193 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2194 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2195 goto fail;
2197 } else {
2198 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2199 goto fail;
2202 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2203 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2204 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2205 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2206 goto fail;
2208 } else {
2209 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2210 goto fail;
2213 cli_unlock(cli1, fnum1, 130, 0);
2214 correct = True;
2216 fail:
2217 cli_close(cli1, fnum1);
2218 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2219 torture_close_connection(cli1);
2221 printf("finished locktest7\n");
2222 return correct;
2226 * This demonstrates a problem with our use of GPFS share modes: A file
2227 * descriptor sitting in the pending close queue holding a GPFS share mode
2228 * blocks opening a file another time. Happens with Word 2007 temp files.
2229 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2230 * open is denied with NT_STATUS_SHARING_VIOLATION.
2233 static bool run_locktest8(int dummy)
2235 struct cli_state *cli1;
2236 const char *fname = "\\lockt8.lck";
2237 uint16_t fnum1, fnum2;
2238 char buf[200];
2239 bool correct = False;
2240 NTSTATUS status;
2242 if (!torture_open_connection(&cli1, 0)) {
2243 return False;
2246 cli_sockopt(cli1, sockops);
2248 printf("starting locktest8\n");
2250 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2252 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2253 &fnum1);
2254 if (!NT_STATUS_IS_OK(status)) {
2255 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2256 return false;
2259 memset(buf, 0, sizeof(buf));
2261 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2262 if (!NT_STATUS_IS_OK(status)) {
2263 d_fprintf(stderr, "cli_open second time returned %s\n",
2264 cli_errstr(cli1));
2265 goto fail;
2268 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2269 printf("Unable to apply read lock on range 1:1, error was "
2270 "%s\n", cli_errstr(cli1));
2271 goto fail;
2274 status = cli_close(cli1, fnum1);
2275 if (!NT_STATUS_IS_OK(status)) {
2276 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2277 goto fail;
2280 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2281 if (!NT_STATUS_IS_OK(status)) {
2282 d_fprintf(stderr, "cli_open third time returned %s\n",
2283 cli_errstr(cli1));
2284 goto fail;
2287 correct = true;
2289 fail:
2290 cli_close(cli1, fnum1);
2291 cli_close(cli1, fnum2);
2292 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2293 torture_close_connection(cli1);
2295 printf("finished locktest8\n");
2296 return correct;
2300 * This test is designed to be run in conjunction with
2301 * external NFS or POSIX locks taken in the filesystem.
2302 * It checks that the smbd server will block until the
2303 * lock is released and then acquire it. JRA.
2306 static bool got_alarm;
2307 static int alarm_fd;
2309 static void alarm_handler(int dummy)
2311 got_alarm = True;
2314 static void alarm_handler_parent(int dummy)
2316 close(alarm_fd);
2319 static void do_local_lock(int read_fd, int write_fd)
2321 int fd;
2322 char c = '\0';
2323 struct flock lock;
2324 const char *local_pathname = NULL;
2325 int ret;
2327 local_pathname = talloc_asprintf(talloc_tos(),
2328 "%s/lockt9.lck", local_path);
2329 if (!local_pathname) {
2330 printf("child: alloc fail\n");
2331 exit(1);
2334 unlink(local_pathname);
2335 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2336 if (fd == -1) {
2337 printf("child: open of %s failed %s.\n",
2338 local_pathname, strerror(errno));
2339 exit(1);
2342 /* Now take a fcntl lock. */
2343 lock.l_type = F_WRLCK;
2344 lock.l_whence = SEEK_SET;
2345 lock.l_start = 0;
2346 lock.l_len = 4;
2347 lock.l_pid = getpid();
2349 ret = fcntl(fd,F_SETLK,&lock);
2350 if (ret == -1) {
2351 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2352 local_pathname, strerror(errno));
2353 exit(1);
2354 } else {
2355 printf("child: got lock 0:4 on file %s.\n",
2356 local_pathname );
2357 fflush(stdout);
2360 CatchSignal(SIGALRM, alarm_handler);
2361 alarm(5);
2362 /* Signal the parent. */
2363 if (write(write_fd, &c, 1) != 1) {
2364 printf("child: start signal fail %s.\n",
2365 strerror(errno));
2366 exit(1);
2368 alarm(0);
2370 alarm(10);
2371 /* Wait for the parent to be ready. */
2372 if (read(read_fd, &c, 1) != 1) {
2373 printf("child: reply signal fail %s.\n",
2374 strerror(errno));
2375 exit(1);
2377 alarm(0);
2379 sleep(5);
2380 close(fd);
2381 printf("child: released lock 0:4 on file %s.\n",
2382 local_pathname );
2383 fflush(stdout);
2384 exit(0);
2387 static bool run_locktest9(int dummy)
2389 struct cli_state *cli1;
2390 const char *fname = "\\lockt9.lck";
2391 uint16_t fnum;
2392 bool correct = False;
2393 int pipe_in[2], pipe_out[2];
2394 pid_t child_pid;
2395 char c = '\0';
2396 int ret;
2397 struct timeval start;
2398 double seconds;
2399 NTSTATUS status;
2401 printf("starting locktest9\n");
2403 if (local_path == NULL) {
2404 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2405 return false;
2408 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2409 return false;
2412 child_pid = fork();
2413 if (child_pid == -1) {
2414 return false;
2417 if (child_pid == 0) {
2418 /* Child. */
2419 do_local_lock(pipe_out[0], pipe_in[1]);
2420 exit(0);
2423 close(pipe_out[0]);
2424 close(pipe_in[1]);
2425 pipe_out[0] = -1;
2426 pipe_in[1] = -1;
2428 /* Parent. */
2429 ret = read(pipe_in[0], &c, 1);
2430 if (ret != 1) {
2431 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2432 strerror(errno));
2433 return false;
2436 if (!torture_open_connection(&cli1, 0)) {
2437 return false;
2440 cli_sockopt(cli1, sockops);
2442 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2443 &fnum);
2444 if (!NT_STATUS_IS_OK(status)) {
2445 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2446 return false;
2449 /* Ensure the child has the lock. */
2450 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2451 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2452 goto fail;
2453 } else {
2454 d_printf("Child has the lock.\n");
2457 /* Tell the child to wait 5 seconds then exit. */
2458 ret = write(pipe_out[1], &c, 1);
2459 if (ret != 1) {
2460 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2461 strerror(errno));
2462 goto fail;
2465 /* Wait 20 seconds for the lock. */
2466 alarm_fd = cli1->fd;
2467 CatchSignal(SIGALRM, alarm_handler_parent);
2468 alarm(20);
2470 start = timeval_current();
2472 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2473 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2474 "%s\n", cli_errstr(cli1));
2475 goto fail_nofd;
2477 alarm(0);
2479 seconds = timeval_elapsed(&start);
2481 printf("Parent got the lock after %.2f seconds.\n",
2482 seconds);
2484 status = cli_close(cli1, fnum);
2485 if (!NT_STATUS_IS_OK(status)) {
2486 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2487 goto fail;
2490 correct = true;
2492 fail:
2493 cli_close(cli1, fnum);
2494 torture_close_connection(cli1);
2496 fail_nofd:
2498 printf("finished locktest9\n");
2499 return correct;
2503 test whether fnums and tids open on one VC are available on another (a major
2504 security hole)
2506 static bool run_fdpasstest(int dummy)
2508 struct cli_state *cli1, *cli2;
2509 const char *fname = "\\fdpass.tst";
2510 uint16_t fnum1;
2511 char buf[1024];
2513 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2514 return False;
2516 cli_sockopt(cli1, sockops);
2517 cli_sockopt(cli2, sockops);
2519 printf("starting fdpasstest\n");
2521 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2523 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2524 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2525 return False;
2528 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2529 printf("write failed (%s)\n", cli_errstr(cli1));
2530 return False;
2533 cli2->vuid = cli1->vuid;
2534 cli2->cnum = cli1->cnum;
2535 cli2->pid = cli1->pid;
2537 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2538 printf("read succeeded! nasty security hole [%s]\n",
2539 buf);
2540 return False;
2543 cli_close(cli1, fnum1);
2544 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2546 torture_close_connection(cli1);
2547 torture_close_connection(cli2);
2549 printf("finished fdpasstest\n");
2550 return True;
2553 static bool run_fdsesstest(int dummy)
2555 struct cli_state *cli;
2556 uint16 new_vuid;
2557 uint16 saved_vuid;
2558 uint16 new_cnum;
2559 uint16 saved_cnum;
2560 const char *fname = "\\fdsess.tst";
2561 const char *fname1 = "\\fdsess1.tst";
2562 uint16_t fnum1;
2563 uint16_t fnum2;
2564 char buf[1024];
2565 bool ret = True;
2567 if (!torture_open_connection(&cli, 0))
2568 return False;
2569 cli_sockopt(cli, sockops);
2571 if (!torture_cli_session_setup2(cli, &new_vuid))
2572 return False;
2574 saved_cnum = cli->cnum;
2575 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2576 return False;
2577 new_cnum = cli->cnum;
2578 cli->cnum = saved_cnum;
2580 printf("starting fdsesstest\n");
2582 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2583 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2585 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2586 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2587 return False;
2590 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2591 printf("write failed (%s)\n", cli_errstr(cli));
2592 return False;
2595 saved_vuid = cli->vuid;
2596 cli->vuid = new_vuid;
2598 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2599 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2600 buf);
2601 ret = False;
2603 /* Try to open a file with different vuid, samba cnum. */
2604 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2605 printf("create with different vuid, same cnum succeeded.\n");
2606 cli_close(cli, fnum2);
2607 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2608 } else {
2609 printf("create with different vuid, same cnum failed.\n");
2610 printf("This will cause problems with service clients.\n");
2611 ret = False;
2614 cli->vuid = saved_vuid;
2616 /* Try with same vuid, different cnum. */
2617 cli->cnum = new_cnum;
2619 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2620 printf("read succeeded with different cnum![%s]\n",
2621 buf);
2622 ret = False;
2625 cli->cnum = saved_cnum;
2626 cli_close(cli, fnum1);
2627 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2629 torture_close_connection(cli);
2631 printf("finished fdsesstest\n");
2632 return ret;
2636 This test checks that
2638 1) the server does not allow an unlink on a file that is open
2640 static bool run_unlinktest(int dummy)
2642 struct cli_state *cli;
2643 const char *fname = "\\unlink.tst";
2644 uint16_t fnum;
2645 bool correct = True;
2647 if (!torture_open_connection(&cli, 0)) {
2648 return False;
2651 cli_sockopt(cli, sockops);
2653 printf("starting unlink test\n");
2655 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2657 cli_setpid(cli, 1);
2659 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2660 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2661 return False;
2664 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2665 printf("error: server allowed unlink on an open file\n");
2666 correct = False;
2667 } else {
2668 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2669 NT_STATUS_SHARING_VIOLATION);
2672 cli_close(cli, fnum);
2673 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2675 if (!torture_close_connection(cli)) {
2676 correct = False;
2679 printf("unlink test finished\n");
2681 return correct;
2686 test how many open files this server supports on the one socket
2688 static bool run_maxfidtest(int dummy)
2690 struct cli_state *cli;
2691 const char *ftemplate = "\\maxfid.%d.%d";
2692 fstring fname;
2693 uint16_t fnums[0x11000];
2694 int i;
2695 int retries=4;
2696 bool correct = True;
2698 cli = current_cli;
2700 if (retries <= 0) {
2701 printf("failed to connect\n");
2702 return False;
2705 cli_sockopt(cli, sockops);
2707 for (i=0; i<0x11000; i++) {
2708 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2709 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2710 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2711 printf("open of %s failed (%s)\n",
2712 fname, cli_errstr(cli));
2713 printf("maximum fnum is %d\n", i);
2714 break;
2716 printf("%6d\r", i);
2718 printf("%6d\n", i);
2719 i--;
2721 printf("cleaning up\n");
2722 for (;i>=0;i--) {
2723 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2724 cli_close(cli, fnums[i]);
2725 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2726 printf("unlink of %s failed (%s)\n",
2727 fname, cli_errstr(cli));
2728 correct = False;
2730 printf("%6d\r", i);
2732 printf("%6d\n", 0);
2734 printf("maxfid test finished\n");
2735 if (!torture_close_connection(cli)) {
2736 correct = False;
2738 return correct;
2741 /* generate a random buffer */
2742 static void rand_buf(char *buf, int len)
2744 while (len--) {
2745 *buf = (char)sys_random();
2746 buf++;
2750 /* send smb negprot commands, not reading the response */
2751 static bool run_negprot_nowait(int dummy)
2753 int i;
2754 static struct cli_state *cli;
2755 bool correct = True;
2757 printf("starting negprot nowait test\n");
2759 if (!(cli = open_nbt_connection())) {
2760 return False;
2763 for (i=0;i<50000;i++) {
2764 cli_negprot_sendsync(cli);
2767 if (!torture_close_connection(cli)) {
2768 correct = False;
2771 printf("finished negprot nowait test\n");
2773 return correct;
2776 /* send smb negprot commands, not reading the response */
2777 static bool run_bad_nbt_session(int dummy)
2779 static struct cli_state *cli;
2781 printf("starting bad nbt session test\n");
2783 if (!(cli = open_bad_nbt_connection())) {
2784 return False;
2787 cli_shutdown(cli);
2788 printf("finished bad nbt session test\n");
2789 return true;
2792 /* send random IPC commands */
2793 static bool run_randomipc(int dummy)
2795 char *rparam = NULL;
2796 char *rdata = NULL;
2797 unsigned int rdrcnt,rprcnt;
2798 char param[1024];
2799 int api, param_len, i;
2800 struct cli_state *cli;
2801 bool correct = True;
2802 int count = 50000;
2804 printf("starting random ipc test\n");
2806 if (!torture_open_connection(&cli, 0)) {
2807 return False;
2810 for (i=0;i<count;i++) {
2811 api = sys_random() % 500;
2812 param_len = (sys_random() % 64);
2814 rand_buf(param, param_len);
2816 SSVAL(param,0,api);
2818 cli_api(cli,
2819 param, param_len, 8,
2820 NULL, 0, BUFFER_SIZE,
2821 &rparam, &rprcnt,
2822 &rdata, &rdrcnt);
2823 if (i % 100 == 0) {
2824 printf("%d/%d\r", i,count);
2827 printf("%d/%d\n", i, count);
2829 if (!torture_close_connection(cli)) {
2830 correct = False;
2833 printf("finished random ipc test\n");
2835 return correct;
2840 static void browse_callback(const char *sname, uint32 stype,
2841 const char *comment, void *state)
2843 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2849 This test checks the browse list code
2852 static bool run_browsetest(int dummy)
2854 static struct cli_state *cli;
2855 bool correct = True;
2857 printf("starting browse test\n");
2859 if (!torture_open_connection(&cli, 0)) {
2860 return False;
2863 printf("domain list:\n");
2864 cli_NetServerEnum(cli, cli->server_domain,
2865 SV_TYPE_DOMAIN_ENUM,
2866 browse_callback, NULL);
2868 printf("machine list:\n");
2869 cli_NetServerEnum(cli, cli->server_domain,
2870 SV_TYPE_ALL,
2871 browse_callback, NULL);
2873 if (!torture_close_connection(cli)) {
2874 correct = False;
2877 printf("browse test finished\n");
2879 return correct;
2885 This checks how the getatr calls works
2887 static bool run_attrtest(int dummy)
2889 struct cli_state *cli;
2890 uint16_t fnum;
2891 time_t t, t2;
2892 const char *fname = "\\attrib123456789.tst";
2893 bool correct = True;
2895 printf("starting attrib test\n");
2897 if (!torture_open_connection(&cli, 0)) {
2898 return False;
2901 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2902 cli_open(cli, fname,
2903 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2904 cli_close(cli, fnum);
2905 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2906 printf("getatr failed (%s)\n", cli_errstr(cli));
2907 correct = False;
2910 if (abs(t - time(NULL)) > 60*60*24*10) {
2911 printf("ERROR: SMBgetatr bug. time is %s",
2912 ctime(&t));
2913 t = time(NULL);
2914 correct = True;
2917 t2 = t-60*60*24; /* 1 day ago */
2919 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2920 printf("setatr failed (%s)\n", cli_errstr(cli));
2921 correct = True;
2924 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2925 printf("getatr failed (%s)\n", cli_errstr(cli));
2926 correct = True;
2929 if (t != t2) {
2930 printf("ERROR: getatr/setatr bug. times are\n%s",
2931 ctime(&t));
2932 printf("%s", ctime(&t2));
2933 correct = True;
2936 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2938 if (!torture_close_connection(cli)) {
2939 correct = False;
2942 printf("attrib test finished\n");
2944 return correct;
2949 This checks a couple of trans2 calls
2951 static bool run_trans2test(int dummy)
2953 struct cli_state *cli;
2954 uint16_t fnum;
2955 SMB_OFF_T size;
2956 time_t c_time, a_time, m_time;
2957 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2958 const char *fname = "\\trans2.tst";
2959 const char *dname = "\\trans2";
2960 const char *fname2 = "\\trans2\\trans2.tst";
2961 char pname[1024];
2962 bool correct = True;
2963 NTSTATUS status;
2964 uint32_t fs_attr;
2966 printf("starting trans2 test\n");
2968 if (!torture_open_connection(&cli, 0)) {
2969 return False;
2972 status = cli_get_fs_attr_info(cli, &fs_attr);
2973 if (!NT_STATUS_IS_OK(status)) {
2974 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2975 nt_errstr(status));
2976 correct = false;
2979 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2980 cli_open(cli, fname,
2981 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2982 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
2983 cli, fnum, NULL, &size, &c_time_ts,
2984 &a_time_ts, &w_time_ts,
2985 &m_time_ts, NULL))) {
2986 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2987 correct = False;
2990 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
2991 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2992 correct = False;
2995 if (strcmp(pname, fname)) {
2996 printf("qfilename gave different name? [%s] [%s]\n",
2997 fname, pname);
2998 correct = False;
3001 cli_close(cli, fnum);
3003 sleep(2);
3005 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3006 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3007 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3008 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3009 return False;
3011 cli_close(cli, fnum);
3013 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3014 NULL);
3015 if (!NT_STATUS_IS_OK(status)) {
3016 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3017 correct = False;
3018 } else {
3019 if (c_time != m_time) {
3020 printf("create time=%s", ctime(&c_time));
3021 printf("modify time=%s", ctime(&m_time));
3022 printf("This system appears to have sticky create times\n");
3024 if (a_time % (60*60) == 0) {
3025 printf("access time=%s", ctime(&a_time));
3026 printf("This system appears to set a midnight access time\n");
3027 correct = False;
3030 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3031 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3032 correct = False;
3037 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3038 cli_open(cli, fname,
3039 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3040 cli_close(cli, fnum);
3041 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3042 &m_time_ts, &size, NULL, NULL);
3043 if (!NT_STATUS_IS_OK(status)) {
3044 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3045 correct = False;
3046 } else {
3047 if (w_time_ts.tv_sec < 60*60*24*2) {
3048 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3049 printf("This system appears to set a initial 0 write time\n");
3050 correct = False;
3054 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3057 /* check if the server updates the directory modification time
3058 when creating a new file */
3059 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3060 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3061 correct = False;
3063 sleep(3);
3064 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3065 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3066 if (!NT_STATUS_IS_OK(status)) {
3067 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3068 correct = False;
3071 cli_open(cli, fname2,
3072 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3073 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
3074 cli_close(cli, fnum);
3075 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3076 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3077 if (!NT_STATUS_IS_OK(status)) {
3078 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3079 correct = False;
3080 } else {
3081 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3082 == 0) {
3083 printf("This system does not update directory modification times\n");
3084 correct = False;
3087 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3088 cli_rmdir(cli, dname);
3090 if (!torture_close_connection(cli)) {
3091 correct = False;
3094 printf("trans2 test finished\n");
3096 return correct;
3100 This checks new W2K calls.
3103 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3105 uint8_t *buf = NULL;
3106 uint32 len;
3107 NTSTATUS status;
3109 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3110 pcli->max_xmit, &buf, &len);
3111 if (!NT_STATUS_IS_OK(status)) {
3112 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3113 nt_errstr(status));
3114 } else {
3115 printf("qfileinfo: level %d, len = %u\n", level, len);
3116 dump_data(0, (uint8 *)buf, len);
3117 printf("\n");
3119 TALLOC_FREE(buf);
3120 return status;
3123 static bool run_w2ktest(int dummy)
3125 struct cli_state *cli;
3126 uint16_t fnum;
3127 const char *fname = "\\w2ktest\\w2k.tst";
3128 int level;
3129 bool correct = True;
3131 printf("starting w2k test\n");
3133 if (!torture_open_connection(&cli, 0)) {
3134 return False;
3137 cli_open(cli, fname,
3138 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3140 for (level = 1004; level < 1040; level++) {
3141 new_trans(cli, fnum, level);
3144 cli_close(cli, fnum);
3146 if (!torture_close_connection(cli)) {
3147 correct = False;
3150 printf("w2k test finished\n");
3152 return correct;
3157 this is a harness for some oplock tests
3159 static bool run_oplock1(int dummy)
3161 struct cli_state *cli1;
3162 const char *fname = "\\lockt1.lck";
3163 uint16_t fnum1;
3164 bool correct = True;
3166 printf("starting oplock test 1\n");
3168 if (!torture_open_connection(&cli1, 0)) {
3169 return False;
3172 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3174 cli_sockopt(cli1, sockops);
3176 cli1->use_oplocks = True;
3178 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3179 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3180 return False;
3183 cli1->use_oplocks = False;
3185 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3186 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3188 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3189 printf("close2 failed (%s)\n", cli_errstr(cli1));
3190 return False;
3193 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3194 printf("unlink failed (%s)\n", cli_errstr(cli1));
3195 return False;
3198 if (!torture_close_connection(cli1)) {
3199 correct = False;
3202 printf("finished oplock test 1\n");
3204 return correct;
3207 static bool run_oplock2(int dummy)
3209 struct cli_state *cli1, *cli2;
3210 const char *fname = "\\lockt2.lck";
3211 uint16_t fnum1, fnum2;
3212 int saved_use_oplocks = use_oplocks;
3213 char buf[4];
3214 bool correct = True;
3215 volatile bool *shared_correct;
3217 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3218 *shared_correct = True;
3220 use_level_II_oplocks = True;
3221 use_oplocks = True;
3223 printf("starting oplock test 2\n");
3225 if (!torture_open_connection(&cli1, 0)) {
3226 use_level_II_oplocks = False;
3227 use_oplocks = saved_use_oplocks;
3228 return False;
3231 cli1->use_oplocks = True;
3232 cli1->use_level_II_oplocks = True;
3234 if (!torture_open_connection(&cli2, 1)) {
3235 use_level_II_oplocks = False;
3236 use_oplocks = saved_use_oplocks;
3237 return False;
3240 cli2->use_oplocks = True;
3241 cli2->use_level_II_oplocks = True;
3243 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3245 cli_sockopt(cli1, sockops);
3246 cli_sockopt(cli2, sockops);
3248 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3249 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3250 return False;
3253 /* Don't need the globals any more. */
3254 use_level_II_oplocks = False;
3255 use_oplocks = saved_use_oplocks;
3257 if (fork() == 0) {
3258 /* Child code */
3259 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3260 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3261 *shared_correct = False;
3262 exit(0);
3265 sleep(2);
3267 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3268 printf("close2 failed (%s)\n", cli_errstr(cli1));
3269 *shared_correct = False;
3272 exit(0);
3275 sleep(2);
3277 /* Ensure cli1 processes the break. Empty file should always return 0
3278 * bytes. */
3280 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3281 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3282 correct = False;
3285 /* Should now be at level II. */
3286 /* Test if sending a write locks causes a break to none. */
3288 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3289 printf("lock failed (%s)\n", cli_errstr(cli1));
3290 correct = False;
3293 cli_unlock(cli1, fnum1, 0, 4);
3295 sleep(2);
3297 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3298 printf("lock failed (%s)\n", cli_errstr(cli1));
3299 correct = False;
3302 cli_unlock(cli1, fnum1, 0, 4);
3304 sleep(2);
3306 cli_read(cli1, fnum1, buf, 0, 4);
3308 #if 0
3309 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3310 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3311 correct = False;
3313 #endif
3315 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3316 printf("close1 failed (%s)\n", cli_errstr(cli1));
3317 correct = False;
3320 sleep(4);
3322 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3323 printf("unlink failed (%s)\n", cli_errstr(cli1));
3324 correct = False;
3327 if (!torture_close_connection(cli1)) {
3328 correct = False;
3331 if (!*shared_correct) {
3332 correct = False;
3335 printf("finished oplock test 2\n");
3337 return correct;
3340 /* handler for oplock 3 tests */
3341 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3343 printf("got oplock break fnum=%d level=%d\n",
3344 fnum, level);
3345 return cli_oplock_ack(cli, fnum, level);
3348 static bool run_oplock3(int dummy)
3350 struct cli_state *cli;
3351 const char *fname = "\\oplockt3.dat";
3352 uint16_t fnum;
3353 char buf[4] = "abcd";
3354 bool correct = True;
3355 volatile bool *shared_correct;
3357 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3358 *shared_correct = True;
3360 printf("starting oplock test 3\n");
3362 if (fork() == 0) {
3363 /* Child code */
3364 use_oplocks = True;
3365 use_level_II_oplocks = True;
3366 if (!torture_open_connection(&cli, 0)) {
3367 *shared_correct = False;
3368 exit(0);
3370 sleep(2);
3371 /* try to trigger a oplock break in parent */
3372 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3373 cli_write(cli, fnum, 0, buf, 0, 4);
3374 exit(0);
3377 /* parent code */
3378 use_oplocks = True;
3379 use_level_II_oplocks = True;
3380 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3381 return False;
3383 cli_oplock_handler(cli, oplock3_handler);
3384 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3385 cli_write(cli, fnum, 0, buf, 0, 4);
3386 cli_close(cli, fnum);
3387 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3388 cli->timeout = 20000;
3389 cli_receive_smb(cli);
3390 printf("finished oplock test 3\n");
3392 return (correct && *shared_correct);
3394 /* What are we looking for here? What's sucess and what's FAILURE? */
3400 Test delete on close semantics.
3402 static bool run_deletetest(int dummy)
3404 struct cli_state *cli1 = NULL;
3405 struct cli_state *cli2 = NULL;
3406 const char *fname = "\\delete.file";
3407 uint16_t fnum1 = (uint16_t)-1;
3408 uint16_t fnum2 = (uint16_t)-1;
3409 bool correct = True;
3411 printf("starting delete test\n");
3413 if (!torture_open_connection(&cli1, 0)) {
3414 return False;
3417 cli_sockopt(cli1, sockops);
3419 /* Test 1 - this should delete the file on close. */
3421 cli_setatr(cli1, fname, 0, 0);
3422 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3424 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3425 0, FILE_OVERWRITE_IF,
3426 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3427 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3428 correct = False;
3429 goto fail;
3432 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3433 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3434 correct = False;
3435 goto fail;
3438 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3439 printf("[1] open of %s succeeded (should fail)\n", fname);
3440 correct = False;
3441 goto fail;
3444 printf("first delete on close test succeeded.\n");
3446 /* Test 2 - this should delete the file on close. */
3448 cli_setatr(cli1, fname, 0, 0);
3449 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3451 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3452 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3453 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3454 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3455 correct = False;
3456 goto fail;
3459 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3460 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3461 correct = False;
3462 goto fail;
3465 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3466 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3467 correct = False;
3468 goto fail;
3471 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3472 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3473 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3474 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3475 correct = False;
3476 goto fail;
3478 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3479 } else
3480 printf("second delete on close test succeeded.\n");
3482 /* Test 3 - ... */
3483 cli_setatr(cli1, fname, 0, 0);
3484 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3486 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3487 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3488 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3489 correct = False;
3490 goto fail;
3493 /* This should fail with a sharing violation - open for delete is only compatible
3494 with SHARE_DELETE. */
3496 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3497 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3498 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3499 correct = False;
3500 goto fail;
3503 /* This should succeed. */
3505 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3506 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3507 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3508 correct = False;
3509 goto fail;
3512 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3513 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3514 correct = False;
3515 goto fail;
3518 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3519 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3520 correct = False;
3521 goto fail;
3524 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3525 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3526 correct = False;
3527 goto fail;
3530 /* This should fail - file should no longer be there. */
3532 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3533 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3534 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3535 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3537 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3538 correct = False;
3539 goto fail;
3540 } else
3541 printf("third delete on close test succeeded.\n");
3543 /* Test 4 ... */
3544 cli_setatr(cli1, fname, 0, 0);
3545 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3547 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3548 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3549 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3550 correct = False;
3551 goto fail;
3554 /* This should succeed. */
3555 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3556 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3557 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3558 correct = False;
3559 goto fail;
3562 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3563 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3564 correct = False;
3565 goto fail;
3568 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3569 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3570 correct = False;
3571 goto fail;
3574 /* This should fail - no more opens once delete on close set. */
3575 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3576 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3577 FILE_OPEN, 0, 0, &fnum2))) {
3578 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3579 correct = False;
3580 goto fail;
3581 } else
3582 printf("fourth delete on close test succeeded.\n");
3584 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3585 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3586 correct = False;
3587 goto fail;
3590 /* Test 5 ... */
3591 cli_setatr(cli1, fname, 0, 0);
3592 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3594 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3595 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3596 correct = False;
3597 goto fail;
3600 /* This should fail - only allowed on NT opens with DELETE access. */
3602 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3603 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3604 correct = False;
3605 goto fail;
3608 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3609 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3610 correct = False;
3611 goto fail;
3614 printf("fifth delete on close test succeeded.\n");
3616 /* Test 6 ... */
3617 cli_setatr(cli1, fname, 0, 0);
3618 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3620 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3621 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3622 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3623 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3624 correct = False;
3625 goto fail;
3628 /* This should fail - only allowed on NT opens with DELETE access. */
3630 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3631 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3632 correct = False;
3633 goto fail;
3636 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3637 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3638 correct = False;
3639 goto fail;
3642 printf("sixth delete on close test succeeded.\n");
3644 /* Test 7 ... */
3645 cli_setatr(cli1, fname, 0, 0);
3646 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3648 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3649 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3650 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3651 correct = False;
3652 goto fail;
3655 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3656 printf("[7] setting delete_on_close on file failed !\n");
3657 correct = False;
3658 goto fail;
3661 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3662 printf("[7] unsetting delete_on_close on file failed !\n");
3663 correct = False;
3664 goto fail;
3667 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3668 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3669 correct = False;
3670 goto fail;
3673 /* This next open should succeed - we reset the flag. */
3675 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3676 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3677 correct = False;
3678 goto fail;
3681 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3682 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3683 correct = False;
3684 goto fail;
3687 printf("seventh delete on close test succeeded.\n");
3689 /* Test 7 ... */
3690 cli_setatr(cli1, fname, 0, 0);
3691 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3693 if (!torture_open_connection(&cli2, 1)) {
3694 printf("[8] failed to open second connection.\n");
3695 correct = False;
3696 goto fail;
3699 cli_sockopt(cli1, sockops);
3701 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3702 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3703 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3704 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3705 correct = False;
3706 goto fail;
3709 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3710 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3711 FILE_OPEN, 0, 0, &fnum2))) {
3712 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3713 correct = False;
3714 goto fail;
3717 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3718 printf("[8] setting delete_on_close on file failed !\n");
3719 correct = False;
3720 goto fail;
3723 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3724 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3725 correct = False;
3726 goto fail;
3729 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3730 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3731 correct = False;
3732 goto fail;
3735 /* This should fail.. */
3736 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3737 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3738 goto fail;
3739 correct = False;
3740 } else
3741 printf("eighth delete on close test succeeded.\n");
3743 /* This should fail - we need to set DELETE_ACCESS. */
3744 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3745 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3746 printf("[9] open of %s succeeded should have failed!\n", fname);
3747 correct = False;
3748 goto fail;
3751 printf("ninth delete on close test succeeded.\n");
3753 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3754 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3755 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3756 correct = False;
3757 goto fail;
3760 /* This should delete the file. */
3761 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3762 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3763 correct = False;
3764 goto fail;
3767 /* This should fail.. */
3768 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3769 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3770 goto fail;
3771 correct = False;
3772 } else
3773 printf("tenth delete on close test succeeded.\n");
3775 cli_setatr(cli1, fname, 0, 0);
3776 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3778 /* What error do we get when attempting to open a read-only file with
3779 delete access ? */
3781 /* Create a readonly file. */
3782 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3783 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3784 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3785 correct = False;
3786 goto fail;
3789 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3790 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3791 correct = False;
3792 goto fail;
3795 /* Now try open for delete access. */
3796 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3797 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3798 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3799 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3800 cli_close(cli1, fnum1);
3801 goto fail;
3802 correct = False;
3803 } else {
3804 NTSTATUS nterr = cli_nt_error(cli1);
3805 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3806 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3807 goto fail;
3808 correct = False;
3809 } else {
3810 printf("eleventh delete on close test succeeded.\n");
3814 printf("finished delete test\n");
3816 fail:
3817 /* FIXME: This will crash if we aborted before cli2 got
3818 * intialized, because these functions don't handle
3819 * uninitialized connections. */
3821 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3822 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3823 cli_setatr(cli1, fname, 0, 0);
3824 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3826 if (cli1 && !torture_close_connection(cli1)) {
3827 correct = False;
3829 if (cli2 && !torture_close_connection(cli2)) {
3830 correct = False;
3832 return correct;
3837 print out server properties
3839 static bool run_properties(int dummy)
3841 struct cli_state *cli;
3842 bool correct = True;
3844 printf("starting properties test\n");
3846 ZERO_STRUCT(cli);
3848 if (!torture_open_connection(&cli, 0)) {
3849 return False;
3852 cli_sockopt(cli, sockops);
3854 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3856 if (!torture_close_connection(cli)) {
3857 correct = False;
3860 return correct;
3865 /* FIRST_DESIRED_ACCESS 0xf019f */
3866 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3867 FILE_READ_EA| /* 0xf */ \
3868 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3869 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3870 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3871 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3872 /* SECOND_DESIRED_ACCESS 0xe0080 */
3873 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3874 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3875 WRITE_OWNER_ACCESS /* 0xe0000 */
3877 #if 0
3878 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3879 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3880 FILE_READ_DATA|\
3881 WRITE_OWNER_ACCESS /* */
3882 #endif
3885 Test ntcreate calls made by xcopy
3887 static bool run_xcopy(int dummy)
3889 static struct cli_state *cli1;
3890 const char *fname = "\\test.txt";
3891 bool correct = True;
3892 uint16_t fnum1, fnum2;
3894 printf("starting xcopy test\n");
3896 if (!torture_open_connection(&cli1, 0)) {
3897 return False;
3900 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3901 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3902 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3903 0x4044, 0, &fnum1))) {
3904 printf("First open failed - %s\n", cli_errstr(cli1));
3905 return False;
3908 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3909 SECOND_DESIRED_ACCESS, 0,
3910 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3911 0x200000, 0, &fnum2))) {
3912 printf("second open failed - %s\n", cli_errstr(cli1));
3913 return False;
3916 if (!torture_close_connection(cli1)) {
3917 correct = False;
3920 return correct;
3924 Test rename on files open with share delete and no share delete.
3926 static bool run_rename(int dummy)
3928 static struct cli_state *cli1;
3929 const char *fname = "\\test.txt";
3930 const char *fname1 = "\\test1.txt";
3931 bool correct = True;
3932 uint16_t fnum1;
3933 uint16_t attr;
3934 NTSTATUS status;
3936 printf("starting rename test\n");
3938 if (!torture_open_connection(&cli1, 0)) {
3939 return False;
3942 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3943 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3944 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3945 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3946 printf("First open failed - %s\n", cli_errstr(cli1));
3947 return False;
3950 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3951 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3952 } else {
3953 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3954 correct = False;
3957 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3958 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3959 return False;
3962 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3963 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3964 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3965 #if 0
3966 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3967 #else
3968 FILE_SHARE_DELETE|FILE_SHARE_READ,
3969 #endif
3970 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3971 if (!NT_STATUS_IS_OK(status)) {
3972 printf("Second open failed - %s\n", cli_errstr(cli1));
3973 return False;
3976 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3977 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3978 correct = False;
3979 } else {
3980 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3983 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3984 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3985 return False;
3988 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3989 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3991 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3992 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3993 printf("Third open failed - %s\n", cli_errstr(cli1));
3994 return False;
3998 #if 0
4000 uint16_t fnum2;
4002 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4003 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4004 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4005 return False;
4007 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4008 printf("[8] setting delete_on_close on file failed !\n");
4009 return False;
4012 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4013 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4014 return False;
4017 #endif
4019 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4020 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4021 correct = False;
4022 } else {
4023 printf("Third rename succeeded (SHARE_NONE)\n");
4026 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4027 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4028 return False;
4031 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4032 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4034 /*----*/
4036 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4037 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4038 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4039 return False;
4042 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4043 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4044 } else {
4045 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4046 correct = False;
4049 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4050 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4051 return False;
4054 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4055 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4057 /*--*/
4059 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4060 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4061 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4062 return False;
4065 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4066 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4067 cli_errstr(cli1));
4068 correct = False;
4069 } else {
4070 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4074 * Now check if the first name still exists ...
4077 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4078 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4079 printf("Opening original file after rename of open file fails: %s\n",
4080 cli_errstr(cli1));
4082 else {
4083 printf("Opening original file after rename of open file works ...\n");
4084 (void)cli_close(cli1, fnum2);
4085 } */
4087 /*--*/
4088 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4089 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4090 return False;
4093 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4094 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4095 printf("getatr on file %s failed - %s ! \n",
4096 fname1,
4097 cli_errstr(cli1));
4098 correct = False;
4099 } else {
4100 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4101 printf("Renamed file %s has wrong attr 0x%x "
4102 "(should be 0x%x)\n",
4103 fname1,
4104 attr,
4105 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4106 correct = False;
4107 } else {
4108 printf("Renamed file %s has archive bit set\n", fname1);
4112 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4113 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4115 if (!torture_close_connection(cli1)) {
4116 correct = False;
4119 return correct;
4122 static bool run_pipe_number(int dummy)
4124 struct cli_state *cli1;
4125 const char *pipe_name = "\\SPOOLSS";
4126 uint16_t fnum;
4127 int num_pipes = 0;
4129 printf("starting pipenumber test\n");
4130 if (!torture_open_connection(&cli1, 0)) {
4131 return False;
4134 cli_sockopt(cli1, sockops);
4135 while(1) {
4136 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4137 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4138 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4139 break;
4141 num_pipes++;
4142 printf("\r%6d", num_pipes);
4145 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4146 torture_close_connection(cli1);
4147 return True;
4151 Test open mode returns on read-only files.
4153 static bool run_opentest(int dummy)
4155 static struct cli_state *cli1;
4156 static struct cli_state *cli2;
4157 const char *fname = "\\readonly.file";
4158 uint16_t fnum1, fnum2;
4159 char buf[20];
4160 SMB_OFF_T fsize;
4161 bool correct = True;
4162 char *tmp_path;
4164 printf("starting open test\n");
4166 if (!torture_open_connection(&cli1, 0)) {
4167 return False;
4170 cli_setatr(cli1, fname, 0, 0);
4171 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4173 cli_sockopt(cli1, sockops);
4175 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4176 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4177 return False;
4180 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4181 printf("close2 failed (%s)\n", cli_errstr(cli1));
4182 return False;
4185 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4186 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4187 return False;
4190 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4191 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4192 return False;
4195 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4196 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4198 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4199 NT_STATUS_ACCESS_DENIED)) {
4200 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4203 printf("finished open test 1\n");
4205 cli_close(cli1, fnum1);
4207 /* Now try not readonly and ensure ERRbadshare is returned. */
4209 cli_setatr(cli1, fname, 0, 0);
4211 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4212 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4213 return False;
4216 /* This will fail - but the error should be ERRshare. */
4217 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4219 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4220 NT_STATUS_SHARING_VIOLATION)) {
4221 printf("correct error code ERRDOS/ERRbadshare returned\n");
4224 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4225 printf("close2 failed (%s)\n", cli_errstr(cli1));
4226 return False;
4229 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4231 printf("finished open test 2\n");
4233 /* Test truncate open disposition on file opened for read. */
4235 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4236 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4237 return False;
4240 /* write 20 bytes. */
4242 memset(buf, '\0', 20);
4244 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4245 printf("write failed (%s)\n", cli_errstr(cli1));
4246 correct = False;
4249 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4250 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4251 return False;
4254 /* Ensure size == 20. */
4255 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4256 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4257 return False;
4260 if (fsize != 20) {
4261 printf("(3) file size != 20\n");
4262 return False;
4265 /* Now test if we can truncate a file opened for readonly. */
4267 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4268 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4269 return False;
4272 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4273 printf("close2 failed (%s)\n", cli_errstr(cli1));
4274 return False;
4277 /* Ensure size == 0. */
4278 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4279 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4280 return False;
4283 if (fsize != 0) {
4284 printf("(3) file size != 0\n");
4285 return False;
4287 printf("finished open test 3\n");
4289 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4291 printf("Do ctemp tests\n");
4292 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4293 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4294 return False;
4296 printf("ctemp gave path %s\n", tmp_path);
4297 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4298 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4300 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4301 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4304 /* Test the non-io opens... */
4306 if (!torture_open_connection(&cli2, 1)) {
4307 return False;
4310 cli_setatr(cli2, fname, 0, 0);
4311 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4313 cli_sockopt(cli2, sockops);
4315 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4317 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4318 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4319 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4320 return False;
4323 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4324 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4325 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4326 return False;
4329 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4330 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4331 return False;
4333 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4334 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4335 return False;
4338 printf("non-io open test #1 passed.\n");
4340 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4342 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4344 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4345 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4346 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4347 return False;
4350 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4351 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4352 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4353 return False;
4356 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4357 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4358 return False;
4360 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4361 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4362 return False;
4365 printf("non-io open test #2 passed.\n");
4367 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4369 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4371 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4372 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4373 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4374 return False;
4377 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4378 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4379 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4380 return False;
4383 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4384 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4385 return False;
4387 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4388 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4389 return False;
4392 printf("non-io open test #3 passed.\n");
4394 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4396 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4398 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4399 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4400 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4401 return False;
4404 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4405 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4406 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4407 return False;
4410 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4412 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4413 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4414 return False;
4417 printf("non-io open test #4 passed.\n");
4419 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4421 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4423 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4424 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4425 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4426 return False;
4429 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4430 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4431 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4432 return False;
4435 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4436 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4437 return False;
4440 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4441 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4442 return False;
4445 printf("non-io open test #5 passed.\n");
4447 printf("TEST #6 testing 1 non-io open, one io open\n");
4449 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4451 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4452 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4453 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4454 return False;
4457 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4458 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4459 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4460 return False;
4463 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4464 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4465 return False;
4468 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4469 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4470 return False;
4473 printf("non-io open test #6 passed.\n");
4475 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4477 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4479 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4480 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4481 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4482 return False;
4485 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4486 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4487 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4488 return False;
4491 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4493 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4494 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4495 return False;
4498 printf("non-io open test #7 passed.\n");
4500 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4502 if (!torture_close_connection(cli1)) {
4503 correct = False;
4505 if (!torture_close_connection(cli2)) {
4506 correct = False;
4509 return correct;
4512 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4514 uint16 major, minor;
4515 uint32 caplow, caphigh;
4516 NTSTATUS status;
4518 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4519 printf("Server doesn't support UNIX CIFS extensions.\n");
4520 return NT_STATUS_NOT_SUPPORTED;
4523 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4524 &caphigh);
4525 if (!NT_STATUS_IS_OK(status)) {
4526 printf("Server didn't return UNIX CIFS extensions: %s\n",
4527 nt_errstr(status));
4528 return status;
4531 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4532 caplow, caphigh);
4533 if (!NT_STATUS_IS_OK(status)) {
4534 printf("Server doesn't support setting UNIX CIFS extensions: "
4535 "%s.\n", nt_errstr(status));
4536 return status;
4539 return NT_STATUS_OK;
4543 Test POSIX open /mkdir calls.
4545 static bool run_simple_posix_open_test(int dummy)
4547 static struct cli_state *cli1;
4548 const char *fname = "posix:file";
4549 const char *hname = "posix:hlink";
4550 const char *sname = "posix:symlink";
4551 const char *dname = "posix:dir";
4552 char buf[10];
4553 char namebuf[11];
4554 uint16_t fnum1 = (uint16_t)-1;
4555 SMB_STRUCT_STAT sbuf;
4556 bool correct = false;
4557 NTSTATUS status;
4559 printf("Starting simple POSIX open test\n");
4561 if (!torture_open_connection(&cli1, 0)) {
4562 return false;
4565 cli_sockopt(cli1, sockops);
4567 status = torture_setup_unix_extensions(cli1);
4568 if (!NT_STATUS_IS_OK(status)) {
4569 return false;
4572 cli_setatr(cli1, fname, 0, 0);
4573 cli_posix_unlink(cli1, fname);
4574 cli_setatr(cli1, dname, 0, 0);
4575 cli_posix_rmdir(cli1, dname);
4576 cli_setatr(cli1, hname, 0, 0);
4577 cli_posix_unlink(cli1, hname);
4578 cli_setatr(cli1, sname, 0, 0);
4579 cli_posix_unlink(cli1, sname);
4581 /* Create a directory. */
4582 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4583 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4584 goto out;
4587 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4588 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4589 goto out;
4592 /* Test ftruncate - set file size. */
4593 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4594 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4595 goto out;
4598 /* Ensure st_size == 1000 */
4599 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4600 printf("stat failed (%s)\n", cli_errstr(cli1));
4601 goto out;
4604 if (sbuf.st_ex_size != 1000) {
4605 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4606 goto out;
4609 /* Test ftruncate - set file size back to zero. */
4610 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4611 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4612 goto out;
4615 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4616 printf("close failed (%s)\n", cli_errstr(cli1));
4617 goto out;
4620 /* Now open the file again for read only. */
4621 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4622 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4623 goto out;
4626 /* Now unlink while open. */
4627 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4628 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4629 goto out;
4632 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4633 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4634 goto out;
4637 /* Ensure the file has gone. */
4638 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4639 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4640 goto out;
4643 /* What happens when we try and POSIX open a directory ? */
4644 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4645 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4646 goto out;
4647 } else {
4648 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4649 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4650 goto out;
4654 /* Create the file. */
4655 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4656 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4657 goto out;
4660 /* Write some data into it. */
4661 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4662 printf("cli_write failed: %s\n", cli_errstr(cli1));
4663 goto out;
4666 cli_close(cli1, fnum1);
4668 /* Now create a hardlink. */
4669 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4670 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4671 goto out;
4674 /* Now create a symlink. */
4675 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4676 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4677 goto out;
4680 /* Open the hardlink for read. */
4681 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4682 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4683 goto out;
4686 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4687 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4688 goto out;
4691 if (memcmp(buf, "TEST DATA\n", 10)) {
4692 printf("invalid data read from hardlink\n");
4693 goto out;
4696 /* Do a POSIX lock/unlock. */
4697 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4698 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4699 goto out;
4702 /* Punch a hole in the locked area. */
4703 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4704 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4705 goto out;
4708 cli_close(cli1, fnum1);
4710 /* Open the symlink for read - this should fail. A POSIX
4711 client should not be doing opens on a symlink. */
4712 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4713 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4714 goto out;
4715 } else {
4716 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4717 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4718 printf("POSIX open of %s should have failed "
4719 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4720 "failed with %s instead.\n",
4721 sname, cli_errstr(cli1));
4722 goto out;
4726 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4727 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4728 goto out;
4731 if (strcmp(namebuf, fname) != 0) {
4732 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4733 sname, fname, namebuf);
4734 goto out;
4737 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4738 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4739 goto out;
4742 printf("Simple POSIX open test passed\n");
4743 correct = true;
4745 out:
4747 if (fnum1 != (uint16_t)-1) {
4748 cli_close(cli1, fnum1);
4749 fnum1 = (uint16_t)-1;
4752 cli_setatr(cli1, sname, 0, 0);
4753 cli_posix_unlink(cli1, sname);
4754 cli_setatr(cli1, hname, 0, 0);
4755 cli_posix_unlink(cli1, hname);
4756 cli_setatr(cli1, fname, 0, 0);
4757 cli_posix_unlink(cli1, fname);
4758 cli_setatr(cli1, dname, 0, 0);
4759 cli_posix_rmdir(cli1, dname);
4761 if (!torture_close_connection(cli1)) {
4762 correct = false;
4765 return correct;
4769 static uint32 open_attrs_table[] = {
4770 FILE_ATTRIBUTE_NORMAL,
4771 FILE_ATTRIBUTE_ARCHIVE,
4772 FILE_ATTRIBUTE_READONLY,
4773 FILE_ATTRIBUTE_HIDDEN,
4774 FILE_ATTRIBUTE_SYSTEM,
4776 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4777 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4778 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4779 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4780 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4781 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4783 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4784 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4785 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4786 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4789 struct trunc_open_results {
4790 unsigned int num;
4791 uint32 init_attr;
4792 uint32 trunc_attr;
4793 uint32 result_attr;
4796 static struct trunc_open_results attr_results[] = {
4797 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4798 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4799 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4800 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4801 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4802 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4803 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4804 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4805 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4806 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4807 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4808 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4809 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4810 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4811 { 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 },
4812 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4813 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4814 { 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 },
4815 { 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 },
4816 { 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 },
4817 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4818 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4819 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4820 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4821 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4822 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4825 static bool run_openattrtest(int dummy)
4827 static struct cli_state *cli1;
4828 const char *fname = "\\openattr.file";
4829 uint16_t fnum1;
4830 bool correct = True;
4831 uint16 attr;
4832 unsigned int i, j, k, l;
4834 printf("starting open attr test\n");
4836 if (!torture_open_connection(&cli1, 0)) {
4837 return False;
4840 cli_sockopt(cli1, sockops);
4842 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4843 cli_setatr(cli1, fname, 0, 0);
4844 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4845 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4846 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4847 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4848 return False;
4851 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4852 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4853 return False;
4856 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4857 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4858 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4859 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4860 if (attr_results[l].num == k) {
4861 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4862 k, open_attrs_table[i],
4863 open_attrs_table[j],
4864 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4865 correct = False;
4868 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4869 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4870 k, open_attrs_table[i], open_attrs_table[j],
4871 cli_errstr(cli1));
4872 correct = False;
4874 #if 0
4875 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4876 #endif
4877 k++;
4878 continue;
4881 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4882 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4883 return False;
4886 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4887 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4888 return False;
4891 #if 0
4892 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4893 k, open_attrs_table[i], open_attrs_table[j], attr );
4894 #endif
4896 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4897 if (attr_results[l].num == k) {
4898 if (attr != attr_results[l].result_attr ||
4899 open_attrs_table[i] != attr_results[l].init_attr ||
4900 open_attrs_table[j] != attr_results[l].trunc_attr) {
4901 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4902 open_attrs_table[i],
4903 open_attrs_table[j],
4904 (unsigned int)attr,
4905 attr_results[l].result_attr);
4906 correct = False;
4908 break;
4911 k++;
4915 cli_setatr(cli1, fname, 0, 0);
4916 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4918 printf("open attr test %s.\n", correct ? "passed" : "failed");
4920 if (!torture_close_connection(cli1)) {
4921 correct = False;
4923 return correct;
4926 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
4927 const char *name, void *state)
4929 int *matched = (int *)state;
4930 if (matched != NULL) {
4931 *matched += 1;
4933 return NT_STATUS_OK;
4937 test directory listing speed
4939 static bool run_dirtest(int dummy)
4941 int i;
4942 static struct cli_state *cli;
4943 uint16_t fnum;
4944 struct timeval core_start;
4945 bool correct = True;
4946 int matched;
4948 printf("starting directory test\n");
4950 if (!torture_open_connection(&cli, 0)) {
4951 return False;
4954 cli_sockopt(cli, sockops);
4956 srandom(0);
4957 for (i=0;i<torture_numops;i++) {
4958 fstring fname;
4959 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4960 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4961 fprintf(stderr,"Failed to open %s\n", fname);
4962 return False;
4964 cli_close(cli, fnum);
4967 core_start = timeval_current();
4969 matched = 0;
4970 cli_list(cli, "a*.*", 0, list_fn, &matched);
4971 printf("Matched %d\n", matched);
4973 matched = 0;
4974 cli_list(cli, "b*.*", 0, list_fn, &matched);
4975 printf("Matched %d\n", matched);
4977 matched = 0;
4978 cli_list(cli, "xyzabc", 0, list_fn, &matched);
4979 printf("Matched %d\n", matched);
4981 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4983 srandom(0);
4984 for (i=0;i<torture_numops;i++) {
4985 fstring fname;
4986 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4987 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4990 if (!torture_close_connection(cli)) {
4991 correct = False;
4994 printf("finished dirtest\n");
4996 return correct;
4999 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5000 void *state)
5002 struct cli_state *pcli = (struct cli_state *)state;
5003 fstring fname;
5004 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5006 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5007 return NT_STATUS_OK;
5009 if (finfo->mode & aDIR) {
5010 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5011 printf("del_fn: failed to rmdir %s\n,", fname );
5012 } else {
5013 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5014 printf("del_fn: failed to unlink %s\n,", fname );
5016 return NT_STATUS_OK;
5021 sees what IOCTLs are supported
5023 bool torture_ioctl_test(int dummy)
5025 static struct cli_state *cli;
5026 uint16_t device, function;
5027 uint16_t fnum;
5028 const char *fname = "\\ioctl.dat";
5029 DATA_BLOB blob;
5030 NTSTATUS status;
5032 if (!torture_open_connection(&cli, 0)) {
5033 return False;
5036 printf("starting ioctl test\n");
5038 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5040 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5041 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5042 return False;
5045 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5046 printf("ioctl device info: %s\n", nt_errstr(status));
5048 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5049 printf("ioctl job info: %s\n", nt_errstr(status));
5051 for (device=0;device<0x100;device++) {
5052 printf("ioctl test with device = 0x%x\n", device);
5053 for (function=0;function<0x100;function++) {
5054 uint32 code = (device<<16) | function;
5056 status = cli_raw_ioctl(cli, fnum, code, &blob);
5058 if (NT_STATUS_IS_OK(status)) {
5059 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5060 (int)blob.length);
5061 data_blob_free(&blob);
5066 if (!torture_close_connection(cli)) {
5067 return False;
5070 return True;
5075 tries varients of chkpath
5077 bool torture_chkpath_test(int dummy)
5079 static struct cli_state *cli;
5080 uint16_t fnum;
5081 bool ret;
5083 if (!torture_open_connection(&cli, 0)) {
5084 return False;
5087 printf("starting chkpath test\n");
5089 /* cleanup from an old run */
5090 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5091 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5092 cli_rmdir(cli, "\\chkpath.dir");
5094 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5095 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5096 return False;
5099 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5100 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5101 return False;
5104 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5105 printf("open1 failed (%s)\n", cli_errstr(cli));
5106 return False;
5108 cli_close(cli, fnum);
5110 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5111 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5112 ret = False;
5115 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5116 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5117 ret = False;
5120 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5121 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5122 NT_STATUS_NOT_A_DIRECTORY);
5123 } else {
5124 printf("* chkpath on a file should fail\n");
5125 ret = False;
5128 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5129 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5130 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5131 } else {
5132 printf("* chkpath on a non existant file should fail\n");
5133 ret = False;
5136 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5137 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5138 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5139 } else {
5140 printf("* chkpath on a non existent component should fail\n");
5141 ret = False;
5144 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5145 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5146 cli_rmdir(cli, "\\chkpath.dir");
5148 if (!torture_close_connection(cli)) {
5149 return False;
5152 return ret;
5155 static bool run_eatest(int dummy)
5157 static struct cli_state *cli;
5158 const char *fname = "\\eatest.txt";
5159 bool correct = True;
5160 uint16_t fnum;
5161 int i;
5162 size_t num_eas;
5163 struct ea_struct *ea_list = NULL;
5164 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5165 NTSTATUS status;
5167 printf("starting eatest\n");
5169 if (!torture_open_connection(&cli, 0)) {
5170 talloc_destroy(mem_ctx);
5171 return False;
5174 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5175 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5176 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5177 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5178 0x4044, 0, &fnum))) {
5179 printf("open failed - %s\n", cli_errstr(cli));
5180 talloc_destroy(mem_ctx);
5181 return False;
5184 for (i = 0; i < 10; i++) {
5185 fstring ea_name, ea_val;
5187 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5188 memset(ea_val, (char)i+1, i+1);
5189 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5190 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5191 talloc_destroy(mem_ctx);
5192 return False;
5196 cli_close(cli, fnum);
5197 for (i = 0; i < 10; i++) {
5198 fstring ea_name, ea_val;
5200 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5201 memset(ea_val, (char)i+1, i+1);
5202 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5203 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5204 talloc_destroy(mem_ctx);
5205 return False;
5209 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5210 if (!NT_STATUS_IS_OK(status)) {
5211 printf("ea_get list failed - %s\n", nt_errstr(status));
5212 correct = False;
5215 printf("num_eas = %d\n", (int)num_eas);
5217 if (num_eas != 20) {
5218 printf("Should be 20 EA's stored... failing.\n");
5219 correct = False;
5222 for (i = 0; i < num_eas; i++) {
5223 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5224 dump_data(0, ea_list[i].value.data,
5225 ea_list[i].value.length);
5228 /* Setting EA's to zero length deletes them. Test this */
5229 printf("Now deleting all EA's - case indepenent....\n");
5231 #if 1
5232 cli_set_ea_path(cli, fname, "", "", 0);
5233 #else
5234 for (i = 0; i < 20; i++) {
5235 fstring ea_name;
5236 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5237 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5238 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5239 talloc_destroy(mem_ctx);
5240 return False;
5243 #endif
5245 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5246 if (!NT_STATUS_IS_OK(status)) {
5247 printf("ea_get list failed - %s\n", nt_errstr(status));
5248 correct = False;
5251 printf("num_eas = %d\n", (int)num_eas);
5252 for (i = 0; i < num_eas; i++) {
5253 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5254 dump_data(0, ea_list[i].value.data,
5255 ea_list[i].value.length);
5258 if (num_eas != 0) {
5259 printf("deleting EA's failed.\n");
5260 correct = False;
5263 /* Try and delete a non existant EA. */
5264 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5265 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5266 correct = False;
5269 talloc_destroy(mem_ctx);
5270 if (!torture_close_connection(cli)) {
5271 correct = False;
5274 return correct;
5277 static bool run_dirtest1(int dummy)
5279 int i;
5280 static struct cli_state *cli;
5281 uint16_t fnum;
5282 int num_seen;
5283 bool correct = True;
5285 printf("starting directory test\n");
5287 if (!torture_open_connection(&cli, 0)) {
5288 return False;
5291 cli_sockopt(cli, sockops);
5293 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5294 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5295 cli_rmdir(cli, "\\LISTDIR");
5296 cli_mkdir(cli, "\\LISTDIR");
5298 /* Create 1000 files and 1000 directories. */
5299 for (i=0;i<1000;i++) {
5300 fstring fname;
5301 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5302 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5303 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5304 fprintf(stderr,"Failed to open %s\n", fname);
5305 return False;
5307 cli_close(cli, fnum);
5309 for (i=0;i<1000;i++) {
5310 fstring fname;
5311 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5312 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5313 fprintf(stderr,"Failed to open %s\n", fname);
5314 return False;
5318 /* Now ensure that doing an old list sees both files and directories. */
5319 num_seen = 0;
5320 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5321 printf("num_seen = %d\n", num_seen );
5322 /* We should see 100 files + 1000 directories + . and .. */
5323 if (num_seen != 2002)
5324 correct = False;
5326 /* Ensure if we have the "must have" bits we only see the
5327 * relevent entries.
5329 num_seen = 0;
5330 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5331 printf("num_seen = %d\n", num_seen );
5332 if (num_seen != 1002)
5333 correct = False;
5335 num_seen = 0;
5336 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5337 printf("num_seen = %d\n", num_seen );
5338 if (num_seen != 1000)
5339 correct = False;
5341 /* Delete everything. */
5342 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5343 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5344 cli_rmdir(cli, "\\LISTDIR");
5346 #if 0
5347 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5348 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5349 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5350 #endif
5352 if (!torture_close_connection(cli)) {
5353 correct = False;
5356 printf("finished dirtest1\n");
5358 return correct;
5361 static bool run_error_map_extract(int dummy) {
5363 static struct cli_state *c_dos;
5364 static struct cli_state *c_nt;
5365 NTSTATUS status;
5367 uint32 error;
5369 uint32 flgs2, errnum;
5370 uint8 errclass;
5372 NTSTATUS nt_status;
5374 fstring user;
5376 /* NT-Error connection */
5378 if (!(c_nt = open_nbt_connection())) {
5379 return False;
5382 c_nt->use_spnego = False;
5384 status = cli_negprot(c_nt);
5386 if (!NT_STATUS_IS_OK(status)) {
5387 printf("%s rejected the NT-error negprot (%s)\n", host,
5388 nt_errstr(status));
5389 cli_shutdown(c_nt);
5390 return False;
5393 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5394 workgroup))) {
5395 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5396 return False;
5399 /* DOS-Error connection */
5401 if (!(c_dos = open_nbt_connection())) {
5402 return False;
5405 c_dos->use_spnego = False;
5406 c_dos->force_dos_errors = True;
5408 status = cli_negprot(c_dos);
5409 if (!NT_STATUS_IS_OK(status)) {
5410 printf("%s rejected the DOS-error negprot (%s)\n", host,
5411 nt_errstr(status));
5412 cli_shutdown(c_dos);
5413 return False;
5416 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5417 workgroup))) {
5418 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5419 return False;
5422 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5423 fstr_sprintf(user, "%X", error);
5425 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5426 password, strlen(password),
5427 password, strlen(password),
5428 workgroup))) {
5429 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5432 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5434 /* Case #1: 32-bit NT errors */
5435 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5436 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5437 } else {
5438 printf("/** Dos error on NT connection! (%s) */\n",
5439 cli_errstr(c_nt));
5440 nt_status = NT_STATUS(0xc0000000);
5443 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5444 password, strlen(password),
5445 password, strlen(password),
5446 workgroup))) {
5447 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5449 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5451 /* Case #1: 32-bit NT errors */
5452 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5453 printf("/** NT error on DOS connection! (%s) */\n",
5454 cli_errstr(c_nt));
5455 errnum = errclass = 0;
5456 } else {
5457 cli_dos_error(c_dos, &errclass, &errnum);
5460 if (NT_STATUS_V(nt_status) != error) {
5461 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5462 get_nt_error_c_code(NT_STATUS(error)),
5463 get_nt_error_c_code(nt_status));
5466 printf("\t{%s,\t%s,\t%s},\n",
5467 smb_dos_err_class(errclass),
5468 smb_dos_err_name(errclass, errnum),
5469 get_nt_error_c_code(NT_STATUS(error)));
5471 return True;
5474 static bool run_sesssetup_bench(int dummy)
5476 static struct cli_state *c;
5477 const char *fname = "\\file.dat";
5478 uint16_t fnum;
5479 NTSTATUS status;
5480 int i;
5482 if (!torture_open_connection(&c, 0)) {
5483 return false;
5486 if (!NT_STATUS_IS_OK(cli_ntcreate(
5487 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5488 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5489 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5490 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5491 return false;
5494 for (i=0; i<torture_numops; i++) {
5495 status = cli_session_setup(
5496 c, username,
5497 password, strlen(password),
5498 password, strlen(password),
5499 workgroup);
5500 if (!NT_STATUS_IS_OK(status)) {
5501 d_printf("(%s) cli_session_setup failed: %s\n",
5502 __location__, nt_errstr(status));
5503 return false;
5506 d_printf("\r%d ", (int)c->vuid);
5508 status = cli_ulogoff(c);
5509 if (!NT_STATUS_IS_OK(status)) {
5510 d_printf("(%s) cli_ulogoff failed: %s\n",
5511 __location__, nt_errstr(status));
5512 return false;
5514 c->vuid = 0;
5517 return true;
5520 static bool subst_test(const char *str, const char *user, const char *domain,
5521 uid_t uid, gid_t gid, const char *expected)
5523 char *subst;
5524 bool result = true;
5526 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5528 if (strcmp(subst, expected) != 0) {
5529 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5530 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5531 expected);
5532 result = false;
5535 TALLOC_FREE(subst);
5536 return result;
5539 static void chain1_open_completion(struct tevent_req *req)
5541 uint16_t fnum;
5542 NTSTATUS status;
5543 status = cli_open_recv(req, &fnum);
5544 TALLOC_FREE(req);
5546 d_printf("cli_open_recv returned %s: %d\n",
5547 nt_errstr(status),
5548 NT_STATUS_IS_OK(status) ? fnum : -1);
5551 static void chain1_write_completion(struct tevent_req *req)
5553 size_t written;
5554 NTSTATUS status;
5555 status = cli_write_andx_recv(req, &written);
5556 TALLOC_FREE(req);
5558 d_printf("cli_write_andx_recv returned %s: %d\n",
5559 nt_errstr(status),
5560 NT_STATUS_IS_OK(status) ? (int)written : -1);
5563 static void chain1_close_completion(struct tevent_req *req)
5565 NTSTATUS status;
5566 bool *done = (bool *)tevent_req_callback_data_void(req);
5568 status = cli_close_recv(req);
5569 *done = true;
5571 TALLOC_FREE(req);
5573 d_printf("cli_close returned %s\n", nt_errstr(status));
5576 static bool run_chain1(int dummy)
5578 struct cli_state *cli1;
5579 struct event_context *evt = event_context_init(NULL);
5580 struct tevent_req *reqs[3], *smbreqs[3];
5581 bool done = false;
5582 const char *str = "foobar";
5583 NTSTATUS status;
5585 printf("starting chain1 test\n");
5586 if (!torture_open_connection(&cli1, 0)) {
5587 return False;
5590 cli_sockopt(cli1, sockops);
5592 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5593 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5594 if (reqs[0] == NULL) return false;
5595 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5598 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5599 (uint8_t *)str, 0, strlen(str)+1,
5600 smbreqs, 1, &smbreqs[1]);
5601 if (reqs[1] == NULL) return false;
5602 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5604 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5605 if (reqs[2] == NULL) return false;
5606 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5608 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5609 if (!NT_STATUS_IS_OK(status)) {
5610 return false;
5613 while (!done) {
5614 event_loop_once(evt);
5617 torture_close_connection(cli1);
5618 return True;
5621 static void chain2_sesssetup_completion(struct tevent_req *req)
5623 NTSTATUS status;
5624 status = cli_session_setup_guest_recv(req);
5625 d_printf("sesssetup returned %s\n", nt_errstr(status));
5628 static void chain2_tcon_completion(struct tevent_req *req)
5630 bool *done = (bool *)tevent_req_callback_data_void(req);
5631 NTSTATUS status;
5632 status = cli_tcon_andx_recv(req);
5633 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5634 *done = true;
5637 static bool run_chain2(int dummy)
5639 struct cli_state *cli1;
5640 struct event_context *evt = event_context_init(NULL);
5641 struct tevent_req *reqs[2], *smbreqs[2];
5642 bool done = false;
5643 NTSTATUS status;
5645 printf("starting chain2 test\n");
5646 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5647 port_to_use, Undefined, 0, NULL);
5648 if (!NT_STATUS_IS_OK(status)) {
5649 return False;
5652 cli_sockopt(cli1, sockops);
5654 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5655 &smbreqs[0]);
5656 if (reqs[0] == NULL) return false;
5657 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5659 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5660 "?????", NULL, 0, &smbreqs[1]);
5661 if (reqs[1] == NULL) return false;
5662 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5664 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5665 if (!NT_STATUS_IS_OK(status)) {
5666 return false;
5669 while (!done) {
5670 event_loop_once(evt);
5673 torture_close_connection(cli1);
5674 return True;
5678 struct torture_createdel_state {
5679 struct tevent_context *ev;
5680 struct cli_state *cli;
5683 static void torture_createdel_created(struct tevent_req *subreq);
5684 static void torture_createdel_closed(struct tevent_req *subreq);
5686 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5687 struct tevent_context *ev,
5688 struct cli_state *cli,
5689 const char *name)
5691 struct tevent_req *req, *subreq;
5692 struct torture_createdel_state *state;
5694 req = tevent_req_create(mem_ctx, &state,
5695 struct torture_createdel_state);
5696 if (req == NULL) {
5697 return NULL;
5699 state->ev = ev;
5700 state->cli = cli;
5702 subreq = cli_ntcreate_send(
5703 state, ev, cli, name, 0,
5704 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5705 FILE_ATTRIBUTE_NORMAL,
5706 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5707 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5709 if (tevent_req_nomem(subreq, req)) {
5710 return tevent_req_post(req, ev);
5712 tevent_req_set_callback(subreq, torture_createdel_created, req);
5713 return req;
5716 static void torture_createdel_created(struct tevent_req *subreq)
5718 struct tevent_req *req = tevent_req_callback_data(
5719 subreq, struct tevent_req);
5720 struct torture_createdel_state *state = tevent_req_data(
5721 req, struct torture_createdel_state);
5722 NTSTATUS status;
5723 uint16_t fnum;
5725 status = cli_ntcreate_recv(subreq, &fnum);
5726 TALLOC_FREE(subreq);
5727 if (!NT_STATUS_IS_OK(status)) {
5728 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5729 nt_errstr(status)));
5730 tevent_req_nterror(req, status);
5731 return;
5734 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5735 if (tevent_req_nomem(subreq, req)) {
5736 return;
5738 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5741 static void torture_createdel_closed(struct tevent_req *subreq)
5743 struct tevent_req *req = tevent_req_callback_data(
5744 subreq, struct tevent_req);
5745 NTSTATUS status;
5747 status = cli_close_recv(subreq);
5748 if (!NT_STATUS_IS_OK(status)) {
5749 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5750 tevent_req_nterror(req, status);
5751 return;
5753 tevent_req_done(req);
5756 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5758 return tevent_req_simple_recv_ntstatus(req);
5761 struct torture_createdels_state {
5762 struct tevent_context *ev;
5763 struct cli_state *cli;
5764 const char *base_name;
5765 int sent;
5766 int received;
5767 int num_files;
5768 struct tevent_req **reqs;
5771 static void torture_createdels_done(struct tevent_req *subreq);
5773 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5774 struct tevent_context *ev,
5775 struct cli_state *cli,
5776 const char *base_name,
5777 int num_parallel,
5778 int num_files)
5780 struct tevent_req *req;
5781 struct torture_createdels_state *state;
5782 int i;
5784 req = tevent_req_create(mem_ctx, &state,
5785 struct torture_createdels_state);
5786 if (req == NULL) {
5787 return NULL;
5789 state->ev = ev;
5790 state->cli = cli;
5791 state->base_name = talloc_strdup(state, base_name);
5792 if (tevent_req_nomem(state->base_name, req)) {
5793 return tevent_req_post(req, ev);
5795 state->num_files = MAX(num_parallel, num_files);
5796 state->sent = 0;
5797 state->received = 0;
5799 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5800 if (tevent_req_nomem(state->reqs, req)) {
5801 return tevent_req_post(req, ev);
5804 for (i=0; i<num_parallel; i++) {
5805 char *name;
5807 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5808 state->sent);
5809 if (tevent_req_nomem(name, req)) {
5810 return tevent_req_post(req, ev);
5812 state->reqs[i] = torture_createdel_send(
5813 state->reqs, state->ev, state->cli, name);
5814 if (tevent_req_nomem(state->reqs[i], req)) {
5815 return tevent_req_post(req, ev);
5817 name = talloc_move(state->reqs[i], &name);
5818 tevent_req_set_callback(state->reqs[i],
5819 torture_createdels_done, req);
5820 state->sent += 1;
5822 return req;
5825 static void torture_createdels_done(struct tevent_req *subreq)
5827 struct tevent_req *req = tevent_req_callback_data(
5828 subreq, struct tevent_req);
5829 struct torture_createdels_state *state = tevent_req_data(
5830 req, struct torture_createdels_state);
5831 size_t num_parallel = talloc_array_length(state->reqs);
5832 NTSTATUS status;
5833 char *name;
5834 int i;
5836 status = torture_createdel_recv(subreq);
5837 if (!NT_STATUS_IS_OK(status)){
5838 DEBUG(10, ("torture_createdel_recv returned %s\n",
5839 nt_errstr(status)));
5840 TALLOC_FREE(subreq);
5841 tevent_req_nterror(req, status);
5842 return;
5845 for (i=0; i<num_parallel; i++) {
5846 if (subreq == state->reqs[i]) {
5847 break;
5850 if (i == num_parallel) {
5851 DEBUG(10, ("received something we did not send\n"));
5852 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5853 return;
5855 TALLOC_FREE(state->reqs[i]);
5857 if (state->sent >= state->num_files) {
5858 tevent_req_done(req);
5859 return;
5862 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5863 state->sent);
5864 if (tevent_req_nomem(name, req)) {
5865 return;
5867 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5868 state->cli, name);
5869 if (tevent_req_nomem(state->reqs[i], req)) {
5870 return;
5872 name = talloc_move(state->reqs[i], &name);
5873 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5874 state->sent += 1;
5877 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5879 return tevent_req_simple_recv_ntstatus(req);
5882 struct swallow_notify_state {
5883 struct tevent_context *ev;
5884 struct cli_state *cli;
5885 uint16_t fnum;
5886 uint32_t completion_filter;
5887 bool recursive;
5888 bool (*fn)(uint32_t action, const char *name, void *priv);
5889 void *priv;
5892 static void swallow_notify_done(struct tevent_req *subreq);
5894 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5895 struct tevent_context *ev,
5896 struct cli_state *cli,
5897 uint16_t fnum,
5898 uint32_t completion_filter,
5899 bool recursive,
5900 bool (*fn)(uint32_t action,
5901 const char *name,
5902 void *priv),
5903 void *priv)
5905 struct tevent_req *req, *subreq;
5906 struct swallow_notify_state *state;
5908 req = tevent_req_create(mem_ctx, &state,
5909 struct swallow_notify_state);
5910 if (req == NULL) {
5911 return NULL;
5913 state->ev = ev;
5914 state->cli = cli;
5915 state->fnum = fnum;
5916 state->completion_filter = completion_filter;
5917 state->recursive = recursive;
5918 state->fn = fn;
5919 state->priv = priv;
5921 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5922 0xffff, state->completion_filter,
5923 state->recursive);
5924 if (tevent_req_nomem(subreq, req)) {
5925 return tevent_req_post(req, ev);
5927 tevent_req_set_callback(subreq, swallow_notify_done, req);
5928 return req;
5931 static void swallow_notify_done(struct tevent_req *subreq)
5933 struct tevent_req *req = tevent_req_callback_data(
5934 subreq, struct tevent_req);
5935 struct swallow_notify_state *state = tevent_req_data(
5936 req, struct swallow_notify_state);
5937 NTSTATUS status;
5938 uint32_t i, num_changes;
5939 struct notify_change *changes;
5941 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5942 TALLOC_FREE(subreq);
5943 if (!NT_STATUS_IS_OK(status)) {
5944 DEBUG(10, ("cli_notify_recv returned %s\n",
5945 nt_errstr(status)));
5946 tevent_req_nterror(req, status);
5947 return;
5950 for (i=0; i<num_changes; i++) {
5951 state->fn(changes[i].action, changes[i].name, state->priv);
5953 TALLOC_FREE(changes);
5955 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5956 0xffff, state->completion_filter,
5957 state->recursive);
5958 if (tevent_req_nomem(subreq, req)) {
5959 return;
5961 tevent_req_set_callback(subreq, swallow_notify_done, req);
5964 static bool print_notifies(uint32_t action, const char *name, void *priv)
5966 if (DEBUGLEVEL > 5) {
5967 d_printf("%d %s\n", (int)action, name);
5969 return true;
5972 static void notify_bench_done(struct tevent_req *req)
5974 int *num_finished = (int *)tevent_req_callback_data_void(req);
5975 *num_finished += 1;
5978 static bool run_notify_bench(int dummy)
5980 const char *dname = "\\notify-bench";
5981 struct tevent_context *ev;
5982 NTSTATUS status;
5983 uint16_t dnum;
5984 struct tevent_req *req1;
5985 struct tevent_req *req2 = NULL;
5986 int i, num_unc_names;
5987 int num_finished = 0;
5989 printf("starting notify-bench test\n");
5991 if (use_multishare_conn) {
5992 char **unc_list;
5993 unc_list = file_lines_load(multishare_conn_fname,
5994 &num_unc_names, 0, NULL);
5995 if (!unc_list || num_unc_names <= 0) {
5996 d_printf("Failed to load unc names list from '%s'\n",
5997 multishare_conn_fname);
5998 return false;
6000 TALLOC_FREE(unc_list);
6001 } else {
6002 num_unc_names = 1;
6005 ev = tevent_context_init(talloc_tos());
6006 if (ev == NULL) {
6007 d_printf("tevent_context_init failed\n");
6008 return false;
6011 for (i=0; i<num_unc_names; i++) {
6012 struct cli_state *cli;
6013 char *base_fname;
6015 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6016 dname, i);
6017 if (base_fname == NULL) {
6018 return false;
6021 if (!torture_open_connection(&cli, i)) {
6022 return false;
6025 status = cli_ntcreate(cli, dname, 0,
6026 MAXIMUM_ALLOWED_ACCESS,
6027 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6028 FILE_SHARE_DELETE,
6029 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6030 &dnum);
6032 if (!NT_STATUS_IS_OK(status)) {
6033 d_printf("Could not create %s: %s\n", dname,
6034 nt_errstr(status));
6035 return false;
6038 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6039 FILE_NOTIFY_CHANGE_FILE_NAME |
6040 FILE_NOTIFY_CHANGE_DIR_NAME |
6041 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6042 FILE_NOTIFY_CHANGE_LAST_WRITE,
6043 false, print_notifies, NULL);
6044 if (req1 == NULL) {
6045 d_printf("Could not create notify request\n");
6046 return false;
6049 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6050 base_fname, 10, torture_numops);
6051 if (req2 == NULL) {
6052 d_printf("Could not create createdels request\n");
6053 return false;
6055 TALLOC_FREE(base_fname);
6057 tevent_req_set_callback(req2, notify_bench_done,
6058 &num_finished);
6061 while (num_finished < num_unc_names) {
6062 int ret;
6063 ret = tevent_loop_once(ev);
6064 if (ret != 0) {
6065 d_printf("tevent_loop_once failed\n");
6066 return false;
6070 if (!tevent_req_poll(req2, ev)) {
6071 d_printf("tevent_req_poll failed\n");
6074 status = torture_createdels_recv(req2);
6075 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6077 return true;
6080 static bool run_mangle1(int dummy)
6082 struct cli_state *cli;
6083 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6084 uint16_t fnum;
6085 fstring alt_name;
6086 NTSTATUS status;
6087 time_t change_time, access_time, write_time;
6088 SMB_OFF_T size;
6089 uint16_t mode;
6091 printf("starting mangle1 test\n");
6092 if (!torture_open_connection(&cli, 0)) {
6093 return False;
6096 cli_sockopt(cli, sockops);
6098 if (!NT_STATUS_IS_OK(cli_ntcreate(
6099 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6100 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6101 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6102 return false;
6104 cli_close(cli, fnum);
6106 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6107 if (!NT_STATUS_IS_OK(status)) {
6108 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6109 nt_errstr(status));
6110 return false;
6112 d_printf("alt_name: %s\n", alt_name);
6114 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6115 d_printf("cli_open(%s) failed: %s\n", alt_name,
6116 cli_errstr(cli));
6117 return false;
6119 cli_close(cli, fnum);
6121 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6122 &write_time, &size, &mode);
6123 if (!NT_STATUS_IS_OK(status)) {
6124 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6125 nt_errstr(status));
6126 return false;
6129 return true;
6132 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6134 size_t *to_pull = (size_t *)priv;
6135 size_t thistime = *to_pull;
6137 thistime = MIN(thistime, n);
6138 if (thistime == 0) {
6139 return 0;
6142 memset(buf, 0, thistime);
6143 *to_pull -= thistime;
6144 return thistime;
6147 static bool run_windows_write(int dummy)
6149 struct cli_state *cli1;
6150 uint16_t fnum;
6151 int i;
6152 bool ret = false;
6153 const char *fname = "\\writetest.txt";
6154 struct timeval start_time;
6155 double seconds;
6156 double kbytes;
6158 printf("starting windows_write test\n");
6159 if (!torture_open_connection(&cli1, 0)) {
6160 return False;
6163 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6164 printf("open failed (%s)\n", cli_errstr(cli1));
6165 return False;
6168 cli_sockopt(cli1, sockops);
6170 start_time = timeval_current();
6172 for (i=0; i<torture_numops; i++) {
6173 char c = 0;
6174 off_t start = i * torture_blocksize;
6175 NTSTATUS status;
6176 size_t to_pull = torture_blocksize - 1;
6178 if (cli_write(cli1, fnum, 0, &c,
6179 start + torture_blocksize - 1, 1) != 1) {
6180 printf("cli_write failed: %s\n", cli_errstr(cli1));
6181 goto fail;
6184 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6185 null_source, &to_pull);
6186 if (!NT_STATUS_IS_OK(status)) {
6187 printf("cli_push returned: %s\n", nt_errstr(status));
6188 goto fail;
6192 seconds = timeval_elapsed(&start_time);
6193 kbytes = (double)torture_blocksize * torture_numops;
6194 kbytes /= 1024;
6196 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6197 (double)seconds, (int)(kbytes/seconds));
6199 ret = true;
6200 fail:
6201 cli_close(cli1, fnum);
6202 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6203 torture_close_connection(cli1);
6204 return ret;
6207 static bool run_cli_echo(int dummy)
6209 struct cli_state *cli;
6210 NTSTATUS status;
6212 printf("starting cli_echo test\n");
6213 if (!torture_open_connection(&cli, 0)) {
6214 return false;
6216 cli_sockopt(cli, sockops);
6218 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6220 d_printf("cli_echo returned %s\n", nt_errstr(status));
6222 torture_close_connection(cli);
6223 return NT_STATUS_IS_OK(status);
6226 static bool run_uid_regression_test(int dummy)
6228 static struct cli_state *cli;
6229 int16_t old_vuid;
6230 int16_t old_cnum;
6231 bool correct = True;
6232 NTSTATUS status;
6234 printf("starting uid regression test\n");
6236 if (!torture_open_connection(&cli, 0)) {
6237 return False;
6240 cli_sockopt(cli, sockops);
6242 /* Ok - now save then logoff our current user. */
6243 old_vuid = cli->vuid;
6245 status = cli_ulogoff(cli);
6246 if (!NT_STATUS_IS_OK(status)) {
6247 d_printf("(%s) cli_ulogoff failed: %s\n",
6248 __location__, nt_errstr(status));
6249 correct = false;
6250 goto out;
6253 cli->vuid = old_vuid;
6255 /* Try an operation. */
6256 status = cli_mkdir(cli, "\\uid_reg_test");
6257 if (NT_STATUS_IS_OK(status)) {
6258 d_printf("(%s) cli_mkdir succeeded\n",
6259 __location__);
6260 correct = false;
6261 goto out;
6262 } else {
6263 /* Should be bad uid. */
6264 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6265 NT_STATUS_USER_SESSION_DELETED)) {
6266 correct = false;
6267 goto out;
6271 old_cnum = cli->cnum;
6273 /* Now try a SMBtdis with the invald vuid set to zero. */
6274 cli->vuid = 0;
6276 /* This should succeed. */
6277 status = cli_tdis(cli);
6279 if (NT_STATUS_IS_OK(status)) {
6280 d_printf("First tdis with invalid vuid should succeed.\n");
6281 } else {
6282 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6283 correct = false;
6284 goto out;
6287 cli->vuid = old_vuid;
6288 cli->cnum = old_cnum;
6290 /* This should fail. */
6291 status = cli_tdis(cli);
6292 if (NT_STATUS_IS_OK(status)) {
6293 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6294 correct = false;
6295 goto out;
6296 } else {
6297 /* Should be bad tid. */
6298 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6299 NT_STATUS_NETWORK_NAME_DELETED)) {
6300 correct = false;
6301 goto out;
6305 cli_rmdir(cli, "\\uid_reg_test");
6307 out:
6309 cli_shutdown(cli);
6310 return correct;
6314 static const char *illegal_chars = "*\\/?<>|\":";
6315 static char force_shortname_chars[] = " +,.[];=\177";
6317 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6318 const char *mask, void *state)
6320 struct cli_state *pcli = (struct cli_state *)state;
6321 fstring fname;
6322 NTSTATUS status = NT_STATUS_OK;
6324 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6326 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6327 return NT_STATUS_OK;
6329 if (finfo->mode & aDIR) {
6330 status = cli_rmdir(pcli, fname);
6331 if (!NT_STATUS_IS_OK(status)) {
6332 printf("del_fn: failed to rmdir %s\n,", fname );
6334 } else {
6335 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6336 if (!NT_STATUS_IS_OK(status)) {
6337 printf("del_fn: failed to unlink %s\n,", fname );
6340 return status;
6343 struct sn_state {
6344 int matched;
6345 int i;
6346 bool val;
6349 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6350 const char *name, void *state)
6352 struct sn_state *s = (struct sn_state *)state;
6353 int i = s->i;
6355 #if 0
6356 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6357 i, finfo->name, finfo->short_name);
6358 #endif
6360 if (strchr(force_shortname_chars, i)) {
6361 if (!finfo->short_name[0]) {
6362 /* Shortname not created when it should be. */
6363 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6364 __location__, finfo->name, i);
6365 s->val = true;
6367 } else if (finfo->short_name[0]){
6368 /* Shortname created when it should not be. */
6369 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6370 __location__, finfo->short_name, finfo->name);
6371 s->val = true;
6373 s->matched += 1;
6374 return NT_STATUS_OK;
6377 static bool run_shortname_test(int dummy)
6379 static struct cli_state *cli;
6380 bool correct = True;
6381 int i;
6382 struct sn_state s;
6383 char fname[20];
6385 printf("starting shortname test\n");
6387 if (!torture_open_connection(&cli, 0)) {
6388 return False;
6391 cli_sockopt(cli, sockops);
6393 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6394 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6395 cli_rmdir(cli, "\\shortname");
6397 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6398 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6399 __location__, cli_errstr(cli));
6400 correct = false;
6401 goto out;
6404 strlcpy(fname, "\\shortname\\", sizeof(fname));
6405 strlcat(fname, "test .txt", sizeof(fname));
6407 s.val = false;
6409 for (i = 32; i < 128; i++) {
6410 NTSTATUS status;
6411 uint16_t fnum = (uint16_t)-1;
6413 s.i = i;
6415 if (strchr(illegal_chars, i)) {
6416 continue;
6418 fname[15] = i;
6420 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6421 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6422 if (!NT_STATUS_IS_OK(status)) {
6423 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6424 __location__, fname, cli_errstr(cli));
6425 correct = false;
6426 goto out;
6428 cli_close(cli, fnum);
6430 s.matched = 0;
6431 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6432 &s);
6433 if (s.matched != 1) {
6434 d_printf("(%s) failed to list %s: %s\n",
6435 __location__, fname, cli_errstr(cli));
6436 correct = false;
6437 goto out;
6439 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6440 d_printf("(%s) failed to delete %s: %s\n",
6441 __location__, fname, cli_errstr(cli));
6442 correct = false;
6443 goto out;
6446 if (s.val) {
6447 correct = false;
6448 goto out;
6452 out:
6454 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6455 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6456 cli_rmdir(cli, "\\shortname");
6457 torture_close_connection(cli);
6458 return correct;
6461 static void pagedsearch_cb(struct tevent_req *req)
6463 int rc;
6464 struct tldap_message *msg;
6465 char *dn;
6467 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6468 if (rc != TLDAP_SUCCESS) {
6469 d_printf("tldap_search_paged_recv failed: %s\n",
6470 tldap_err2string(rc));
6471 return;
6473 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6474 TALLOC_FREE(msg);
6475 return;
6477 if (!tldap_entry_dn(msg, &dn)) {
6478 d_printf("tldap_entry_dn failed\n");
6479 return;
6481 d_printf("%s\n", dn);
6482 TALLOC_FREE(msg);
6485 static bool run_tldap(int dummy)
6487 struct tldap_context *ld;
6488 int fd, rc;
6489 NTSTATUS status;
6490 struct sockaddr_storage addr;
6491 struct tevent_context *ev;
6492 struct tevent_req *req;
6493 char *basedn;
6494 const char *filter;
6496 if (!resolve_name(host, &addr, 0, false)) {
6497 d_printf("could not find host %s\n", host);
6498 return false;
6500 status = open_socket_out(&addr, 389, 9999, &fd);
6501 if (!NT_STATUS_IS_OK(status)) {
6502 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6503 return false;
6506 ld = tldap_context_create(talloc_tos(), fd);
6507 if (ld == NULL) {
6508 close(fd);
6509 d_printf("tldap_context_create failed\n");
6510 return false;
6513 rc = tldap_fetch_rootdse(ld);
6514 if (rc != TLDAP_SUCCESS) {
6515 d_printf("tldap_fetch_rootdse failed: %s\n",
6516 tldap_errstr(talloc_tos(), ld, rc));
6517 return false;
6520 basedn = tldap_talloc_single_attribute(
6521 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6522 if (basedn == NULL) {
6523 d_printf("no defaultNamingContext\n");
6524 return false;
6526 d_printf("defaultNamingContext: %s\n", basedn);
6528 ev = tevent_context_init(talloc_tos());
6529 if (ev == NULL) {
6530 d_printf("tevent_context_init failed\n");
6531 return false;
6534 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6535 TLDAP_SCOPE_SUB, "(objectclass=*)",
6536 NULL, 0, 0,
6537 NULL, 0, NULL, 0, 0, 0, 0, 5);
6538 if (req == NULL) {
6539 d_printf("tldap_search_paged_send failed\n");
6540 return false;
6542 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6544 tevent_req_poll(req, ev);
6546 TALLOC_FREE(req);
6548 /* test search filters against rootDSE */
6549 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6550 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6552 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6553 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6554 talloc_tos(), NULL, NULL);
6555 if (rc != TLDAP_SUCCESS) {
6556 d_printf("tldap_search with complex filter failed: %s\n",
6557 tldap_errstr(talloc_tos(), ld, rc));
6558 return false;
6561 TALLOC_FREE(ld);
6562 return true;
6565 /* Torture test to ensure no regression of :
6566 https://bugzilla.samba.org/show_bug.cgi?id=7084
6569 static bool run_dir_createtime(int dummy)
6571 struct cli_state *cli;
6572 const char *dname = "\\testdir";
6573 const char *fname = "\\testdir\\testfile";
6574 NTSTATUS status;
6575 struct timespec create_time;
6576 struct timespec create_time1;
6577 uint16_t fnum;
6578 bool ret = false;
6580 if (!torture_open_connection(&cli, 0)) {
6581 return false;
6584 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6585 cli_rmdir(cli, dname);
6587 status = cli_mkdir(cli, dname);
6588 if (!NT_STATUS_IS_OK(status)) {
6589 printf("mkdir failed: %s\n", nt_errstr(status));
6590 goto out;
6593 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6594 NULL, NULL, NULL);
6595 if (!NT_STATUS_IS_OK(status)) {
6596 printf("cli_qpathinfo2 returned %s\n",
6597 nt_errstr(status));
6598 goto out;
6601 /* Sleep 3 seconds, then create a file. */
6602 sleep(3);
6604 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6605 DENY_NONE, &fnum);
6606 if (!NT_STATUS_IS_OK(status)) {
6607 printf("cli_open failed: %s\n", nt_errstr(status));
6608 goto out;
6611 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6612 NULL, NULL, NULL);
6613 if (!NT_STATUS_IS_OK(status)) {
6614 printf("cli_qpathinfo2 (2) returned %s\n",
6615 nt_errstr(status));
6616 goto out;
6619 if (timespec_compare(&create_time1, &create_time)) {
6620 printf("run_dir_createtime: create time was updated (error)\n");
6621 } else {
6622 printf("run_dir_createtime: create time was not updated (correct)\n");
6623 ret = true;
6626 out:
6628 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6629 cli_rmdir(cli, dname);
6630 if (!torture_close_connection(cli)) {
6631 ret = false;
6633 return ret;
6637 static bool run_streamerror(int dummy)
6639 struct cli_state *cli;
6640 const char *dname = "\\testdir";
6641 const char *streamname =
6642 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6643 NTSTATUS status;
6644 time_t change_time, access_time, write_time;
6645 SMB_OFF_T size;
6646 uint16_t mode, fnum;
6647 bool ret = true;
6649 if (!torture_open_connection(&cli, 0)) {
6650 return false;
6653 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6654 cli_rmdir(cli, dname);
6656 status = cli_mkdir(cli, dname);
6657 if (!NT_STATUS_IS_OK(status)) {
6658 printf("mkdir failed: %s\n", nt_errstr(status));
6659 return false;
6662 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6663 &size, &mode);
6664 status = cli_nt_error(cli);
6666 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6667 printf("pathinfo returned %s, expected "
6668 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6669 nt_errstr(status));
6670 ret = false;
6673 status = cli_ntcreate(cli, streamname, 0x16,
6674 FILE_READ_DATA|FILE_READ_EA|
6675 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6676 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6677 FILE_OPEN, 0, 0, &fnum);
6679 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6680 printf("ntcreate returned %s, expected "
6681 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6682 nt_errstr(status));
6683 ret = false;
6687 cli_rmdir(cli, dname);
6688 return ret;
6691 static bool run_local_substitute(int dummy)
6693 bool ok = true;
6695 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6696 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6697 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6698 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6699 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6700 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6701 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6702 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6704 /* Different captialization rules in sub_basic... */
6706 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6707 "blaDOM") == 0);
6709 return ok;
6712 static bool run_local_base64(int dummy)
6714 int i;
6715 bool ret = true;
6717 for (i=1; i<2000; i++) {
6718 DATA_BLOB blob1, blob2;
6719 char *b64;
6721 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6722 blob1.length = i;
6723 generate_random_buffer(blob1.data, blob1.length);
6725 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6726 if (b64 == NULL) {
6727 d_fprintf(stderr, "base64_encode_data_blob failed "
6728 "for %d bytes\n", i);
6729 ret = false;
6731 blob2 = base64_decode_data_blob(b64);
6732 TALLOC_FREE(b64);
6734 if (data_blob_cmp(&blob1, &blob2)) {
6735 d_fprintf(stderr, "data_blob_cmp failed for %d "
6736 "bytes\n", i);
6737 ret = false;
6739 TALLOC_FREE(blob1.data);
6740 data_blob_free(&blob2);
6742 return ret;
6745 static bool run_local_gencache(int dummy)
6747 char *val;
6748 time_t tm;
6749 DATA_BLOB blob;
6751 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6752 d_printf("%s: gencache_set() failed\n", __location__);
6753 return False;
6756 if (!gencache_get("foo", NULL, NULL)) {
6757 d_printf("%s: gencache_get() failed\n", __location__);
6758 return False;
6761 if (!gencache_get("foo", &val, &tm)) {
6762 d_printf("%s: gencache_get() failed\n", __location__);
6763 return False;
6766 if (strcmp(val, "bar") != 0) {
6767 d_printf("%s: gencache_get() returned %s, expected %s\n",
6768 __location__, val, "bar");
6769 SAFE_FREE(val);
6770 return False;
6773 SAFE_FREE(val);
6775 if (!gencache_del("foo")) {
6776 d_printf("%s: gencache_del() failed\n", __location__);
6777 return False;
6779 if (gencache_del("foo")) {
6780 d_printf("%s: second gencache_del() succeeded\n",
6781 __location__);
6782 return False;
6785 if (gencache_get("foo", &val, &tm)) {
6786 d_printf("%s: gencache_get() on deleted entry "
6787 "succeeded\n", __location__);
6788 return False;
6791 blob = data_blob_string_const_null("bar");
6792 tm = time(NULL) + 60;
6794 if (!gencache_set_data_blob("foo", &blob, tm)) {
6795 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6796 return False;
6799 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6800 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6801 return False;
6804 if (strcmp((const char *)blob.data, "bar") != 0) {
6805 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6806 __location__, (const char *)blob.data, "bar");
6807 data_blob_free(&blob);
6808 return False;
6811 data_blob_free(&blob);
6813 if (!gencache_del("foo")) {
6814 d_printf("%s: gencache_del() failed\n", __location__);
6815 return False;
6817 if (gencache_del("foo")) {
6818 d_printf("%s: second gencache_del() succeeded\n",
6819 __location__);
6820 return False;
6823 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6824 d_printf("%s: gencache_get_data_blob() on deleted entry "
6825 "succeeded\n", __location__);
6826 return False;
6829 return True;
6832 static bool rbt_testval(struct db_context *db, const char *key,
6833 const char *value)
6835 struct db_record *rec;
6836 TDB_DATA data = string_tdb_data(value);
6837 bool ret = false;
6838 NTSTATUS status;
6840 rec = db->fetch_locked(db, db, string_tdb_data(key));
6841 if (rec == NULL) {
6842 d_fprintf(stderr, "fetch_locked failed\n");
6843 goto done;
6845 status = rec->store(rec, data, 0);
6846 if (!NT_STATUS_IS_OK(status)) {
6847 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6848 goto done;
6850 TALLOC_FREE(rec);
6852 rec = db->fetch_locked(db, db, string_tdb_data(key));
6853 if (rec == NULL) {
6854 d_fprintf(stderr, "second fetch_locked failed\n");
6855 goto done;
6857 if ((rec->value.dsize != data.dsize)
6858 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6859 d_fprintf(stderr, "Got wrong data back\n");
6860 goto done;
6863 ret = true;
6864 done:
6865 TALLOC_FREE(rec);
6866 return ret;
6869 static bool run_local_rbtree(int dummy)
6871 struct db_context *db;
6872 bool ret = false;
6873 int i;
6875 db = db_open_rbt(NULL);
6877 if (db == NULL) {
6878 d_fprintf(stderr, "db_open_rbt failed\n");
6879 return false;
6882 for (i=0; i<1000; i++) {
6883 char *key, *value;
6885 if (asprintf(&key, "key%ld", random()) == -1) {
6886 goto done;
6888 if (asprintf(&value, "value%ld", random()) == -1) {
6889 SAFE_FREE(key);
6890 goto done;
6893 if (!rbt_testval(db, key, value)) {
6894 SAFE_FREE(key);
6895 SAFE_FREE(value);
6896 goto done;
6899 SAFE_FREE(value);
6900 if (asprintf(&value, "value%ld", random()) == -1) {
6901 SAFE_FREE(key);
6902 goto done;
6905 if (!rbt_testval(db, key, value)) {
6906 SAFE_FREE(key);
6907 SAFE_FREE(value);
6908 goto done;
6911 SAFE_FREE(key);
6912 SAFE_FREE(value);
6915 ret = true;
6917 done:
6918 TALLOC_FREE(db);
6919 return ret;
6922 struct talloc_dict_test {
6923 int content;
6926 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6928 int *count = (int *)priv;
6929 *count += 1;
6930 return 0;
6933 static bool run_local_talloc_dict(int dummy)
6935 struct talloc_dict *dict;
6936 struct talloc_dict_test *t;
6937 int key, count;
6939 dict = talloc_dict_init(talloc_tos());
6940 if (dict == NULL) {
6941 return false;
6944 t = talloc(talloc_tos(), struct talloc_dict_test);
6945 if (t == NULL) {
6946 return false;
6949 key = 1;
6950 t->content = 1;
6951 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6952 return false;
6955 count = 0;
6956 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6957 return false;
6960 if (count != 1) {
6961 return false;
6964 TALLOC_FREE(dict);
6966 return true;
6969 static bool run_local_string_to_sid(int dummy) {
6970 struct dom_sid sid;
6972 if (string_to_sid(&sid, "S--1-5-32-545")) {
6973 printf("allowing S--1-5-32-545\n");
6974 return false;
6976 if (string_to_sid(&sid, "S-1-5-32-+545")) {
6977 printf("allowing S-1-5-32-+545\n");
6978 return false;
6980 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")) {
6981 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6982 return false;
6984 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
6985 printf("allowing S-1-5-32-545-abc\n");
6986 return false;
6988 if (!string_to_sid(&sid, "S-1-5-32-545")) {
6989 printf("could not parse S-1-5-32-545\n");
6990 return false;
6992 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
6993 printf("mis-parsed S-1-5-32-545 as %s\n",
6994 sid_string_tos(&sid));
6995 return false;
6997 return true;
7000 static bool run_local_binary_to_sid(int dummy) {
7001 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7002 static const char good_binary_sid[] = {
7003 0x1, /* revision number */
7004 15, /* num auths */
7005 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7006 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7007 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7008 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7009 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7010 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7011 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7012 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7013 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7014 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7015 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7016 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7017 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7018 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7019 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7020 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7023 static const char long_binary_sid[] = {
7024 0x1, /* revision number */
7025 15, /* num auths */
7026 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7027 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7028 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7029 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7030 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7031 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7032 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7033 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7034 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7035 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7036 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7037 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7038 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7039 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7040 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7041 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7042 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7043 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7044 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7047 static const char long_binary_sid2[] = {
7048 0x1, /* revision number */
7049 32, /* num auths */
7050 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7051 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7052 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7053 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7054 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7055 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7056 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7057 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7058 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7059 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7060 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7061 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7062 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7063 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7064 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7065 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7066 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7067 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7068 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7069 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7070 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7071 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7072 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7073 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7074 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7075 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7076 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7077 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7078 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7079 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7080 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7081 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7082 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7085 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7086 return false;
7088 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7089 return false;
7091 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7092 return false;
7094 return true;
7097 /* Split a path name into filename and stream name components. Canonicalise
7098 * such that an implicit $DATA token is always explicit.
7100 * The "specification" of this function can be found in the
7101 * run_local_stream_name() function in torture.c, I've tried those
7102 * combinations against a W2k3 server.
7105 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7106 char **pbase, char **pstream)
7108 char *base = NULL;
7109 char *stream = NULL;
7110 char *sname; /* stream name */
7111 const char *stype; /* stream type */
7113 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7115 sname = strchr_m(fname, ':');
7117 if (lp_posix_pathnames() || (sname == NULL)) {
7118 if (pbase != NULL) {
7119 base = talloc_strdup(mem_ctx, fname);
7120 NT_STATUS_HAVE_NO_MEMORY(base);
7122 goto done;
7125 if (pbase != NULL) {
7126 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7127 NT_STATUS_HAVE_NO_MEMORY(base);
7130 sname += 1;
7132 stype = strchr_m(sname, ':');
7134 if (stype == NULL) {
7135 sname = talloc_strdup(mem_ctx, sname);
7136 stype = "$DATA";
7138 else {
7139 if (StrCaseCmp(stype, ":$DATA") != 0) {
7141 * If there is an explicit stream type, so far we only
7142 * allow $DATA. Is there anything else allowed? -- vl
7144 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7145 TALLOC_FREE(base);
7146 return NT_STATUS_OBJECT_NAME_INVALID;
7148 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7149 stype += 1;
7152 if (sname == NULL) {
7153 TALLOC_FREE(base);
7154 return NT_STATUS_NO_MEMORY;
7157 if (sname[0] == '\0') {
7159 * no stream name, so no stream
7161 goto done;
7164 if (pstream != NULL) {
7165 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7166 if (stream == NULL) {
7167 TALLOC_FREE(sname);
7168 TALLOC_FREE(base);
7169 return NT_STATUS_NO_MEMORY;
7172 * upper-case the type field
7174 strupper_m(strchr_m(stream, ':')+1);
7177 done:
7178 if (pbase != NULL) {
7179 *pbase = base;
7181 if (pstream != NULL) {
7182 *pstream = stream;
7184 return NT_STATUS_OK;
7187 static bool test_stream_name(const char *fname, const char *expected_base,
7188 const char *expected_stream,
7189 NTSTATUS expected_status)
7191 NTSTATUS status;
7192 char *base = NULL;
7193 char *stream = NULL;
7195 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7196 if (!NT_STATUS_EQUAL(status, expected_status)) {
7197 goto error;
7200 if (!NT_STATUS_IS_OK(status)) {
7201 return true;
7204 if (base == NULL) goto error;
7206 if (strcmp(expected_base, base) != 0) goto error;
7208 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7209 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7211 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7212 goto error;
7214 TALLOC_FREE(base);
7215 TALLOC_FREE(stream);
7216 return true;
7218 error:
7219 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7220 fname, expected_base ? expected_base : "<NULL>",
7221 expected_stream ? expected_stream : "<NULL>",
7222 nt_errstr(expected_status));
7223 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7224 base ? base : "<NULL>", stream ? stream : "<NULL>",
7225 nt_errstr(status));
7226 TALLOC_FREE(base);
7227 TALLOC_FREE(stream);
7228 return false;
7231 static bool run_local_stream_name(int dummy)
7233 bool ret = true;
7235 ret &= test_stream_name(
7236 "bla", "bla", NULL, NT_STATUS_OK);
7237 ret &= test_stream_name(
7238 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7239 ret &= test_stream_name(
7240 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7241 ret &= test_stream_name(
7242 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7243 ret &= test_stream_name(
7244 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7245 ret &= test_stream_name(
7246 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7247 ret &= test_stream_name(
7248 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7249 ret &= test_stream_name(
7250 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7252 return ret;
7255 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7257 if (a.length != b.length) {
7258 printf("a.length=%d != b.length=%d\n",
7259 (int)a.length, (int)b.length);
7260 return false;
7262 if (memcmp(a.data, b.data, a.length) != 0) {
7263 printf("a.data and b.data differ\n");
7264 return false;
7266 return true;
7269 static bool run_local_memcache(int dummy)
7271 struct memcache *cache;
7272 DATA_BLOB k1, k2;
7273 DATA_BLOB d1, d2, d3;
7274 DATA_BLOB v1, v2, v3;
7276 TALLOC_CTX *mem_ctx;
7277 char *str1, *str2;
7278 size_t size1, size2;
7279 bool ret = false;
7281 cache = memcache_init(NULL, 100);
7283 if (cache == NULL) {
7284 printf("memcache_init failed\n");
7285 return false;
7288 d1 = data_blob_const("d1", 2);
7289 d2 = data_blob_const("d2", 2);
7290 d3 = data_blob_const("d3", 2);
7292 k1 = data_blob_const("d1", 2);
7293 k2 = data_blob_const("d2", 2);
7295 memcache_add(cache, STAT_CACHE, k1, d1);
7296 memcache_add(cache, GETWD_CACHE, k2, d2);
7298 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7299 printf("could not find k1\n");
7300 return false;
7302 if (!data_blob_equal(d1, v1)) {
7303 return false;
7306 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7307 printf("could not find k2\n");
7308 return false;
7310 if (!data_blob_equal(d2, v2)) {
7311 return false;
7314 memcache_add(cache, STAT_CACHE, k1, d3);
7316 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7317 printf("could not find replaced k1\n");
7318 return false;
7320 if (!data_blob_equal(d3, v3)) {
7321 return false;
7324 memcache_add(cache, GETWD_CACHE, k1, d1);
7326 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7327 printf("Did find k2, should have been purged\n");
7328 return false;
7331 TALLOC_FREE(cache);
7333 cache = memcache_init(NULL, 0);
7335 mem_ctx = talloc_init("foo");
7337 str1 = talloc_strdup(mem_ctx, "string1");
7338 str2 = talloc_strdup(mem_ctx, "string2");
7340 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7341 data_blob_string_const("torture"), &str1);
7342 size1 = talloc_total_size(cache);
7344 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7345 data_blob_string_const("torture"), &str2);
7346 size2 = talloc_total_size(cache);
7348 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7350 if (size2 > size1) {
7351 printf("memcache leaks memory!\n");
7352 goto fail;
7355 ret = true;
7356 fail:
7357 TALLOC_FREE(cache);
7358 return ret;
7361 static void wbclient_done(struct tevent_req *req)
7363 wbcErr wbc_err;
7364 struct winbindd_response *wb_resp;
7365 int *i = (int *)tevent_req_callback_data_void(req);
7367 wbc_err = wb_trans_recv(req, req, &wb_resp);
7368 TALLOC_FREE(req);
7369 *i += 1;
7370 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7373 static bool run_local_wbclient(int dummy)
7375 struct event_context *ev;
7376 struct wb_context **wb_ctx;
7377 struct winbindd_request wb_req;
7378 bool result = false;
7379 int i, j;
7381 BlockSignals(True, SIGPIPE);
7383 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7384 if (ev == NULL) {
7385 goto fail;
7388 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7389 if (wb_ctx == NULL) {
7390 goto fail;
7393 ZERO_STRUCT(wb_req);
7394 wb_req.cmd = WINBINDD_PING;
7396 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7398 for (i=0; i<nprocs; i++) {
7399 wb_ctx[i] = wb_context_init(ev, NULL);
7400 if (wb_ctx[i] == NULL) {
7401 goto fail;
7403 for (j=0; j<torture_numops; j++) {
7404 struct tevent_req *req;
7405 req = wb_trans_send(ev, ev, wb_ctx[i],
7406 (j % 2) == 0, &wb_req);
7407 if (req == NULL) {
7408 goto fail;
7410 tevent_req_set_callback(req, wbclient_done, &i);
7414 i = 0;
7416 while (i < nprocs * torture_numops) {
7417 event_loop_once(ev);
7420 result = true;
7421 fail:
7422 TALLOC_FREE(ev);
7423 return result;
7426 static void getaddrinfo_finished(struct tevent_req *req)
7428 char *name = (char *)tevent_req_callback_data_void(req);
7429 struct addrinfo *ainfo;
7430 int res;
7432 res = getaddrinfo_recv(req, &ainfo);
7433 if (res != 0) {
7434 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7435 return;
7437 d_printf("gai(%s) succeeded\n", name);
7438 freeaddrinfo(ainfo);
7441 static bool run_getaddrinfo_send(int dummy)
7443 TALLOC_CTX *frame = talloc_stackframe();
7444 struct fncall_context *ctx;
7445 struct tevent_context *ev;
7446 bool result = false;
7447 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7448 "www.slashdot.org", "heise.de" };
7449 struct tevent_req *reqs[4];
7450 int i;
7452 ev = event_context_init(frame);
7453 if (ev == NULL) {
7454 goto fail;
7457 ctx = fncall_context_init(frame, 4);
7459 for (i=0; i<ARRAY_SIZE(names); i++) {
7460 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7461 NULL);
7462 if (reqs[i] == NULL) {
7463 goto fail;
7465 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7466 (void *)names[i]);
7469 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7470 tevent_loop_once(ev);
7473 result = true;
7474 fail:
7475 TALLOC_FREE(frame);
7476 return result;
7479 static bool dbtrans_inc(struct db_context *db)
7481 struct db_record *rec;
7482 uint32_t *val;
7483 bool ret = false;
7484 NTSTATUS status;
7486 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7487 if (rec == NULL) {
7488 printf(__location__ "fetch_lock failed\n");
7489 return false;
7492 if (rec->value.dsize != sizeof(uint32_t)) {
7493 printf(__location__ "value.dsize = %d\n",
7494 (int)rec->value.dsize);
7495 goto fail;
7498 val = (uint32_t *)rec->value.dptr;
7499 *val += 1;
7501 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7502 sizeof(uint32_t)),
7504 if (!NT_STATUS_IS_OK(status)) {
7505 printf(__location__ "store failed: %s\n",
7506 nt_errstr(status));
7507 goto fail;
7510 ret = true;
7511 fail:
7512 TALLOC_FREE(rec);
7513 return ret;
7516 static bool run_local_dbtrans(int dummy)
7518 struct db_context *db;
7519 struct db_record *rec;
7520 NTSTATUS status;
7521 uint32_t initial;
7522 int res;
7524 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7525 O_RDWR|O_CREAT, 0600);
7526 if (db == NULL) {
7527 printf("Could not open transtest.db\n");
7528 return false;
7531 res = db->transaction_start(db);
7532 if (res == -1) {
7533 printf(__location__ "transaction_start failed\n");
7534 return false;
7537 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7538 if (rec == NULL) {
7539 printf(__location__ "fetch_lock failed\n");
7540 return false;
7543 if (rec->value.dptr == NULL) {
7544 initial = 0;
7545 status = rec->store(
7546 rec, make_tdb_data((uint8_t *)&initial,
7547 sizeof(initial)),
7549 if (!NT_STATUS_IS_OK(status)) {
7550 printf(__location__ "store returned %s\n",
7551 nt_errstr(status));
7552 return false;
7556 TALLOC_FREE(rec);
7558 res = db->transaction_commit(db);
7559 if (res == -1) {
7560 printf(__location__ "transaction_commit failed\n");
7561 return false;
7564 while (true) {
7565 uint32_t val, val2;
7566 int i;
7568 res = db->transaction_start(db);
7569 if (res == -1) {
7570 printf(__location__ "transaction_start failed\n");
7571 break;
7574 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7575 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7576 break;
7579 for (i=0; i<10; i++) {
7580 if (!dbtrans_inc(db)) {
7581 return false;
7585 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7586 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7587 break;
7590 if (val2 != val + 10) {
7591 printf(__location__ "val=%d, val2=%d\n",
7592 (int)val, (int)val2);
7593 break;
7596 printf("val2=%d\r", val2);
7598 res = db->transaction_commit(db);
7599 if (res == -1) {
7600 printf(__location__ "transaction_commit failed\n");
7601 break;
7605 TALLOC_FREE(db);
7606 return true;
7610 * Just a dummy test to be run under a debugger. There's no real way
7611 * to inspect the tevent_select specific function from outside of
7612 * tevent_select.c.
7615 static bool run_local_tevent_select(int dummy)
7617 struct tevent_context *ev;
7618 struct tevent_fd *fd1, *fd2;
7619 bool result = false;
7621 ev = tevent_context_init_byname(NULL, "select");
7622 if (ev == NULL) {
7623 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7624 goto fail;
7627 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7628 if (fd1 == NULL) {
7629 d_fprintf(stderr, "tevent_add_fd failed\n");
7630 goto fail;
7632 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7633 if (fd2 == NULL) {
7634 d_fprintf(stderr, "tevent_add_fd failed\n");
7635 goto fail;
7637 TALLOC_FREE(fd2);
7639 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7640 if (fd2 == NULL) {
7641 d_fprintf(stderr, "tevent_add_fd failed\n");
7642 goto fail;
7645 result = true;
7646 fail:
7647 TALLOC_FREE(ev);
7648 return result;
7651 static double create_procs(bool (*fn)(int), bool *result)
7653 int i, status;
7654 volatile pid_t *child_status;
7655 volatile bool *child_status_out;
7656 int synccount;
7657 int tries = 8;
7658 struct timeval start;
7660 synccount = 0;
7662 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7663 if (!child_status) {
7664 printf("Failed to setup shared memory\n");
7665 return -1;
7668 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7669 if (!child_status_out) {
7670 printf("Failed to setup result status shared memory\n");
7671 return -1;
7674 for (i = 0; i < nprocs; i++) {
7675 child_status[i] = 0;
7676 child_status_out[i] = True;
7679 start = timeval_current();
7681 for (i=0;i<nprocs;i++) {
7682 procnum = i;
7683 if (fork() == 0) {
7684 pid_t mypid = getpid();
7685 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7687 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7689 while (1) {
7690 if (torture_open_connection(&current_cli, i)) break;
7691 if (tries-- == 0) {
7692 printf("pid %d failed to start\n", (int)getpid());
7693 _exit(1);
7695 smb_msleep(10);
7698 child_status[i] = getpid();
7700 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7702 child_status_out[i] = fn(i);
7703 _exit(0);
7707 do {
7708 synccount = 0;
7709 for (i=0;i<nprocs;i++) {
7710 if (child_status[i]) synccount++;
7712 if (synccount == nprocs) break;
7713 smb_msleep(10);
7714 } while (timeval_elapsed(&start) < 30);
7716 if (synccount != nprocs) {
7717 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7718 *result = False;
7719 return timeval_elapsed(&start);
7722 /* start the client load */
7723 start = timeval_current();
7725 for (i=0;i<nprocs;i++) {
7726 child_status[i] = 0;
7729 printf("%d clients started\n", nprocs);
7731 for (i=0;i<nprocs;i++) {
7732 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7735 printf("\n");
7737 for (i=0;i<nprocs;i++) {
7738 if (!child_status_out[i]) {
7739 *result = False;
7742 return timeval_elapsed(&start);
7745 #define FLAG_MULTIPROC 1
7747 static struct {
7748 const char *name;
7749 bool (*fn)(int);
7750 unsigned flags;
7751 } torture_ops[] = {
7752 {"FDPASS", run_fdpasstest, 0},
7753 {"LOCK1", run_locktest1, 0},
7754 {"LOCK2", run_locktest2, 0},
7755 {"LOCK3", run_locktest3, 0},
7756 {"LOCK4", run_locktest4, 0},
7757 {"LOCK5", run_locktest5, 0},
7758 {"LOCK6", run_locktest6, 0},
7759 {"LOCK7", run_locktest7, 0},
7760 {"LOCK8", run_locktest8, 0},
7761 {"LOCK9", run_locktest9, 0},
7762 {"UNLINK", run_unlinktest, 0},
7763 {"BROWSE", run_browsetest, 0},
7764 {"ATTR", run_attrtest, 0},
7765 {"TRANS2", run_trans2test, 0},
7766 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7767 {"TORTURE",run_torture, FLAG_MULTIPROC},
7768 {"RANDOMIPC", run_randomipc, 0},
7769 {"NEGNOWAIT", run_negprot_nowait, 0},
7770 {"NBENCH", run_nbench, 0},
7771 {"NBENCH2", run_nbench2, 0},
7772 {"OPLOCK1", run_oplock1, 0},
7773 {"OPLOCK2", run_oplock2, 0},
7774 {"OPLOCK3", run_oplock3, 0},
7775 {"DIR", run_dirtest, 0},
7776 {"DIR1", run_dirtest1, 0},
7777 {"DIR-CREATETIME", run_dir_createtime, 0},
7778 {"DENY1", torture_denytest1, 0},
7779 {"DENY2", torture_denytest2, 0},
7780 {"TCON", run_tcon_test, 0},
7781 {"TCONDEV", run_tcon_devtype_test, 0},
7782 {"RW1", run_readwritetest, 0},
7783 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7784 {"RW3", run_readwritelarge, 0},
7785 {"OPEN", run_opentest, 0},
7786 {"POSIX", run_simple_posix_open_test, 0},
7787 {"POSIX-APPEND", run_posix_append, 0},
7788 {"ASYNC-ECHO", run_async_echo, 0},
7789 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7790 { "SHORTNAME-TEST", run_shortname_test, 0},
7791 #if 1
7792 {"OPENATTR", run_openattrtest, 0},
7793 #endif
7794 {"XCOPY", run_xcopy, 0},
7795 {"RENAME", run_rename, 0},
7796 {"DELETE", run_deletetest, 0},
7797 {"PROPERTIES", run_properties, 0},
7798 {"MANGLE", torture_mangle, 0},
7799 {"MANGLE1", run_mangle1, 0},
7800 {"W2K", run_w2ktest, 0},
7801 {"TRANS2SCAN", torture_trans2_scan, 0},
7802 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7803 {"UTABLE", torture_utable, 0},
7804 {"CASETABLE", torture_casetable, 0},
7805 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7806 {"PIPE_NUMBER", run_pipe_number, 0},
7807 {"TCON2", run_tcon2_test, 0},
7808 {"IOCTL", torture_ioctl_test, 0},
7809 {"CHKPATH", torture_chkpath_test, 0},
7810 {"FDSESS", run_fdsesstest, 0},
7811 { "EATEST", run_eatest, 0},
7812 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7813 { "CHAIN1", run_chain1, 0},
7814 { "CHAIN2", run_chain2, 0},
7815 { "WINDOWS-WRITE", run_windows_write, 0},
7816 { "CLI_ECHO", run_cli_echo, 0},
7817 { "GETADDRINFO", run_getaddrinfo_send, 0},
7818 { "TLDAP", run_tldap },
7819 { "STREAMERROR", run_streamerror },
7820 { "NOTIFY-BENCH", run_notify_bench },
7821 { "BAD-NBT-SESSION", run_bad_nbt_session },
7822 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7823 { "LOCAL-GENCACHE", run_local_gencache, 0},
7824 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7825 { "LOCAL-BASE64", run_local_base64, 0},
7826 { "LOCAL-RBTREE", run_local_rbtree, 0},
7827 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7828 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7829 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7830 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
7831 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
7832 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7833 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
7834 {NULL, NULL, 0}};
7838 /****************************************************************************
7839 run a specified test or "ALL"
7840 ****************************************************************************/
7841 static bool run_test(const char *name)
7843 bool ret = True;
7844 bool result = True;
7845 bool found = False;
7846 int i;
7847 double t;
7848 if (strequal(name,"ALL")) {
7849 for (i=0;torture_ops[i].name;i++) {
7850 run_test(torture_ops[i].name);
7852 found = True;
7855 for (i=0;torture_ops[i].name;i++) {
7856 fstr_sprintf(randomfname, "\\XX%x",
7857 (unsigned)random());
7859 if (strequal(name, torture_ops[i].name)) {
7860 found = True;
7861 printf("Running %s\n", name);
7862 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7863 t = create_procs(torture_ops[i].fn, &result);
7864 if (!result) {
7865 ret = False;
7866 printf("TEST %s FAILED!\n", name);
7868 } else {
7869 struct timeval start;
7870 start = timeval_current();
7871 if (!torture_ops[i].fn(0)) {
7872 ret = False;
7873 printf("TEST %s FAILED!\n", name);
7875 t = timeval_elapsed(&start);
7877 printf("%s took %g secs\n\n", name, t);
7881 if (!found) {
7882 printf("Did not find a test named %s\n", name);
7883 ret = False;
7886 return ret;
7890 static void usage(void)
7892 int i;
7894 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7895 printf("Please use samba4 torture.\n\n");
7897 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7899 printf("\t-d debuglevel\n");
7900 printf("\t-U user%%pass\n");
7901 printf("\t-k use kerberos\n");
7902 printf("\t-N numprocs\n");
7903 printf("\t-n my_netbios_name\n");
7904 printf("\t-W workgroup\n");
7905 printf("\t-o num_operations\n");
7906 printf("\t-O socket_options\n");
7907 printf("\t-m maximum protocol\n");
7908 printf("\t-L use oplocks\n");
7909 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7910 printf("\t-A showall\n");
7911 printf("\t-p port\n");
7912 printf("\t-s seed\n");
7913 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7914 printf("\n\n");
7916 printf("tests are:");
7917 for (i=0;torture_ops[i].name;i++) {
7918 printf(" %s", torture_ops[i].name);
7920 printf("\n");
7922 printf("default test is ALL\n");
7924 exit(1);
7927 /****************************************************************************
7928 main program
7929 ****************************************************************************/
7930 int main(int argc,char *argv[])
7932 int opt, i;
7933 char *p;
7934 int gotuser = 0;
7935 int gotpass = 0;
7936 bool correct = True;
7937 TALLOC_CTX *frame = talloc_stackframe();
7938 int seed = time(NULL);
7940 #ifdef HAVE_SETBUFFER
7941 setbuffer(stdout, NULL, 0);
7942 #endif
7944 setup_logging("smbtorture", DEBUG_STDOUT);
7946 load_case_tables();
7948 if (is_default_dyn_CONFIGFILE()) {
7949 if(getenv("SMB_CONF_PATH")) {
7950 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7953 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7954 load_interfaces();
7956 if (argc < 2) {
7957 usage();
7960 for(p = argv[1]; *p; p++)
7961 if(*p == '\\')
7962 *p = '/';
7964 if (strncmp(argv[1], "//", 2)) {
7965 usage();
7968 fstrcpy(host, &argv[1][2]);
7969 p = strchr_m(&host[2],'/');
7970 if (!p) {
7971 usage();
7973 *p = 0;
7974 fstrcpy(share, p+1);
7976 fstrcpy(myname, get_myname(talloc_tos()));
7977 if (!*myname) {
7978 fprintf(stderr, "Failed to get my hostname.\n");
7979 return 1;
7982 if (*username == 0 && getenv("LOGNAME")) {
7983 fstrcpy(username,getenv("LOGNAME"));
7986 argc--;
7987 argv++;
7989 fstrcpy(workgroup, lp_workgroup());
7991 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7992 switch (opt) {
7993 case 'p':
7994 port_to_use = atoi(optarg);
7995 break;
7996 case 's':
7997 seed = atoi(optarg);
7998 break;
7999 case 'W':
8000 fstrcpy(workgroup,optarg);
8001 break;
8002 case 'm':
8003 max_protocol = interpret_protocol(optarg, max_protocol);
8004 break;
8005 case 'N':
8006 nprocs = atoi(optarg);
8007 break;
8008 case 'o':
8009 torture_numops = atoi(optarg);
8010 break;
8011 case 'd':
8012 lp_set_cmdline("log level", optarg);
8013 break;
8014 case 'O':
8015 sockops = optarg;
8016 break;
8017 case 'L':
8018 use_oplocks = True;
8019 break;
8020 case 'l':
8021 local_path = optarg;
8022 break;
8023 case 'A':
8024 torture_showall = True;
8025 break;
8026 case 'n':
8027 fstrcpy(myname, optarg);
8028 break;
8029 case 'c':
8030 client_txt = optarg;
8031 break;
8032 case 'e':
8033 do_encrypt = true;
8034 break;
8035 case 'k':
8036 #ifdef HAVE_KRB5
8037 use_kerberos = True;
8038 #else
8039 d_printf("No kerberos support compiled in\n");
8040 exit(1);
8041 #endif
8042 break;
8043 case 'U':
8044 gotuser = 1;
8045 fstrcpy(username,optarg);
8046 p = strchr_m(username,'%');
8047 if (p) {
8048 *p = 0;
8049 fstrcpy(password, p+1);
8050 gotpass = 1;
8052 break;
8053 case 'b':
8054 fstrcpy(multishare_conn_fname, optarg);
8055 use_multishare_conn = True;
8056 break;
8057 case 'B':
8058 torture_blocksize = atoi(optarg);
8059 break;
8060 default:
8061 printf("Unknown option %c (%d)\n", (char)opt, opt);
8062 usage();
8066 d_printf("using seed %d\n", seed);
8068 srandom(seed);
8070 if(use_kerberos && !gotuser) gotpass = True;
8072 while (!gotpass) {
8073 p = getpass("Password:");
8074 if (p) {
8075 fstrcpy(password, p);
8076 gotpass = 1;
8080 printf("host=%s share=%s user=%s myname=%s\n",
8081 host, share, username, myname);
8083 if (argc == optind) {
8084 correct = run_test("ALL");
8085 } else {
8086 for (i=optind;i<argc;i++) {
8087 if (!run_test(argv[i])) {
8088 correct = False;
8093 TALLOC_FREE(frame);
8095 if (correct) {
8096 return(0);
8097 } else {
8098 return(1);