s3: Move setting the name_query timeout
[Samba.git] / source3 / torture / torture.c
blob175c2179444f5a299fcda3638c25b502d00e004e
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 "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
26 #include "tldap.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
29 #include "memcache.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap.h"
32 #include "talloc_dict.h"
33 #include "async_smb.h"
34 #include "libsmb/clirap.h"
35 #include "trans2.h"
36 #include "libsmb/nmblib.h"
38 extern char *optarg;
39 extern int optind;
41 static fstring host, workgroup, share, password, username, myname;
42 static int max_protocol = PROTOCOL_NT1;
43 static const char *sockops="TCP_NODELAY";
44 static int nprocs=1;
45 static int port_to_use=0;
46 int torture_numops=100;
47 int torture_blocksize=1024*1024;
48 static int procnum; /* records process count number when forking */
49 static struct cli_state *current_cli;
50 static fstring randomfname;
51 static bool use_oplocks;
52 static bool use_level_II_oplocks;
53 static const char *client_txt = "client_oplocks.txt";
54 static bool use_kerberos;
55 static fstring multishare_conn_fname;
56 static bool use_multishare_conn = False;
57 static bool do_encrypt;
58 static const char *local_path = NULL;
59 static int signing_state = Undefined;
61 bool torture_showall = False;
63 static double create_procs(bool (*fn)(int), bool *result);
66 /* return a pointer to a anonymous shared memory segment of size "size"
67 which will persist across fork() but will disappear when all processes
68 exit
70 The memory is not zeroed
72 This function uses system5 shared memory. It takes advantage of a property
73 that the memory is not destroyed if it is attached when the id is removed
75 void *shm_setup(int size)
77 int shmid;
78 void *ret;
80 #ifdef __QNXNTO__
81 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
82 if (shmid == -1) {
83 printf("can't get shared memory\n");
84 exit(1);
86 shm_unlink("private");
87 if (ftruncate(shmid, size) == -1) {
88 printf("can't set shared memory size\n");
89 exit(1);
91 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
92 if (ret == MAP_FAILED) {
93 printf("can't map shared memory\n");
94 exit(1);
96 #else
97 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
98 if (shmid == -1) {
99 printf("can't get shared memory\n");
100 exit(1);
102 ret = (void *)shmat(shmid, 0, 0);
103 if (!ret || ret == (void *)-1) {
104 printf("can't attach to shared memory\n");
105 return NULL;
107 /* the following releases the ipc, but note that this process
108 and all its children will still have access to the memory, its
109 just that the shmid is no longer valid for other shm calls. This
110 means we don't leave behind lots of shm segments after we exit
112 See Stevens "advanced programming in unix env" for details
114 shmctl(shmid, IPC_RMID, 0);
115 #endif
117 return ret;
120 /********************************************************************
121 Ensure a connection is encrypted.
122 ********************************************************************/
124 static bool force_cli_encryption(struct cli_state *c,
125 const char *sharename)
127 uint16 major, minor;
128 uint32 caplow, caphigh;
129 NTSTATUS status;
131 if (!SERVER_HAS_UNIX_CIFS(c)) {
132 d_printf("Encryption required and "
133 "server that doesn't support "
134 "UNIX extensions - failing connect\n");
135 return false;
138 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
139 &caphigh);
140 if (!NT_STATUS_IS_OK(status)) {
141 d_printf("Encryption required and "
142 "can't get UNIX CIFS extensions "
143 "version from server: %s\n", nt_errstr(status));
144 return false;
147 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
148 d_printf("Encryption required and "
149 "share %s doesn't support "
150 "encryption.\n", sharename);
151 return false;
154 if (c->use_kerberos) {
155 status = cli_gss_smb_encryption_start(c);
156 } else {
157 status = cli_raw_ntlm_smb_encryption_start(c,
158 username,
159 password,
160 workgroup);
163 if (!NT_STATUS_IS_OK(status)) {
164 d_printf("Encryption required and "
165 "setup failed with error %s.\n",
166 nt_errstr(status));
167 return false;
170 return true;
174 static struct cli_state *open_nbt_connection(void)
176 struct nmb_name called, calling;
177 struct sockaddr_storage ss;
178 struct cli_state *c;
179 NTSTATUS status;
181 make_nmb_name(&calling, myname, 0x0);
182 make_nmb_name(&called , host, 0x20);
184 zero_sockaddr(&ss);
186 if (!(c = cli_initialise_ex(signing_state))) {
187 printf("Failed initialize cli_struct to connect with %s\n", host);
188 return NULL;
191 c->port = port_to_use;
193 status = cli_connect(c, host, &ss);
194 if (!NT_STATUS_IS_OK(status)) {
195 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
196 return NULL;
199 c->use_kerberos = use_kerberos;
201 c->timeout = 120000; /* set a really long timeout (2 minutes) */
202 if (use_oplocks) c->use_oplocks = True;
203 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
205 if (!cli_session_request(c, &calling, &called)) {
207 * Well, that failed, try *SMBSERVER ...
208 * However, we must reconnect as well ...
210 status = cli_connect(c, host, &ss);
211 if (!NT_STATUS_IS_OK(status)) {
212 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
213 return NULL;
216 make_nmb_name(&called, "*SMBSERVER", 0x20);
217 if (!cli_session_request(c, &calling, &called)) {
218 printf("%s rejected the session\n",host);
219 printf("We tried with a called name of %s & %s\n",
220 host, "*SMBSERVER");
221 cli_shutdown(c);
222 return NULL;
226 return c;
229 /****************************************************************************
230 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
231 ****************************************************************************/
233 static bool cli_bad_session_request(struct cli_state *cli,
234 struct nmb_name *calling, struct nmb_name *called)
236 char *p;
237 int len = 4;
238 int namelen = 0;
239 char *tmp;
241 memcpy(&(cli->calling), calling, sizeof(*calling));
242 memcpy(&(cli->called ), called , sizeof(*called ));
244 /* put in the destination name */
246 tmp = name_mangle(talloc_tos(), cli->called.name,
247 cli->called.name_type);
248 if (tmp == NULL) {
249 return false;
252 p = cli->outbuf+len;
253 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
254 if (namelen > 0) {
255 memcpy(p, tmp, namelen);
256 len += namelen;
258 TALLOC_FREE(tmp);
260 /* Deliberately corrupt the name len (first byte) */
261 *p = 100;
263 /* and my name */
265 tmp = name_mangle(talloc_tos(), cli->calling.name,
266 cli->calling.name_type);
267 if (tmp == NULL) {
268 return false;
271 p = cli->outbuf+len;
272 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
273 if (namelen > 0) {
274 memcpy(p, tmp, namelen);
275 len += namelen;
277 TALLOC_FREE(tmp);
278 /* Deliberately corrupt the name len (first byte) */
279 *p = 100;
281 /* send a session request (RFC 1002) */
282 /* setup the packet length
283 * Remove four bytes from the length count, since the length
284 * field in the NBT Session Service header counts the number
285 * of bytes which follow. The cli_send_smb() function knows
286 * about this and accounts for those four bytes.
287 * CRH.
289 len -= 4;
290 _smb_setlen(cli->outbuf,len);
291 SCVAL(cli->outbuf,0,0x81);
293 cli_send_smb(cli);
294 DEBUG(5,("Sent session request\n"));
296 if (!cli_receive_smb(cli))
297 return False;
299 if (CVAL(cli->inbuf,0) != 0x82) {
300 /* This is the wrong place to put the error... JRA. */
301 cli->rap_error = CVAL(cli->inbuf,4);
302 return False;
304 return(True);
307 static struct cli_state *open_bad_nbt_connection(void)
309 struct nmb_name called, calling;
310 struct sockaddr_storage ss;
311 struct cli_state *c;
312 NTSTATUS status;
314 make_nmb_name(&calling, myname, 0x0);
315 make_nmb_name(&called , host, 0x20);
317 zero_sockaddr(&ss);
319 if (!(c = cli_initialise_ex(signing_state))) {
320 printf("Failed initialize cli_struct to connect with %s\n", host);
321 return NULL;
324 c->port = 139;
326 status = cli_connect(c, host, &ss);
327 if (!NT_STATUS_IS_OK(status)) {
328 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
329 return NULL;
332 c->timeout = 4000; /* set a short timeout (4 seconds) */
334 if (!cli_bad_session_request(c, &calling, &called)) {
335 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
336 return NULL;
339 return c;
343 /* Insert a NULL at the first separator of the given path and return a pointer
344 * to the remainder of the string.
346 static char *
347 terminate_path_at_separator(char * path)
349 char * p;
351 if (!path) {
352 return NULL;
355 if ((p = strchr_m(path, '/'))) {
356 *p = '\0';
357 return p + 1;
360 if ((p = strchr_m(path, '\\'))) {
361 *p = '\0';
362 return p + 1;
365 /* No separator. */
366 return NULL;
370 parse a //server/share type UNC name
372 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
373 char **hostname, char **sharename)
375 char *p;
377 *hostname = *sharename = NULL;
379 if (strncmp(unc_name, "\\\\", 2) &&
380 strncmp(unc_name, "//", 2)) {
381 return False;
384 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
385 p = terminate_path_at_separator(*hostname);
387 if (p && *p) {
388 *sharename = talloc_strdup(mem_ctx, p);
389 terminate_path_at_separator(*sharename);
392 if (*hostname && *sharename) {
393 return True;
396 TALLOC_FREE(*hostname);
397 TALLOC_FREE(*sharename);
398 return False;
401 static bool torture_open_connection_share(struct cli_state **c,
402 const char *hostname,
403 const char *sharename)
405 int flags = 0;
406 NTSTATUS status;
408 if (use_kerberos)
409 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
410 if (use_oplocks)
411 flags |= CLI_FULL_CONNECTION_OPLOCKS;
412 if (use_level_II_oplocks)
413 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
415 status = cli_full_connection(c, myname,
416 hostname, NULL, port_to_use,
417 sharename, "?????",
418 username, workgroup,
419 password, flags, signing_state);
420 if (!NT_STATUS_IS_OK(status)) {
421 printf("failed to open share connection: //%s/%s port:%d - %s\n",
422 hostname, sharename, port_to_use, nt_errstr(status));
423 return False;
426 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
428 if (do_encrypt) {
429 return force_cli_encryption(*c,
430 sharename);
432 return True;
435 bool torture_open_connection(struct cli_state **c, int conn_index)
437 char **unc_list = NULL;
438 int num_unc_names = 0;
439 bool result;
441 if (use_multishare_conn==True) {
442 char *h, *s;
443 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
444 if (!unc_list || num_unc_names <= 0) {
445 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
446 exit(1);
449 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
450 NULL, &h, &s)) {
451 printf("Failed to parse UNC name %s\n",
452 unc_list[conn_index % num_unc_names]);
453 TALLOC_FREE(unc_list);
454 exit(1);
457 result = torture_open_connection_share(c, h, s);
459 /* h, s were copied earlier */
460 TALLOC_FREE(unc_list);
461 return result;
464 return torture_open_connection_share(c, host, share);
467 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
469 uint16 old_vuid = cli->vuid;
470 fstring old_user_name;
471 size_t passlen = strlen(password);
472 NTSTATUS status;
473 bool ret;
475 fstrcpy(old_user_name, cli->user_name);
476 cli->vuid = 0;
477 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
478 password, passlen,
479 password, passlen,
480 workgroup));
481 *new_vuid = cli->vuid;
482 cli->vuid = old_vuid;
483 status = cli_set_username(cli, old_user_name);
484 if (!NT_STATUS_IS_OK(status)) {
485 return false;
487 return ret;
491 bool torture_close_connection(struct cli_state *c)
493 bool ret = True;
494 NTSTATUS status;
496 status = cli_tdis(c);
497 if (!NT_STATUS_IS_OK(status)) {
498 printf("tdis failed (%s)\n", nt_errstr(status));
499 ret = False;
502 cli_shutdown(c);
504 return ret;
508 /* check if the server produced the expected error code */
509 static bool check_error(int line, struct cli_state *c,
510 uint8 eclass, uint32 ecode, NTSTATUS nterr)
512 if (cli_is_dos_error(c)) {
513 uint8 cclass;
514 uint32 num;
516 /* Check DOS error */
518 cli_dos_error(c, &cclass, &num);
520 if (eclass != cclass || ecode != num) {
521 printf("unexpected error code class=%d code=%d\n",
522 (int)cclass, (int)num);
523 printf(" expected %d/%d %s (line=%d)\n",
524 (int)eclass, (int)ecode, nt_errstr(nterr), line);
525 return False;
528 } else {
529 NTSTATUS status;
531 /* Check NT error */
533 status = cli_nt_error(c);
535 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
536 printf("unexpected error code %s\n", nt_errstr(status));
537 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
538 return False;
542 return True;
546 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
548 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
549 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
551 return True;
555 static bool rw_torture(struct cli_state *c)
557 const char *lockfname = "\\torture.lck";
558 fstring fname;
559 uint16_t fnum;
560 uint16_t fnum2;
561 pid_t pid2, pid = getpid();
562 int i, j;
563 char buf[1024];
564 bool correct = True;
565 NTSTATUS status;
567 memset(buf, '\0', sizeof(buf));
569 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
570 DENY_NONE, &fnum2);
571 if (!NT_STATUS_IS_OK(status)) {
572 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
574 if (!NT_STATUS_IS_OK(status)) {
575 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
576 return False;
579 for (i=0;i<torture_numops;i++) {
580 unsigned n = (unsigned)sys_random()%10;
581 if (i % 10 == 0) {
582 printf("%d\r", i); fflush(stdout);
584 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
586 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
587 return False;
590 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
591 printf("open failed (%s)\n", cli_errstr(c));
592 correct = False;
593 break;
596 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
597 printf("write failed (%s)\n", cli_errstr(c));
598 correct = False;
601 for (j=0;j<50;j++) {
602 if (cli_write(c, fnum, 0, (char *)buf,
603 sizeof(pid)+(j*sizeof(buf)),
604 sizeof(buf)) != sizeof(buf)) {
605 printf("write failed (%s)\n", cli_errstr(c));
606 correct = False;
610 pid2 = 0;
612 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
613 printf("read failed (%s)\n", cli_errstr(c));
614 correct = False;
617 if (pid2 != pid) {
618 printf("data corruption!\n");
619 correct = False;
622 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
623 printf("close failed (%s)\n", cli_errstr(c));
624 correct = False;
627 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
628 printf("unlink failed (%s)\n", cli_errstr(c));
629 correct = False;
632 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
633 printf("unlock failed (%s)\n", cli_errstr(c));
634 correct = False;
638 cli_close(c, fnum2);
639 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
641 printf("%d\n", i);
643 return correct;
646 static bool run_torture(int dummy)
648 struct cli_state *cli;
649 bool ret;
651 cli = current_cli;
653 cli_sockopt(cli, sockops);
655 ret = rw_torture(cli);
657 if (!torture_close_connection(cli)) {
658 ret = False;
661 return ret;
664 static bool rw_torture3(struct cli_state *c, char *lockfname)
666 uint16_t fnum = (uint16_t)-1;
667 unsigned int i = 0;
668 char buf[131072];
669 char buf_rd[131072];
670 unsigned count;
671 unsigned countprev = 0;
672 ssize_t sent = 0;
673 bool correct = True;
674 NTSTATUS status = NT_STATUS_OK;
676 srandom(1);
677 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
679 SIVAL(buf, i, sys_random());
682 if (procnum == 0)
684 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, aSYSTEM | aHIDDEN))) {
685 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
688 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
689 DENY_NONE, &fnum))) {
690 printf("first open read/write of %s failed (%s)\n",
691 lockfname, cli_errstr(c));
692 return False;
695 else
697 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
699 status = cli_open(c, lockfname, O_RDONLY,
700 DENY_NONE, &fnum);
701 if (!NT_STATUS_IS_OK(status)) {
702 break;
704 smb_msleep(10);
706 if (!NT_STATUS_IS_OK(status)) {
707 printf("second open read-only of %s failed (%s)\n",
708 lockfname, cli_errstr(c));
709 return False;
713 i = 0;
714 for (count = 0; count < sizeof(buf); count += sent)
716 if (count >= countprev) {
717 printf("%d %8d\r", i, count);
718 fflush(stdout);
719 i++;
720 countprev += (sizeof(buf) / 20);
723 if (procnum == 0)
725 sent = ((unsigned)sys_random()%(20))+ 1;
726 if (sent > sizeof(buf) - count)
728 sent = sizeof(buf) - count;
731 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
732 printf("write failed (%s)\n", cli_errstr(c));
733 correct = False;
736 else
738 sent = cli_read(c, fnum, buf_rd+count, count,
739 sizeof(buf)-count);
740 if (sent < 0)
742 printf("read failed offset:%d size:%ld (%s)\n",
743 count, (unsigned long)sizeof(buf)-count,
744 cli_errstr(c));
745 correct = False;
746 sent = 0;
748 if (sent > 0)
750 if (memcmp(buf_rd+count, buf+count, sent) != 0)
752 printf("read/write compare failed\n");
753 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
754 correct = False;
755 break;
762 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
763 printf("close failed (%s)\n", cli_errstr(c));
764 correct = False;
767 return correct;
770 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
772 const char *lockfname = "\\torture2.lck";
773 uint16_t fnum1;
774 uint16_t fnum2;
775 int i;
776 char buf[131072];
777 char buf_rd[131072];
778 bool correct = True;
779 ssize_t bytes_read;
781 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
782 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
785 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
786 DENY_NONE, &fnum1))) {
787 printf("first open read/write of %s failed (%s)\n",
788 lockfname, cli_errstr(c1));
789 return False;
791 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
792 DENY_NONE, &fnum2))) {
793 printf("second open read-only of %s failed (%s)\n",
794 lockfname, cli_errstr(c2));
795 cli_close(c1, fnum1);
796 return False;
799 for (i=0;i<torture_numops;i++)
801 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
802 if (i % 10 == 0) {
803 printf("%d\r", i); fflush(stdout);
806 generate_random_buffer((unsigned char *)buf, buf_size);
808 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
809 printf("write failed (%s)\n", cli_errstr(c1));
810 correct = False;
811 break;
814 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
815 printf("read failed (%s)\n", cli_errstr(c2));
816 printf("read %d, expected %ld\n", (int)bytes_read,
817 (unsigned long)buf_size);
818 correct = False;
819 break;
822 if (memcmp(buf_rd, buf, buf_size) != 0)
824 printf("read/write compare failed\n");
825 correct = False;
826 break;
830 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
831 printf("close failed (%s)\n", cli_errstr(c2));
832 correct = False;
834 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
835 printf("close failed (%s)\n", cli_errstr(c1));
836 correct = False;
839 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
840 printf("unlink failed (%s)\n", cli_errstr(c1));
841 correct = False;
844 return correct;
847 static bool run_readwritetest(int dummy)
849 struct cli_state *cli1, *cli2;
850 bool test1, test2 = False;
852 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
853 return False;
855 cli_sockopt(cli1, sockops);
856 cli_sockopt(cli2, sockops);
858 printf("starting readwritetest\n");
860 test1 = rw_torture2(cli1, cli2);
861 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
863 if (test1) {
864 test2 = rw_torture2(cli1, cli1);
865 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
868 if (!torture_close_connection(cli1)) {
869 test1 = False;
872 if (!torture_close_connection(cli2)) {
873 test2 = False;
876 return (test1 && test2);
879 static bool run_readwritemulti(int dummy)
881 struct cli_state *cli;
882 bool test;
884 cli = current_cli;
886 cli_sockopt(cli, sockops);
888 printf("run_readwritemulti: fname %s\n", randomfname);
889 test = rw_torture3(cli, randomfname);
891 if (!torture_close_connection(cli)) {
892 test = False;
895 return test;
898 static bool run_readwritelarge_internal(int max_xmit_k)
900 static struct cli_state *cli1;
901 uint16_t fnum1;
902 const char *lockfname = "\\large.dat";
903 SMB_OFF_T fsize;
904 char buf[126*1024];
905 bool correct = True;
907 if (!torture_open_connection(&cli1, 0)) {
908 return False;
910 cli_sockopt(cli1, sockops);
911 memset(buf,'\0',sizeof(buf));
913 cli1->max_xmit = max_xmit_k*1024;
915 if (signing_state == Required) {
916 /* Horrible cheat to force
917 multiple signed outstanding
918 packets against a Samba server.
920 cli1->is_samba = false;
923 printf("starting readwritelarge_internal\n");
925 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
927 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
928 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
929 return False;
932 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
934 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
935 cli1, fnum1, NULL, &fsize, NULL, NULL,
936 NULL, NULL, NULL))) {
937 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
938 correct = False;
941 if (fsize == sizeof(buf))
942 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
943 (unsigned long)fsize);
944 else {
945 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
946 (unsigned long)fsize);
947 correct = False;
950 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
951 printf("close failed (%s)\n", cli_errstr(cli1));
952 correct = False;
955 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
956 printf("unlink failed (%s)\n", cli_errstr(cli1));
957 correct = False;
960 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
961 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
962 return False;
965 cli1->max_xmit = 4*1024;
967 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
969 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
970 cli1, fnum1, NULL, &fsize, NULL, NULL,
971 NULL, NULL, NULL))) {
972 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
973 correct = False;
976 if (fsize == sizeof(buf))
977 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
978 (unsigned long)fsize);
979 else {
980 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
981 (unsigned long)fsize);
982 correct = False;
985 #if 0
986 /* ToDo - set allocation. JRA */
987 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
988 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
989 return False;
991 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
992 NULL, NULL)) {
993 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
994 correct = False;
996 if (fsize != 0)
997 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
998 #endif
1000 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1001 printf("close failed (%s)\n", cli_errstr(cli1));
1002 correct = False;
1005 if (!torture_close_connection(cli1)) {
1006 correct = False;
1008 return correct;
1011 static bool run_readwritelarge(int dummy)
1013 return run_readwritelarge_internal(128);
1016 static bool run_readwritelarge_signtest(int dummy)
1018 bool ret;
1019 signing_state = Required;
1020 ret = run_readwritelarge_internal(2);
1021 signing_state = Undefined;
1022 return ret;
1025 int line_count = 0;
1026 int nbio_id;
1028 #define ival(s) strtol(s, NULL, 0)
1030 /* run a test that simulates an approximate netbench client load */
1031 static bool run_netbench(int client)
1033 struct cli_state *cli;
1034 int i;
1035 char line[1024];
1036 char cname[20];
1037 FILE *f;
1038 const char *params[20];
1039 bool correct = True;
1041 cli = current_cli;
1043 nbio_id = client;
1045 cli_sockopt(cli, sockops);
1047 nb_setup(cli);
1049 slprintf(cname,sizeof(cname)-1, "client%d", client);
1051 f = fopen(client_txt, "r");
1053 if (!f) {
1054 perror(client_txt);
1055 return False;
1058 while (fgets(line, sizeof(line)-1, f)) {
1059 char *saveptr;
1060 line_count++;
1062 line[strlen(line)-1] = 0;
1064 /* printf("[%d] %s\n", line_count, line); */
1066 all_string_sub(line,"client1", cname, sizeof(line));
1068 /* parse the command parameters */
1069 params[0] = strtok_r(line, " ", &saveptr);
1070 i = 0;
1071 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1073 params[i] = "";
1075 if (i < 2) continue;
1077 if (!strncmp(params[0],"SMB", 3)) {
1078 printf("ERROR: You are using a dbench 1 load file\n");
1079 exit(1);
1082 if (!strcmp(params[0],"NTCreateX")) {
1083 nb_createx(params[1], ival(params[2]), ival(params[3]),
1084 ival(params[4]));
1085 } else if (!strcmp(params[0],"Close")) {
1086 nb_close(ival(params[1]));
1087 } else if (!strcmp(params[0],"Rename")) {
1088 nb_rename(params[1], params[2]);
1089 } else if (!strcmp(params[0],"Unlink")) {
1090 nb_unlink(params[1]);
1091 } else if (!strcmp(params[0],"Deltree")) {
1092 nb_deltree(params[1]);
1093 } else if (!strcmp(params[0],"Rmdir")) {
1094 nb_rmdir(params[1]);
1095 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1096 nb_qpathinfo(params[1]);
1097 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1098 nb_qfileinfo(ival(params[1]));
1099 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1100 nb_qfsinfo(ival(params[1]));
1101 } else if (!strcmp(params[0],"FIND_FIRST")) {
1102 nb_findfirst(params[1]);
1103 } else if (!strcmp(params[0],"WriteX")) {
1104 nb_writex(ival(params[1]),
1105 ival(params[2]), ival(params[3]), ival(params[4]));
1106 } else if (!strcmp(params[0],"ReadX")) {
1107 nb_readx(ival(params[1]),
1108 ival(params[2]), ival(params[3]), ival(params[4]));
1109 } else if (!strcmp(params[0],"Flush")) {
1110 nb_flush(ival(params[1]));
1111 } else {
1112 printf("Unknown operation %s\n", params[0]);
1113 exit(1);
1116 fclose(f);
1118 nb_cleanup();
1120 if (!torture_close_connection(cli)) {
1121 correct = False;
1124 return correct;
1128 /* run a test that simulates an approximate netbench client load */
1129 static bool run_nbench(int dummy)
1131 double t;
1132 bool correct = True;
1134 nbio_shmem(nprocs);
1136 nbio_id = -1;
1138 signal(SIGALRM, nb_alarm);
1139 alarm(1);
1140 t = create_procs(run_netbench, &correct);
1141 alarm(0);
1143 printf("\nThroughput %g MB/sec\n",
1144 1.0e-6 * nbio_total() / t);
1145 return correct;
1150 This test checks for two things:
1152 1) correct support for retaining locks over a close (ie. the server
1153 must not use posix semantics)
1154 2) support for lock timeouts
1156 static bool run_locktest1(int dummy)
1158 struct cli_state *cli1, *cli2;
1159 const char *fname = "\\lockt1.lck";
1160 uint16_t fnum1, fnum2, fnum3;
1161 time_t t1, t2;
1162 unsigned lock_timeout;
1164 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1165 return False;
1167 cli_sockopt(cli1, sockops);
1168 cli_sockopt(cli2, sockops);
1170 printf("starting locktest1\n");
1172 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1174 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1175 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1176 return False;
1178 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1179 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1180 return False;
1182 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1183 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1184 return False;
1187 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1188 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1189 return False;
1193 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1194 printf("lock2 succeeded! This is a locking bug\n");
1195 return False;
1196 } else {
1197 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1198 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1202 lock_timeout = (1 + (random() % 20));
1203 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1204 t1 = time(NULL);
1205 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1206 printf("lock3 succeeded! This is a locking bug\n");
1207 return False;
1208 } else {
1209 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1210 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1212 t2 = time(NULL);
1214 if (ABS(t2 - t1) < lock_timeout-1) {
1215 printf("error: This server appears not to support timed lock requests\n");
1218 printf("server slept for %u seconds for a %u second timeout\n",
1219 (unsigned int)(t2-t1), lock_timeout);
1221 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1222 printf("close1 failed (%s)\n", cli_errstr(cli1));
1223 return False;
1226 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1227 printf("lock4 succeeded! This is a locking bug\n");
1228 return False;
1229 } else {
1230 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1231 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1234 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1235 printf("close2 failed (%s)\n", cli_errstr(cli1));
1236 return False;
1239 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1240 printf("close3 failed (%s)\n", cli_errstr(cli2));
1241 return False;
1244 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1245 printf("unlink failed (%s)\n", cli_errstr(cli1));
1246 return False;
1250 if (!torture_close_connection(cli1)) {
1251 return False;
1254 if (!torture_close_connection(cli2)) {
1255 return False;
1258 printf("Passed locktest1\n");
1259 return True;
1263 this checks to see if a secondary tconx can use open files from an
1264 earlier tconx
1266 static bool run_tcon_test(int dummy)
1268 static struct cli_state *cli;
1269 const char *fname = "\\tcontest.tmp";
1270 uint16 fnum1;
1271 uint16 cnum1, cnum2, cnum3;
1272 uint16 vuid1, vuid2;
1273 char buf[4];
1274 bool ret = True;
1275 NTSTATUS status;
1277 memset(buf, '\0', sizeof(buf));
1279 if (!torture_open_connection(&cli, 0)) {
1280 return False;
1282 cli_sockopt(cli, sockops);
1284 printf("starting tcontest\n");
1286 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1288 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1289 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1290 return False;
1293 cnum1 = cli->cnum;
1294 vuid1 = cli->vuid;
1296 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1297 printf("initial write failed (%s)", cli_errstr(cli));
1298 return False;
1301 status = cli_tcon_andx(cli, share, "?????",
1302 password, strlen(password)+1);
1303 if (!NT_STATUS_IS_OK(status)) {
1304 printf("%s refused 2nd tree connect (%s)\n", host,
1305 nt_errstr(status));
1306 cli_shutdown(cli);
1307 return False;
1310 cnum2 = cli->cnum;
1311 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1312 vuid2 = cli->vuid + 1;
1314 /* try a write with the wrong tid */
1315 cli->cnum = cnum2;
1317 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1318 printf("* server allows write with wrong TID\n");
1319 ret = False;
1320 } else {
1321 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1325 /* try a write with an invalid tid */
1326 cli->cnum = cnum3;
1328 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1329 printf("* server allows write with invalid TID\n");
1330 ret = False;
1331 } else {
1332 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1335 /* try a write with an invalid vuid */
1336 cli->vuid = vuid2;
1337 cli->cnum = cnum1;
1339 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1340 printf("* server allows write with invalid VUID\n");
1341 ret = False;
1342 } else {
1343 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1346 cli->cnum = cnum1;
1347 cli->vuid = vuid1;
1349 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1350 printf("close failed (%s)\n", cli_errstr(cli));
1351 return False;
1354 cli->cnum = cnum2;
1356 status = cli_tdis(cli);
1357 if (!NT_STATUS_IS_OK(status)) {
1358 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1359 return False;
1362 cli->cnum = cnum1;
1364 if (!torture_close_connection(cli)) {
1365 return False;
1368 return ret;
1373 checks for old style tcon support
1375 static bool run_tcon2_test(int dummy)
1377 static struct cli_state *cli;
1378 uint16 cnum, max_xmit;
1379 char *service;
1380 NTSTATUS status;
1382 if (!torture_open_connection(&cli, 0)) {
1383 return False;
1385 cli_sockopt(cli, sockops);
1387 printf("starting tcon2 test\n");
1389 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1390 return false;
1393 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1395 SAFE_FREE(service);
1397 if (!NT_STATUS_IS_OK(status)) {
1398 printf("tcon2 failed : %s\n", nt_errstr(status));
1399 } else {
1400 printf("tcon OK : max_xmit=%d cnum=%d\n",
1401 (int)max_xmit, (int)cnum);
1404 if (!torture_close_connection(cli)) {
1405 return False;
1408 printf("Passed tcon2 test\n");
1409 return True;
1412 static bool tcon_devtest(struct cli_state *cli,
1413 const char *myshare, const char *devtype,
1414 const char *return_devtype,
1415 NTSTATUS expected_error)
1417 NTSTATUS status;
1418 bool ret;
1420 status = cli_tcon_andx(cli, myshare, devtype,
1421 password, strlen(password)+1);
1423 if (NT_STATUS_IS_OK(expected_error)) {
1424 if (NT_STATUS_IS_OK(status)) {
1425 if (strcmp(cli->dev, return_devtype) == 0) {
1426 ret = True;
1427 } else {
1428 printf("tconX to share %s with type %s "
1429 "succeeded but returned the wrong "
1430 "device type (got [%s] but should have got [%s])\n",
1431 myshare, devtype, cli->dev, return_devtype);
1432 ret = False;
1434 } else {
1435 printf("tconX to share %s with type %s "
1436 "should have succeeded but failed\n",
1437 myshare, devtype);
1438 ret = False;
1440 cli_tdis(cli);
1441 } else {
1442 if (NT_STATUS_IS_OK(status)) {
1443 printf("tconx to share %s with type %s "
1444 "should have failed but succeeded\n",
1445 myshare, devtype);
1446 ret = False;
1447 } else {
1448 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1449 expected_error)) {
1450 ret = True;
1451 } else {
1452 printf("Returned unexpected error\n");
1453 ret = False;
1457 return ret;
1461 checks for correct tconX support
1463 static bool run_tcon_devtype_test(int dummy)
1465 static struct cli_state *cli1 = NULL;
1466 int flags = 0;
1467 NTSTATUS status;
1468 bool ret = True;
1470 status = cli_full_connection(&cli1, myname,
1471 host, NULL, port_to_use,
1472 NULL, NULL,
1473 username, workgroup,
1474 password, flags, signing_state);
1476 if (!NT_STATUS_IS_OK(status)) {
1477 printf("could not open connection\n");
1478 return False;
1481 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1482 ret = False;
1484 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1485 ret = False;
1487 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1488 ret = False;
1490 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1491 ret = False;
1493 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1494 ret = False;
1496 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1497 ret = False;
1499 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1500 ret = False;
1502 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1503 ret = False;
1505 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1506 ret = False;
1508 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1509 ret = False;
1511 cli_shutdown(cli1);
1513 if (ret)
1514 printf("Passed tcondevtest\n");
1516 return ret;
1521 This test checks that
1523 1) the server supports multiple locking contexts on the one SMB
1524 connection, distinguished by PID.
1526 2) the server correctly fails overlapping locks made by the same PID (this
1527 goes against POSIX behaviour, which is why it is tricky to implement)
1529 3) the server denies unlock requests by an incorrect client PID
1531 static bool run_locktest2(int dummy)
1533 static struct cli_state *cli;
1534 const char *fname = "\\lockt2.lck";
1535 uint16_t fnum1, fnum2, fnum3;
1536 bool correct = True;
1538 if (!torture_open_connection(&cli, 0)) {
1539 return False;
1542 cli_sockopt(cli, sockops);
1544 printf("starting locktest2\n");
1546 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1548 cli_setpid(cli, 1);
1550 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1551 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1552 return False;
1555 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1556 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1557 return False;
1560 cli_setpid(cli, 2);
1562 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1563 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1564 return False;
1567 cli_setpid(cli, 1);
1569 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1570 printf("lock1 failed (%s)\n", cli_errstr(cli));
1571 return False;
1574 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1575 printf("WRITE lock1 succeeded! This is a locking bug\n");
1576 correct = False;
1577 } else {
1578 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1579 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1582 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1583 printf("WRITE lock2 succeeded! This is a locking bug\n");
1584 correct = False;
1585 } else {
1586 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1587 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1590 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1591 printf("READ lock2 succeeded! This is a locking bug\n");
1592 correct = False;
1593 } else {
1594 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1595 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1598 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1599 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1601 cli_setpid(cli, 2);
1602 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1603 printf("unlock at 100 succeeded! This is a locking bug\n");
1604 correct = False;
1607 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1608 printf("unlock1 succeeded! This is a locking bug\n");
1609 correct = False;
1610 } else {
1611 if (!check_error(__LINE__, cli,
1612 ERRDOS, ERRlock,
1613 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1616 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1617 printf("unlock2 succeeded! This is a locking bug\n");
1618 correct = False;
1619 } else {
1620 if (!check_error(__LINE__, cli,
1621 ERRDOS, ERRlock,
1622 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1625 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1626 printf("lock3 succeeded! This is a locking bug\n");
1627 correct = False;
1628 } else {
1629 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1632 cli_setpid(cli, 1);
1634 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1635 printf("close1 failed (%s)\n", cli_errstr(cli));
1636 return False;
1639 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1640 printf("close2 failed (%s)\n", cli_errstr(cli));
1641 return False;
1644 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1645 printf("close3 failed (%s)\n", cli_errstr(cli));
1646 return False;
1649 if (!torture_close_connection(cli)) {
1650 correct = False;
1653 printf("locktest2 finished\n");
1655 return correct;
1660 This test checks that
1662 1) the server supports the full offset range in lock requests
1664 static bool run_locktest3(int dummy)
1666 static struct cli_state *cli1, *cli2;
1667 const char *fname = "\\lockt3.lck";
1668 uint16_t fnum1, fnum2;
1669 int i;
1670 uint32 offset;
1671 bool correct = True;
1673 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1675 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1676 return False;
1678 cli_sockopt(cli1, sockops);
1679 cli_sockopt(cli2, sockops);
1681 printf("starting locktest3\n");
1683 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1685 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1686 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1687 return False;
1689 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1690 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1691 return False;
1694 for (offset=i=0;i<torture_numops;i++) {
1695 NEXT_OFFSET;
1696 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1697 printf("lock1 %d failed (%s)\n",
1699 cli_errstr(cli1));
1700 return False;
1703 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1704 printf("lock2 %d failed (%s)\n",
1706 cli_errstr(cli1));
1707 return False;
1711 for (offset=i=0;i<torture_numops;i++) {
1712 NEXT_OFFSET;
1714 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1715 printf("error: lock1 %d succeeded!\n", i);
1716 return False;
1719 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1720 printf("error: lock2 %d succeeded!\n", i);
1721 return False;
1724 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1725 printf("error: lock3 %d succeeded!\n", i);
1726 return False;
1729 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1730 printf("error: lock4 %d succeeded!\n", i);
1731 return False;
1735 for (offset=i=0;i<torture_numops;i++) {
1736 NEXT_OFFSET;
1738 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1739 printf("unlock1 %d failed (%s)\n",
1741 cli_errstr(cli1));
1742 return False;
1745 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1746 printf("unlock2 %d failed (%s)\n",
1748 cli_errstr(cli1));
1749 return False;
1753 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1754 printf("close1 failed (%s)\n", cli_errstr(cli1));
1755 return False;
1758 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1759 printf("close2 failed (%s)\n", cli_errstr(cli2));
1760 return False;
1763 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1764 printf("unlink failed (%s)\n", cli_errstr(cli1));
1765 return False;
1768 if (!torture_close_connection(cli1)) {
1769 correct = False;
1772 if (!torture_close_connection(cli2)) {
1773 correct = False;
1776 printf("finished locktest3\n");
1778 return correct;
1781 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1782 printf("** "); correct = False; \
1786 looks at overlapping locks
1788 static bool run_locktest4(int dummy)
1790 static struct cli_state *cli1, *cli2;
1791 const char *fname = "\\lockt4.lck";
1792 uint16_t fnum1, fnum2, f;
1793 bool ret;
1794 char buf[1000];
1795 bool correct = True;
1797 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1798 return False;
1801 cli_sockopt(cli1, sockops);
1802 cli_sockopt(cli2, sockops);
1804 printf("starting locktest4\n");
1806 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1808 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1809 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1811 memset(buf, 0, sizeof(buf));
1813 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1814 printf("Failed to create file\n");
1815 correct = False;
1816 goto fail;
1819 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1820 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1821 EXPECTED(ret, False);
1822 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1824 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1825 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1826 EXPECTED(ret, True);
1827 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1829 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1830 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1831 EXPECTED(ret, False);
1832 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1834 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1835 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1836 EXPECTED(ret, True);
1837 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1839 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1840 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1841 EXPECTED(ret, False);
1842 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1844 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1845 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1846 EXPECTED(ret, True);
1847 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1849 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1850 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1851 EXPECTED(ret, True);
1852 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1854 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1855 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1856 EXPECTED(ret, False);
1857 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1859 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1860 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1861 EXPECTED(ret, False);
1862 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1864 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1865 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1866 EXPECTED(ret, True);
1867 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1869 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1870 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1871 EXPECTED(ret, False);
1872 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1874 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1875 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1876 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1877 EXPECTED(ret, False);
1878 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1881 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1882 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1883 EXPECTED(ret, False);
1884 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1886 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1887 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1888 EXPECTED(ret, False);
1889 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1892 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1893 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1894 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1895 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1896 EXPECTED(ret, True);
1897 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1900 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1901 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1902 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1903 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1904 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1905 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1906 EXPECTED(ret, True);
1907 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1909 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1910 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1911 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1912 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1913 EXPECTED(ret, True);
1914 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1916 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1917 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1918 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1919 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1920 EXPECTED(ret, True);
1921 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1923 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1924 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1925 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1926 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1927 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1928 EXPECTED(ret, True);
1929 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1931 cli_close(cli1, fnum1);
1932 cli_close(cli2, fnum2);
1933 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1934 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1935 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1936 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1937 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1938 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1939 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1940 cli_close(cli1, f);
1941 cli_close(cli1, fnum1);
1942 EXPECTED(ret, True);
1943 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1945 fail:
1946 cli_close(cli1, fnum1);
1947 cli_close(cli2, fnum2);
1948 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1949 torture_close_connection(cli1);
1950 torture_close_connection(cli2);
1952 printf("finished locktest4\n");
1953 return correct;
1957 looks at lock upgrade/downgrade.
1959 static bool run_locktest5(int dummy)
1961 static struct cli_state *cli1, *cli2;
1962 const char *fname = "\\lockt5.lck";
1963 uint16_t fnum1, fnum2, fnum3;
1964 bool ret;
1965 char buf[1000];
1966 bool correct = True;
1968 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1969 return False;
1972 cli_sockopt(cli1, sockops);
1973 cli_sockopt(cli2, sockops);
1975 printf("starting locktest5\n");
1977 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1979 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1980 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1981 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1983 memset(buf, 0, sizeof(buf));
1985 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1986 printf("Failed to create file\n");
1987 correct = False;
1988 goto fail;
1991 /* Check for NT bug... */
1992 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1993 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1994 cli_close(cli1, fnum1);
1995 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1996 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1997 EXPECTED(ret, True);
1998 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1999 cli_close(cli1, fnum1);
2000 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2001 cli_unlock(cli1, fnum3, 0, 1);
2003 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2004 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2005 EXPECTED(ret, True);
2006 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2008 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2009 EXPECTED(ret, False);
2011 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2013 /* Unlock the process 2 lock. */
2014 cli_unlock(cli2, fnum2, 0, 4);
2016 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2017 EXPECTED(ret, False);
2019 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2021 /* Unlock the process 1 fnum3 lock. */
2022 cli_unlock(cli1, fnum3, 0, 4);
2024 /* Stack 2 more locks here. */
2025 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2026 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2028 EXPECTED(ret, True);
2029 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2031 /* Unlock the first process lock, then check this was the WRITE lock that was
2032 removed. */
2034 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2035 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2037 EXPECTED(ret, True);
2038 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2040 /* Unlock the process 2 lock. */
2041 cli_unlock(cli2, fnum2, 0, 4);
2043 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2045 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2046 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2047 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2049 EXPECTED(ret, True);
2050 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2052 /* Ensure the next unlock fails. */
2053 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2054 EXPECTED(ret, False);
2055 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2057 /* Ensure connection 2 can get a write lock. */
2058 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2059 EXPECTED(ret, True);
2061 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2064 fail:
2065 cli_close(cli1, fnum1);
2066 cli_close(cli2, fnum2);
2067 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2068 if (!torture_close_connection(cli1)) {
2069 correct = False;
2071 if (!torture_close_connection(cli2)) {
2072 correct = False;
2075 printf("finished locktest5\n");
2077 return correct;
2081 tries the unusual lockingX locktype bits
2083 static bool run_locktest6(int dummy)
2085 static struct cli_state *cli;
2086 const char *fname[1] = { "\\lock6.txt" };
2087 int i;
2088 uint16_t fnum;
2089 NTSTATUS status;
2091 if (!torture_open_connection(&cli, 0)) {
2092 return False;
2095 cli_sockopt(cli, sockops);
2097 printf("starting locktest6\n");
2099 for (i=0;i<1;i++) {
2100 printf("Testing %s\n", fname[i]);
2102 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2104 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2105 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2106 cli_close(cli, fnum);
2107 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2109 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2110 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2111 cli_close(cli, fnum);
2112 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2114 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2117 torture_close_connection(cli);
2119 printf("finished locktest6\n");
2120 return True;
2123 static bool run_locktest7(int dummy)
2125 struct cli_state *cli1;
2126 const char *fname = "\\lockt7.lck";
2127 uint16_t fnum1;
2128 char buf[200];
2129 bool correct = False;
2131 if (!torture_open_connection(&cli1, 0)) {
2132 return False;
2135 cli_sockopt(cli1, sockops);
2137 printf("starting locktest7\n");
2139 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2141 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2143 memset(buf, 0, sizeof(buf));
2145 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2146 printf("Failed to create file\n");
2147 goto fail;
2150 cli_setpid(cli1, 1);
2152 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2153 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2154 goto fail;
2155 } else {
2156 printf("pid1 successfully locked range 130:4 for READ\n");
2159 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2160 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2161 goto fail;
2162 } else {
2163 printf("pid1 successfully read the range 130:4\n");
2166 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2167 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2168 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2169 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2170 goto fail;
2172 } else {
2173 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2174 goto fail;
2177 cli_setpid(cli1, 2);
2179 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2180 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2181 } else {
2182 printf("pid2 successfully read the range 130:4\n");
2185 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2186 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2187 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2188 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2189 goto fail;
2191 } else {
2192 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2193 goto fail;
2196 cli_setpid(cli1, 1);
2197 cli_unlock(cli1, fnum1, 130, 4);
2199 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2200 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2201 goto fail;
2202 } else {
2203 printf("pid1 successfully locked range 130:4 for WRITE\n");
2206 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2207 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2208 goto fail;
2209 } else {
2210 printf("pid1 successfully read the range 130:4\n");
2213 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2214 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2215 goto fail;
2216 } else {
2217 printf("pid1 successfully wrote to the range 130:4\n");
2220 cli_setpid(cli1, 2);
2222 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2223 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2224 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2225 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2226 goto fail;
2228 } else {
2229 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2230 goto fail;
2233 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2234 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2235 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2236 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2237 goto fail;
2239 } else {
2240 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2241 goto fail;
2244 cli_unlock(cli1, fnum1, 130, 0);
2245 correct = True;
2247 fail:
2248 cli_close(cli1, fnum1);
2249 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2250 torture_close_connection(cli1);
2252 printf("finished locktest7\n");
2253 return correct;
2257 * This demonstrates a problem with our use of GPFS share modes: A file
2258 * descriptor sitting in the pending close queue holding a GPFS share mode
2259 * blocks opening a file another time. Happens with Word 2007 temp files.
2260 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2261 * open is denied with NT_STATUS_SHARING_VIOLATION.
2264 static bool run_locktest8(int dummy)
2266 struct cli_state *cli1;
2267 const char *fname = "\\lockt8.lck";
2268 uint16_t fnum1, fnum2;
2269 char buf[200];
2270 bool correct = False;
2271 NTSTATUS status;
2273 if (!torture_open_connection(&cli1, 0)) {
2274 return False;
2277 cli_sockopt(cli1, sockops);
2279 printf("starting locktest8\n");
2281 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2283 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2284 &fnum1);
2285 if (!NT_STATUS_IS_OK(status)) {
2286 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2287 return false;
2290 memset(buf, 0, sizeof(buf));
2292 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2293 if (!NT_STATUS_IS_OK(status)) {
2294 d_fprintf(stderr, "cli_open second time returned %s\n",
2295 cli_errstr(cli1));
2296 goto fail;
2299 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2300 printf("Unable to apply read lock on range 1:1, error was "
2301 "%s\n", cli_errstr(cli1));
2302 goto fail;
2305 status = cli_close(cli1, fnum1);
2306 if (!NT_STATUS_IS_OK(status)) {
2307 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2308 goto fail;
2311 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2312 if (!NT_STATUS_IS_OK(status)) {
2313 d_fprintf(stderr, "cli_open third time returned %s\n",
2314 cli_errstr(cli1));
2315 goto fail;
2318 correct = true;
2320 fail:
2321 cli_close(cli1, fnum1);
2322 cli_close(cli1, fnum2);
2323 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2324 torture_close_connection(cli1);
2326 printf("finished locktest8\n");
2327 return correct;
2331 * This test is designed to be run in conjunction with
2332 * external NFS or POSIX locks taken in the filesystem.
2333 * It checks that the smbd server will block until the
2334 * lock is released and then acquire it. JRA.
2337 static bool got_alarm;
2338 static int alarm_fd;
2340 static void alarm_handler(int dummy)
2342 got_alarm = True;
2345 static void alarm_handler_parent(int dummy)
2347 close(alarm_fd);
2350 static void do_local_lock(int read_fd, int write_fd)
2352 int fd;
2353 char c = '\0';
2354 struct flock lock;
2355 const char *local_pathname = NULL;
2356 int ret;
2358 local_pathname = talloc_asprintf(talloc_tos(),
2359 "%s/lockt9.lck", local_path);
2360 if (!local_pathname) {
2361 printf("child: alloc fail\n");
2362 exit(1);
2365 unlink(local_pathname);
2366 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2367 if (fd == -1) {
2368 printf("child: open of %s failed %s.\n",
2369 local_pathname, strerror(errno));
2370 exit(1);
2373 /* Now take a fcntl lock. */
2374 lock.l_type = F_WRLCK;
2375 lock.l_whence = SEEK_SET;
2376 lock.l_start = 0;
2377 lock.l_len = 4;
2378 lock.l_pid = getpid();
2380 ret = fcntl(fd,F_SETLK,&lock);
2381 if (ret == -1) {
2382 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2383 local_pathname, strerror(errno));
2384 exit(1);
2385 } else {
2386 printf("child: got lock 0:4 on file %s.\n",
2387 local_pathname );
2388 fflush(stdout);
2391 CatchSignal(SIGALRM, alarm_handler);
2392 alarm(5);
2393 /* Signal the parent. */
2394 if (write(write_fd, &c, 1) != 1) {
2395 printf("child: start signal fail %s.\n",
2396 strerror(errno));
2397 exit(1);
2399 alarm(0);
2401 alarm(10);
2402 /* Wait for the parent to be ready. */
2403 if (read(read_fd, &c, 1) != 1) {
2404 printf("child: reply signal fail %s.\n",
2405 strerror(errno));
2406 exit(1);
2408 alarm(0);
2410 sleep(5);
2411 close(fd);
2412 printf("child: released lock 0:4 on file %s.\n",
2413 local_pathname );
2414 fflush(stdout);
2415 exit(0);
2418 static bool run_locktest9(int dummy)
2420 struct cli_state *cli1;
2421 const char *fname = "\\lockt9.lck";
2422 uint16_t fnum;
2423 bool correct = False;
2424 int pipe_in[2], pipe_out[2];
2425 pid_t child_pid;
2426 char c = '\0';
2427 int ret;
2428 struct timeval start;
2429 double seconds;
2430 NTSTATUS status;
2432 printf("starting locktest9\n");
2434 if (local_path == NULL) {
2435 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2436 return false;
2439 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2440 return false;
2443 child_pid = fork();
2444 if (child_pid == -1) {
2445 return false;
2448 if (child_pid == 0) {
2449 /* Child. */
2450 do_local_lock(pipe_out[0], pipe_in[1]);
2451 exit(0);
2454 close(pipe_out[0]);
2455 close(pipe_in[1]);
2456 pipe_out[0] = -1;
2457 pipe_in[1] = -1;
2459 /* Parent. */
2460 ret = read(pipe_in[0], &c, 1);
2461 if (ret != 1) {
2462 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2463 strerror(errno));
2464 return false;
2467 if (!torture_open_connection(&cli1, 0)) {
2468 return false;
2471 cli_sockopt(cli1, sockops);
2473 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2474 &fnum);
2475 if (!NT_STATUS_IS_OK(status)) {
2476 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2477 return false;
2480 /* Ensure the child has the lock. */
2481 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2482 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2483 goto fail;
2484 } else {
2485 d_printf("Child has the lock.\n");
2488 /* Tell the child to wait 5 seconds then exit. */
2489 ret = write(pipe_out[1], &c, 1);
2490 if (ret != 1) {
2491 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2492 strerror(errno));
2493 goto fail;
2496 /* Wait 20 seconds for the lock. */
2497 alarm_fd = cli1->fd;
2498 CatchSignal(SIGALRM, alarm_handler_parent);
2499 alarm(20);
2501 start = timeval_current();
2503 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2504 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2505 "%s\n", cli_errstr(cli1));
2506 goto fail_nofd;
2508 alarm(0);
2510 seconds = timeval_elapsed(&start);
2512 printf("Parent got the lock after %.2f seconds.\n",
2513 seconds);
2515 status = cli_close(cli1, fnum);
2516 if (!NT_STATUS_IS_OK(status)) {
2517 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2518 goto fail;
2521 correct = true;
2523 fail:
2524 cli_close(cli1, fnum);
2525 torture_close_connection(cli1);
2527 fail_nofd:
2529 printf("finished locktest9\n");
2530 return correct;
2534 test whether fnums and tids open on one VC are available on another (a major
2535 security hole)
2537 static bool run_fdpasstest(int dummy)
2539 struct cli_state *cli1, *cli2;
2540 const char *fname = "\\fdpass.tst";
2541 uint16_t fnum1;
2542 char buf[1024];
2544 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2545 return False;
2547 cli_sockopt(cli1, sockops);
2548 cli_sockopt(cli2, sockops);
2550 printf("starting fdpasstest\n");
2552 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2554 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2555 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2556 return False;
2559 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2560 printf("write failed (%s)\n", cli_errstr(cli1));
2561 return False;
2564 cli2->vuid = cli1->vuid;
2565 cli2->cnum = cli1->cnum;
2566 cli2->pid = cli1->pid;
2568 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2569 printf("read succeeded! nasty security hole [%s]\n",
2570 buf);
2571 return False;
2574 cli_close(cli1, fnum1);
2575 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2577 torture_close_connection(cli1);
2578 torture_close_connection(cli2);
2580 printf("finished fdpasstest\n");
2581 return True;
2584 static bool run_fdsesstest(int dummy)
2586 struct cli_state *cli;
2587 uint16 new_vuid;
2588 uint16 saved_vuid;
2589 uint16 new_cnum;
2590 uint16 saved_cnum;
2591 const char *fname = "\\fdsess.tst";
2592 const char *fname1 = "\\fdsess1.tst";
2593 uint16_t fnum1;
2594 uint16_t fnum2;
2595 char buf[1024];
2596 bool ret = True;
2598 if (!torture_open_connection(&cli, 0))
2599 return False;
2600 cli_sockopt(cli, sockops);
2602 if (!torture_cli_session_setup2(cli, &new_vuid))
2603 return False;
2605 saved_cnum = cli->cnum;
2606 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2607 return False;
2608 new_cnum = cli->cnum;
2609 cli->cnum = saved_cnum;
2611 printf("starting fdsesstest\n");
2613 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2614 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2616 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2617 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2618 return False;
2621 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2622 printf("write failed (%s)\n", cli_errstr(cli));
2623 return False;
2626 saved_vuid = cli->vuid;
2627 cli->vuid = new_vuid;
2629 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2630 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2631 buf);
2632 ret = False;
2634 /* Try to open a file with different vuid, samba cnum. */
2635 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2636 printf("create with different vuid, same cnum succeeded.\n");
2637 cli_close(cli, fnum2);
2638 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2639 } else {
2640 printf("create with different vuid, same cnum failed.\n");
2641 printf("This will cause problems with service clients.\n");
2642 ret = False;
2645 cli->vuid = saved_vuid;
2647 /* Try with same vuid, different cnum. */
2648 cli->cnum = new_cnum;
2650 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2651 printf("read succeeded with different cnum![%s]\n",
2652 buf);
2653 ret = False;
2656 cli->cnum = saved_cnum;
2657 cli_close(cli, fnum1);
2658 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2660 torture_close_connection(cli);
2662 printf("finished fdsesstest\n");
2663 return ret;
2667 This test checks that
2669 1) the server does not allow an unlink on a file that is open
2671 static bool run_unlinktest(int dummy)
2673 struct cli_state *cli;
2674 const char *fname = "\\unlink.tst";
2675 uint16_t fnum;
2676 bool correct = True;
2678 if (!torture_open_connection(&cli, 0)) {
2679 return False;
2682 cli_sockopt(cli, sockops);
2684 printf("starting unlink test\n");
2686 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2688 cli_setpid(cli, 1);
2690 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2691 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2692 return False;
2695 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2696 printf("error: server allowed unlink on an open file\n");
2697 correct = False;
2698 } else {
2699 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2700 NT_STATUS_SHARING_VIOLATION);
2703 cli_close(cli, fnum);
2704 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2706 if (!torture_close_connection(cli)) {
2707 correct = False;
2710 printf("unlink test finished\n");
2712 return correct;
2717 test how many open files this server supports on the one socket
2719 static bool run_maxfidtest(int dummy)
2721 struct cli_state *cli;
2722 const char *ftemplate = "\\maxfid.%d.%d";
2723 fstring fname;
2724 uint16_t fnums[0x11000];
2725 int i;
2726 int retries=4;
2727 bool correct = True;
2729 cli = current_cli;
2731 if (retries <= 0) {
2732 printf("failed to connect\n");
2733 return False;
2736 cli_sockopt(cli, sockops);
2738 for (i=0; i<0x11000; i++) {
2739 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2740 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2741 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2742 printf("open of %s failed (%s)\n",
2743 fname, cli_errstr(cli));
2744 printf("maximum fnum is %d\n", i);
2745 break;
2747 printf("%6d\r", i);
2749 printf("%6d\n", i);
2750 i--;
2752 printf("cleaning up\n");
2753 for (;i>=0;i--) {
2754 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2755 cli_close(cli, fnums[i]);
2756 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2757 printf("unlink of %s failed (%s)\n",
2758 fname, cli_errstr(cli));
2759 correct = False;
2761 printf("%6d\r", i);
2763 printf("%6d\n", 0);
2765 printf("maxfid test finished\n");
2766 if (!torture_close_connection(cli)) {
2767 correct = False;
2769 return correct;
2772 /* generate a random buffer */
2773 static void rand_buf(char *buf, int len)
2775 while (len--) {
2776 *buf = (char)sys_random();
2777 buf++;
2781 /* send smb negprot commands, not reading the response */
2782 static bool run_negprot_nowait(int dummy)
2784 struct tevent_context *ev;
2785 int i;
2786 struct cli_state *cli;
2787 bool correct = True;
2789 printf("starting negprot nowait test\n");
2791 ev = tevent_context_init(talloc_tos());
2792 if (ev == NULL) {
2793 return false;
2796 if (!(cli = open_nbt_connection())) {
2797 TALLOC_FREE(ev);
2798 return False;
2801 for (i=0;i<50000;i++) {
2802 struct tevent_req *req;
2804 req = cli_negprot_send(ev, ev, cli);
2805 if (req == NULL) {
2806 TALLOC_FREE(ev);
2807 return false;
2809 if (!tevent_req_poll(req, ev)) {
2810 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2811 strerror(errno));
2812 TALLOC_FREE(ev);
2813 return false;
2815 TALLOC_FREE(req);
2818 if (torture_close_connection(cli)) {
2819 correct = False;
2822 printf("finished negprot nowait test\n");
2824 return correct;
2827 /* send smb negprot commands, not reading the response */
2828 static bool run_bad_nbt_session(int dummy)
2830 static struct cli_state *cli;
2832 printf("starting bad nbt session test\n");
2834 if (!(cli = open_bad_nbt_connection())) {
2835 return False;
2838 cli_shutdown(cli);
2839 printf("finished bad nbt session test\n");
2840 return true;
2843 /* send random IPC commands */
2844 static bool run_randomipc(int dummy)
2846 char *rparam = NULL;
2847 char *rdata = NULL;
2848 unsigned int rdrcnt,rprcnt;
2849 char param[1024];
2850 int api, param_len, i;
2851 struct cli_state *cli;
2852 bool correct = True;
2853 int count = 50000;
2855 printf("starting random ipc test\n");
2857 if (!torture_open_connection(&cli, 0)) {
2858 return False;
2861 for (i=0;i<count;i++) {
2862 api = sys_random() % 500;
2863 param_len = (sys_random() % 64);
2865 rand_buf(param, param_len);
2867 SSVAL(param,0,api);
2869 cli_api(cli,
2870 param, param_len, 8,
2871 NULL, 0, BUFFER_SIZE,
2872 &rparam, &rprcnt,
2873 &rdata, &rdrcnt);
2874 if (i % 100 == 0) {
2875 printf("%d/%d\r", i,count);
2878 printf("%d/%d\n", i, count);
2880 if (!torture_close_connection(cli)) {
2881 correct = False;
2884 printf("finished random ipc test\n");
2886 return correct;
2891 static void browse_callback(const char *sname, uint32 stype,
2892 const char *comment, void *state)
2894 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2900 This test checks the browse list code
2903 static bool run_browsetest(int dummy)
2905 static struct cli_state *cli;
2906 bool correct = True;
2908 printf("starting browse test\n");
2910 if (!torture_open_connection(&cli, 0)) {
2911 return False;
2914 printf("domain list:\n");
2915 cli_NetServerEnum(cli, cli->server_domain,
2916 SV_TYPE_DOMAIN_ENUM,
2917 browse_callback, NULL);
2919 printf("machine list:\n");
2920 cli_NetServerEnum(cli, cli->server_domain,
2921 SV_TYPE_ALL,
2922 browse_callback, NULL);
2924 if (!torture_close_connection(cli)) {
2925 correct = False;
2928 printf("browse test finished\n");
2930 return correct;
2936 This checks how the getatr calls works
2938 static bool run_attrtest(int dummy)
2940 struct cli_state *cli;
2941 uint16_t fnum;
2942 time_t t, t2;
2943 const char *fname = "\\attrib123456789.tst";
2944 bool correct = True;
2946 printf("starting attrib test\n");
2948 if (!torture_open_connection(&cli, 0)) {
2949 return False;
2952 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2953 cli_open(cli, fname,
2954 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2955 cli_close(cli, fnum);
2956 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2957 printf("getatr failed (%s)\n", cli_errstr(cli));
2958 correct = False;
2961 if (abs(t - time(NULL)) > 60*60*24*10) {
2962 printf("ERROR: SMBgetatr bug. time is %s",
2963 ctime(&t));
2964 t = time(NULL);
2965 correct = True;
2968 t2 = t-60*60*24; /* 1 day ago */
2970 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2971 printf("setatr failed (%s)\n", cli_errstr(cli));
2972 correct = True;
2975 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2976 printf("getatr failed (%s)\n", cli_errstr(cli));
2977 correct = True;
2980 if (t != t2) {
2981 printf("ERROR: getatr/setatr bug. times are\n%s",
2982 ctime(&t));
2983 printf("%s", ctime(&t2));
2984 correct = True;
2987 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2989 if (!torture_close_connection(cli)) {
2990 correct = False;
2993 printf("attrib test finished\n");
2995 return correct;
3000 This checks a couple of trans2 calls
3002 static bool run_trans2test(int dummy)
3004 struct cli_state *cli;
3005 uint16_t fnum;
3006 SMB_OFF_T size;
3007 time_t c_time, a_time, m_time;
3008 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3009 const char *fname = "\\trans2.tst";
3010 const char *dname = "\\trans2";
3011 const char *fname2 = "\\trans2\\trans2.tst";
3012 char pname[1024];
3013 bool correct = True;
3014 NTSTATUS status;
3015 uint32_t fs_attr;
3017 printf("starting trans2 test\n");
3019 if (!torture_open_connection(&cli, 0)) {
3020 return False;
3023 status = cli_get_fs_attr_info(cli, &fs_attr);
3024 if (!NT_STATUS_IS_OK(status)) {
3025 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3026 nt_errstr(status));
3027 correct = false;
3030 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3031 cli_open(cli, fname,
3032 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3033 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3034 cli, fnum, NULL, &size, &c_time_ts,
3035 &a_time_ts, &w_time_ts,
3036 &m_time_ts, NULL))) {
3037 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3038 correct = False;
3041 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3042 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3043 correct = False;
3046 if (strcmp(pname, fname)) {
3047 printf("qfilename gave different name? [%s] [%s]\n",
3048 fname, pname);
3049 correct = False;
3052 cli_close(cli, fnum);
3054 sleep(2);
3056 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3057 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3058 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3059 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3060 return False;
3062 cli_close(cli, fnum);
3064 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3065 NULL);
3066 if (!NT_STATUS_IS_OK(status)) {
3067 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3068 correct = False;
3069 } else {
3070 if (c_time != m_time) {
3071 printf("create time=%s", ctime(&c_time));
3072 printf("modify time=%s", ctime(&m_time));
3073 printf("This system appears to have sticky create times\n");
3075 if (a_time % (60*60) == 0) {
3076 printf("access time=%s", ctime(&a_time));
3077 printf("This system appears to set a midnight access time\n");
3078 correct = False;
3081 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3082 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3083 correct = False;
3088 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3089 cli_open(cli, fname,
3090 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3091 cli_close(cli, fnum);
3092 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3093 &m_time_ts, &size, NULL, NULL);
3094 if (!NT_STATUS_IS_OK(status)) {
3095 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3096 correct = False;
3097 } else {
3098 if (w_time_ts.tv_sec < 60*60*24*2) {
3099 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3100 printf("This system appears to set a initial 0 write time\n");
3101 correct = False;
3105 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3108 /* check if the server updates the directory modification time
3109 when creating a new file */
3110 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3111 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3112 correct = False;
3114 sleep(3);
3115 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3116 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3117 if (!NT_STATUS_IS_OK(status)) {
3118 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3119 correct = False;
3122 cli_open(cli, fname2,
3123 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3124 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
3125 cli_close(cli, fnum);
3126 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3127 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3128 if (!NT_STATUS_IS_OK(status)) {
3129 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3130 correct = False;
3131 } else {
3132 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3133 == 0) {
3134 printf("This system does not update directory modification times\n");
3135 correct = False;
3138 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3139 cli_rmdir(cli, dname);
3141 if (!torture_close_connection(cli)) {
3142 correct = False;
3145 printf("trans2 test finished\n");
3147 return correct;
3151 This checks new W2K calls.
3154 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3156 uint8_t *buf = NULL;
3157 uint32 len;
3158 NTSTATUS status;
3160 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3161 pcli->max_xmit, &buf, &len);
3162 if (!NT_STATUS_IS_OK(status)) {
3163 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3164 nt_errstr(status));
3165 } else {
3166 printf("qfileinfo: level %d, len = %u\n", level, len);
3167 dump_data(0, (uint8 *)buf, len);
3168 printf("\n");
3170 TALLOC_FREE(buf);
3171 return status;
3174 static bool run_w2ktest(int dummy)
3176 struct cli_state *cli;
3177 uint16_t fnum;
3178 const char *fname = "\\w2ktest\\w2k.tst";
3179 int level;
3180 bool correct = True;
3182 printf("starting w2k test\n");
3184 if (!torture_open_connection(&cli, 0)) {
3185 return False;
3188 cli_open(cli, fname,
3189 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3191 for (level = 1004; level < 1040; level++) {
3192 new_trans(cli, fnum, level);
3195 cli_close(cli, fnum);
3197 if (!torture_close_connection(cli)) {
3198 correct = False;
3201 printf("w2k test finished\n");
3203 return correct;
3208 this is a harness for some oplock tests
3210 static bool run_oplock1(int dummy)
3212 struct cli_state *cli1;
3213 const char *fname = "\\lockt1.lck";
3214 uint16_t fnum1;
3215 bool correct = True;
3217 printf("starting oplock test 1\n");
3219 if (!torture_open_connection(&cli1, 0)) {
3220 return False;
3223 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3225 cli_sockopt(cli1, sockops);
3227 cli1->use_oplocks = True;
3229 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3230 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3231 return False;
3234 cli1->use_oplocks = False;
3236 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3237 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3239 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3240 printf("close2 failed (%s)\n", cli_errstr(cli1));
3241 return False;
3244 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3245 printf("unlink failed (%s)\n", cli_errstr(cli1));
3246 return False;
3249 if (!torture_close_connection(cli1)) {
3250 correct = False;
3253 printf("finished oplock test 1\n");
3255 return correct;
3258 static bool run_oplock2(int dummy)
3260 struct cli_state *cli1, *cli2;
3261 const char *fname = "\\lockt2.lck";
3262 uint16_t fnum1, fnum2;
3263 int saved_use_oplocks = use_oplocks;
3264 char buf[4];
3265 bool correct = True;
3266 volatile bool *shared_correct;
3268 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3269 *shared_correct = True;
3271 use_level_II_oplocks = True;
3272 use_oplocks = True;
3274 printf("starting oplock test 2\n");
3276 if (!torture_open_connection(&cli1, 0)) {
3277 use_level_II_oplocks = False;
3278 use_oplocks = saved_use_oplocks;
3279 return False;
3282 cli1->use_oplocks = True;
3283 cli1->use_level_II_oplocks = True;
3285 if (!torture_open_connection(&cli2, 1)) {
3286 use_level_II_oplocks = False;
3287 use_oplocks = saved_use_oplocks;
3288 return False;
3291 cli2->use_oplocks = True;
3292 cli2->use_level_II_oplocks = True;
3294 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3296 cli_sockopt(cli1, sockops);
3297 cli_sockopt(cli2, sockops);
3299 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3300 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3301 return False;
3304 /* Don't need the globals any more. */
3305 use_level_II_oplocks = False;
3306 use_oplocks = saved_use_oplocks;
3308 if (fork() == 0) {
3309 /* Child code */
3310 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3311 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3312 *shared_correct = False;
3313 exit(0);
3316 sleep(2);
3318 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3319 printf("close2 failed (%s)\n", cli_errstr(cli1));
3320 *shared_correct = False;
3323 exit(0);
3326 sleep(2);
3328 /* Ensure cli1 processes the break. Empty file should always return 0
3329 * bytes. */
3331 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3332 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3333 correct = False;
3336 /* Should now be at level II. */
3337 /* Test if sending a write locks causes a break to none. */
3339 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3340 printf("lock failed (%s)\n", cli_errstr(cli1));
3341 correct = False;
3344 cli_unlock(cli1, fnum1, 0, 4);
3346 sleep(2);
3348 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3349 printf("lock failed (%s)\n", cli_errstr(cli1));
3350 correct = False;
3353 cli_unlock(cli1, fnum1, 0, 4);
3355 sleep(2);
3357 cli_read(cli1, fnum1, buf, 0, 4);
3359 #if 0
3360 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3361 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3362 correct = False;
3364 #endif
3366 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3367 printf("close1 failed (%s)\n", cli_errstr(cli1));
3368 correct = False;
3371 sleep(4);
3373 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3374 printf("unlink failed (%s)\n", cli_errstr(cli1));
3375 correct = False;
3378 if (!torture_close_connection(cli1)) {
3379 correct = False;
3382 if (!*shared_correct) {
3383 correct = False;
3386 printf("finished oplock test 2\n");
3388 return correct;
3391 /* handler for oplock 3 tests */
3392 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3394 printf("got oplock break fnum=%d level=%d\n",
3395 fnum, level);
3396 return cli_oplock_ack(cli, fnum, level);
3399 static bool run_oplock3(int dummy)
3401 struct cli_state *cli;
3402 const char *fname = "\\oplockt3.dat";
3403 uint16_t fnum;
3404 char buf[4] = "abcd";
3405 bool correct = True;
3406 volatile bool *shared_correct;
3408 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3409 *shared_correct = True;
3411 printf("starting oplock test 3\n");
3413 if (fork() == 0) {
3414 /* Child code */
3415 use_oplocks = True;
3416 use_level_II_oplocks = True;
3417 if (!torture_open_connection(&cli, 0)) {
3418 *shared_correct = False;
3419 exit(0);
3421 sleep(2);
3422 /* try to trigger a oplock break in parent */
3423 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3424 cli_write(cli, fnum, 0, buf, 0, 4);
3425 exit(0);
3428 /* parent code */
3429 use_oplocks = True;
3430 use_level_II_oplocks = True;
3431 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3432 return False;
3434 cli_oplock_handler(cli, oplock3_handler);
3435 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3436 cli_write(cli, fnum, 0, buf, 0, 4);
3437 cli_close(cli, fnum);
3438 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3439 cli->timeout = 20000;
3440 cli_receive_smb(cli);
3441 printf("finished oplock test 3\n");
3443 return (correct && *shared_correct);
3445 /* What are we looking for here? What's sucess and what's FAILURE? */
3448 /* handler for oplock 4 tests */
3449 bool *oplock4_shared_correct;
3451 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3453 printf("got oplock break fnum=%d level=%d\n",
3454 fnum, level);
3455 *oplock4_shared_correct = true;
3456 cli_oplock_ack(cli, fnum, level);
3457 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3460 static bool run_oplock4(int dummy)
3462 struct cli_state *cli1, *cli2;
3463 const char *fname = "\\lockt4.lck";
3464 const char *fname_ln = "\\lockt4_ln.lck";
3465 uint16_t fnum1, fnum2;
3466 int saved_use_oplocks = use_oplocks;
3467 NTSTATUS status;
3468 bool correct = true;
3470 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3471 *oplock4_shared_correct = false;
3473 printf("starting oplock test 4\n");
3475 if (!torture_open_connection(&cli1, 0)) {
3476 use_level_II_oplocks = false;
3477 use_oplocks = saved_use_oplocks;
3478 return false;
3481 if (!torture_open_connection(&cli2, 1)) {
3482 use_level_II_oplocks = false;
3483 use_oplocks = saved_use_oplocks;
3484 return false;
3487 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3488 cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN);
3490 cli_sockopt(cli1, sockops);
3491 cli_sockopt(cli2, sockops);
3493 /* Create the file. */
3494 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3495 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3496 return false;
3499 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3500 printf("close1 failed (%s)\n", cli_errstr(cli1));
3501 return false;
3504 /* Now create a hardlink. */
3505 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3506 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3507 return false;
3510 /* Prove that opening hardlinks cause deny modes to conflict. */
3511 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3512 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3513 return false;
3516 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3517 if (NT_STATUS_IS_OK(status)) {
3518 printf("open of %s succeeded - should fail with sharing violation.\n",
3519 fname_ln);
3520 return false;
3523 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3524 printf("open of %s should fail with sharing violation. Got %s\n",
3525 fname_ln, nt_errstr(status));
3526 return false;
3529 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3530 printf("close1 failed (%s)\n", cli_errstr(cli1));
3531 return false;
3534 cli1->use_oplocks = true;
3535 cli1->use_level_II_oplocks = true;
3537 cli2->use_oplocks = true;
3538 cli2->use_level_II_oplocks = true;
3540 cli_oplock_handler(cli1, oplock4_handler);
3541 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3542 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3543 return false;
3546 if (fork() == 0) {
3547 /* Child code */
3548 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3549 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3550 *oplock4_shared_correct = false;
3551 exit(0);
3554 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3555 printf("close2 failed (%s)\n", cli_errstr(cli1));
3556 *oplock4_shared_correct = false;
3559 exit(0);
3562 sleep(2);
3564 /* Process the oplock break. */
3565 cli_receive_smb(cli1);
3567 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3568 printf("close1 failed (%s)\n", cli_errstr(cli1));
3569 correct = false;
3572 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3573 printf("unlink failed (%s)\n", cli_errstr(cli1));
3574 correct = false;
3576 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN))) {
3577 printf("unlink failed (%s)\n", cli_errstr(cli1));
3578 correct = false;
3581 if (!torture_close_connection(cli1)) {
3582 correct = false;
3585 if (!*oplock4_shared_correct) {
3586 correct = false;
3589 printf("finished oplock test 4\n");
3591 return correct;
3596 Test delete on close semantics.
3598 static bool run_deletetest(int dummy)
3600 struct cli_state *cli1 = NULL;
3601 struct cli_state *cli2 = NULL;
3602 const char *fname = "\\delete.file";
3603 uint16_t fnum1 = (uint16_t)-1;
3604 uint16_t fnum2 = (uint16_t)-1;
3605 bool correct = True;
3607 printf("starting delete test\n");
3609 if (!torture_open_connection(&cli1, 0)) {
3610 return False;
3613 cli_sockopt(cli1, sockops);
3615 /* Test 1 - this should delete the file on close. */
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, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3621 0, FILE_OVERWRITE_IF,
3622 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3623 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3624 correct = False;
3625 goto fail;
3628 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3629 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3630 correct = False;
3631 goto fail;
3634 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3635 printf("[1] open of %s succeeded (should fail)\n", fname);
3636 correct = False;
3637 goto fail;
3640 printf("first delete on close test succeeded.\n");
3642 /* Test 2 - this should delete the file on close. */
3644 cli_setatr(cli1, fname, 0, 0);
3645 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3647 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3648 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3649 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3650 printf("[2] 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("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3657 correct = False;
3658 goto fail;
3661 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3662 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3663 correct = False;
3664 goto fail;
3667 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3668 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3669 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3670 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3671 correct = False;
3672 goto fail;
3674 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3675 } else
3676 printf("second delete on close test succeeded.\n");
3678 /* Test 3 - ... */
3679 cli_setatr(cli1, fname, 0, 0);
3680 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3682 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3683 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3684 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3685 correct = False;
3686 goto fail;
3689 /* This should fail with a sharing violation - open for delete is only compatible
3690 with SHARE_DELETE. */
3692 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3693 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3694 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3695 correct = False;
3696 goto fail;
3699 /* This should succeed. */
3701 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3702 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3703 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3704 correct = False;
3705 goto fail;
3708 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3709 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3710 correct = False;
3711 goto fail;
3714 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3715 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3716 correct = False;
3717 goto fail;
3720 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3721 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3722 correct = False;
3723 goto fail;
3726 /* This should fail - file should no longer be there. */
3728 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3729 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3730 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3731 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3733 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3734 correct = False;
3735 goto fail;
3736 } else
3737 printf("third delete on close test succeeded.\n");
3739 /* Test 4 ... */
3740 cli_setatr(cli1, fname, 0, 0);
3741 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3743 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3744 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3745 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3746 correct = False;
3747 goto fail;
3750 /* This should succeed. */
3751 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3752 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3753 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3754 correct = False;
3755 goto fail;
3758 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3759 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3760 correct = False;
3761 goto fail;
3764 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3765 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3766 correct = False;
3767 goto fail;
3770 /* This should fail - no more opens once delete on close set. */
3771 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3772 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3773 FILE_OPEN, 0, 0, &fnum2))) {
3774 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3775 correct = False;
3776 goto fail;
3777 } else
3778 printf("fourth delete on close test succeeded.\n");
3780 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3781 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3782 correct = False;
3783 goto fail;
3786 /* Test 5 ... */
3787 cli_setatr(cli1, fname, 0, 0);
3788 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3790 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3791 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3792 correct = False;
3793 goto fail;
3796 /* This should fail - only allowed on NT opens with DELETE access. */
3798 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3799 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3800 correct = False;
3801 goto fail;
3804 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3805 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3806 correct = False;
3807 goto fail;
3810 printf("fifth delete on close test succeeded.\n");
3812 /* Test 6 ... */
3813 cli_setatr(cli1, fname, 0, 0);
3814 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3816 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3817 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3818 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3819 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3820 correct = False;
3821 goto fail;
3824 /* This should fail - only allowed on NT opens with DELETE access. */
3826 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3827 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3828 correct = False;
3829 goto fail;
3832 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3833 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3834 correct = False;
3835 goto fail;
3838 printf("sixth delete on close test succeeded.\n");
3840 /* Test 7 ... */
3841 cli_setatr(cli1, fname, 0, 0);
3842 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3844 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3845 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3846 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3847 correct = False;
3848 goto fail;
3851 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3852 printf("[7] setting delete_on_close on file failed !\n");
3853 correct = False;
3854 goto fail;
3857 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3858 printf("[7] unsetting delete_on_close on file failed !\n");
3859 correct = False;
3860 goto fail;
3863 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3864 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3865 correct = False;
3866 goto fail;
3869 /* This next open should succeed - we reset the flag. */
3871 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3872 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3873 correct = False;
3874 goto fail;
3877 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3878 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3879 correct = False;
3880 goto fail;
3883 printf("seventh delete on close test succeeded.\n");
3885 /* Test 7 ... */
3886 cli_setatr(cli1, fname, 0, 0);
3887 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3889 if (!torture_open_connection(&cli2, 1)) {
3890 printf("[8] failed to open second connection.\n");
3891 correct = False;
3892 goto fail;
3895 cli_sockopt(cli1, sockops);
3897 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3898 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3899 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3900 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3901 correct = False;
3902 goto fail;
3905 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3906 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3907 FILE_OPEN, 0, 0, &fnum2))) {
3908 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3909 correct = False;
3910 goto fail;
3913 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3914 printf("[8] setting delete_on_close on file failed !\n");
3915 correct = False;
3916 goto fail;
3919 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3920 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3921 correct = False;
3922 goto fail;
3925 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3926 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3927 correct = False;
3928 goto fail;
3931 /* This should fail.. */
3932 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3933 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3934 goto fail;
3935 correct = False;
3936 } else
3937 printf("eighth delete on close test succeeded.\n");
3939 /* This should fail - we need to set DELETE_ACCESS. */
3940 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3941 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3942 printf("[9] open of %s succeeded should have failed!\n", fname);
3943 correct = False;
3944 goto fail;
3947 printf("ninth delete on close test succeeded.\n");
3949 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3950 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3951 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3952 correct = False;
3953 goto fail;
3956 /* This should delete the file. */
3957 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3958 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3959 correct = False;
3960 goto fail;
3963 /* This should fail.. */
3964 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3965 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3966 goto fail;
3967 correct = False;
3968 } else
3969 printf("tenth delete on close test succeeded.\n");
3971 cli_setatr(cli1, fname, 0, 0);
3972 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3974 /* What error do we get when attempting to open a read-only file with
3975 delete access ? */
3977 /* Create a readonly file. */
3978 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3979 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3980 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3981 correct = False;
3982 goto fail;
3985 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3986 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3987 correct = False;
3988 goto fail;
3991 /* Now try open for delete access. */
3992 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3993 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3994 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3995 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3996 cli_close(cli1, fnum1);
3997 goto fail;
3998 correct = False;
3999 } else {
4000 NTSTATUS nterr = cli_nt_error(cli1);
4001 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4002 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4003 goto fail;
4004 correct = False;
4005 } else {
4006 printf("eleventh delete on close test succeeded.\n");
4010 printf("finished delete test\n");
4012 fail:
4013 /* FIXME: This will crash if we aborted before cli2 got
4014 * intialized, because these functions don't handle
4015 * uninitialized connections. */
4017 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4018 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4019 cli_setatr(cli1, fname, 0, 0);
4020 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4022 if (cli1 && !torture_close_connection(cli1)) {
4023 correct = False;
4025 if (cli2 && !torture_close_connection(cli2)) {
4026 correct = False;
4028 return correct;
4031 static bool run_deletetest_ln(int dummy)
4033 struct cli_state *cli;
4034 const char *fname = "\\delete1";
4035 const char *fname_ln = "\\delete1_ln";
4036 uint16_t fnum;
4037 uint16_t fnum1;
4038 NTSTATUS status;
4039 bool correct = true;
4040 time_t t;
4042 printf("starting deletetest-ln\n");
4044 if (!torture_open_connection(&cli, 0)) {
4045 return false;
4048 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4049 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4051 cli_sockopt(cli, sockops);
4053 /* Create the file. */
4054 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4055 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4056 return false;
4059 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4060 printf("close1 failed (%s)\n", cli_errstr(cli));
4061 return false;
4064 /* Now create a hardlink. */
4065 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4066 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4067 return false;
4070 /* Open the original file. */
4071 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4072 FILE_ATTRIBUTE_NORMAL,
4073 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4074 FILE_OPEN_IF, 0, 0, &fnum);
4075 if (!NT_STATUS_IS_OK(status)) {
4076 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4077 return false;
4080 /* Unlink the hard link path. */
4081 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4082 FILE_ATTRIBUTE_NORMAL,
4083 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4084 FILE_OPEN_IF, 0, 0, &fnum1);
4085 if (!NT_STATUS_IS_OK(status)) {
4086 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4087 return false;
4089 status = cli_nt_delete_on_close(cli, fnum1, true);
4090 if (!NT_STATUS_IS_OK(status)) {
4091 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4092 __location__, fname_ln, nt_errstr(status));
4093 return false;
4096 status = cli_close(cli, fnum1);
4097 if (!NT_STATUS_IS_OK(status)) {
4098 printf("close %s failed (%s)\n",
4099 fname_ln, nt_errstr(status));
4100 return false;
4103 status = cli_close(cli, fnum);
4104 if (!NT_STATUS_IS_OK(status)) {
4105 printf("close %s failed (%s)\n",
4106 fname, nt_errstr(status));
4107 return false;
4110 /* Ensure the original file is still there. */
4111 status = cli_getatr(cli, fname, NULL, NULL, &t);
4112 if (!NT_STATUS_IS_OK(status)) {
4113 printf("%s getatr on file %s failed (%s)\n",
4114 __location__,
4115 fname,
4116 nt_errstr(status));
4117 correct = False;
4120 /* Ensure the link path is gone. */
4121 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4122 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4123 printf("%s, getatr for file %s returned wrong error code %s "
4124 "- should have been deleted\n",
4125 __location__,
4126 fname_ln, nt_errstr(status));
4127 correct = False;
4130 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4131 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4133 if (!torture_close_connection(cli)) {
4134 correct = false;
4137 printf("finished deletetest-ln\n");
4139 return correct;
4143 print out server properties
4145 static bool run_properties(int dummy)
4147 struct cli_state *cli;
4148 bool correct = True;
4150 printf("starting properties test\n");
4152 ZERO_STRUCT(cli);
4154 if (!torture_open_connection(&cli, 0)) {
4155 return False;
4158 cli_sockopt(cli, sockops);
4160 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4162 if (!torture_close_connection(cli)) {
4163 correct = False;
4166 return correct;
4171 /* FIRST_DESIRED_ACCESS 0xf019f */
4172 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4173 FILE_READ_EA| /* 0xf */ \
4174 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4175 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4176 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4177 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4178 /* SECOND_DESIRED_ACCESS 0xe0080 */
4179 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4180 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4181 WRITE_OWNER_ACCESS /* 0xe0000 */
4183 #if 0
4184 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4185 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4186 FILE_READ_DATA|\
4187 WRITE_OWNER_ACCESS /* */
4188 #endif
4191 Test ntcreate calls made by xcopy
4193 static bool run_xcopy(int dummy)
4195 static struct cli_state *cli1;
4196 const char *fname = "\\test.txt";
4197 bool correct = True;
4198 uint16_t fnum1, fnum2;
4200 printf("starting xcopy test\n");
4202 if (!torture_open_connection(&cli1, 0)) {
4203 return False;
4206 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4207 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4208 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4209 0x4044, 0, &fnum1))) {
4210 printf("First open failed - %s\n", cli_errstr(cli1));
4211 return False;
4214 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4215 SECOND_DESIRED_ACCESS, 0,
4216 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4217 0x200000, 0, &fnum2))) {
4218 printf("second open failed - %s\n", cli_errstr(cli1));
4219 return False;
4222 if (!torture_close_connection(cli1)) {
4223 correct = False;
4226 return correct;
4230 Test rename on files open with share delete and no share delete.
4232 static bool run_rename(int dummy)
4234 static struct cli_state *cli1;
4235 const char *fname = "\\test.txt";
4236 const char *fname1 = "\\test1.txt";
4237 bool correct = True;
4238 uint16_t fnum1;
4239 uint16_t attr;
4240 NTSTATUS status;
4242 printf("starting rename test\n");
4244 if (!torture_open_connection(&cli1, 0)) {
4245 return False;
4248 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4249 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4250 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4251 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4252 printf("First open failed - %s\n", cli_errstr(cli1));
4253 return False;
4256 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4257 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4258 } else {
4259 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4260 correct = False;
4263 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4264 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4265 return False;
4268 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4269 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4270 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4271 #if 0
4272 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4273 #else
4274 FILE_SHARE_DELETE|FILE_SHARE_READ,
4275 #endif
4276 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4277 if (!NT_STATUS_IS_OK(status)) {
4278 printf("Second open failed - %s\n", cli_errstr(cli1));
4279 return False;
4282 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4283 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4284 correct = False;
4285 } else {
4286 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4289 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4290 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4291 return False;
4294 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4295 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4297 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4298 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4299 printf("Third open failed - %s\n", cli_errstr(cli1));
4300 return False;
4304 #if 0
4306 uint16_t fnum2;
4308 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4309 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4310 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4311 return False;
4313 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4314 printf("[8] setting delete_on_close on file failed !\n");
4315 return False;
4318 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4319 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4320 return False;
4323 #endif
4325 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4326 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4327 correct = False;
4328 } else {
4329 printf("Third rename succeeded (SHARE_NONE)\n");
4332 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4333 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4334 return False;
4337 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4338 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4340 /*----*/
4342 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4343 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4344 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4345 return False;
4348 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4349 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4350 } else {
4351 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4352 correct = False;
4355 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4356 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4357 return False;
4360 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4361 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4363 /*--*/
4365 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4366 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4367 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4368 return False;
4371 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4372 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4373 cli_errstr(cli1));
4374 correct = False;
4375 } else {
4376 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4380 * Now check if the first name still exists ...
4383 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4384 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4385 printf("Opening original file after rename of open file fails: %s\n",
4386 cli_errstr(cli1));
4388 else {
4389 printf("Opening original file after rename of open file works ...\n");
4390 (void)cli_close(cli1, fnum2);
4391 } */
4393 /*--*/
4394 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4395 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4396 return False;
4399 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4400 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4401 printf("getatr on file %s failed - %s ! \n",
4402 fname1,
4403 cli_errstr(cli1));
4404 correct = False;
4405 } else {
4406 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4407 printf("Renamed file %s has wrong attr 0x%x "
4408 "(should be 0x%x)\n",
4409 fname1,
4410 attr,
4411 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4412 correct = False;
4413 } else {
4414 printf("Renamed file %s has archive bit set\n", fname1);
4418 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4419 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4421 if (!torture_close_connection(cli1)) {
4422 correct = False;
4425 return correct;
4428 static bool run_pipe_number(int dummy)
4430 struct cli_state *cli1;
4431 const char *pipe_name = "\\SPOOLSS";
4432 uint16_t fnum;
4433 int num_pipes = 0;
4435 printf("starting pipenumber test\n");
4436 if (!torture_open_connection(&cli1, 0)) {
4437 return False;
4440 cli_sockopt(cli1, sockops);
4441 while(1) {
4442 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4443 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4444 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4445 break;
4447 num_pipes++;
4448 printf("\r%6d", num_pipes);
4451 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4452 torture_close_connection(cli1);
4453 return True;
4457 Test open mode returns on read-only files.
4459 static bool run_opentest(int dummy)
4461 static struct cli_state *cli1;
4462 static struct cli_state *cli2;
4463 const char *fname = "\\readonly.file";
4464 uint16_t fnum1, fnum2;
4465 char buf[20];
4466 SMB_OFF_T fsize;
4467 bool correct = True;
4468 char *tmp_path;
4469 NTSTATUS status;
4471 printf("starting open test\n");
4473 if (!torture_open_connection(&cli1, 0)) {
4474 return False;
4477 cli_setatr(cli1, fname, 0, 0);
4478 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4480 cli_sockopt(cli1, sockops);
4482 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4483 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4484 return False;
4487 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4488 printf("close2 failed (%s)\n", cli_errstr(cli1));
4489 return False;
4492 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4493 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4494 return False;
4497 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4498 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4499 return False;
4502 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4503 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4505 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4506 NT_STATUS_ACCESS_DENIED)) {
4507 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4510 printf("finished open test 1\n");
4512 cli_close(cli1, fnum1);
4514 /* Now try not readonly and ensure ERRbadshare is returned. */
4516 cli_setatr(cli1, fname, 0, 0);
4518 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4519 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4520 return False;
4523 /* This will fail - but the error should be ERRshare. */
4524 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4526 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4527 NT_STATUS_SHARING_VIOLATION)) {
4528 printf("correct error code ERRDOS/ERRbadshare returned\n");
4531 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4532 printf("close2 failed (%s)\n", cli_errstr(cli1));
4533 return False;
4536 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4538 printf("finished open test 2\n");
4540 /* Test truncate open disposition on file opened for read. */
4542 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4543 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4544 return False;
4547 /* write 20 bytes. */
4549 memset(buf, '\0', 20);
4551 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4552 printf("write failed (%s)\n", cli_errstr(cli1));
4553 correct = False;
4556 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4557 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4558 return False;
4561 /* Ensure size == 20. */
4562 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4563 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4564 return False;
4567 if (fsize != 20) {
4568 printf("(3) file size != 20\n");
4569 return False;
4572 /* Now test if we can truncate a file opened for readonly. */
4574 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4575 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4576 return False;
4579 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4580 printf("close2 failed (%s)\n", cli_errstr(cli1));
4581 return False;
4584 /* Ensure size == 0. */
4585 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4586 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4587 return False;
4590 if (fsize != 0) {
4591 printf("(3) file size != 0\n");
4592 return False;
4594 printf("finished open test 3\n");
4596 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4598 printf("Do ctemp tests\n");
4599 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4600 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4601 return False;
4603 printf("ctemp gave path %s\n", tmp_path);
4604 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4605 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4607 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4608 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4611 /* Test the non-io opens... */
4613 if (!torture_open_connection(&cli2, 1)) {
4614 return False;
4617 cli_setatr(cli2, fname, 0, 0);
4618 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4620 cli_sockopt(cli2, sockops);
4622 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4624 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4625 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4626 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4627 return False;
4630 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4631 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4632 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4633 return False;
4636 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4637 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4638 return False;
4640 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4641 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4642 return False;
4645 printf("non-io open test #1 passed.\n");
4647 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4649 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4651 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4652 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4653 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4654 return False;
4657 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4658 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4659 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4660 return False;
4663 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4664 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4665 return False;
4667 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4668 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4669 return False;
4672 printf("non-io open test #2 passed.\n");
4674 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4676 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4678 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4679 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4680 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4681 return False;
4684 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4685 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4686 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4687 return False;
4690 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4691 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4692 return False;
4694 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4695 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4696 return False;
4699 printf("non-io open test #3 passed.\n");
4701 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4703 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4705 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4706 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4707 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4708 return False;
4711 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4712 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4713 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4714 return False;
4717 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4719 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4720 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4721 return False;
4724 printf("non-io open test #4 passed.\n");
4726 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4728 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4730 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4731 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4732 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4733 return False;
4736 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4737 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4738 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4739 return False;
4742 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4743 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4744 return False;
4747 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4748 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4749 return False;
4752 printf("non-io open test #5 passed.\n");
4754 printf("TEST #6 testing 1 non-io open, one io open\n");
4756 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4758 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4759 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4760 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4761 return False;
4764 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4765 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4766 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4767 return False;
4770 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4771 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4772 return False;
4775 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4776 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4777 return False;
4780 printf("non-io open test #6 passed.\n");
4782 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4784 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4786 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4787 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4788 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4789 return False;
4792 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4793 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4794 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4795 return False;
4798 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4800 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4801 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4802 return False;
4805 printf("non-io open test #7 passed.\n");
4807 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4809 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4810 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4811 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4812 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4813 if (!NT_STATUS_IS_OK(status)) {
4814 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4815 correct = false;
4816 goto out;
4819 /* Write to ensure we have to update the file time. */
4820 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4821 printf("TEST #8 cli_write failed: %s\n", cli_errstr(cli1));
4822 correct = false;
4823 goto out;
4826 status = cli_close(cli1, fnum1);
4827 if (!NT_STATUS_IS_OK(status)) {
4828 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4829 correct = false;
4832 out:
4834 if (!torture_close_connection(cli1)) {
4835 correct = False;
4837 if (!torture_close_connection(cli2)) {
4838 correct = False;
4841 return correct;
4844 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4846 uint16 major, minor;
4847 uint32 caplow, caphigh;
4848 NTSTATUS status;
4850 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4851 printf("Server doesn't support UNIX CIFS extensions.\n");
4852 return NT_STATUS_NOT_SUPPORTED;
4855 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4856 &caphigh);
4857 if (!NT_STATUS_IS_OK(status)) {
4858 printf("Server didn't return UNIX CIFS extensions: %s\n",
4859 nt_errstr(status));
4860 return status;
4863 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4864 caplow, caphigh);
4865 if (!NT_STATUS_IS_OK(status)) {
4866 printf("Server doesn't support setting UNIX CIFS extensions: "
4867 "%s.\n", nt_errstr(status));
4868 return status;
4871 return NT_STATUS_OK;
4875 Test POSIX open /mkdir calls.
4877 static bool run_simple_posix_open_test(int dummy)
4879 static struct cli_state *cli1;
4880 const char *fname = "posix:file";
4881 const char *hname = "posix:hlink";
4882 const char *sname = "posix:symlink";
4883 const char *dname = "posix:dir";
4884 char buf[10];
4885 char namebuf[11];
4886 uint16_t fnum1 = (uint16_t)-1;
4887 SMB_STRUCT_STAT sbuf;
4888 bool correct = false;
4889 NTSTATUS status;
4891 printf("Starting simple POSIX open test\n");
4893 if (!torture_open_connection(&cli1, 0)) {
4894 return false;
4897 cli_sockopt(cli1, sockops);
4899 status = torture_setup_unix_extensions(cli1);
4900 if (!NT_STATUS_IS_OK(status)) {
4901 return false;
4904 cli_setatr(cli1, fname, 0, 0);
4905 cli_posix_unlink(cli1, fname);
4906 cli_setatr(cli1, dname, 0, 0);
4907 cli_posix_rmdir(cli1, dname);
4908 cli_setatr(cli1, hname, 0, 0);
4909 cli_posix_unlink(cli1, hname);
4910 cli_setatr(cli1, sname, 0, 0);
4911 cli_posix_unlink(cli1, sname);
4913 /* Create a directory. */
4914 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4915 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4916 goto out;
4919 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4920 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4921 goto out;
4924 /* Test ftruncate - set file size. */
4925 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4926 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4927 goto out;
4930 /* Ensure st_size == 1000 */
4931 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4932 printf("stat failed (%s)\n", cli_errstr(cli1));
4933 goto out;
4936 if (sbuf.st_ex_size != 1000) {
4937 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4938 goto out;
4941 /* Test ftruncate - set file size back to zero. */
4942 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4943 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4944 goto out;
4947 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4948 printf("close failed (%s)\n", cli_errstr(cli1));
4949 goto out;
4952 /* Now open the file again for read only. */
4953 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4954 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4955 goto out;
4958 /* Now unlink while open. */
4959 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4960 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4961 goto out;
4964 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4965 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4966 goto out;
4969 /* Ensure the file has gone. */
4970 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4971 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4972 goto out;
4975 /* What happens when we try and POSIX open a directory ? */
4976 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4977 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4978 goto out;
4979 } else {
4980 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4981 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4982 goto out;
4986 /* Create the file. */
4987 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4988 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4989 goto out;
4992 /* Write some data into it. */
4993 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4994 printf("cli_write failed: %s\n", cli_errstr(cli1));
4995 goto out;
4998 cli_close(cli1, fnum1);
5000 /* Now create a hardlink. */
5001 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5002 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5003 goto out;
5006 /* Now create a symlink. */
5007 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5008 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5009 goto out;
5012 /* Open the hardlink for read. */
5013 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5014 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5015 goto out;
5018 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5019 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5020 goto out;
5023 if (memcmp(buf, "TEST DATA\n", 10)) {
5024 printf("invalid data read from hardlink\n");
5025 goto out;
5028 /* Do a POSIX lock/unlock. */
5029 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5030 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5031 goto out;
5034 /* Punch a hole in the locked area. */
5035 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5036 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5037 goto out;
5040 cli_close(cli1, fnum1);
5042 /* Open the symlink for read - this should fail. A POSIX
5043 client should not be doing opens on a symlink. */
5044 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5045 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5046 goto out;
5047 } else {
5048 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5049 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5050 printf("POSIX open of %s should have failed "
5051 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5052 "failed with %s instead.\n",
5053 sname, cli_errstr(cli1));
5054 goto out;
5058 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5059 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5060 goto out;
5063 if (strcmp(namebuf, fname) != 0) {
5064 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5065 sname, fname, namebuf);
5066 goto out;
5069 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5070 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5071 goto out;
5074 printf("Simple POSIX open test passed\n");
5075 correct = true;
5077 out:
5079 if (fnum1 != (uint16_t)-1) {
5080 cli_close(cli1, fnum1);
5081 fnum1 = (uint16_t)-1;
5084 cli_setatr(cli1, sname, 0, 0);
5085 cli_posix_unlink(cli1, sname);
5086 cli_setatr(cli1, hname, 0, 0);
5087 cli_posix_unlink(cli1, hname);
5088 cli_setatr(cli1, fname, 0, 0);
5089 cli_posix_unlink(cli1, fname);
5090 cli_setatr(cli1, dname, 0, 0);
5091 cli_posix_rmdir(cli1, dname);
5093 if (!torture_close_connection(cli1)) {
5094 correct = false;
5097 return correct;
5101 static uint32 open_attrs_table[] = {
5102 FILE_ATTRIBUTE_NORMAL,
5103 FILE_ATTRIBUTE_ARCHIVE,
5104 FILE_ATTRIBUTE_READONLY,
5105 FILE_ATTRIBUTE_HIDDEN,
5106 FILE_ATTRIBUTE_SYSTEM,
5108 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5109 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5110 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5111 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5112 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5113 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5115 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5116 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5117 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5118 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5121 struct trunc_open_results {
5122 unsigned int num;
5123 uint32 init_attr;
5124 uint32 trunc_attr;
5125 uint32 result_attr;
5128 static struct trunc_open_results attr_results[] = {
5129 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5130 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5131 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5132 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5133 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5134 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5135 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5136 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5137 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5138 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5139 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5140 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5141 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5142 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5143 { 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 },
5144 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5145 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5146 { 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 },
5147 { 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 },
5148 { 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 },
5149 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5150 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5151 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5152 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5153 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5154 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5157 static bool run_openattrtest(int dummy)
5159 static struct cli_state *cli1;
5160 const char *fname = "\\openattr.file";
5161 uint16_t fnum1;
5162 bool correct = True;
5163 uint16 attr;
5164 unsigned int i, j, k, l;
5166 printf("starting open attr test\n");
5168 if (!torture_open_connection(&cli1, 0)) {
5169 return False;
5172 cli_sockopt(cli1, sockops);
5174 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5175 cli_setatr(cli1, fname, 0, 0);
5176 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5177 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5178 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5179 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5180 return False;
5183 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5184 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5185 return False;
5188 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5189 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5190 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5191 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5192 if (attr_results[l].num == k) {
5193 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5194 k, open_attrs_table[i],
5195 open_attrs_table[j],
5196 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5197 correct = False;
5200 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5201 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5202 k, open_attrs_table[i], open_attrs_table[j],
5203 cli_errstr(cli1));
5204 correct = False;
5206 #if 0
5207 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5208 #endif
5209 k++;
5210 continue;
5213 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5214 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5215 return False;
5218 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5219 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5220 return False;
5223 #if 0
5224 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5225 k, open_attrs_table[i], open_attrs_table[j], attr );
5226 #endif
5228 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5229 if (attr_results[l].num == k) {
5230 if (attr != attr_results[l].result_attr ||
5231 open_attrs_table[i] != attr_results[l].init_attr ||
5232 open_attrs_table[j] != attr_results[l].trunc_attr) {
5233 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5234 open_attrs_table[i],
5235 open_attrs_table[j],
5236 (unsigned int)attr,
5237 attr_results[l].result_attr);
5238 correct = False;
5240 break;
5243 k++;
5247 cli_setatr(cli1, fname, 0, 0);
5248 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5250 printf("open attr test %s.\n", correct ? "passed" : "failed");
5252 if (!torture_close_connection(cli1)) {
5253 correct = False;
5255 return correct;
5258 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5259 const char *name, void *state)
5261 int *matched = (int *)state;
5262 if (matched != NULL) {
5263 *matched += 1;
5265 return NT_STATUS_OK;
5269 test directory listing speed
5271 static bool run_dirtest(int dummy)
5273 int i;
5274 static struct cli_state *cli;
5275 uint16_t fnum;
5276 struct timeval core_start;
5277 bool correct = True;
5278 int matched;
5280 printf("starting directory test\n");
5282 if (!torture_open_connection(&cli, 0)) {
5283 return False;
5286 cli_sockopt(cli, sockops);
5288 srandom(0);
5289 for (i=0;i<torture_numops;i++) {
5290 fstring fname;
5291 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5292 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5293 fprintf(stderr,"Failed to open %s\n", fname);
5294 return False;
5296 cli_close(cli, fnum);
5299 core_start = timeval_current();
5301 matched = 0;
5302 cli_list(cli, "a*.*", 0, list_fn, &matched);
5303 printf("Matched %d\n", matched);
5305 matched = 0;
5306 cli_list(cli, "b*.*", 0, list_fn, &matched);
5307 printf("Matched %d\n", matched);
5309 matched = 0;
5310 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5311 printf("Matched %d\n", matched);
5313 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5315 srandom(0);
5316 for (i=0;i<torture_numops;i++) {
5317 fstring fname;
5318 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5319 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5322 if (!torture_close_connection(cli)) {
5323 correct = False;
5326 printf("finished dirtest\n");
5328 return correct;
5331 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5332 void *state)
5334 struct cli_state *pcli = (struct cli_state *)state;
5335 fstring fname;
5336 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5338 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5339 return NT_STATUS_OK;
5341 if (finfo->mode & aDIR) {
5342 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5343 printf("del_fn: failed to rmdir %s\n,", fname );
5344 } else {
5345 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5346 printf("del_fn: failed to unlink %s\n,", fname );
5348 return NT_STATUS_OK;
5353 sees what IOCTLs are supported
5355 bool torture_ioctl_test(int dummy)
5357 static struct cli_state *cli;
5358 uint16_t device, function;
5359 uint16_t fnum;
5360 const char *fname = "\\ioctl.dat";
5361 DATA_BLOB blob;
5362 NTSTATUS status;
5364 if (!torture_open_connection(&cli, 0)) {
5365 return False;
5368 printf("starting ioctl test\n");
5370 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5372 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5373 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5374 return False;
5377 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5378 printf("ioctl device info: %s\n", nt_errstr(status));
5380 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5381 printf("ioctl job info: %s\n", nt_errstr(status));
5383 for (device=0;device<0x100;device++) {
5384 printf("ioctl test with device = 0x%x\n", device);
5385 for (function=0;function<0x100;function++) {
5386 uint32 code = (device<<16) | function;
5388 status = cli_raw_ioctl(cli, fnum, code, &blob);
5390 if (NT_STATUS_IS_OK(status)) {
5391 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5392 (int)blob.length);
5393 data_blob_free(&blob);
5398 if (!torture_close_connection(cli)) {
5399 return False;
5402 return True;
5407 tries varients of chkpath
5409 bool torture_chkpath_test(int dummy)
5411 static struct cli_state *cli;
5412 uint16_t fnum;
5413 bool ret;
5415 if (!torture_open_connection(&cli, 0)) {
5416 return False;
5419 printf("starting chkpath test\n");
5421 /* cleanup from an old run */
5422 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5423 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5424 cli_rmdir(cli, "\\chkpath.dir");
5426 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5427 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5428 return False;
5431 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5432 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5433 return False;
5436 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5437 printf("open1 failed (%s)\n", cli_errstr(cli));
5438 return False;
5440 cli_close(cli, fnum);
5442 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5443 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5444 ret = False;
5447 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5448 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5449 ret = False;
5452 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5453 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5454 NT_STATUS_NOT_A_DIRECTORY);
5455 } else {
5456 printf("* chkpath on a file should fail\n");
5457 ret = False;
5460 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5461 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5462 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5463 } else {
5464 printf("* chkpath on a non existant file should fail\n");
5465 ret = False;
5468 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5469 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5470 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5471 } else {
5472 printf("* chkpath on a non existent component should fail\n");
5473 ret = False;
5476 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5477 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5478 cli_rmdir(cli, "\\chkpath.dir");
5480 if (!torture_close_connection(cli)) {
5481 return False;
5484 return ret;
5487 static bool run_eatest(int dummy)
5489 static struct cli_state *cli;
5490 const char *fname = "\\eatest.txt";
5491 bool correct = True;
5492 uint16_t fnum;
5493 int i;
5494 size_t num_eas;
5495 struct ea_struct *ea_list = NULL;
5496 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5497 NTSTATUS status;
5499 printf("starting eatest\n");
5501 if (!torture_open_connection(&cli, 0)) {
5502 talloc_destroy(mem_ctx);
5503 return False;
5506 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5507 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5508 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5509 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5510 0x4044, 0, &fnum))) {
5511 printf("open failed - %s\n", cli_errstr(cli));
5512 talloc_destroy(mem_ctx);
5513 return False;
5516 for (i = 0; i < 10; i++) {
5517 fstring ea_name, ea_val;
5519 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5520 memset(ea_val, (char)i+1, i+1);
5521 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5522 if (!NT_STATUS_IS_OK(status)) {
5523 printf("ea_set of name %s failed - %s\n", ea_name,
5524 nt_errstr(status));
5525 talloc_destroy(mem_ctx);
5526 return False;
5530 cli_close(cli, fnum);
5531 for (i = 0; i < 10; i++) {
5532 fstring ea_name, ea_val;
5534 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5535 memset(ea_val, (char)i+1, i+1);
5536 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5537 if (!NT_STATUS_IS_OK(status)) {
5538 printf("ea_set of name %s failed - %s\n", ea_name,
5539 nt_errstr(status));
5540 talloc_destroy(mem_ctx);
5541 return False;
5545 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5546 if (!NT_STATUS_IS_OK(status)) {
5547 printf("ea_get list failed - %s\n", nt_errstr(status));
5548 correct = False;
5551 printf("num_eas = %d\n", (int)num_eas);
5553 if (num_eas != 20) {
5554 printf("Should be 20 EA's stored... failing.\n");
5555 correct = False;
5558 for (i = 0; i < num_eas; i++) {
5559 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5560 dump_data(0, ea_list[i].value.data,
5561 ea_list[i].value.length);
5564 /* Setting EA's to zero length deletes them. Test this */
5565 printf("Now deleting all EA's - case indepenent....\n");
5567 #if 1
5568 cli_set_ea_path(cli, fname, "", "", 0);
5569 #else
5570 for (i = 0; i < 20; i++) {
5571 fstring ea_name;
5572 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5573 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5574 if (!NT_STATUS_IS_OK(status)) {
5575 printf("ea_set of name %s failed - %s\n", ea_name,
5576 nt_errstr(status));
5577 talloc_destroy(mem_ctx);
5578 return False;
5581 #endif
5583 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5584 if (!NT_STATUS_IS_OK(status)) {
5585 printf("ea_get list failed - %s\n", nt_errstr(status));
5586 correct = False;
5589 printf("num_eas = %d\n", (int)num_eas);
5590 for (i = 0; i < num_eas; i++) {
5591 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5592 dump_data(0, ea_list[i].value.data,
5593 ea_list[i].value.length);
5596 if (num_eas != 0) {
5597 printf("deleting EA's failed.\n");
5598 correct = False;
5601 /* Try and delete a non existant EA. */
5602 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5603 if (!NT_STATUS_IS_OK(status)) {
5604 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5605 nt_errstr(status));
5606 correct = False;
5609 talloc_destroy(mem_ctx);
5610 if (!torture_close_connection(cli)) {
5611 correct = False;
5614 return correct;
5617 static bool run_dirtest1(int dummy)
5619 int i;
5620 static struct cli_state *cli;
5621 uint16_t fnum;
5622 int num_seen;
5623 bool correct = True;
5625 printf("starting directory test\n");
5627 if (!torture_open_connection(&cli, 0)) {
5628 return False;
5631 cli_sockopt(cli, sockops);
5633 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5634 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5635 cli_rmdir(cli, "\\LISTDIR");
5636 cli_mkdir(cli, "\\LISTDIR");
5638 /* Create 1000 files and 1000 directories. */
5639 for (i=0;i<1000;i++) {
5640 fstring fname;
5641 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5642 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5643 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5644 fprintf(stderr,"Failed to open %s\n", fname);
5645 return False;
5647 cli_close(cli, fnum);
5649 for (i=0;i<1000;i++) {
5650 fstring fname;
5651 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5652 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5653 fprintf(stderr,"Failed to open %s\n", fname);
5654 return False;
5658 /* Now ensure that doing an old list sees both files and directories. */
5659 num_seen = 0;
5660 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5661 printf("num_seen = %d\n", num_seen );
5662 /* We should see 100 files + 1000 directories + . and .. */
5663 if (num_seen != 2002)
5664 correct = False;
5666 /* Ensure if we have the "must have" bits we only see the
5667 * relevent entries.
5669 num_seen = 0;
5670 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5671 printf("num_seen = %d\n", num_seen );
5672 if (num_seen != 1002)
5673 correct = False;
5675 num_seen = 0;
5676 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5677 printf("num_seen = %d\n", num_seen );
5678 if (num_seen != 1000)
5679 correct = False;
5681 /* Delete everything. */
5682 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5683 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5684 cli_rmdir(cli, "\\LISTDIR");
5686 #if 0
5687 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5688 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5689 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5690 #endif
5692 if (!torture_close_connection(cli)) {
5693 correct = False;
5696 printf("finished dirtest1\n");
5698 return correct;
5701 static bool run_error_map_extract(int dummy) {
5703 static struct cli_state *c_dos;
5704 static struct cli_state *c_nt;
5705 NTSTATUS status;
5707 uint32 error;
5709 uint32 flgs2, errnum;
5710 uint8 errclass;
5712 NTSTATUS nt_status;
5714 fstring user;
5716 /* NT-Error connection */
5718 if (!(c_nt = open_nbt_connection())) {
5719 return False;
5722 c_nt->use_spnego = False;
5724 status = cli_negprot(c_nt);
5726 if (!NT_STATUS_IS_OK(status)) {
5727 printf("%s rejected the NT-error negprot (%s)\n", host,
5728 nt_errstr(status));
5729 cli_shutdown(c_nt);
5730 return False;
5733 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5734 workgroup))) {
5735 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5736 return False;
5739 /* DOS-Error connection */
5741 if (!(c_dos = open_nbt_connection())) {
5742 return False;
5745 c_dos->use_spnego = False;
5746 c_dos->force_dos_errors = True;
5748 status = cli_negprot(c_dos);
5749 if (!NT_STATUS_IS_OK(status)) {
5750 printf("%s rejected the DOS-error negprot (%s)\n", host,
5751 nt_errstr(status));
5752 cli_shutdown(c_dos);
5753 return False;
5756 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5757 workgroup))) {
5758 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5759 return False;
5762 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5763 fstr_sprintf(user, "%X", error);
5765 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5766 password, strlen(password),
5767 password, strlen(password),
5768 workgroup))) {
5769 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5772 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5774 /* Case #1: 32-bit NT errors */
5775 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5776 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5777 } else {
5778 printf("/** Dos error on NT connection! (%s) */\n",
5779 cli_errstr(c_nt));
5780 nt_status = NT_STATUS(0xc0000000);
5783 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5784 password, strlen(password),
5785 password, strlen(password),
5786 workgroup))) {
5787 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5789 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5791 /* Case #1: 32-bit NT errors */
5792 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5793 printf("/** NT error on DOS connection! (%s) */\n",
5794 cli_errstr(c_nt));
5795 errnum = errclass = 0;
5796 } else {
5797 cli_dos_error(c_dos, &errclass, &errnum);
5800 if (NT_STATUS_V(nt_status) != error) {
5801 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5802 get_nt_error_c_code(NT_STATUS(error)),
5803 get_nt_error_c_code(nt_status));
5806 printf("\t{%s,\t%s,\t%s},\n",
5807 smb_dos_err_class(errclass),
5808 smb_dos_err_name(errclass, errnum),
5809 get_nt_error_c_code(NT_STATUS(error)));
5811 return True;
5814 static bool run_sesssetup_bench(int dummy)
5816 static struct cli_state *c;
5817 const char *fname = "\\file.dat";
5818 uint16_t fnum;
5819 NTSTATUS status;
5820 int i;
5822 if (!torture_open_connection(&c, 0)) {
5823 return false;
5826 if (!NT_STATUS_IS_OK(cli_ntcreate(
5827 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5828 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5829 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5830 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5831 return false;
5834 for (i=0; i<torture_numops; i++) {
5835 status = cli_session_setup(
5836 c, username,
5837 password, strlen(password),
5838 password, strlen(password),
5839 workgroup);
5840 if (!NT_STATUS_IS_OK(status)) {
5841 d_printf("(%s) cli_session_setup failed: %s\n",
5842 __location__, nt_errstr(status));
5843 return false;
5846 d_printf("\r%d ", (int)c->vuid);
5848 status = cli_ulogoff(c);
5849 if (!NT_STATUS_IS_OK(status)) {
5850 d_printf("(%s) cli_ulogoff failed: %s\n",
5851 __location__, nt_errstr(status));
5852 return false;
5854 c->vuid = 0;
5857 return true;
5860 static bool subst_test(const char *str, const char *user, const char *domain,
5861 uid_t uid, gid_t gid, const char *expected)
5863 char *subst;
5864 bool result = true;
5866 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5868 if (strcmp(subst, expected) != 0) {
5869 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5870 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5871 expected);
5872 result = false;
5875 TALLOC_FREE(subst);
5876 return result;
5879 static void chain1_open_completion(struct tevent_req *req)
5881 uint16_t fnum;
5882 NTSTATUS status;
5883 status = cli_open_recv(req, &fnum);
5884 TALLOC_FREE(req);
5886 d_printf("cli_open_recv returned %s: %d\n",
5887 nt_errstr(status),
5888 NT_STATUS_IS_OK(status) ? fnum : -1);
5891 static void chain1_write_completion(struct tevent_req *req)
5893 size_t written;
5894 NTSTATUS status;
5895 status = cli_write_andx_recv(req, &written);
5896 TALLOC_FREE(req);
5898 d_printf("cli_write_andx_recv returned %s: %d\n",
5899 nt_errstr(status),
5900 NT_STATUS_IS_OK(status) ? (int)written : -1);
5903 static void chain1_close_completion(struct tevent_req *req)
5905 NTSTATUS status;
5906 bool *done = (bool *)tevent_req_callback_data_void(req);
5908 status = cli_close_recv(req);
5909 *done = true;
5911 TALLOC_FREE(req);
5913 d_printf("cli_close returned %s\n", nt_errstr(status));
5916 static bool run_chain1(int dummy)
5918 struct cli_state *cli1;
5919 struct event_context *evt = event_context_init(NULL);
5920 struct tevent_req *reqs[3], *smbreqs[3];
5921 bool done = false;
5922 const char *str = "foobar";
5923 NTSTATUS status;
5925 printf("starting chain1 test\n");
5926 if (!torture_open_connection(&cli1, 0)) {
5927 return False;
5930 cli_sockopt(cli1, sockops);
5932 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5933 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5934 if (reqs[0] == NULL) return false;
5935 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5938 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5939 (uint8_t *)str, 0, strlen(str)+1,
5940 smbreqs, 1, &smbreqs[1]);
5941 if (reqs[1] == NULL) return false;
5942 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5944 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5945 if (reqs[2] == NULL) return false;
5946 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5948 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5949 if (!NT_STATUS_IS_OK(status)) {
5950 return false;
5953 while (!done) {
5954 event_loop_once(evt);
5957 torture_close_connection(cli1);
5958 return True;
5961 static void chain2_sesssetup_completion(struct tevent_req *req)
5963 NTSTATUS status;
5964 status = cli_session_setup_guest_recv(req);
5965 d_printf("sesssetup returned %s\n", nt_errstr(status));
5968 static void chain2_tcon_completion(struct tevent_req *req)
5970 bool *done = (bool *)tevent_req_callback_data_void(req);
5971 NTSTATUS status;
5972 status = cli_tcon_andx_recv(req);
5973 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5974 *done = true;
5977 static bool run_chain2(int dummy)
5979 struct cli_state *cli1;
5980 struct event_context *evt = event_context_init(NULL);
5981 struct tevent_req *reqs[2], *smbreqs[2];
5982 bool done = false;
5983 NTSTATUS status;
5985 printf("starting chain2 test\n");
5986 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5987 port_to_use, Undefined, 0);
5988 if (!NT_STATUS_IS_OK(status)) {
5989 return False;
5992 cli_sockopt(cli1, sockops);
5994 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5995 &smbreqs[0]);
5996 if (reqs[0] == NULL) return false;
5997 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5999 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6000 "?????", NULL, 0, &smbreqs[1]);
6001 if (reqs[1] == NULL) return false;
6002 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6004 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6005 if (!NT_STATUS_IS_OK(status)) {
6006 return false;
6009 while (!done) {
6010 event_loop_once(evt);
6013 torture_close_connection(cli1);
6014 return True;
6018 struct torture_createdel_state {
6019 struct tevent_context *ev;
6020 struct cli_state *cli;
6023 static void torture_createdel_created(struct tevent_req *subreq);
6024 static void torture_createdel_closed(struct tevent_req *subreq);
6026 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6027 struct tevent_context *ev,
6028 struct cli_state *cli,
6029 const char *name)
6031 struct tevent_req *req, *subreq;
6032 struct torture_createdel_state *state;
6034 req = tevent_req_create(mem_ctx, &state,
6035 struct torture_createdel_state);
6036 if (req == NULL) {
6037 return NULL;
6039 state->ev = ev;
6040 state->cli = cli;
6042 subreq = cli_ntcreate_send(
6043 state, ev, cli, name, 0,
6044 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6045 FILE_ATTRIBUTE_NORMAL,
6046 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6047 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6049 if (tevent_req_nomem(subreq, req)) {
6050 return tevent_req_post(req, ev);
6052 tevent_req_set_callback(subreq, torture_createdel_created, req);
6053 return req;
6056 static void torture_createdel_created(struct tevent_req *subreq)
6058 struct tevent_req *req = tevent_req_callback_data(
6059 subreq, struct tevent_req);
6060 struct torture_createdel_state *state = tevent_req_data(
6061 req, struct torture_createdel_state);
6062 NTSTATUS status;
6063 uint16_t fnum;
6065 status = cli_ntcreate_recv(subreq, &fnum);
6066 TALLOC_FREE(subreq);
6067 if (!NT_STATUS_IS_OK(status)) {
6068 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6069 nt_errstr(status)));
6070 tevent_req_nterror(req, status);
6071 return;
6074 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6075 if (tevent_req_nomem(subreq, req)) {
6076 return;
6078 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6081 static void torture_createdel_closed(struct tevent_req *subreq)
6083 struct tevent_req *req = tevent_req_callback_data(
6084 subreq, struct tevent_req);
6085 NTSTATUS status;
6087 status = cli_close_recv(subreq);
6088 if (!NT_STATUS_IS_OK(status)) {
6089 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6090 tevent_req_nterror(req, status);
6091 return;
6093 tevent_req_done(req);
6096 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6098 return tevent_req_simple_recv_ntstatus(req);
6101 struct torture_createdels_state {
6102 struct tevent_context *ev;
6103 struct cli_state *cli;
6104 const char *base_name;
6105 int sent;
6106 int received;
6107 int num_files;
6108 struct tevent_req **reqs;
6111 static void torture_createdels_done(struct tevent_req *subreq);
6113 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6114 struct tevent_context *ev,
6115 struct cli_state *cli,
6116 const char *base_name,
6117 int num_parallel,
6118 int num_files)
6120 struct tevent_req *req;
6121 struct torture_createdels_state *state;
6122 int i;
6124 req = tevent_req_create(mem_ctx, &state,
6125 struct torture_createdels_state);
6126 if (req == NULL) {
6127 return NULL;
6129 state->ev = ev;
6130 state->cli = cli;
6131 state->base_name = talloc_strdup(state, base_name);
6132 if (tevent_req_nomem(state->base_name, req)) {
6133 return tevent_req_post(req, ev);
6135 state->num_files = MAX(num_parallel, num_files);
6136 state->sent = 0;
6137 state->received = 0;
6139 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6140 if (tevent_req_nomem(state->reqs, req)) {
6141 return tevent_req_post(req, ev);
6144 for (i=0; i<num_parallel; i++) {
6145 char *name;
6147 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6148 state->sent);
6149 if (tevent_req_nomem(name, req)) {
6150 return tevent_req_post(req, ev);
6152 state->reqs[i] = torture_createdel_send(
6153 state->reqs, state->ev, state->cli, name);
6154 if (tevent_req_nomem(state->reqs[i], req)) {
6155 return tevent_req_post(req, ev);
6157 name = talloc_move(state->reqs[i], &name);
6158 tevent_req_set_callback(state->reqs[i],
6159 torture_createdels_done, req);
6160 state->sent += 1;
6162 return req;
6165 static void torture_createdels_done(struct tevent_req *subreq)
6167 struct tevent_req *req = tevent_req_callback_data(
6168 subreq, struct tevent_req);
6169 struct torture_createdels_state *state = tevent_req_data(
6170 req, struct torture_createdels_state);
6171 size_t num_parallel = talloc_array_length(state->reqs);
6172 NTSTATUS status;
6173 char *name;
6174 int i;
6176 status = torture_createdel_recv(subreq);
6177 if (!NT_STATUS_IS_OK(status)){
6178 DEBUG(10, ("torture_createdel_recv returned %s\n",
6179 nt_errstr(status)));
6180 TALLOC_FREE(subreq);
6181 tevent_req_nterror(req, status);
6182 return;
6185 for (i=0; i<num_parallel; i++) {
6186 if (subreq == state->reqs[i]) {
6187 break;
6190 if (i == num_parallel) {
6191 DEBUG(10, ("received something we did not send\n"));
6192 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6193 return;
6195 TALLOC_FREE(state->reqs[i]);
6197 if (state->sent >= state->num_files) {
6198 tevent_req_done(req);
6199 return;
6202 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6203 state->sent);
6204 if (tevent_req_nomem(name, req)) {
6205 return;
6207 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6208 state->cli, name);
6209 if (tevent_req_nomem(state->reqs[i], req)) {
6210 return;
6212 name = talloc_move(state->reqs[i], &name);
6213 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6214 state->sent += 1;
6217 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6219 return tevent_req_simple_recv_ntstatus(req);
6222 struct swallow_notify_state {
6223 struct tevent_context *ev;
6224 struct cli_state *cli;
6225 uint16_t fnum;
6226 uint32_t completion_filter;
6227 bool recursive;
6228 bool (*fn)(uint32_t action, const char *name, void *priv);
6229 void *priv;
6232 static void swallow_notify_done(struct tevent_req *subreq);
6234 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6235 struct tevent_context *ev,
6236 struct cli_state *cli,
6237 uint16_t fnum,
6238 uint32_t completion_filter,
6239 bool recursive,
6240 bool (*fn)(uint32_t action,
6241 const char *name,
6242 void *priv),
6243 void *priv)
6245 struct tevent_req *req, *subreq;
6246 struct swallow_notify_state *state;
6248 req = tevent_req_create(mem_ctx, &state,
6249 struct swallow_notify_state);
6250 if (req == NULL) {
6251 return NULL;
6253 state->ev = ev;
6254 state->cli = cli;
6255 state->fnum = fnum;
6256 state->completion_filter = completion_filter;
6257 state->recursive = recursive;
6258 state->fn = fn;
6259 state->priv = priv;
6261 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6262 0xffff, state->completion_filter,
6263 state->recursive);
6264 if (tevent_req_nomem(subreq, req)) {
6265 return tevent_req_post(req, ev);
6267 tevent_req_set_callback(subreq, swallow_notify_done, req);
6268 return req;
6271 static void swallow_notify_done(struct tevent_req *subreq)
6273 struct tevent_req *req = tevent_req_callback_data(
6274 subreq, struct tevent_req);
6275 struct swallow_notify_state *state = tevent_req_data(
6276 req, struct swallow_notify_state);
6277 NTSTATUS status;
6278 uint32_t i, num_changes;
6279 struct notify_change *changes;
6281 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6282 TALLOC_FREE(subreq);
6283 if (!NT_STATUS_IS_OK(status)) {
6284 DEBUG(10, ("cli_notify_recv returned %s\n",
6285 nt_errstr(status)));
6286 tevent_req_nterror(req, status);
6287 return;
6290 for (i=0; i<num_changes; i++) {
6291 state->fn(changes[i].action, changes[i].name, state->priv);
6293 TALLOC_FREE(changes);
6295 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6296 0xffff, state->completion_filter,
6297 state->recursive);
6298 if (tevent_req_nomem(subreq, req)) {
6299 return;
6301 tevent_req_set_callback(subreq, swallow_notify_done, req);
6304 static bool print_notifies(uint32_t action, const char *name, void *priv)
6306 if (DEBUGLEVEL > 5) {
6307 d_printf("%d %s\n", (int)action, name);
6309 return true;
6312 static void notify_bench_done(struct tevent_req *req)
6314 int *num_finished = (int *)tevent_req_callback_data_void(req);
6315 *num_finished += 1;
6318 static bool run_notify_bench(int dummy)
6320 const char *dname = "\\notify-bench";
6321 struct tevent_context *ev;
6322 NTSTATUS status;
6323 uint16_t dnum;
6324 struct tevent_req *req1;
6325 struct tevent_req *req2 = NULL;
6326 int i, num_unc_names;
6327 int num_finished = 0;
6329 printf("starting notify-bench test\n");
6331 if (use_multishare_conn) {
6332 char **unc_list;
6333 unc_list = file_lines_load(multishare_conn_fname,
6334 &num_unc_names, 0, NULL);
6335 if (!unc_list || num_unc_names <= 0) {
6336 d_printf("Failed to load unc names list from '%s'\n",
6337 multishare_conn_fname);
6338 return false;
6340 TALLOC_FREE(unc_list);
6341 } else {
6342 num_unc_names = 1;
6345 ev = tevent_context_init(talloc_tos());
6346 if (ev == NULL) {
6347 d_printf("tevent_context_init failed\n");
6348 return false;
6351 for (i=0; i<num_unc_names; i++) {
6352 struct cli_state *cli;
6353 char *base_fname;
6355 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6356 dname, i);
6357 if (base_fname == NULL) {
6358 return false;
6361 if (!torture_open_connection(&cli, i)) {
6362 return false;
6365 status = cli_ntcreate(cli, dname, 0,
6366 MAXIMUM_ALLOWED_ACCESS,
6367 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6368 FILE_SHARE_DELETE,
6369 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6370 &dnum);
6372 if (!NT_STATUS_IS_OK(status)) {
6373 d_printf("Could not create %s: %s\n", dname,
6374 nt_errstr(status));
6375 return false;
6378 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6379 FILE_NOTIFY_CHANGE_FILE_NAME |
6380 FILE_NOTIFY_CHANGE_DIR_NAME |
6381 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6382 FILE_NOTIFY_CHANGE_LAST_WRITE,
6383 false, print_notifies, NULL);
6384 if (req1 == NULL) {
6385 d_printf("Could not create notify request\n");
6386 return false;
6389 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6390 base_fname, 10, torture_numops);
6391 if (req2 == NULL) {
6392 d_printf("Could not create createdels request\n");
6393 return false;
6395 TALLOC_FREE(base_fname);
6397 tevent_req_set_callback(req2, notify_bench_done,
6398 &num_finished);
6401 while (num_finished < num_unc_names) {
6402 int ret;
6403 ret = tevent_loop_once(ev);
6404 if (ret != 0) {
6405 d_printf("tevent_loop_once failed\n");
6406 return false;
6410 if (!tevent_req_poll(req2, ev)) {
6411 d_printf("tevent_req_poll failed\n");
6414 status = torture_createdels_recv(req2);
6415 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6417 return true;
6420 static bool run_mangle1(int dummy)
6422 struct cli_state *cli;
6423 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6424 uint16_t fnum;
6425 fstring alt_name;
6426 NTSTATUS status;
6427 time_t change_time, access_time, write_time;
6428 SMB_OFF_T size;
6429 uint16_t mode;
6431 printf("starting mangle1 test\n");
6432 if (!torture_open_connection(&cli, 0)) {
6433 return False;
6436 cli_sockopt(cli, sockops);
6438 if (!NT_STATUS_IS_OK(cli_ntcreate(
6439 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6440 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6441 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6442 return false;
6444 cli_close(cli, fnum);
6446 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6447 if (!NT_STATUS_IS_OK(status)) {
6448 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6449 nt_errstr(status));
6450 return false;
6452 d_printf("alt_name: %s\n", alt_name);
6454 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6455 d_printf("cli_open(%s) failed: %s\n", alt_name,
6456 cli_errstr(cli));
6457 return false;
6459 cli_close(cli, fnum);
6461 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6462 &write_time, &size, &mode);
6463 if (!NT_STATUS_IS_OK(status)) {
6464 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6465 nt_errstr(status));
6466 return false;
6469 return true;
6472 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6474 size_t *to_pull = (size_t *)priv;
6475 size_t thistime = *to_pull;
6477 thistime = MIN(thistime, n);
6478 if (thistime == 0) {
6479 return 0;
6482 memset(buf, 0, thistime);
6483 *to_pull -= thistime;
6484 return thistime;
6487 static bool run_windows_write(int dummy)
6489 struct cli_state *cli1;
6490 uint16_t fnum;
6491 int i;
6492 bool ret = false;
6493 const char *fname = "\\writetest.txt";
6494 struct timeval start_time;
6495 double seconds;
6496 double kbytes;
6498 printf("starting windows_write test\n");
6499 if (!torture_open_connection(&cli1, 0)) {
6500 return False;
6503 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6504 printf("open failed (%s)\n", cli_errstr(cli1));
6505 return False;
6508 cli_sockopt(cli1, sockops);
6510 start_time = timeval_current();
6512 for (i=0; i<torture_numops; i++) {
6513 char c = 0;
6514 off_t start = i * torture_blocksize;
6515 NTSTATUS status;
6516 size_t to_pull = torture_blocksize - 1;
6518 if (cli_write(cli1, fnum, 0, &c,
6519 start + torture_blocksize - 1, 1) != 1) {
6520 printf("cli_write failed: %s\n", cli_errstr(cli1));
6521 goto fail;
6524 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6525 null_source, &to_pull);
6526 if (!NT_STATUS_IS_OK(status)) {
6527 printf("cli_push returned: %s\n", nt_errstr(status));
6528 goto fail;
6532 seconds = timeval_elapsed(&start_time);
6533 kbytes = (double)torture_blocksize * torture_numops;
6534 kbytes /= 1024;
6536 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6537 (double)seconds, (int)(kbytes/seconds));
6539 ret = true;
6540 fail:
6541 cli_close(cli1, fnum);
6542 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6543 torture_close_connection(cli1);
6544 return ret;
6547 static bool run_cli_echo(int dummy)
6549 struct cli_state *cli;
6550 NTSTATUS status;
6552 printf("starting cli_echo test\n");
6553 if (!torture_open_connection(&cli, 0)) {
6554 return false;
6556 cli_sockopt(cli, sockops);
6558 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6560 d_printf("cli_echo returned %s\n", nt_errstr(status));
6562 torture_close_connection(cli);
6563 return NT_STATUS_IS_OK(status);
6566 static bool run_uid_regression_test(int dummy)
6568 static struct cli_state *cli;
6569 int16_t old_vuid;
6570 int16_t old_cnum;
6571 bool correct = True;
6572 NTSTATUS status;
6574 printf("starting uid regression test\n");
6576 if (!torture_open_connection(&cli, 0)) {
6577 return False;
6580 cli_sockopt(cli, sockops);
6582 /* Ok - now save then logoff our current user. */
6583 old_vuid = cli->vuid;
6585 status = cli_ulogoff(cli);
6586 if (!NT_STATUS_IS_OK(status)) {
6587 d_printf("(%s) cli_ulogoff failed: %s\n",
6588 __location__, nt_errstr(status));
6589 correct = false;
6590 goto out;
6593 cli->vuid = old_vuid;
6595 /* Try an operation. */
6596 status = cli_mkdir(cli, "\\uid_reg_test");
6597 if (NT_STATUS_IS_OK(status)) {
6598 d_printf("(%s) cli_mkdir succeeded\n",
6599 __location__);
6600 correct = false;
6601 goto out;
6602 } else {
6603 /* Should be bad uid. */
6604 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6605 NT_STATUS_USER_SESSION_DELETED)) {
6606 correct = false;
6607 goto out;
6611 old_cnum = cli->cnum;
6613 /* Now try a SMBtdis with the invald vuid set to zero. */
6614 cli->vuid = 0;
6616 /* This should succeed. */
6617 status = cli_tdis(cli);
6619 if (NT_STATUS_IS_OK(status)) {
6620 d_printf("First tdis with invalid vuid should succeed.\n");
6621 } else {
6622 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6623 correct = false;
6624 goto out;
6627 cli->vuid = old_vuid;
6628 cli->cnum = old_cnum;
6630 /* This should fail. */
6631 status = cli_tdis(cli);
6632 if (NT_STATUS_IS_OK(status)) {
6633 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6634 correct = false;
6635 goto out;
6636 } else {
6637 /* Should be bad tid. */
6638 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6639 NT_STATUS_NETWORK_NAME_DELETED)) {
6640 correct = false;
6641 goto out;
6645 cli_rmdir(cli, "\\uid_reg_test");
6647 out:
6649 cli_shutdown(cli);
6650 return correct;
6654 static const char *illegal_chars = "*\\/?<>|\":";
6655 static char force_shortname_chars[] = " +,.[];=\177";
6657 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6658 const char *mask, void *state)
6660 struct cli_state *pcli = (struct cli_state *)state;
6661 fstring fname;
6662 NTSTATUS status = NT_STATUS_OK;
6664 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6666 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6667 return NT_STATUS_OK;
6669 if (finfo->mode & aDIR) {
6670 status = cli_rmdir(pcli, fname);
6671 if (!NT_STATUS_IS_OK(status)) {
6672 printf("del_fn: failed to rmdir %s\n,", fname );
6674 } else {
6675 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6676 if (!NT_STATUS_IS_OK(status)) {
6677 printf("del_fn: failed to unlink %s\n,", fname );
6680 return status;
6683 struct sn_state {
6684 int matched;
6685 int i;
6686 bool val;
6689 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6690 const char *name, void *state)
6692 struct sn_state *s = (struct sn_state *)state;
6693 int i = s->i;
6695 #if 0
6696 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6697 i, finfo->name, finfo->short_name);
6698 #endif
6700 if (strchr(force_shortname_chars, i)) {
6701 if (!finfo->short_name[0]) {
6702 /* Shortname not created when it should be. */
6703 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6704 __location__, finfo->name, i);
6705 s->val = true;
6707 } else if (finfo->short_name[0]){
6708 /* Shortname created when it should not be. */
6709 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6710 __location__, finfo->short_name, finfo->name);
6711 s->val = true;
6713 s->matched += 1;
6714 return NT_STATUS_OK;
6717 static bool run_shortname_test(int dummy)
6719 static struct cli_state *cli;
6720 bool correct = True;
6721 int i;
6722 struct sn_state s;
6723 char fname[20];
6725 printf("starting shortname test\n");
6727 if (!torture_open_connection(&cli, 0)) {
6728 return False;
6731 cli_sockopt(cli, sockops);
6733 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6734 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6735 cli_rmdir(cli, "\\shortname");
6737 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6738 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6739 __location__, cli_errstr(cli));
6740 correct = false;
6741 goto out;
6744 strlcpy(fname, "\\shortname\\", sizeof(fname));
6745 strlcat(fname, "test .txt", sizeof(fname));
6747 s.val = false;
6749 for (i = 32; i < 128; i++) {
6750 NTSTATUS status;
6751 uint16_t fnum = (uint16_t)-1;
6753 s.i = i;
6755 if (strchr(illegal_chars, i)) {
6756 continue;
6758 fname[15] = i;
6760 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6761 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6762 if (!NT_STATUS_IS_OK(status)) {
6763 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6764 __location__, fname, cli_errstr(cli));
6765 correct = false;
6766 goto out;
6768 cli_close(cli, fnum);
6770 s.matched = 0;
6771 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6772 &s);
6773 if (s.matched != 1) {
6774 d_printf("(%s) failed to list %s: %s\n",
6775 __location__, fname, cli_errstr(cli));
6776 correct = false;
6777 goto out;
6779 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6780 d_printf("(%s) failed to delete %s: %s\n",
6781 __location__, fname, cli_errstr(cli));
6782 correct = false;
6783 goto out;
6786 if (s.val) {
6787 correct = false;
6788 goto out;
6792 out:
6794 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6795 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6796 cli_rmdir(cli, "\\shortname");
6797 torture_close_connection(cli);
6798 return correct;
6801 static void pagedsearch_cb(struct tevent_req *req)
6803 int rc;
6804 struct tldap_message *msg;
6805 char *dn;
6807 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6808 if (rc != TLDAP_SUCCESS) {
6809 d_printf("tldap_search_paged_recv failed: %s\n",
6810 tldap_err2string(rc));
6811 return;
6813 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6814 TALLOC_FREE(msg);
6815 return;
6817 if (!tldap_entry_dn(msg, &dn)) {
6818 d_printf("tldap_entry_dn failed\n");
6819 return;
6821 d_printf("%s\n", dn);
6822 TALLOC_FREE(msg);
6825 static bool run_tldap(int dummy)
6827 struct tldap_context *ld;
6828 int fd, rc;
6829 NTSTATUS status;
6830 struct sockaddr_storage addr;
6831 struct tevent_context *ev;
6832 struct tevent_req *req;
6833 char *basedn;
6834 const char *filter;
6836 if (!resolve_name(host, &addr, 0, false)) {
6837 d_printf("could not find host %s\n", host);
6838 return false;
6840 status = open_socket_out(&addr, 389, 9999, &fd);
6841 if (!NT_STATUS_IS_OK(status)) {
6842 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6843 return false;
6846 ld = tldap_context_create(talloc_tos(), fd);
6847 if (ld == NULL) {
6848 close(fd);
6849 d_printf("tldap_context_create failed\n");
6850 return false;
6853 rc = tldap_fetch_rootdse(ld);
6854 if (rc != TLDAP_SUCCESS) {
6855 d_printf("tldap_fetch_rootdse failed: %s\n",
6856 tldap_errstr(talloc_tos(), ld, rc));
6857 return false;
6860 basedn = tldap_talloc_single_attribute(
6861 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6862 if (basedn == NULL) {
6863 d_printf("no defaultNamingContext\n");
6864 return false;
6866 d_printf("defaultNamingContext: %s\n", basedn);
6868 ev = tevent_context_init(talloc_tos());
6869 if (ev == NULL) {
6870 d_printf("tevent_context_init failed\n");
6871 return false;
6874 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6875 TLDAP_SCOPE_SUB, "(objectclass=*)",
6876 NULL, 0, 0,
6877 NULL, 0, NULL, 0, 0, 0, 0, 5);
6878 if (req == NULL) {
6879 d_printf("tldap_search_paged_send failed\n");
6880 return false;
6882 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6884 tevent_req_poll(req, ev);
6886 TALLOC_FREE(req);
6888 /* test search filters against rootDSE */
6889 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6890 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6892 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6893 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6894 talloc_tos(), NULL, NULL);
6895 if (rc != TLDAP_SUCCESS) {
6896 d_printf("tldap_search with complex filter failed: %s\n",
6897 tldap_errstr(talloc_tos(), ld, rc));
6898 return false;
6901 TALLOC_FREE(ld);
6902 return true;
6905 /* Torture test to ensure no regression of :
6906 https://bugzilla.samba.org/show_bug.cgi?id=7084
6909 static bool run_dir_createtime(int dummy)
6911 struct cli_state *cli;
6912 const char *dname = "\\testdir";
6913 const char *fname = "\\testdir\\testfile";
6914 NTSTATUS status;
6915 struct timespec create_time;
6916 struct timespec create_time1;
6917 uint16_t fnum;
6918 bool ret = false;
6920 if (!torture_open_connection(&cli, 0)) {
6921 return false;
6924 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6925 cli_rmdir(cli, dname);
6927 status = cli_mkdir(cli, dname);
6928 if (!NT_STATUS_IS_OK(status)) {
6929 printf("mkdir failed: %s\n", nt_errstr(status));
6930 goto out;
6933 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6934 NULL, NULL, NULL);
6935 if (!NT_STATUS_IS_OK(status)) {
6936 printf("cli_qpathinfo2 returned %s\n",
6937 nt_errstr(status));
6938 goto out;
6941 /* Sleep 3 seconds, then create a file. */
6942 sleep(3);
6944 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6945 DENY_NONE, &fnum);
6946 if (!NT_STATUS_IS_OK(status)) {
6947 printf("cli_open failed: %s\n", nt_errstr(status));
6948 goto out;
6951 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6952 NULL, NULL, NULL);
6953 if (!NT_STATUS_IS_OK(status)) {
6954 printf("cli_qpathinfo2 (2) returned %s\n",
6955 nt_errstr(status));
6956 goto out;
6959 if (timespec_compare(&create_time1, &create_time)) {
6960 printf("run_dir_createtime: create time was updated (error)\n");
6961 } else {
6962 printf("run_dir_createtime: create time was not updated (correct)\n");
6963 ret = true;
6966 out:
6968 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6969 cli_rmdir(cli, dname);
6970 if (!torture_close_connection(cli)) {
6971 ret = false;
6973 return ret;
6977 static bool run_streamerror(int dummy)
6979 struct cli_state *cli;
6980 const char *dname = "\\testdir";
6981 const char *streamname =
6982 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6983 NTSTATUS status;
6984 time_t change_time, access_time, write_time;
6985 SMB_OFF_T size;
6986 uint16_t mode, fnum;
6987 bool ret = true;
6989 if (!torture_open_connection(&cli, 0)) {
6990 return false;
6993 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6994 cli_rmdir(cli, dname);
6996 status = cli_mkdir(cli, dname);
6997 if (!NT_STATUS_IS_OK(status)) {
6998 printf("mkdir failed: %s\n", nt_errstr(status));
6999 return false;
7002 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7003 &size, &mode);
7004 status = cli_nt_error(cli);
7006 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7007 printf("pathinfo returned %s, expected "
7008 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7009 nt_errstr(status));
7010 ret = false;
7013 status = cli_ntcreate(cli, streamname, 0x16,
7014 FILE_READ_DATA|FILE_READ_EA|
7015 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7016 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7017 FILE_OPEN, 0, 0, &fnum);
7019 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7020 printf("ntcreate returned %s, expected "
7021 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7022 nt_errstr(status));
7023 ret = false;
7027 cli_rmdir(cli, dname);
7028 return ret;
7031 static bool run_local_substitute(int dummy)
7033 bool ok = true;
7035 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7036 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7037 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7038 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7039 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7040 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7041 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7042 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7044 /* Different captialization rules in sub_basic... */
7046 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7047 "blaDOM") == 0);
7049 return ok;
7052 static bool run_local_base64(int dummy)
7054 int i;
7055 bool ret = true;
7057 for (i=1; i<2000; i++) {
7058 DATA_BLOB blob1, blob2;
7059 char *b64;
7061 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7062 blob1.length = i;
7063 generate_random_buffer(blob1.data, blob1.length);
7065 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7066 if (b64 == NULL) {
7067 d_fprintf(stderr, "base64_encode_data_blob failed "
7068 "for %d bytes\n", i);
7069 ret = false;
7071 blob2 = base64_decode_data_blob(b64);
7072 TALLOC_FREE(b64);
7074 if (data_blob_cmp(&blob1, &blob2)) {
7075 d_fprintf(stderr, "data_blob_cmp failed for %d "
7076 "bytes\n", i);
7077 ret = false;
7079 TALLOC_FREE(blob1.data);
7080 data_blob_free(&blob2);
7082 return ret;
7085 static bool run_local_gencache(int dummy)
7087 char *val;
7088 time_t tm;
7089 DATA_BLOB blob;
7091 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7092 d_printf("%s: gencache_set() failed\n", __location__);
7093 return False;
7096 if (!gencache_get("foo", NULL, NULL)) {
7097 d_printf("%s: gencache_get() failed\n", __location__);
7098 return False;
7101 if (!gencache_get("foo", &val, &tm)) {
7102 d_printf("%s: gencache_get() failed\n", __location__);
7103 return False;
7106 if (strcmp(val, "bar") != 0) {
7107 d_printf("%s: gencache_get() returned %s, expected %s\n",
7108 __location__, val, "bar");
7109 SAFE_FREE(val);
7110 return False;
7113 SAFE_FREE(val);
7115 if (!gencache_del("foo")) {
7116 d_printf("%s: gencache_del() failed\n", __location__);
7117 return False;
7119 if (gencache_del("foo")) {
7120 d_printf("%s: second gencache_del() succeeded\n",
7121 __location__);
7122 return False;
7125 if (gencache_get("foo", &val, &tm)) {
7126 d_printf("%s: gencache_get() on deleted entry "
7127 "succeeded\n", __location__);
7128 return False;
7131 blob = data_blob_string_const_null("bar");
7132 tm = time(NULL) + 60;
7134 if (!gencache_set_data_blob("foo", &blob, tm)) {
7135 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7136 return False;
7139 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7140 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7141 return False;
7144 if (strcmp((const char *)blob.data, "bar") != 0) {
7145 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7146 __location__, (const char *)blob.data, "bar");
7147 data_blob_free(&blob);
7148 return False;
7151 data_blob_free(&blob);
7153 if (!gencache_del("foo")) {
7154 d_printf("%s: gencache_del() failed\n", __location__);
7155 return False;
7157 if (gencache_del("foo")) {
7158 d_printf("%s: second gencache_del() succeeded\n",
7159 __location__);
7160 return False;
7163 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7164 d_printf("%s: gencache_get_data_blob() on deleted entry "
7165 "succeeded\n", __location__);
7166 return False;
7169 return True;
7172 static bool rbt_testval(struct db_context *db, const char *key,
7173 const char *value)
7175 struct db_record *rec;
7176 TDB_DATA data = string_tdb_data(value);
7177 bool ret = false;
7178 NTSTATUS status;
7180 rec = db->fetch_locked(db, db, string_tdb_data(key));
7181 if (rec == NULL) {
7182 d_fprintf(stderr, "fetch_locked failed\n");
7183 goto done;
7185 status = rec->store(rec, data, 0);
7186 if (!NT_STATUS_IS_OK(status)) {
7187 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7188 goto done;
7190 TALLOC_FREE(rec);
7192 rec = db->fetch_locked(db, db, string_tdb_data(key));
7193 if (rec == NULL) {
7194 d_fprintf(stderr, "second fetch_locked failed\n");
7195 goto done;
7197 if ((rec->value.dsize != data.dsize)
7198 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7199 d_fprintf(stderr, "Got wrong data back\n");
7200 goto done;
7203 ret = true;
7204 done:
7205 TALLOC_FREE(rec);
7206 return ret;
7209 static bool run_local_rbtree(int dummy)
7211 struct db_context *db;
7212 bool ret = false;
7213 int i;
7215 db = db_open_rbt(NULL);
7217 if (db == NULL) {
7218 d_fprintf(stderr, "db_open_rbt failed\n");
7219 return false;
7222 for (i=0; i<1000; i++) {
7223 char *key, *value;
7225 if (asprintf(&key, "key%ld", random()) == -1) {
7226 goto done;
7228 if (asprintf(&value, "value%ld", random()) == -1) {
7229 SAFE_FREE(key);
7230 goto done;
7233 if (!rbt_testval(db, key, value)) {
7234 SAFE_FREE(key);
7235 SAFE_FREE(value);
7236 goto done;
7239 SAFE_FREE(value);
7240 if (asprintf(&value, "value%ld", random()) == -1) {
7241 SAFE_FREE(key);
7242 goto done;
7245 if (!rbt_testval(db, key, value)) {
7246 SAFE_FREE(key);
7247 SAFE_FREE(value);
7248 goto done;
7251 SAFE_FREE(key);
7252 SAFE_FREE(value);
7255 ret = true;
7257 done:
7258 TALLOC_FREE(db);
7259 return ret;
7262 struct talloc_dict_test {
7263 int content;
7266 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7268 int *count = (int *)priv;
7269 *count += 1;
7270 return 0;
7273 static bool run_local_talloc_dict(int dummy)
7275 struct talloc_dict *dict;
7276 struct talloc_dict_test *t;
7277 int key, count;
7279 dict = talloc_dict_init(talloc_tos());
7280 if (dict == NULL) {
7281 return false;
7284 t = talloc(talloc_tos(), struct talloc_dict_test);
7285 if (t == NULL) {
7286 return false;
7289 key = 1;
7290 t->content = 1;
7291 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7292 return false;
7295 count = 0;
7296 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7297 return false;
7300 if (count != 1) {
7301 return false;
7304 TALLOC_FREE(dict);
7306 return true;
7309 static bool run_local_string_to_sid(int dummy) {
7310 struct dom_sid sid;
7312 if (string_to_sid(&sid, "S--1-5-32-545")) {
7313 printf("allowing S--1-5-32-545\n");
7314 return false;
7316 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7317 printf("allowing S-1-5-32-+545\n");
7318 return false;
7320 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")) {
7321 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7322 return false;
7324 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7325 printf("allowing S-1-5-32-545-abc\n");
7326 return false;
7328 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7329 printf("could not parse S-1-5-32-545\n");
7330 return false;
7332 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7333 printf("mis-parsed S-1-5-32-545 as %s\n",
7334 sid_string_tos(&sid));
7335 return false;
7337 return true;
7340 static bool run_local_binary_to_sid(int dummy) {
7341 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7342 static const char good_binary_sid[] = {
7343 0x1, /* revision number */
7344 15, /* num auths */
7345 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7346 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7347 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7348 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7349 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7350 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7351 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7352 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7353 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7354 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7355 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7356 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7357 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7358 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7359 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7360 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7363 static const char long_binary_sid[] = {
7364 0x1, /* revision number */
7365 15, /* num auths */
7366 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7367 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7368 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7369 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7370 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7371 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7372 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7373 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7374 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7375 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7376 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7377 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7378 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7379 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7380 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7381 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7382 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7383 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7384 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7387 static const char long_binary_sid2[] = {
7388 0x1, /* revision number */
7389 32, /* num auths */
7390 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7391 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7392 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7393 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7394 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7395 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7396 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7397 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7398 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7399 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7400 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7401 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7402 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7403 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7404 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7405 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7406 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7407 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7408 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7409 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7410 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7411 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7412 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7413 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7414 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7415 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7416 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7417 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7418 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7419 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7420 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7421 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7422 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7425 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7426 return false;
7428 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7429 return false;
7431 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7432 return false;
7434 return true;
7437 /* Split a path name into filename and stream name components. Canonicalise
7438 * such that an implicit $DATA token is always explicit.
7440 * The "specification" of this function can be found in the
7441 * run_local_stream_name() function in torture.c, I've tried those
7442 * combinations against a W2k3 server.
7445 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7446 char **pbase, char **pstream)
7448 char *base = NULL;
7449 char *stream = NULL;
7450 char *sname; /* stream name */
7451 const char *stype; /* stream type */
7453 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7455 sname = strchr_m(fname, ':');
7457 if (lp_posix_pathnames() || (sname == NULL)) {
7458 if (pbase != NULL) {
7459 base = talloc_strdup(mem_ctx, fname);
7460 NT_STATUS_HAVE_NO_MEMORY(base);
7462 goto done;
7465 if (pbase != NULL) {
7466 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7467 NT_STATUS_HAVE_NO_MEMORY(base);
7470 sname += 1;
7472 stype = strchr_m(sname, ':');
7474 if (stype == NULL) {
7475 sname = talloc_strdup(mem_ctx, sname);
7476 stype = "$DATA";
7478 else {
7479 if (StrCaseCmp(stype, ":$DATA") != 0) {
7481 * If there is an explicit stream type, so far we only
7482 * allow $DATA. Is there anything else allowed? -- vl
7484 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7485 TALLOC_FREE(base);
7486 return NT_STATUS_OBJECT_NAME_INVALID;
7488 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7489 stype += 1;
7492 if (sname == NULL) {
7493 TALLOC_FREE(base);
7494 return NT_STATUS_NO_MEMORY;
7497 if (sname[0] == '\0') {
7499 * no stream name, so no stream
7501 goto done;
7504 if (pstream != NULL) {
7505 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7506 if (stream == NULL) {
7507 TALLOC_FREE(sname);
7508 TALLOC_FREE(base);
7509 return NT_STATUS_NO_MEMORY;
7512 * upper-case the type field
7514 strupper_m(strchr_m(stream, ':')+1);
7517 done:
7518 if (pbase != NULL) {
7519 *pbase = base;
7521 if (pstream != NULL) {
7522 *pstream = stream;
7524 return NT_STATUS_OK;
7527 static bool test_stream_name(const char *fname, const char *expected_base,
7528 const char *expected_stream,
7529 NTSTATUS expected_status)
7531 NTSTATUS status;
7532 char *base = NULL;
7533 char *stream = NULL;
7535 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7536 if (!NT_STATUS_EQUAL(status, expected_status)) {
7537 goto error;
7540 if (!NT_STATUS_IS_OK(status)) {
7541 return true;
7544 if (base == NULL) goto error;
7546 if (strcmp(expected_base, base) != 0) goto error;
7548 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7549 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7551 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7552 goto error;
7554 TALLOC_FREE(base);
7555 TALLOC_FREE(stream);
7556 return true;
7558 error:
7559 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7560 fname, expected_base ? expected_base : "<NULL>",
7561 expected_stream ? expected_stream : "<NULL>",
7562 nt_errstr(expected_status));
7563 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7564 base ? base : "<NULL>", stream ? stream : "<NULL>",
7565 nt_errstr(status));
7566 TALLOC_FREE(base);
7567 TALLOC_FREE(stream);
7568 return false;
7571 static bool run_local_stream_name(int dummy)
7573 bool ret = true;
7575 ret &= test_stream_name(
7576 "bla", "bla", NULL, NT_STATUS_OK);
7577 ret &= test_stream_name(
7578 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7579 ret &= test_stream_name(
7580 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7581 ret &= test_stream_name(
7582 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7583 ret &= test_stream_name(
7584 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7585 ret &= test_stream_name(
7586 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7587 ret &= test_stream_name(
7588 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7589 ret &= test_stream_name(
7590 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7592 return ret;
7595 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7597 if (a.length != b.length) {
7598 printf("a.length=%d != b.length=%d\n",
7599 (int)a.length, (int)b.length);
7600 return false;
7602 if (memcmp(a.data, b.data, a.length) != 0) {
7603 printf("a.data and b.data differ\n");
7604 return false;
7606 return true;
7609 static bool run_local_memcache(int dummy)
7611 struct memcache *cache;
7612 DATA_BLOB k1, k2;
7613 DATA_BLOB d1, d2, d3;
7614 DATA_BLOB v1, v2, v3;
7616 TALLOC_CTX *mem_ctx;
7617 char *str1, *str2;
7618 size_t size1, size2;
7619 bool ret = false;
7621 cache = memcache_init(NULL, 100);
7623 if (cache == NULL) {
7624 printf("memcache_init failed\n");
7625 return false;
7628 d1 = data_blob_const("d1", 2);
7629 d2 = data_blob_const("d2", 2);
7630 d3 = data_blob_const("d3", 2);
7632 k1 = data_blob_const("d1", 2);
7633 k2 = data_blob_const("d2", 2);
7635 memcache_add(cache, STAT_CACHE, k1, d1);
7636 memcache_add(cache, GETWD_CACHE, k2, d2);
7638 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7639 printf("could not find k1\n");
7640 return false;
7642 if (!data_blob_equal(d1, v1)) {
7643 return false;
7646 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7647 printf("could not find k2\n");
7648 return false;
7650 if (!data_blob_equal(d2, v2)) {
7651 return false;
7654 memcache_add(cache, STAT_CACHE, k1, d3);
7656 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7657 printf("could not find replaced k1\n");
7658 return false;
7660 if (!data_blob_equal(d3, v3)) {
7661 return false;
7664 memcache_add(cache, GETWD_CACHE, k1, d1);
7666 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7667 printf("Did find k2, should have been purged\n");
7668 return false;
7671 TALLOC_FREE(cache);
7673 cache = memcache_init(NULL, 0);
7675 mem_ctx = talloc_init("foo");
7677 str1 = talloc_strdup(mem_ctx, "string1");
7678 str2 = talloc_strdup(mem_ctx, "string2");
7680 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7681 data_blob_string_const("torture"), &str1);
7682 size1 = talloc_total_size(cache);
7684 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7685 data_blob_string_const("torture"), &str2);
7686 size2 = talloc_total_size(cache);
7688 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7690 if (size2 > size1) {
7691 printf("memcache leaks memory!\n");
7692 goto fail;
7695 ret = true;
7696 fail:
7697 TALLOC_FREE(cache);
7698 return ret;
7701 static void wbclient_done(struct tevent_req *req)
7703 wbcErr wbc_err;
7704 struct winbindd_response *wb_resp;
7705 int *i = (int *)tevent_req_callback_data_void(req);
7707 wbc_err = wb_trans_recv(req, req, &wb_resp);
7708 TALLOC_FREE(req);
7709 *i += 1;
7710 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7713 static bool run_local_wbclient(int dummy)
7715 struct event_context *ev;
7716 struct wb_context **wb_ctx;
7717 struct winbindd_request wb_req;
7718 bool result = false;
7719 int i, j;
7721 BlockSignals(True, SIGPIPE);
7723 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7724 if (ev == NULL) {
7725 goto fail;
7728 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7729 if (wb_ctx == NULL) {
7730 goto fail;
7733 ZERO_STRUCT(wb_req);
7734 wb_req.cmd = WINBINDD_PING;
7736 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7738 for (i=0; i<nprocs; i++) {
7739 wb_ctx[i] = wb_context_init(ev, NULL);
7740 if (wb_ctx[i] == NULL) {
7741 goto fail;
7743 for (j=0; j<torture_numops; j++) {
7744 struct tevent_req *req;
7745 req = wb_trans_send(ev, ev, wb_ctx[i],
7746 (j % 2) == 0, &wb_req);
7747 if (req == NULL) {
7748 goto fail;
7750 tevent_req_set_callback(req, wbclient_done, &i);
7754 i = 0;
7756 while (i < nprocs * torture_numops) {
7757 event_loop_once(ev);
7760 result = true;
7761 fail:
7762 TALLOC_FREE(ev);
7763 return result;
7766 static void getaddrinfo_finished(struct tevent_req *req)
7768 char *name = (char *)tevent_req_callback_data_void(req);
7769 struct addrinfo *ainfo;
7770 int res;
7772 res = getaddrinfo_recv(req, &ainfo);
7773 if (res != 0) {
7774 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7775 return;
7777 d_printf("gai(%s) succeeded\n", name);
7778 freeaddrinfo(ainfo);
7781 static bool run_getaddrinfo_send(int dummy)
7783 TALLOC_CTX *frame = talloc_stackframe();
7784 struct fncall_context *ctx;
7785 struct tevent_context *ev;
7786 bool result = false;
7787 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7788 "www.slashdot.org", "heise.de" };
7789 struct tevent_req *reqs[4];
7790 int i;
7792 ev = event_context_init(frame);
7793 if (ev == NULL) {
7794 goto fail;
7797 ctx = fncall_context_init(frame, 4);
7799 for (i=0; i<ARRAY_SIZE(names); i++) {
7800 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7801 NULL);
7802 if (reqs[i] == NULL) {
7803 goto fail;
7805 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7806 (void *)names[i]);
7809 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7810 tevent_loop_once(ev);
7813 result = true;
7814 fail:
7815 TALLOC_FREE(frame);
7816 return result;
7819 static bool dbtrans_inc(struct db_context *db)
7821 struct db_record *rec;
7822 uint32_t *val;
7823 bool ret = false;
7824 NTSTATUS status;
7826 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7827 if (rec == NULL) {
7828 printf(__location__ "fetch_lock failed\n");
7829 return false;
7832 if (rec->value.dsize != sizeof(uint32_t)) {
7833 printf(__location__ "value.dsize = %d\n",
7834 (int)rec->value.dsize);
7835 goto fail;
7838 val = (uint32_t *)rec->value.dptr;
7839 *val += 1;
7841 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7842 sizeof(uint32_t)),
7844 if (!NT_STATUS_IS_OK(status)) {
7845 printf(__location__ "store failed: %s\n",
7846 nt_errstr(status));
7847 goto fail;
7850 ret = true;
7851 fail:
7852 TALLOC_FREE(rec);
7853 return ret;
7856 static bool run_local_dbtrans(int dummy)
7858 struct db_context *db;
7859 struct db_record *rec;
7860 NTSTATUS status;
7861 uint32_t initial;
7862 int res;
7864 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7865 O_RDWR|O_CREAT, 0600);
7866 if (db == NULL) {
7867 printf("Could not open transtest.db\n");
7868 return false;
7871 res = db->transaction_start(db);
7872 if (res == -1) {
7873 printf(__location__ "transaction_start failed\n");
7874 return false;
7877 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7878 if (rec == NULL) {
7879 printf(__location__ "fetch_lock failed\n");
7880 return false;
7883 if (rec->value.dptr == NULL) {
7884 initial = 0;
7885 status = rec->store(
7886 rec, make_tdb_data((uint8_t *)&initial,
7887 sizeof(initial)),
7889 if (!NT_STATUS_IS_OK(status)) {
7890 printf(__location__ "store returned %s\n",
7891 nt_errstr(status));
7892 return false;
7896 TALLOC_FREE(rec);
7898 res = db->transaction_commit(db);
7899 if (res == -1) {
7900 printf(__location__ "transaction_commit failed\n");
7901 return false;
7904 while (true) {
7905 uint32_t val, val2;
7906 int i;
7908 res = db->transaction_start(db);
7909 if (res == -1) {
7910 printf(__location__ "transaction_start failed\n");
7911 break;
7914 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7915 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7916 break;
7919 for (i=0; i<10; i++) {
7920 if (!dbtrans_inc(db)) {
7921 return false;
7925 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7926 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7927 break;
7930 if (val2 != val + 10) {
7931 printf(__location__ "val=%d, val2=%d\n",
7932 (int)val, (int)val2);
7933 break;
7936 printf("val2=%d\r", val2);
7938 res = db->transaction_commit(db);
7939 if (res == -1) {
7940 printf(__location__ "transaction_commit failed\n");
7941 break;
7945 TALLOC_FREE(db);
7946 return true;
7950 * Just a dummy test to be run under a debugger. There's no real way
7951 * to inspect the tevent_select specific function from outside of
7952 * tevent_select.c.
7955 static bool run_local_tevent_select(int dummy)
7957 struct tevent_context *ev;
7958 struct tevent_fd *fd1, *fd2;
7959 bool result = false;
7961 ev = tevent_context_init_byname(NULL, "select");
7962 if (ev == NULL) {
7963 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7964 goto fail;
7967 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7968 if (fd1 == NULL) {
7969 d_fprintf(stderr, "tevent_add_fd failed\n");
7970 goto fail;
7972 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7973 if (fd2 == NULL) {
7974 d_fprintf(stderr, "tevent_add_fd failed\n");
7975 goto fail;
7977 TALLOC_FREE(fd2);
7979 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7980 if (fd2 == NULL) {
7981 d_fprintf(stderr, "tevent_add_fd failed\n");
7982 goto fail;
7985 result = true;
7986 fail:
7987 TALLOC_FREE(ev);
7988 return result;
7991 static double create_procs(bool (*fn)(int), bool *result)
7993 int i, status;
7994 volatile pid_t *child_status;
7995 volatile bool *child_status_out;
7996 int synccount;
7997 int tries = 8;
7998 struct timeval start;
8000 synccount = 0;
8002 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8003 if (!child_status) {
8004 printf("Failed to setup shared memory\n");
8005 return -1;
8008 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8009 if (!child_status_out) {
8010 printf("Failed to setup result status shared memory\n");
8011 return -1;
8014 for (i = 0; i < nprocs; i++) {
8015 child_status[i] = 0;
8016 child_status_out[i] = True;
8019 start = timeval_current();
8021 for (i=0;i<nprocs;i++) {
8022 procnum = i;
8023 if (fork() == 0) {
8024 pid_t mypid = getpid();
8025 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8027 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8029 while (1) {
8030 if (torture_open_connection(&current_cli, i)) break;
8031 if (tries-- == 0) {
8032 printf("pid %d failed to start\n", (int)getpid());
8033 _exit(1);
8035 smb_msleep(10);
8038 child_status[i] = getpid();
8040 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8042 child_status_out[i] = fn(i);
8043 _exit(0);
8047 do {
8048 synccount = 0;
8049 for (i=0;i<nprocs;i++) {
8050 if (child_status[i]) synccount++;
8052 if (synccount == nprocs) break;
8053 smb_msleep(10);
8054 } while (timeval_elapsed(&start) < 30);
8056 if (synccount != nprocs) {
8057 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8058 *result = False;
8059 return timeval_elapsed(&start);
8062 /* start the client load */
8063 start = timeval_current();
8065 for (i=0;i<nprocs;i++) {
8066 child_status[i] = 0;
8069 printf("%d clients started\n", nprocs);
8071 for (i=0;i<nprocs;i++) {
8072 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8075 printf("\n");
8077 for (i=0;i<nprocs;i++) {
8078 if (!child_status_out[i]) {
8079 *result = False;
8082 return timeval_elapsed(&start);
8085 #define FLAG_MULTIPROC 1
8087 static struct {
8088 const char *name;
8089 bool (*fn)(int);
8090 unsigned flags;
8091 } torture_ops[] = {
8092 {"FDPASS", run_fdpasstest, 0},
8093 {"LOCK1", run_locktest1, 0},
8094 {"LOCK2", run_locktest2, 0},
8095 {"LOCK3", run_locktest3, 0},
8096 {"LOCK4", run_locktest4, 0},
8097 {"LOCK5", run_locktest5, 0},
8098 {"LOCK6", run_locktest6, 0},
8099 {"LOCK7", run_locktest7, 0},
8100 {"LOCK8", run_locktest8, 0},
8101 {"LOCK9", run_locktest9, 0},
8102 {"UNLINK", run_unlinktest, 0},
8103 {"BROWSE", run_browsetest, 0},
8104 {"ATTR", run_attrtest, 0},
8105 {"TRANS2", run_trans2test, 0},
8106 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8107 {"TORTURE",run_torture, FLAG_MULTIPROC},
8108 {"RANDOMIPC", run_randomipc, 0},
8109 {"NEGNOWAIT", run_negprot_nowait, 0},
8110 {"NBENCH", run_nbench, 0},
8111 {"NBENCH2", run_nbench2, 0},
8112 {"OPLOCK1", run_oplock1, 0},
8113 {"OPLOCK2", run_oplock2, 0},
8114 {"OPLOCK3", run_oplock3, 0},
8115 {"OPLOCK4", run_oplock4, 0},
8116 {"DIR", run_dirtest, 0},
8117 {"DIR1", run_dirtest1, 0},
8118 {"DIR-CREATETIME", run_dir_createtime, 0},
8119 {"DENY1", torture_denytest1, 0},
8120 {"DENY2", torture_denytest2, 0},
8121 {"TCON", run_tcon_test, 0},
8122 {"TCONDEV", run_tcon_devtype_test, 0},
8123 {"RW1", run_readwritetest, 0},
8124 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8125 {"RW3", run_readwritelarge, 0},
8126 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8127 {"OPEN", run_opentest, 0},
8128 {"POSIX", run_simple_posix_open_test, 0},
8129 {"POSIX-APPEND", run_posix_append, 0},
8130 {"ASYNC-ECHO", run_async_echo, 0},
8131 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8132 { "SHORTNAME-TEST", run_shortname_test, 0},
8133 { "ADDRCHANGE", run_addrchange, 0},
8134 #if 1
8135 {"OPENATTR", run_openattrtest, 0},
8136 #endif
8137 {"XCOPY", run_xcopy, 0},
8138 {"RENAME", run_rename, 0},
8139 {"DELETE", run_deletetest, 0},
8140 {"DELETE-LN", run_deletetest_ln, 0},
8141 {"PROPERTIES", run_properties, 0},
8142 {"MANGLE", torture_mangle, 0},
8143 {"MANGLE1", run_mangle1, 0},
8144 {"W2K", run_w2ktest, 0},
8145 {"TRANS2SCAN", torture_trans2_scan, 0},
8146 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8147 {"UTABLE", torture_utable, 0},
8148 {"CASETABLE", torture_casetable, 0},
8149 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8150 {"PIPE_NUMBER", run_pipe_number, 0},
8151 {"TCON2", run_tcon2_test, 0},
8152 {"IOCTL", torture_ioctl_test, 0},
8153 {"CHKPATH", torture_chkpath_test, 0},
8154 {"FDSESS", run_fdsesstest, 0},
8155 { "EATEST", run_eatest, 0},
8156 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8157 { "CHAIN1", run_chain1, 0},
8158 { "CHAIN2", run_chain2, 0},
8159 { "WINDOWS-WRITE", run_windows_write, 0},
8160 { "CLI_ECHO", run_cli_echo, 0},
8161 { "GETADDRINFO", run_getaddrinfo_send, 0},
8162 { "TLDAP", run_tldap },
8163 { "STREAMERROR", run_streamerror },
8164 { "NOTIFY-BENCH", run_notify_bench },
8165 { "BAD-NBT-SESSION", run_bad_nbt_session },
8166 { "SMB-ANY-CONNECT", run_smb_any_connect },
8167 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8168 { "LOCAL-GENCACHE", run_local_gencache, 0},
8169 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8170 { "LOCAL-BASE64", run_local_base64, 0},
8171 { "LOCAL-RBTREE", run_local_rbtree, 0},
8172 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8173 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8174 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8175 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8176 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8177 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8178 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8179 {NULL, NULL, 0}};
8183 /****************************************************************************
8184 run a specified test or "ALL"
8185 ****************************************************************************/
8186 static bool run_test(const char *name)
8188 bool ret = True;
8189 bool result = True;
8190 bool found = False;
8191 int i;
8192 double t;
8193 if (strequal(name,"ALL")) {
8194 for (i=0;torture_ops[i].name;i++) {
8195 run_test(torture_ops[i].name);
8197 found = True;
8200 for (i=0;torture_ops[i].name;i++) {
8201 fstr_sprintf(randomfname, "\\XX%x",
8202 (unsigned)random());
8204 if (strequal(name, torture_ops[i].name)) {
8205 found = True;
8206 printf("Running %s\n", name);
8207 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8208 t = create_procs(torture_ops[i].fn, &result);
8209 if (!result) {
8210 ret = False;
8211 printf("TEST %s FAILED!\n", name);
8213 } else {
8214 struct timeval start;
8215 start = timeval_current();
8216 if (!torture_ops[i].fn(0)) {
8217 ret = False;
8218 printf("TEST %s FAILED!\n", name);
8220 t = timeval_elapsed(&start);
8222 printf("%s took %g secs\n\n", name, t);
8226 if (!found) {
8227 printf("Did not find a test named %s\n", name);
8228 ret = False;
8231 return ret;
8235 static void usage(void)
8237 int i;
8239 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8240 printf("Please use samba4 torture.\n\n");
8242 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8244 printf("\t-d debuglevel\n");
8245 printf("\t-U user%%pass\n");
8246 printf("\t-k use kerberos\n");
8247 printf("\t-N numprocs\n");
8248 printf("\t-n my_netbios_name\n");
8249 printf("\t-W workgroup\n");
8250 printf("\t-o num_operations\n");
8251 printf("\t-O socket_options\n");
8252 printf("\t-m maximum protocol\n");
8253 printf("\t-L use oplocks\n");
8254 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8255 printf("\t-A showall\n");
8256 printf("\t-p port\n");
8257 printf("\t-s seed\n");
8258 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8259 printf("\n\n");
8261 printf("tests are:");
8262 for (i=0;torture_ops[i].name;i++) {
8263 printf(" %s", torture_ops[i].name);
8265 printf("\n");
8267 printf("default test is ALL\n");
8269 exit(1);
8272 /****************************************************************************
8273 main program
8274 ****************************************************************************/
8275 int main(int argc,char *argv[])
8277 int opt, i;
8278 char *p;
8279 int gotuser = 0;
8280 int gotpass = 0;
8281 bool correct = True;
8282 TALLOC_CTX *frame = talloc_stackframe();
8283 int seed = time(NULL);
8285 #ifdef HAVE_SETBUFFER
8286 setbuffer(stdout, NULL, 0);
8287 #endif
8289 setup_logging("smbtorture", DEBUG_STDOUT);
8291 load_case_tables();
8293 if (is_default_dyn_CONFIGFILE()) {
8294 if(getenv("SMB_CONF_PATH")) {
8295 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8298 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8299 load_interfaces();
8301 if (argc < 2) {
8302 usage();
8305 for(p = argv[1]; *p; p++)
8306 if(*p == '\\')
8307 *p = '/';
8309 if (strncmp(argv[1], "//", 2)) {
8310 usage();
8313 fstrcpy(host, &argv[1][2]);
8314 p = strchr_m(&host[2],'/');
8315 if (!p) {
8316 usage();
8318 *p = 0;
8319 fstrcpy(share, p+1);
8321 fstrcpy(myname, get_myname(talloc_tos()));
8322 if (!*myname) {
8323 fprintf(stderr, "Failed to get my hostname.\n");
8324 return 1;
8327 if (*username == 0 && getenv("LOGNAME")) {
8328 fstrcpy(username,getenv("LOGNAME"));
8331 argc--;
8332 argv++;
8334 fstrcpy(workgroup, lp_workgroup());
8336 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8337 switch (opt) {
8338 case 'p':
8339 port_to_use = atoi(optarg);
8340 break;
8341 case 's':
8342 seed = atoi(optarg);
8343 break;
8344 case 'W':
8345 fstrcpy(workgroup,optarg);
8346 break;
8347 case 'm':
8348 max_protocol = interpret_protocol(optarg, max_protocol);
8349 break;
8350 case 'N':
8351 nprocs = atoi(optarg);
8352 break;
8353 case 'o':
8354 torture_numops = atoi(optarg);
8355 break;
8356 case 'd':
8357 lp_set_cmdline("log level", optarg);
8358 break;
8359 case 'O':
8360 sockops = optarg;
8361 break;
8362 case 'L':
8363 use_oplocks = True;
8364 break;
8365 case 'l':
8366 local_path = optarg;
8367 break;
8368 case 'A':
8369 torture_showall = True;
8370 break;
8371 case 'n':
8372 fstrcpy(myname, optarg);
8373 break;
8374 case 'c':
8375 client_txt = optarg;
8376 break;
8377 case 'e':
8378 do_encrypt = true;
8379 break;
8380 case 'k':
8381 #ifdef HAVE_KRB5
8382 use_kerberos = True;
8383 #else
8384 d_printf("No kerberos support compiled in\n");
8385 exit(1);
8386 #endif
8387 break;
8388 case 'U':
8389 gotuser = 1;
8390 fstrcpy(username,optarg);
8391 p = strchr_m(username,'%');
8392 if (p) {
8393 *p = 0;
8394 fstrcpy(password, p+1);
8395 gotpass = 1;
8397 break;
8398 case 'b':
8399 fstrcpy(multishare_conn_fname, optarg);
8400 use_multishare_conn = True;
8401 break;
8402 case 'B':
8403 torture_blocksize = atoi(optarg);
8404 break;
8405 default:
8406 printf("Unknown option %c (%d)\n", (char)opt, opt);
8407 usage();
8411 d_printf("using seed %d\n", seed);
8413 srandom(seed);
8415 if(use_kerberos && !gotuser) gotpass = True;
8417 while (!gotpass) {
8418 p = getpass("Password:");
8419 if (p) {
8420 fstrcpy(password, p);
8421 gotpass = 1;
8425 printf("host=%s share=%s user=%s myname=%s\n",
8426 host, share, username, myname);
8428 if (argc == optind) {
8429 correct = run_test("ALL");
8430 } else {
8431 for (i=optind;i<argc;i++) {
8432 if (!run_test(argv[i])) {
8433 correct = False;
8438 TALLOC_FREE(frame);
8440 if (correct) {
8441 return(0);
8442 } else {
8443 return(1);