s3-rpc_server: Added a winreg based svcctl registry init.
[Samba.git] / source3 / torture / torture.c
blob48eb708a70f17141caa2a7be0c4efc31073f69ff
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 "wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/security.h"
25 #include "tldap.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
28 #include "memcache.h"
29 #include "nsswitch/winbind_client.h"
30 #include "dbwrap.h"
31 #include "talloc_dict.h"
32 #include "async_smb.h"
34 extern char *optarg;
35 extern int optind;
37 static fstring host, workgroup, share, password, username, myname;
38 static int max_protocol = PROTOCOL_NT1;
39 static const char *sockops="TCP_NODELAY";
40 static int nprocs=1;
41 static int port_to_use=0;
42 int torture_numops=100;
43 int torture_blocksize=1024*1024;
44 static int procnum; /* records process count number when forking */
45 static struct cli_state *current_cli;
46 static fstring randomfname;
47 static bool use_oplocks;
48 static bool use_level_II_oplocks;
49 static const char *client_txt = "client_oplocks.txt";
50 static bool use_kerberos;
51 static fstring multishare_conn_fname;
52 static bool use_multishare_conn = False;
53 static bool do_encrypt;
54 static const char *local_path = NULL;
55 static int signing_state = Undefined;
57 bool torture_showall = False;
59 static double create_procs(bool (*fn)(int), bool *result);
62 /* return a pointer to a anonymous shared memory segment of size "size"
63 which will persist across fork() but will disappear when all processes
64 exit
66 The memory is not zeroed
68 This function uses system5 shared memory. It takes advantage of a property
69 that the memory is not destroyed if it is attached when the id is removed
71 void *shm_setup(int size)
73 int shmid;
74 void *ret;
76 #ifdef __QNXNTO__
77 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
78 if (shmid == -1) {
79 printf("can't get shared memory\n");
80 exit(1);
82 shm_unlink("private");
83 if (ftruncate(shmid, size) == -1) {
84 printf("can't set shared memory size\n");
85 exit(1);
87 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
88 if (ret == MAP_FAILED) {
89 printf("can't map shared memory\n");
90 exit(1);
92 #else
93 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
94 if (shmid == -1) {
95 printf("can't get shared memory\n");
96 exit(1);
98 ret = (void *)shmat(shmid, 0, 0);
99 if (!ret || ret == (void *)-1) {
100 printf("can't attach to shared memory\n");
101 return NULL;
103 /* the following releases the ipc, but note that this process
104 and all its children will still have access to the memory, its
105 just that the shmid is no longer valid for other shm calls. This
106 means we don't leave behind lots of shm segments after we exit
108 See Stevens "advanced programming in unix env" for details
110 shmctl(shmid, IPC_RMID, 0);
111 #endif
113 return ret;
116 /********************************************************************
117 Ensure a connection is encrypted.
118 ********************************************************************/
120 static bool force_cli_encryption(struct cli_state *c,
121 const char *sharename)
123 uint16 major, minor;
124 uint32 caplow, caphigh;
125 NTSTATUS status;
127 if (!SERVER_HAS_UNIX_CIFS(c)) {
128 d_printf("Encryption required and "
129 "server that doesn't support "
130 "UNIX extensions - failing connect\n");
131 return false;
134 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
135 &caphigh);
136 if (!NT_STATUS_IS_OK(status)) {
137 d_printf("Encryption required and "
138 "can't get UNIX CIFS extensions "
139 "version from server: %s\n", nt_errstr(status));
140 return false;
143 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
144 d_printf("Encryption required and "
145 "share %s doesn't support "
146 "encryption.\n", sharename);
147 return false;
150 if (c->use_kerberos) {
151 status = cli_gss_smb_encryption_start(c);
152 } else {
153 status = cli_raw_ntlm_smb_encryption_start(c,
154 username,
155 password,
156 workgroup);
159 if (!NT_STATUS_IS_OK(status)) {
160 d_printf("Encryption required and "
161 "setup failed with error %s.\n",
162 nt_errstr(status));
163 return false;
166 return true;
170 static struct cli_state *open_nbt_connection(void)
172 struct nmb_name called, calling;
173 struct sockaddr_storage ss;
174 struct cli_state *c;
175 NTSTATUS status;
177 make_nmb_name(&calling, myname, 0x0);
178 make_nmb_name(&called , host, 0x20);
180 zero_sockaddr(&ss);
182 if (!(c = cli_initialise_ex(signing_state))) {
183 printf("Failed initialize cli_struct to connect with %s\n", host);
184 return NULL;
187 c->port = port_to_use;
189 status = cli_connect(c, host, &ss);
190 if (!NT_STATUS_IS_OK(status)) {
191 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
192 return NULL;
195 c->use_kerberos = use_kerberos;
197 c->timeout = 120000; /* set a really long timeout (2 minutes) */
198 if (use_oplocks) c->use_oplocks = True;
199 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
201 if (!cli_session_request(c, &calling, &called)) {
203 * Well, that failed, try *SMBSERVER ...
204 * However, we must reconnect as well ...
206 status = cli_connect(c, host, &ss);
207 if (!NT_STATUS_IS_OK(status)) {
208 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
209 return NULL;
212 make_nmb_name(&called, "*SMBSERVER", 0x20);
213 if (!cli_session_request(c, &calling, &called)) {
214 printf("%s rejected the session\n",host);
215 printf("We tried with a called name of %s & %s\n",
216 host, "*SMBSERVER");
217 cli_shutdown(c);
218 return NULL;
222 return c;
225 /****************************************************************************
226 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
227 ****************************************************************************/
229 static bool cli_bad_session_request(struct cli_state *cli,
230 struct nmb_name *calling, struct nmb_name *called)
232 char *p;
233 int len = 4;
234 int namelen = 0;
235 char *tmp;
237 memcpy(&(cli->calling), calling, sizeof(*calling));
238 memcpy(&(cli->called ), called , sizeof(*called ));
240 /* put in the destination name */
242 tmp = name_mangle(talloc_tos(), cli->called.name,
243 cli->called.name_type);
244 if (tmp == NULL) {
245 return false;
248 p = cli->outbuf+len;
249 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
250 if (namelen > 0) {
251 memcpy(p, tmp, namelen);
252 len += namelen;
254 TALLOC_FREE(tmp);
256 /* Deliberately corrupt the name len (first byte) */
257 *p = 100;
259 /* and my name */
261 tmp = name_mangle(talloc_tos(), cli->calling.name,
262 cli->calling.name_type);
263 if (tmp == NULL) {
264 return false;
267 p = cli->outbuf+len;
268 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
269 if (namelen > 0) {
270 memcpy(p, tmp, namelen);
271 len += namelen;
273 TALLOC_FREE(tmp);
274 /* Deliberately corrupt the name len (first byte) */
275 *p = 100;
277 /* send a session request (RFC 1002) */
278 /* setup the packet length
279 * Remove four bytes from the length count, since the length
280 * field in the NBT Session Service header counts the number
281 * of bytes which follow. The cli_send_smb() function knows
282 * about this and accounts for those four bytes.
283 * CRH.
285 len -= 4;
286 _smb_setlen(cli->outbuf,len);
287 SCVAL(cli->outbuf,0,0x81);
289 cli_send_smb(cli);
290 DEBUG(5,("Sent session request\n"));
292 if (!cli_receive_smb(cli))
293 return False;
295 if (CVAL(cli->inbuf,0) != 0x82) {
296 /* This is the wrong place to put the error... JRA. */
297 cli->rap_error = CVAL(cli->inbuf,4);
298 return False;
300 return(True);
303 static struct cli_state *open_bad_nbt_connection(void)
305 struct nmb_name called, calling;
306 struct sockaddr_storage ss;
307 struct cli_state *c;
308 NTSTATUS status;
310 make_nmb_name(&calling, myname, 0x0);
311 make_nmb_name(&called , host, 0x20);
313 zero_sockaddr(&ss);
315 if (!(c = cli_initialise_ex(signing_state))) {
316 printf("Failed initialize cli_struct to connect with %s\n", host);
317 return NULL;
320 c->port = 139;
322 status = cli_connect(c, host, &ss);
323 if (!NT_STATUS_IS_OK(status)) {
324 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
325 return NULL;
328 c->timeout = 4000; /* set a short timeout (4 seconds) */
330 if (!cli_bad_session_request(c, &calling, &called)) {
331 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
332 return NULL;
335 return c;
339 /* Insert a NULL at the first separator of the given path and return a pointer
340 * to the remainder of the string.
342 static char *
343 terminate_path_at_separator(char * path)
345 char * p;
347 if (!path) {
348 return NULL;
351 if ((p = strchr_m(path, '/'))) {
352 *p = '\0';
353 return p + 1;
356 if ((p = strchr_m(path, '\\'))) {
357 *p = '\0';
358 return p + 1;
361 /* No separator. */
362 return NULL;
366 parse a //server/share type UNC name
368 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
369 char **hostname, char **sharename)
371 char *p;
373 *hostname = *sharename = NULL;
375 if (strncmp(unc_name, "\\\\", 2) &&
376 strncmp(unc_name, "//", 2)) {
377 return False;
380 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
381 p = terminate_path_at_separator(*hostname);
383 if (p && *p) {
384 *sharename = talloc_strdup(mem_ctx, p);
385 terminate_path_at_separator(*sharename);
388 if (*hostname && *sharename) {
389 return True;
392 TALLOC_FREE(*hostname);
393 TALLOC_FREE(*sharename);
394 return False;
397 static bool torture_open_connection_share(struct cli_state **c,
398 const char *hostname,
399 const char *sharename)
401 int flags = 0;
402 NTSTATUS status;
404 if (use_kerberos)
405 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
406 if (use_oplocks)
407 flags |= CLI_FULL_CONNECTION_OPLOCKS;
408 if (use_level_II_oplocks)
409 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
411 status = cli_full_connection(c, myname,
412 hostname, NULL, port_to_use,
413 sharename, "?????",
414 username, workgroup,
415 password, flags, signing_state);
416 if (!NT_STATUS_IS_OK(status)) {
417 printf("failed to open share connection: //%s/%s port:%d - %s\n",
418 hostname, sharename, port_to_use, nt_errstr(status));
419 return False;
422 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
424 if (do_encrypt) {
425 return force_cli_encryption(*c,
426 sharename);
428 return True;
431 bool torture_open_connection(struct cli_state **c, int conn_index)
433 char **unc_list = NULL;
434 int num_unc_names = 0;
435 bool result;
437 if (use_multishare_conn==True) {
438 char *h, *s;
439 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
440 if (!unc_list || num_unc_names <= 0) {
441 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
442 exit(1);
445 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
446 NULL, &h, &s)) {
447 printf("Failed to parse UNC name %s\n",
448 unc_list[conn_index % num_unc_names]);
449 TALLOC_FREE(unc_list);
450 exit(1);
453 result = torture_open_connection_share(c, h, s);
455 /* h, s were copied earlier */
456 TALLOC_FREE(unc_list);
457 return result;
460 return torture_open_connection_share(c, host, share);
463 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
465 uint16 old_vuid = cli->vuid;
466 fstring old_user_name;
467 size_t passlen = strlen(password);
468 NTSTATUS status;
469 bool ret;
471 fstrcpy(old_user_name, cli->user_name);
472 cli->vuid = 0;
473 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
474 password, passlen,
475 password, passlen,
476 workgroup));
477 *new_vuid = cli->vuid;
478 cli->vuid = old_vuid;
479 status = cli_set_username(cli, old_user_name);
480 if (!NT_STATUS_IS_OK(status)) {
481 return false;
483 return ret;
487 bool torture_close_connection(struct cli_state *c)
489 bool ret = True;
490 NTSTATUS status;
492 status = cli_tdis(c);
493 if (!NT_STATUS_IS_OK(status)) {
494 printf("tdis failed (%s)\n", nt_errstr(status));
495 ret = False;
498 cli_shutdown(c);
500 return ret;
504 /* check if the server produced the expected error code */
505 static bool check_error(int line, struct cli_state *c,
506 uint8 eclass, uint32 ecode, NTSTATUS nterr)
508 if (cli_is_dos_error(c)) {
509 uint8 cclass;
510 uint32 num;
512 /* Check DOS error */
514 cli_dos_error(c, &cclass, &num);
516 if (eclass != cclass || ecode != num) {
517 printf("unexpected error code class=%d code=%d\n",
518 (int)cclass, (int)num);
519 printf(" expected %d/%d %s (line=%d)\n",
520 (int)eclass, (int)ecode, nt_errstr(nterr), line);
521 return False;
524 } else {
525 NTSTATUS status;
527 /* Check NT error */
529 status = cli_nt_error(c);
531 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
532 printf("unexpected error code %s\n", nt_errstr(status));
533 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
534 return False;
538 return True;
542 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
544 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
545 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
547 return True;
551 static bool rw_torture(struct cli_state *c)
553 const char *lockfname = "\\torture.lck";
554 fstring fname;
555 uint16_t fnum;
556 uint16_t fnum2;
557 pid_t pid2, pid = getpid();
558 int i, j;
559 char buf[1024];
560 bool correct = True;
561 NTSTATUS status;
563 memset(buf, '\0', sizeof(buf));
565 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
566 DENY_NONE, &fnum2);
567 if (!NT_STATUS_IS_OK(status)) {
568 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
570 if (!NT_STATUS_IS_OK(status)) {
571 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
572 return False;
575 for (i=0;i<torture_numops;i++) {
576 unsigned n = (unsigned)sys_random()%10;
577 if (i % 10 == 0) {
578 printf("%d\r", i); fflush(stdout);
580 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
582 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
583 return False;
586 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
587 printf("open failed (%s)\n", cli_errstr(c));
588 correct = False;
589 break;
592 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
593 printf("write failed (%s)\n", cli_errstr(c));
594 correct = False;
597 for (j=0;j<50;j++) {
598 if (cli_write(c, fnum, 0, (char *)buf,
599 sizeof(pid)+(j*sizeof(buf)),
600 sizeof(buf)) != sizeof(buf)) {
601 printf("write failed (%s)\n", cli_errstr(c));
602 correct = False;
606 pid2 = 0;
608 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
609 printf("read failed (%s)\n", cli_errstr(c));
610 correct = False;
613 if (pid2 != pid) {
614 printf("data corruption!\n");
615 correct = False;
618 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
619 printf("close failed (%s)\n", cli_errstr(c));
620 correct = False;
623 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
624 printf("unlink failed (%s)\n", cli_errstr(c));
625 correct = False;
628 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
629 printf("unlock failed (%s)\n", cli_errstr(c));
630 correct = False;
634 cli_close(c, fnum2);
635 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
637 printf("%d\n", i);
639 return correct;
642 static bool run_torture(int dummy)
644 struct cli_state *cli;
645 bool ret;
647 cli = current_cli;
649 cli_sockopt(cli, sockops);
651 ret = rw_torture(cli);
653 if (!torture_close_connection(cli)) {
654 ret = False;
657 return ret;
660 static bool rw_torture3(struct cli_state *c, char *lockfname)
662 uint16_t fnum = (uint16_t)-1;
663 unsigned int i = 0;
664 char buf[131072];
665 char buf_rd[131072];
666 unsigned count;
667 unsigned countprev = 0;
668 ssize_t sent = 0;
669 bool correct = True;
670 NTSTATUS status = NT_STATUS_OK;
672 srandom(1);
673 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
675 SIVAL(buf, i, sys_random());
678 if (procnum == 0)
680 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
681 DENY_NONE, &fnum))) {
682 printf("first open read/write of %s failed (%s)\n",
683 lockfname, cli_errstr(c));
684 return False;
687 else
689 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
691 status = cli_open(c, lockfname, O_RDONLY,
692 DENY_NONE, &fnum);
693 if (!NT_STATUS_IS_OK(status)) {
694 break;
696 smb_msleep(10);
698 if (!NT_STATUS_IS_OK(status)) {
699 printf("second open read-only of %s failed (%s)\n",
700 lockfname, cli_errstr(c));
701 return False;
705 i = 0;
706 for (count = 0; count < sizeof(buf); count += sent)
708 if (count >= countprev) {
709 printf("%d %8d\r", i, count);
710 fflush(stdout);
711 i++;
712 countprev += (sizeof(buf) / 20);
715 if (procnum == 0)
717 sent = ((unsigned)sys_random()%(20))+ 1;
718 if (sent > sizeof(buf) - count)
720 sent = sizeof(buf) - count;
723 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
724 printf("write failed (%s)\n", cli_errstr(c));
725 correct = False;
728 else
730 sent = cli_read(c, fnum, buf_rd+count, count,
731 sizeof(buf)-count);
732 if (sent < 0)
734 printf("read failed offset:%d size:%ld (%s)\n",
735 count, (unsigned long)sizeof(buf)-count,
736 cli_errstr(c));
737 correct = False;
738 sent = 0;
740 if (sent > 0)
742 if (memcmp(buf_rd+count, buf+count, sent) != 0)
744 printf("read/write compare failed\n");
745 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
746 correct = False;
747 break;
754 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
755 printf("close failed (%s)\n", cli_errstr(c));
756 correct = False;
759 return correct;
762 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
764 const char *lockfname = "\\torture2.lck";
765 uint16_t fnum1;
766 uint16_t fnum2;
767 int i;
768 char buf[131072];
769 char buf_rd[131072];
770 bool correct = True;
771 ssize_t bytes_read;
773 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
774 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
777 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
778 DENY_NONE, &fnum1))) {
779 printf("first open read/write of %s failed (%s)\n",
780 lockfname, cli_errstr(c1));
781 return False;
783 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
784 DENY_NONE, &fnum2))) {
785 printf("second open read-only of %s failed (%s)\n",
786 lockfname, cli_errstr(c2));
787 cli_close(c1, fnum1);
788 return False;
791 for (i=0;i<torture_numops;i++)
793 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
794 if (i % 10 == 0) {
795 printf("%d\r", i); fflush(stdout);
798 generate_random_buffer((unsigned char *)buf, buf_size);
800 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
801 printf("write failed (%s)\n", cli_errstr(c1));
802 correct = False;
803 break;
806 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
807 printf("read failed (%s)\n", cli_errstr(c2));
808 printf("read %d, expected %ld\n", (int)bytes_read,
809 (unsigned long)buf_size);
810 correct = False;
811 break;
814 if (memcmp(buf_rd, buf, buf_size) != 0)
816 printf("read/write compare failed\n");
817 correct = False;
818 break;
822 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
823 printf("close failed (%s)\n", cli_errstr(c2));
824 correct = False;
826 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
827 printf("close failed (%s)\n", cli_errstr(c1));
828 correct = False;
831 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
832 printf("unlink failed (%s)\n", cli_errstr(c1));
833 correct = False;
836 return correct;
839 static bool run_readwritetest(int dummy)
841 struct cli_state *cli1, *cli2;
842 bool test1, test2 = False;
844 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
845 return False;
847 cli_sockopt(cli1, sockops);
848 cli_sockopt(cli2, sockops);
850 printf("starting readwritetest\n");
852 test1 = rw_torture2(cli1, cli2);
853 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
855 if (test1) {
856 test2 = rw_torture2(cli1, cli1);
857 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
860 if (!torture_close_connection(cli1)) {
861 test1 = False;
864 if (!torture_close_connection(cli2)) {
865 test2 = False;
868 return (test1 && test2);
871 static bool run_readwritemulti(int dummy)
873 struct cli_state *cli;
874 bool test;
876 cli = current_cli;
878 cli_sockopt(cli, sockops);
880 printf("run_readwritemulti: fname %s\n", randomfname);
881 test = rw_torture3(cli, randomfname);
883 if (!torture_close_connection(cli)) {
884 test = False;
887 return test;
890 static bool run_readwritelarge_internal(int max_xmit_k)
892 static struct cli_state *cli1;
893 uint16_t fnum1;
894 const char *lockfname = "\\large.dat";
895 SMB_OFF_T fsize;
896 char buf[126*1024];
897 bool correct = True;
899 if (!torture_open_connection(&cli1, 0)) {
900 return False;
902 cli_sockopt(cli1, sockops);
903 memset(buf,'\0',sizeof(buf));
905 cli1->max_xmit = max_xmit_k*1024;
907 if (signing_state == Required) {
908 /* Horrible cheat to force
909 multiple signed outstanding
910 packets against a Samba server.
912 cli1->is_samba = false;
915 printf("starting readwritelarge_internal\n");
917 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
919 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
920 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
921 return False;
924 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
926 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
927 cli1, fnum1, NULL, &fsize, NULL, NULL,
928 NULL, NULL, NULL))) {
929 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
930 correct = False;
933 if (fsize == sizeof(buf))
934 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
935 (unsigned long)fsize);
936 else {
937 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
938 (unsigned long)fsize);
939 correct = False;
942 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
943 printf("close failed (%s)\n", cli_errstr(cli1));
944 correct = False;
947 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
948 printf("unlink failed (%s)\n", cli_errstr(cli1));
949 correct = False;
952 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
953 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
954 return False;
957 cli1->max_xmit = 4*1024;
959 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
961 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
962 cli1, fnum1, NULL, &fsize, NULL, NULL,
963 NULL, NULL, NULL))) {
964 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
965 correct = False;
968 if (fsize == sizeof(buf))
969 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
970 (unsigned long)fsize);
971 else {
972 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
973 (unsigned long)fsize);
974 correct = False;
977 #if 0
978 /* ToDo - set allocation. JRA */
979 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
980 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
981 return False;
983 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
984 NULL, NULL)) {
985 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
986 correct = False;
988 if (fsize != 0)
989 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
990 #endif
992 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
993 printf("close failed (%s)\n", cli_errstr(cli1));
994 correct = False;
997 if (!torture_close_connection(cli1)) {
998 correct = False;
1000 return correct;
1003 static bool run_readwritelarge(int dummy)
1005 return run_readwritelarge_internal(128);
1008 static bool run_readwritelarge_signtest(int dummy)
1010 bool ret;
1011 signing_state = Required;
1012 ret = run_readwritelarge_internal(2);
1013 signing_state = Undefined;
1014 return ret;
1017 int line_count = 0;
1018 int nbio_id;
1020 #define ival(s) strtol(s, NULL, 0)
1022 /* run a test that simulates an approximate netbench client load */
1023 static bool run_netbench(int client)
1025 struct cli_state *cli;
1026 int i;
1027 char line[1024];
1028 char cname[20];
1029 FILE *f;
1030 const char *params[20];
1031 bool correct = True;
1033 cli = current_cli;
1035 nbio_id = client;
1037 cli_sockopt(cli, sockops);
1039 nb_setup(cli);
1041 slprintf(cname,sizeof(cname)-1, "client%d", client);
1043 f = fopen(client_txt, "r");
1045 if (!f) {
1046 perror(client_txt);
1047 return False;
1050 while (fgets(line, sizeof(line)-1, f)) {
1051 char *saveptr;
1052 line_count++;
1054 line[strlen(line)-1] = 0;
1056 /* printf("[%d] %s\n", line_count, line); */
1058 all_string_sub(line,"client1", cname, sizeof(line));
1060 /* parse the command parameters */
1061 params[0] = strtok_r(line, " ", &saveptr);
1062 i = 0;
1063 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1065 params[i] = "";
1067 if (i < 2) continue;
1069 if (!strncmp(params[0],"SMB", 3)) {
1070 printf("ERROR: You are using a dbench 1 load file\n");
1071 exit(1);
1074 if (!strcmp(params[0],"NTCreateX")) {
1075 nb_createx(params[1], ival(params[2]), ival(params[3]),
1076 ival(params[4]));
1077 } else if (!strcmp(params[0],"Close")) {
1078 nb_close(ival(params[1]));
1079 } else if (!strcmp(params[0],"Rename")) {
1080 nb_rename(params[1], params[2]);
1081 } else if (!strcmp(params[0],"Unlink")) {
1082 nb_unlink(params[1]);
1083 } else if (!strcmp(params[0],"Deltree")) {
1084 nb_deltree(params[1]);
1085 } else if (!strcmp(params[0],"Rmdir")) {
1086 nb_rmdir(params[1]);
1087 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1088 nb_qpathinfo(params[1]);
1089 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1090 nb_qfileinfo(ival(params[1]));
1091 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1092 nb_qfsinfo(ival(params[1]));
1093 } else if (!strcmp(params[0],"FIND_FIRST")) {
1094 nb_findfirst(params[1]);
1095 } else if (!strcmp(params[0],"WriteX")) {
1096 nb_writex(ival(params[1]),
1097 ival(params[2]), ival(params[3]), ival(params[4]));
1098 } else if (!strcmp(params[0],"ReadX")) {
1099 nb_readx(ival(params[1]),
1100 ival(params[2]), ival(params[3]), ival(params[4]));
1101 } else if (!strcmp(params[0],"Flush")) {
1102 nb_flush(ival(params[1]));
1103 } else {
1104 printf("Unknown operation %s\n", params[0]);
1105 exit(1);
1108 fclose(f);
1110 nb_cleanup();
1112 if (!torture_close_connection(cli)) {
1113 correct = False;
1116 return correct;
1120 /* run a test that simulates an approximate netbench client load */
1121 static bool run_nbench(int dummy)
1123 double t;
1124 bool correct = True;
1126 nbio_shmem(nprocs);
1128 nbio_id = -1;
1130 signal(SIGALRM, nb_alarm);
1131 alarm(1);
1132 t = create_procs(run_netbench, &correct);
1133 alarm(0);
1135 printf("\nThroughput %g MB/sec\n",
1136 1.0e-6 * nbio_total() / t);
1137 return correct;
1142 This test checks for two things:
1144 1) correct support for retaining locks over a close (ie. the server
1145 must not use posix semantics)
1146 2) support for lock timeouts
1148 static bool run_locktest1(int dummy)
1150 struct cli_state *cli1, *cli2;
1151 const char *fname = "\\lockt1.lck";
1152 uint16_t fnum1, fnum2, fnum3;
1153 time_t t1, t2;
1154 unsigned lock_timeout;
1156 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1157 return False;
1159 cli_sockopt(cli1, sockops);
1160 cli_sockopt(cli2, sockops);
1162 printf("starting locktest1\n");
1164 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1166 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1167 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1168 return False;
1170 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1171 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1172 return False;
1174 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1175 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1176 return False;
1179 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1180 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1181 return False;
1185 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1186 printf("lock2 succeeded! This is a locking bug\n");
1187 return False;
1188 } else {
1189 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1190 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1194 lock_timeout = (1 + (random() % 20));
1195 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1196 t1 = time(NULL);
1197 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1198 printf("lock3 succeeded! This is a locking bug\n");
1199 return False;
1200 } else {
1201 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1202 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1204 t2 = time(NULL);
1206 if (ABS(t2 - t1) < lock_timeout-1) {
1207 printf("error: This server appears not to support timed lock requests\n");
1210 printf("server slept for %u seconds for a %u second timeout\n",
1211 (unsigned int)(t2-t1), lock_timeout);
1213 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1214 printf("close1 failed (%s)\n", cli_errstr(cli1));
1215 return False;
1218 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1219 printf("lock4 succeeded! This is a locking bug\n");
1220 return False;
1221 } else {
1222 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1223 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1226 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1227 printf("close2 failed (%s)\n", cli_errstr(cli1));
1228 return False;
1231 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1232 printf("close3 failed (%s)\n", cli_errstr(cli2));
1233 return False;
1236 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1237 printf("unlink failed (%s)\n", cli_errstr(cli1));
1238 return False;
1242 if (!torture_close_connection(cli1)) {
1243 return False;
1246 if (!torture_close_connection(cli2)) {
1247 return False;
1250 printf("Passed locktest1\n");
1251 return True;
1255 this checks to see if a secondary tconx can use open files from an
1256 earlier tconx
1258 static bool run_tcon_test(int dummy)
1260 static struct cli_state *cli;
1261 const char *fname = "\\tcontest.tmp";
1262 uint16 fnum1;
1263 uint16 cnum1, cnum2, cnum3;
1264 uint16 vuid1, vuid2;
1265 char buf[4];
1266 bool ret = True;
1267 NTSTATUS status;
1269 memset(buf, '\0', sizeof(buf));
1271 if (!torture_open_connection(&cli, 0)) {
1272 return False;
1274 cli_sockopt(cli, sockops);
1276 printf("starting tcontest\n");
1278 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1280 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1281 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1282 return False;
1285 cnum1 = cli->cnum;
1286 vuid1 = cli->vuid;
1288 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1289 printf("initial write failed (%s)", cli_errstr(cli));
1290 return False;
1293 status = cli_tcon_andx(cli, share, "?????",
1294 password, strlen(password)+1);
1295 if (!NT_STATUS_IS_OK(status)) {
1296 printf("%s refused 2nd tree connect (%s)\n", host,
1297 nt_errstr(status));
1298 cli_shutdown(cli);
1299 return False;
1302 cnum2 = cli->cnum;
1303 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1304 vuid2 = cli->vuid + 1;
1306 /* try a write with the wrong tid */
1307 cli->cnum = cnum2;
1309 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1310 printf("* server allows write with wrong TID\n");
1311 ret = False;
1312 } else {
1313 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1317 /* try a write with an invalid tid */
1318 cli->cnum = cnum3;
1320 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1321 printf("* server allows write with invalid TID\n");
1322 ret = False;
1323 } else {
1324 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1327 /* try a write with an invalid vuid */
1328 cli->vuid = vuid2;
1329 cli->cnum = cnum1;
1331 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1332 printf("* server allows write with invalid VUID\n");
1333 ret = False;
1334 } else {
1335 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1338 cli->cnum = cnum1;
1339 cli->vuid = vuid1;
1341 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1342 printf("close failed (%s)\n", cli_errstr(cli));
1343 return False;
1346 cli->cnum = cnum2;
1348 status = cli_tdis(cli);
1349 if (!NT_STATUS_IS_OK(status)) {
1350 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1351 return False;
1354 cli->cnum = cnum1;
1356 if (!torture_close_connection(cli)) {
1357 return False;
1360 return ret;
1365 checks for old style tcon support
1367 static bool run_tcon2_test(int dummy)
1369 static struct cli_state *cli;
1370 uint16 cnum, max_xmit;
1371 char *service;
1372 NTSTATUS status;
1374 if (!torture_open_connection(&cli, 0)) {
1375 return False;
1377 cli_sockopt(cli, sockops);
1379 printf("starting tcon2 test\n");
1381 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1382 return false;
1385 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 printf("tcon2 failed : %s\n", cli_errstr(cli));
1389 } else {
1390 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1391 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1394 if (!torture_close_connection(cli)) {
1395 return False;
1398 printf("Passed tcon2 test\n");
1399 return True;
1402 static bool tcon_devtest(struct cli_state *cli,
1403 const char *myshare, const char *devtype,
1404 const char *return_devtype,
1405 NTSTATUS expected_error)
1407 NTSTATUS status;
1408 bool ret;
1410 status = cli_tcon_andx(cli, myshare, devtype,
1411 password, strlen(password)+1);
1413 if (NT_STATUS_IS_OK(expected_error)) {
1414 if (NT_STATUS_IS_OK(status)) {
1415 if (strcmp(cli->dev, return_devtype) == 0) {
1416 ret = True;
1417 } else {
1418 printf("tconX to share %s with type %s "
1419 "succeeded but returned the wrong "
1420 "device type (got [%s] but should have got [%s])\n",
1421 myshare, devtype, cli->dev, return_devtype);
1422 ret = False;
1424 } else {
1425 printf("tconX to share %s with type %s "
1426 "should have succeeded but failed\n",
1427 myshare, devtype);
1428 ret = False;
1430 cli_tdis(cli);
1431 } else {
1432 if (NT_STATUS_IS_OK(status)) {
1433 printf("tconx to share %s with type %s "
1434 "should have failed but succeeded\n",
1435 myshare, devtype);
1436 ret = False;
1437 } else {
1438 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1439 expected_error)) {
1440 ret = True;
1441 } else {
1442 printf("Returned unexpected error\n");
1443 ret = False;
1447 return ret;
1451 checks for correct tconX support
1453 static bool run_tcon_devtype_test(int dummy)
1455 static struct cli_state *cli1 = NULL;
1456 int flags = 0;
1457 NTSTATUS status;
1458 bool ret = True;
1460 status = cli_full_connection(&cli1, myname,
1461 host, NULL, port_to_use,
1462 NULL, NULL,
1463 username, workgroup,
1464 password, flags, signing_state);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 printf("could not open connection\n");
1468 return False;
1471 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1472 ret = False;
1474 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1475 ret = False;
1477 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1478 ret = False;
1480 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1481 ret = False;
1483 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1484 ret = False;
1486 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1487 ret = False;
1489 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1490 ret = False;
1492 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1493 ret = False;
1495 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1496 ret = False;
1498 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1499 ret = False;
1501 cli_shutdown(cli1);
1503 if (ret)
1504 printf("Passed tcondevtest\n");
1506 return ret;
1511 This test checks that
1513 1) the server supports multiple locking contexts on the one SMB
1514 connection, distinguished by PID.
1516 2) the server correctly fails overlapping locks made by the same PID (this
1517 goes against POSIX behaviour, which is why it is tricky to implement)
1519 3) the server denies unlock requests by an incorrect client PID
1521 static bool run_locktest2(int dummy)
1523 static struct cli_state *cli;
1524 const char *fname = "\\lockt2.lck";
1525 uint16_t fnum1, fnum2, fnum3;
1526 bool correct = True;
1528 if (!torture_open_connection(&cli, 0)) {
1529 return False;
1532 cli_sockopt(cli, sockops);
1534 printf("starting locktest2\n");
1536 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1538 cli_setpid(cli, 1);
1540 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1541 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1542 return False;
1545 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1546 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1547 return False;
1550 cli_setpid(cli, 2);
1552 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1553 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1554 return False;
1557 cli_setpid(cli, 1);
1559 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1560 printf("lock1 failed (%s)\n", cli_errstr(cli));
1561 return False;
1564 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1565 printf("WRITE lock1 succeeded! This is a locking bug\n");
1566 correct = False;
1567 } else {
1568 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1569 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1572 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1573 printf("WRITE lock2 succeeded! This is a locking bug\n");
1574 correct = False;
1575 } else {
1576 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1577 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1580 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1581 printf("READ lock2 succeeded! This is a locking bug\n");
1582 correct = False;
1583 } else {
1584 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1585 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1588 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1589 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1591 cli_setpid(cli, 2);
1592 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1593 printf("unlock at 100 succeeded! This is a locking bug\n");
1594 correct = False;
1597 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1598 printf("unlock1 succeeded! This is a locking bug\n");
1599 correct = False;
1600 } else {
1601 if (!check_error(__LINE__, cli,
1602 ERRDOS, ERRlock,
1603 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1606 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1607 printf("unlock2 succeeded! This is a locking bug\n");
1608 correct = False;
1609 } else {
1610 if (!check_error(__LINE__, cli,
1611 ERRDOS, ERRlock,
1612 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1615 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1616 printf("lock3 succeeded! This is a locking bug\n");
1617 correct = False;
1618 } else {
1619 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1622 cli_setpid(cli, 1);
1624 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1625 printf("close1 failed (%s)\n", cli_errstr(cli));
1626 return False;
1629 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1630 printf("close2 failed (%s)\n", cli_errstr(cli));
1631 return False;
1634 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1635 printf("close3 failed (%s)\n", cli_errstr(cli));
1636 return False;
1639 if (!torture_close_connection(cli)) {
1640 correct = False;
1643 printf("locktest2 finished\n");
1645 return correct;
1650 This test checks that
1652 1) the server supports the full offset range in lock requests
1654 static bool run_locktest3(int dummy)
1656 static struct cli_state *cli1, *cli2;
1657 const char *fname = "\\lockt3.lck";
1658 uint16_t fnum1, fnum2;
1659 int i;
1660 uint32 offset;
1661 bool correct = True;
1663 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1665 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1666 return False;
1668 cli_sockopt(cli1, sockops);
1669 cli_sockopt(cli2, sockops);
1671 printf("starting locktest3\n");
1673 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1675 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1676 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1677 return False;
1679 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1680 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1681 return False;
1684 for (offset=i=0;i<torture_numops;i++) {
1685 NEXT_OFFSET;
1686 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1687 printf("lock1 %d failed (%s)\n",
1689 cli_errstr(cli1));
1690 return False;
1693 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1694 printf("lock2 %d failed (%s)\n",
1696 cli_errstr(cli1));
1697 return False;
1701 for (offset=i=0;i<torture_numops;i++) {
1702 NEXT_OFFSET;
1704 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1705 printf("error: lock1 %d succeeded!\n", i);
1706 return False;
1709 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1710 printf("error: lock2 %d succeeded!\n", i);
1711 return False;
1714 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1715 printf("error: lock3 %d succeeded!\n", i);
1716 return False;
1719 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1720 printf("error: lock4 %d succeeded!\n", i);
1721 return False;
1725 for (offset=i=0;i<torture_numops;i++) {
1726 NEXT_OFFSET;
1728 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1729 printf("unlock1 %d failed (%s)\n",
1731 cli_errstr(cli1));
1732 return False;
1735 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1736 printf("unlock2 %d failed (%s)\n",
1738 cli_errstr(cli1));
1739 return False;
1743 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1744 printf("close1 failed (%s)\n", cli_errstr(cli1));
1745 return False;
1748 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1749 printf("close2 failed (%s)\n", cli_errstr(cli2));
1750 return False;
1753 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1754 printf("unlink failed (%s)\n", cli_errstr(cli1));
1755 return False;
1758 if (!torture_close_connection(cli1)) {
1759 correct = False;
1762 if (!torture_close_connection(cli2)) {
1763 correct = False;
1766 printf("finished locktest3\n");
1768 return correct;
1771 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1772 printf("** "); correct = False; \
1776 looks at overlapping locks
1778 static bool run_locktest4(int dummy)
1780 static struct cli_state *cli1, *cli2;
1781 const char *fname = "\\lockt4.lck";
1782 uint16_t fnum1, fnum2, f;
1783 bool ret;
1784 char buf[1000];
1785 bool correct = True;
1787 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1788 return False;
1791 cli_sockopt(cli1, sockops);
1792 cli_sockopt(cli2, sockops);
1794 printf("starting locktest4\n");
1796 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1798 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1799 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1801 memset(buf, 0, sizeof(buf));
1803 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1804 printf("Failed to create file\n");
1805 correct = False;
1806 goto fail;
1809 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1810 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1811 EXPECTED(ret, False);
1812 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1814 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1815 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1816 EXPECTED(ret, True);
1817 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1819 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1820 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1821 EXPECTED(ret, False);
1822 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1824 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1825 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1826 EXPECTED(ret, True);
1827 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1829 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1830 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1831 EXPECTED(ret, False);
1832 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1834 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1835 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1836 EXPECTED(ret, True);
1837 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1839 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1840 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1841 EXPECTED(ret, True);
1842 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1844 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1845 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1846 EXPECTED(ret, False);
1847 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1849 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1850 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1851 EXPECTED(ret, False);
1852 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1854 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1855 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1856 EXPECTED(ret, True);
1857 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1859 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1860 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1861 EXPECTED(ret, False);
1862 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1864 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1865 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1866 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1867 EXPECTED(ret, False);
1868 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1871 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1872 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1873 EXPECTED(ret, False);
1874 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1876 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1877 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1878 EXPECTED(ret, False);
1879 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1882 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1883 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1884 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1885 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1886 EXPECTED(ret, True);
1887 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1890 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1891 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1892 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1893 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1894 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1895 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1896 EXPECTED(ret, True);
1897 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1899 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1900 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1901 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1902 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1903 EXPECTED(ret, True);
1904 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1906 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1907 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1908 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1909 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1910 EXPECTED(ret, True);
1911 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1913 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1914 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1915 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1916 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1917 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1918 EXPECTED(ret, True);
1919 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1921 cli_close(cli1, fnum1);
1922 cli_close(cli2, fnum2);
1923 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1924 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1925 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1926 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1927 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1928 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1929 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1930 cli_close(cli1, f);
1931 cli_close(cli1, fnum1);
1932 EXPECTED(ret, True);
1933 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1935 fail:
1936 cli_close(cli1, fnum1);
1937 cli_close(cli2, fnum2);
1938 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1939 torture_close_connection(cli1);
1940 torture_close_connection(cli2);
1942 printf("finished locktest4\n");
1943 return correct;
1947 looks at lock upgrade/downgrade.
1949 static bool run_locktest5(int dummy)
1951 static struct cli_state *cli1, *cli2;
1952 const char *fname = "\\lockt5.lck";
1953 uint16_t fnum1, fnum2, fnum3;
1954 bool ret;
1955 char buf[1000];
1956 bool correct = True;
1958 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1959 return False;
1962 cli_sockopt(cli1, sockops);
1963 cli_sockopt(cli2, sockops);
1965 printf("starting locktest5\n");
1967 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1969 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1970 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1971 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1973 memset(buf, 0, sizeof(buf));
1975 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1976 printf("Failed to create file\n");
1977 correct = False;
1978 goto fail;
1981 /* Check for NT bug... */
1982 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1983 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1984 cli_close(cli1, fnum1);
1985 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1986 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1987 EXPECTED(ret, True);
1988 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1989 cli_close(cli1, fnum1);
1990 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1991 cli_unlock(cli1, fnum3, 0, 1);
1993 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1994 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1995 EXPECTED(ret, True);
1996 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1998 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1999 EXPECTED(ret, False);
2001 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2003 /* Unlock the process 2 lock. */
2004 cli_unlock(cli2, fnum2, 0, 4);
2006 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2007 EXPECTED(ret, False);
2009 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2011 /* Unlock the process 1 fnum3 lock. */
2012 cli_unlock(cli1, fnum3, 0, 4);
2014 /* Stack 2 more locks here. */
2015 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2016 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2018 EXPECTED(ret, True);
2019 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2021 /* Unlock the first process lock, then check this was the WRITE lock that was
2022 removed. */
2024 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2025 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2027 EXPECTED(ret, True);
2028 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2030 /* Unlock the process 2 lock. */
2031 cli_unlock(cli2, fnum2, 0, 4);
2033 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2035 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2036 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2037 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2039 EXPECTED(ret, True);
2040 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2042 /* Ensure the next unlock fails. */
2043 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2044 EXPECTED(ret, False);
2045 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2047 /* Ensure connection 2 can get a write lock. */
2048 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2049 EXPECTED(ret, True);
2051 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2054 fail:
2055 cli_close(cli1, fnum1);
2056 cli_close(cli2, fnum2);
2057 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2058 if (!torture_close_connection(cli1)) {
2059 correct = False;
2061 if (!torture_close_connection(cli2)) {
2062 correct = False;
2065 printf("finished locktest5\n");
2067 return correct;
2071 tries the unusual lockingX locktype bits
2073 static bool run_locktest6(int dummy)
2075 static struct cli_state *cli;
2076 const char *fname[1] = { "\\lock6.txt" };
2077 int i;
2078 uint16_t fnum;
2079 NTSTATUS status;
2081 if (!torture_open_connection(&cli, 0)) {
2082 return False;
2085 cli_sockopt(cli, sockops);
2087 printf("starting locktest6\n");
2089 for (i=0;i<1;i++) {
2090 printf("Testing %s\n", fname[i]);
2092 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2094 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2095 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2096 cli_close(cli, fnum);
2097 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2099 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2100 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2101 cli_close(cli, fnum);
2102 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2104 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2107 torture_close_connection(cli);
2109 printf("finished locktest6\n");
2110 return True;
2113 static bool run_locktest7(int dummy)
2115 struct cli_state *cli1;
2116 const char *fname = "\\lockt7.lck";
2117 uint16_t fnum1;
2118 char buf[200];
2119 bool correct = False;
2121 if (!torture_open_connection(&cli1, 0)) {
2122 return False;
2125 cli_sockopt(cli1, sockops);
2127 printf("starting locktest7\n");
2129 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2131 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2133 memset(buf, 0, sizeof(buf));
2135 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2136 printf("Failed to create file\n");
2137 goto fail;
2140 cli_setpid(cli1, 1);
2142 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2143 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2144 goto fail;
2145 } else {
2146 printf("pid1 successfully locked range 130:4 for READ\n");
2149 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2150 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2151 goto fail;
2152 } else {
2153 printf("pid1 successfully read the range 130:4\n");
2156 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2157 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2158 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2159 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2160 goto fail;
2162 } else {
2163 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2164 goto fail;
2167 cli_setpid(cli1, 2);
2169 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2170 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2171 } else {
2172 printf("pid2 successfully read the range 130:4\n");
2175 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2176 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2177 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2178 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2179 goto fail;
2181 } else {
2182 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2183 goto fail;
2186 cli_setpid(cli1, 1);
2187 cli_unlock(cli1, fnum1, 130, 4);
2189 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2190 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2191 goto fail;
2192 } else {
2193 printf("pid1 successfully locked range 130:4 for WRITE\n");
2196 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2197 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2198 goto fail;
2199 } else {
2200 printf("pid1 successfully read the range 130:4\n");
2203 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2204 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2205 goto fail;
2206 } else {
2207 printf("pid1 successfully wrote to the range 130:4\n");
2210 cli_setpid(cli1, 2);
2212 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2213 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2214 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2215 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2216 goto fail;
2218 } else {
2219 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2220 goto fail;
2223 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2224 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2225 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2226 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2227 goto fail;
2229 } else {
2230 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2231 goto fail;
2234 cli_unlock(cli1, fnum1, 130, 0);
2235 correct = True;
2237 fail:
2238 cli_close(cli1, fnum1);
2239 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2240 torture_close_connection(cli1);
2242 printf("finished locktest7\n");
2243 return correct;
2247 * This demonstrates a problem with our use of GPFS share modes: A file
2248 * descriptor sitting in the pending close queue holding a GPFS share mode
2249 * blocks opening a file another time. Happens with Word 2007 temp files.
2250 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2251 * open is denied with NT_STATUS_SHARING_VIOLATION.
2254 static bool run_locktest8(int dummy)
2256 struct cli_state *cli1;
2257 const char *fname = "\\lockt8.lck";
2258 uint16_t fnum1, fnum2;
2259 char buf[200];
2260 bool correct = False;
2261 NTSTATUS status;
2263 if (!torture_open_connection(&cli1, 0)) {
2264 return False;
2267 cli_sockopt(cli1, sockops);
2269 printf("starting locktest8\n");
2271 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2273 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2274 &fnum1);
2275 if (!NT_STATUS_IS_OK(status)) {
2276 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2277 return false;
2280 memset(buf, 0, sizeof(buf));
2282 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2283 if (!NT_STATUS_IS_OK(status)) {
2284 d_fprintf(stderr, "cli_open second time returned %s\n",
2285 cli_errstr(cli1));
2286 goto fail;
2289 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2290 printf("Unable to apply read lock on range 1:1, error was "
2291 "%s\n", cli_errstr(cli1));
2292 goto fail;
2295 status = cli_close(cli1, fnum1);
2296 if (!NT_STATUS_IS_OK(status)) {
2297 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2298 goto fail;
2301 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2302 if (!NT_STATUS_IS_OK(status)) {
2303 d_fprintf(stderr, "cli_open third time returned %s\n",
2304 cli_errstr(cli1));
2305 goto fail;
2308 correct = true;
2310 fail:
2311 cli_close(cli1, fnum1);
2312 cli_close(cli1, fnum2);
2313 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2314 torture_close_connection(cli1);
2316 printf("finished locktest8\n");
2317 return correct;
2321 * This test is designed to be run in conjunction with
2322 * external NFS or POSIX locks taken in the filesystem.
2323 * It checks that the smbd server will block until the
2324 * lock is released and then acquire it. JRA.
2327 static bool got_alarm;
2328 static int alarm_fd;
2330 static void alarm_handler(int dummy)
2332 got_alarm = True;
2335 static void alarm_handler_parent(int dummy)
2337 close(alarm_fd);
2340 static void do_local_lock(int read_fd, int write_fd)
2342 int fd;
2343 char c = '\0';
2344 struct flock lock;
2345 const char *local_pathname = NULL;
2346 int ret;
2348 local_pathname = talloc_asprintf(talloc_tos(),
2349 "%s/lockt9.lck", local_path);
2350 if (!local_pathname) {
2351 printf("child: alloc fail\n");
2352 exit(1);
2355 unlink(local_pathname);
2356 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2357 if (fd == -1) {
2358 printf("child: open of %s failed %s.\n",
2359 local_pathname, strerror(errno));
2360 exit(1);
2363 /* Now take a fcntl lock. */
2364 lock.l_type = F_WRLCK;
2365 lock.l_whence = SEEK_SET;
2366 lock.l_start = 0;
2367 lock.l_len = 4;
2368 lock.l_pid = getpid();
2370 ret = fcntl(fd,F_SETLK,&lock);
2371 if (ret == -1) {
2372 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2373 local_pathname, strerror(errno));
2374 exit(1);
2375 } else {
2376 printf("child: got lock 0:4 on file %s.\n",
2377 local_pathname );
2378 fflush(stdout);
2381 CatchSignal(SIGALRM, alarm_handler);
2382 alarm(5);
2383 /* Signal the parent. */
2384 if (write(write_fd, &c, 1) != 1) {
2385 printf("child: start signal fail %s.\n",
2386 strerror(errno));
2387 exit(1);
2389 alarm(0);
2391 alarm(10);
2392 /* Wait for the parent to be ready. */
2393 if (read(read_fd, &c, 1) != 1) {
2394 printf("child: reply signal fail %s.\n",
2395 strerror(errno));
2396 exit(1);
2398 alarm(0);
2400 sleep(5);
2401 close(fd);
2402 printf("child: released lock 0:4 on file %s.\n",
2403 local_pathname );
2404 fflush(stdout);
2405 exit(0);
2408 static bool run_locktest9(int dummy)
2410 struct cli_state *cli1;
2411 const char *fname = "\\lockt9.lck";
2412 uint16_t fnum;
2413 bool correct = False;
2414 int pipe_in[2], pipe_out[2];
2415 pid_t child_pid;
2416 char c = '\0';
2417 int ret;
2418 struct timeval start;
2419 double seconds;
2420 NTSTATUS status;
2422 printf("starting locktest9\n");
2424 if (local_path == NULL) {
2425 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2426 return false;
2429 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2430 return false;
2433 child_pid = fork();
2434 if (child_pid == -1) {
2435 return false;
2438 if (child_pid == 0) {
2439 /* Child. */
2440 do_local_lock(pipe_out[0], pipe_in[1]);
2441 exit(0);
2444 close(pipe_out[0]);
2445 close(pipe_in[1]);
2446 pipe_out[0] = -1;
2447 pipe_in[1] = -1;
2449 /* Parent. */
2450 ret = read(pipe_in[0], &c, 1);
2451 if (ret != 1) {
2452 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2453 strerror(errno));
2454 return false;
2457 if (!torture_open_connection(&cli1, 0)) {
2458 return false;
2461 cli_sockopt(cli1, sockops);
2463 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2464 &fnum);
2465 if (!NT_STATUS_IS_OK(status)) {
2466 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2467 return false;
2470 /* Ensure the child has the lock. */
2471 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2472 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2473 goto fail;
2474 } else {
2475 d_printf("Child has the lock.\n");
2478 /* Tell the child to wait 5 seconds then exit. */
2479 ret = write(pipe_out[1], &c, 1);
2480 if (ret != 1) {
2481 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2482 strerror(errno));
2483 goto fail;
2486 /* Wait 20 seconds for the lock. */
2487 alarm_fd = cli1->fd;
2488 CatchSignal(SIGALRM, alarm_handler_parent);
2489 alarm(20);
2491 start = timeval_current();
2493 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2494 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2495 "%s\n", cli_errstr(cli1));
2496 goto fail_nofd;
2498 alarm(0);
2500 seconds = timeval_elapsed(&start);
2502 printf("Parent got the lock after %.2f seconds.\n",
2503 seconds);
2505 status = cli_close(cli1, fnum);
2506 if (!NT_STATUS_IS_OK(status)) {
2507 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2508 goto fail;
2511 correct = true;
2513 fail:
2514 cli_close(cli1, fnum);
2515 torture_close_connection(cli1);
2517 fail_nofd:
2519 printf("finished locktest9\n");
2520 return correct;
2524 test whether fnums and tids open on one VC are available on another (a major
2525 security hole)
2527 static bool run_fdpasstest(int dummy)
2529 struct cli_state *cli1, *cli2;
2530 const char *fname = "\\fdpass.tst";
2531 uint16_t fnum1;
2532 char buf[1024];
2534 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2535 return False;
2537 cli_sockopt(cli1, sockops);
2538 cli_sockopt(cli2, sockops);
2540 printf("starting fdpasstest\n");
2542 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2544 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2545 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2546 return False;
2549 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2550 printf("write failed (%s)\n", cli_errstr(cli1));
2551 return False;
2554 cli2->vuid = cli1->vuid;
2555 cli2->cnum = cli1->cnum;
2556 cli2->pid = cli1->pid;
2558 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2559 printf("read succeeded! nasty security hole [%s]\n",
2560 buf);
2561 return False;
2564 cli_close(cli1, fnum1);
2565 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2567 torture_close_connection(cli1);
2568 torture_close_connection(cli2);
2570 printf("finished fdpasstest\n");
2571 return True;
2574 static bool run_fdsesstest(int dummy)
2576 struct cli_state *cli;
2577 uint16 new_vuid;
2578 uint16 saved_vuid;
2579 uint16 new_cnum;
2580 uint16 saved_cnum;
2581 const char *fname = "\\fdsess.tst";
2582 const char *fname1 = "\\fdsess1.tst";
2583 uint16_t fnum1;
2584 uint16_t fnum2;
2585 char buf[1024];
2586 bool ret = True;
2588 if (!torture_open_connection(&cli, 0))
2589 return False;
2590 cli_sockopt(cli, sockops);
2592 if (!torture_cli_session_setup2(cli, &new_vuid))
2593 return False;
2595 saved_cnum = cli->cnum;
2596 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2597 return False;
2598 new_cnum = cli->cnum;
2599 cli->cnum = saved_cnum;
2601 printf("starting fdsesstest\n");
2603 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2604 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2606 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2607 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2608 return False;
2611 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2612 printf("write failed (%s)\n", cli_errstr(cli));
2613 return False;
2616 saved_vuid = cli->vuid;
2617 cli->vuid = new_vuid;
2619 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2620 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2621 buf);
2622 ret = False;
2624 /* Try to open a file with different vuid, samba cnum. */
2625 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2626 printf("create with different vuid, same cnum succeeded.\n");
2627 cli_close(cli, fnum2);
2628 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2629 } else {
2630 printf("create with different vuid, same cnum failed.\n");
2631 printf("This will cause problems with service clients.\n");
2632 ret = False;
2635 cli->vuid = saved_vuid;
2637 /* Try with same vuid, different cnum. */
2638 cli->cnum = new_cnum;
2640 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2641 printf("read succeeded with different cnum![%s]\n",
2642 buf);
2643 ret = False;
2646 cli->cnum = saved_cnum;
2647 cli_close(cli, fnum1);
2648 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2650 torture_close_connection(cli);
2652 printf("finished fdsesstest\n");
2653 return ret;
2657 This test checks that
2659 1) the server does not allow an unlink on a file that is open
2661 static bool run_unlinktest(int dummy)
2663 struct cli_state *cli;
2664 const char *fname = "\\unlink.tst";
2665 uint16_t fnum;
2666 bool correct = True;
2668 if (!torture_open_connection(&cli, 0)) {
2669 return False;
2672 cli_sockopt(cli, sockops);
2674 printf("starting unlink test\n");
2676 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2678 cli_setpid(cli, 1);
2680 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2681 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2682 return False;
2685 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2686 printf("error: server allowed unlink on an open file\n");
2687 correct = False;
2688 } else {
2689 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2690 NT_STATUS_SHARING_VIOLATION);
2693 cli_close(cli, fnum);
2694 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2696 if (!torture_close_connection(cli)) {
2697 correct = False;
2700 printf("unlink test finished\n");
2702 return correct;
2707 test how many open files this server supports on the one socket
2709 static bool run_maxfidtest(int dummy)
2711 struct cli_state *cli;
2712 const char *ftemplate = "\\maxfid.%d.%d";
2713 fstring fname;
2714 uint16_t fnums[0x11000];
2715 int i;
2716 int retries=4;
2717 bool correct = True;
2719 cli = current_cli;
2721 if (retries <= 0) {
2722 printf("failed to connect\n");
2723 return False;
2726 cli_sockopt(cli, sockops);
2728 for (i=0; i<0x11000; i++) {
2729 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2730 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2731 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2732 printf("open of %s failed (%s)\n",
2733 fname, cli_errstr(cli));
2734 printf("maximum fnum is %d\n", i);
2735 break;
2737 printf("%6d\r", i);
2739 printf("%6d\n", i);
2740 i--;
2742 printf("cleaning up\n");
2743 for (;i>=0;i--) {
2744 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2745 cli_close(cli, fnums[i]);
2746 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2747 printf("unlink of %s failed (%s)\n",
2748 fname, cli_errstr(cli));
2749 correct = False;
2751 printf("%6d\r", i);
2753 printf("%6d\n", 0);
2755 printf("maxfid test finished\n");
2756 if (!torture_close_connection(cli)) {
2757 correct = False;
2759 return correct;
2762 /* generate a random buffer */
2763 static void rand_buf(char *buf, int len)
2765 while (len--) {
2766 *buf = (char)sys_random();
2767 buf++;
2771 /* send smb negprot commands, not reading the response */
2772 static bool run_negprot_nowait(int dummy)
2774 int i;
2775 static struct cli_state *cli;
2776 bool correct = True;
2778 printf("starting negprot nowait test\n");
2780 if (!(cli = open_nbt_connection())) {
2781 return False;
2784 for (i=0;i<50000;i++) {
2785 cli_negprot_sendsync(cli);
2788 if (!torture_close_connection(cli)) {
2789 correct = False;
2792 printf("finished negprot nowait test\n");
2794 return correct;
2797 /* send smb negprot commands, not reading the response */
2798 static bool run_bad_nbt_session(int dummy)
2800 static struct cli_state *cli;
2802 printf("starting bad nbt session test\n");
2804 if (!(cli = open_bad_nbt_connection())) {
2805 return False;
2808 cli_shutdown(cli);
2809 printf("finished bad nbt session test\n");
2810 return true;
2813 /* send random IPC commands */
2814 static bool run_randomipc(int dummy)
2816 char *rparam = NULL;
2817 char *rdata = NULL;
2818 unsigned int rdrcnt,rprcnt;
2819 char param[1024];
2820 int api, param_len, i;
2821 struct cli_state *cli;
2822 bool correct = True;
2823 int count = 50000;
2825 printf("starting random ipc test\n");
2827 if (!torture_open_connection(&cli, 0)) {
2828 return False;
2831 for (i=0;i<count;i++) {
2832 api = sys_random() % 500;
2833 param_len = (sys_random() % 64);
2835 rand_buf(param, param_len);
2837 SSVAL(param,0,api);
2839 cli_api(cli,
2840 param, param_len, 8,
2841 NULL, 0, BUFFER_SIZE,
2842 &rparam, &rprcnt,
2843 &rdata, &rdrcnt);
2844 if (i % 100 == 0) {
2845 printf("%d/%d\r", i,count);
2848 printf("%d/%d\n", i, count);
2850 if (!torture_close_connection(cli)) {
2851 correct = False;
2854 printf("finished random ipc test\n");
2856 return correct;
2861 static void browse_callback(const char *sname, uint32 stype,
2862 const char *comment, void *state)
2864 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2870 This test checks the browse list code
2873 static bool run_browsetest(int dummy)
2875 static struct cli_state *cli;
2876 bool correct = True;
2878 printf("starting browse test\n");
2880 if (!torture_open_connection(&cli, 0)) {
2881 return False;
2884 printf("domain list:\n");
2885 cli_NetServerEnum(cli, cli->server_domain,
2886 SV_TYPE_DOMAIN_ENUM,
2887 browse_callback, NULL);
2889 printf("machine list:\n");
2890 cli_NetServerEnum(cli, cli->server_domain,
2891 SV_TYPE_ALL,
2892 browse_callback, NULL);
2894 if (!torture_close_connection(cli)) {
2895 correct = False;
2898 printf("browse test finished\n");
2900 return correct;
2906 This checks how the getatr calls works
2908 static bool run_attrtest(int dummy)
2910 struct cli_state *cli;
2911 uint16_t fnum;
2912 time_t t, t2;
2913 const char *fname = "\\attrib123456789.tst";
2914 bool correct = True;
2916 printf("starting attrib test\n");
2918 if (!torture_open_connection(&cli, 0)) {
2919 return False;
2922 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2923 cli_open(cli, fname,
2924 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2925 cli_close(cli, fnum);
2926 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2927 printf("getatr failed (%s)\n", cli_errstr(cli));
2928 correct = False;
2931 if (abs(t - time(NULL)) > 60*60*24*10) {
2932 printf("ERROR: SMBgetatr bug. time is %s",
2933 ctime(&t));
2934 t = time(NULL);
2935 correct = True;
2938 t2 = t-60*60*24; /* 1 day ago */
2940 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2941 printf("setatr failed (%s)\n", cli_errstr(cli));
2942 correct = True;
2945 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2946 printf("getatr failed (%s)\n", cli_errstr(cli));
2947 correct = True;
2950 if (t != t2) {
2951 printf("ERROR: getatr/setatr bug. times are\n%s",
2952 ctime(&t));
2953 printf("%s", ctime(&t2));
2954 correct = True;
2957 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2959 if (!torture_close_connection(cli)) {
2960 correct = False;
2963 printf("attrib test finished\n");
2965 return correct;
2970 This checks a couple of trans2 calls
2972 static bool run_trans2test(int dummy)
2974 struct cli_state *cli;
2975 uint16_t fnum;
2976 SMB_OFF_T size;
2977 time_t c_time, a_time, m_time;
2978 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2979 const char *fname = "\\trans2.tst";
2980 const char *dname = "\\trans2";
2981 const char *fname2 = "\\trans2\\trans2.tst";
2982 char pname[1024];
2983 bool correct = True;
2984 NTSTATUS status;
2985 uint32_t fs_attr;
2987 printf("starting trans2 test\n");
2989 if (!torture_open_connection(&cli, 0)) {
2990 return False;
2993 status = cli_get_fs_attr_info(cli, &fs_attr);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2996 nt_errstr(status));
2997 correct = false;
3000 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3001 cli_open(cli, fname,
3002 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3003 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3004 cli, fnum, NULL, &size, &c_time_ts,
3005 &a_time_ts, &w_time_ts,
3006 &m_time_ts, NULL))) {
3007 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3008 correct = False;
3011 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3012 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3013 correct = False;
3016 if (strcmp(pname, fname)) {
3017 printf("qfilename gave different name? [%s] [%s]\n",
3018 fname, pname);
3019 correct = False;
3022 cli_close(cli, fnum);
3024 sleep(2);
3026 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3027 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3028 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3029 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3030 return False;
3032 cli_close(cli, fnum);
3034 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3035 NULL);
3036 if (!NT_STATUS_IS_OK(status)) {
3037 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3038 correct = False;
3039 } else {
3040 if (c_time != m_time) {
3041 printf("create time=%s", ctime(&c_time));
3042 printf("modify time=%s", ctime(&m_time));
3043 printf("This system appears to have sticky create times\n");
3045 if (a_time % (60*60) == 0) {
3046 printf("access time=%s", ctime(&a_time));
3047 printf("This system appears to set a midnight access time\n");
3048 correct = False;
3051 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3052 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3053 correct = False;
3058 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3059 cli_open(cli, fname,
3060 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3061 cli_close(cli, fnum);
3062 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3063 &m_time_ts, &size, NULL, NULL);
3064 if (!NT_STATUS_IS_OK(status)) {
3065 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3066 correct = False;
3067 } else {
3068 if (w_time_ts.tv_sec < 60*60*24*2) {
3069 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3070 printf("This system appears to set a initial 0 write time\n");
3071 correct = False;
3075 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3078 /* check if the server updates the directory modification time
3079 when creating a new file */
3080 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3081 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3082 correct = False;
3084 sleep(3);
3085 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3086 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3089 correct = False;
3092 cli_open(cli, fname2,
3093 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3094 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
3095 cli_close(cli, fnum);
3096 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3097 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3098 if (!NT_STATUS_IS_OK(status)) {
3099 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3100 correct = False;
3101 } else {
3102 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3103 == 0) {
3104 printf("This system does not update directory modification times\n");
3105 correct = False;
3108 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3109 cli_rmdir(cli, dname);
3111 if (!torture_close_connection(cli)) {
3112 correct = False;
3115 printf("trans2 test finished\n");
3117 return correct;
3121 This checks new W2K calls.
3124 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3126 uint8_t *buf = NULL;
3127 uint32 len;
3128 NTSTATUS status;
3130 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3131 pcli->max_xmit, &buf, &len);
3132 if (!NT_STATUS_IS_OK(status)) {
3133 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3134 nt_errstr(status));
3135 } else {
3136 printf("qfileinfo: level %d, len = %u\n", level, len);
3137 dump_data(0, (uint8 *)buf, len);
3138 printf("\n");
3140 TALLOC_FREE(buf);
3141 return status;
3144 static bool run_w2ktest(int dummy)
3146 struct cli_state *cli;
3147 uint16_t fnum;
3148 const char *fname = "\\w2ktest\\w2k.tst";
3149 int level;
3150 bool correct = True;
3152 printf("starting w2k test\n");
3154 if (!torture_open_connection(&cli, 0)) {
3155 return False;
3158 cli_open(cli, fname,
3159 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3161 for (level = 1004; level < 1040; level++) {
3162 new_trans(cli, fnum, level);
3165 cli_close(cli, fnum);
3167 if (!torture_close_connection(cli)) {
3168 correct = False;
3171 printf("w2k test finished\n");
3173 return correct;
3178 this is a harness for some oplock tests
3180 static bool run_oplock1(int dummy)
3182 struct cli_state *cli1;
3183 const char *fname = "\\lockt1.lck";
3184 uint16_t fnum1;
3185 bool correct = True;
3187 printf("starting oplock test 1\n");
3189 if (!torture_open_connection(&cli1, 0)) {
3190 return False;
3193 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3195 cli_sockopt(cli1, sockops);
3197 cli1->use_oplocks = True;
3199 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3200 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3201 return False;
3204 cli1->use_oplocks = False;
3206 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3207 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3209 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3210 printf("close2 failed (%s)\n", cli_errstr(cli1));
3211 return False;
3214 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3215 printf("unlink failed (%s)\n", cli_errstr(cli1));
3216 return False;
3219 if (!torture_close_connection(cli1)) {
3220 correct = False;
3223 printf("finished oplock test 1\n");
3225 return correct;
3228 static bool run_oplock2(int dummy)
3230 struct cli_state *cli1, *cli2;
3231 const char *fname = "\\lockt2.lck";
3232 uint16_t fnum1, fnum2;
3233 int saved_use_oplocks = use_oplocks;
3234 char buf[4];
3235 bool correct = True;
3236 volatile bool *shared_correct;
3238 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3239 *shared_correct = True;
3241 use_level_II_oplocks = True;
3242 use_oplocks = True;
3244 printf("starting oplock test 2\n");
3246 if (!torture_open_connection(&cli1, 0)) {
3247 use_level_II_oplocks = False;
3248 use_oplocks = saved_use_oplocks;
3249 return False;
3252 cli1->use_oplocks = True;
3253 cli1->use_level_II_oplocks = True;
3255 if (!torture_open_connection(&cli2, 1)) {
3256 use_level_II_oplocks = False;
3257 use_oplocks = saved_use_oplocks;
3258 return False;
3261 cli2->use_oplocks = True;
3262 cli2->use_level_II_oplocks = True;
3264 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3266 cli_sockopt(cli1, sockops);
3267 cli_sockopt(cli2, sockops);
3269 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3270 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3271 return False;
3274 /* Don't need the globals any more. */
3275 use_level_II_oplocks = False;
3276 use_oplocks = saved_use_oplocks;
3278 if (fork() == 0) {
3279 /* Child code */
3280 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3281 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3282 *shared_correct = False;
3283 exit(0);
3286 sleep(2);
3288 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3289 printf("close2 failed (%s)\n", cli_errstr(cli1));
3290 *shared_correct = False;
3293 exit(0);
3296 sleep(2);
3298 /* Ensure cli1 processes the break. Empty file should always return 0
3299 * bytes. */
3301 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3302 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3303 correct = False;
3306 /* Should now be at level II. */
3307 /* Test if sending a write locks causes a break to none. */
3309 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3310 printf("lock failed (%s)\n", cli_errstr(cli1));
3311 correct = False;
3314 cli_unlock(cli1, fnum1, 0, 4);
3316 sleep(2);
3318 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3319 printf("lock failed (%s)\n", cli_errstr(cli1));
3320 correct = False;
3323 cli_unlock(cli1, fnum1, 0, 4);
3325 sleep(2);
3327 cli_read(cli1, fnum1, buf, 0, 4);
3329 #if 0
3330 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3331 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3332 correct = False;
3334 #endif
3336 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3337 printf("close1 failed (%s)\n", cli_errstr(cli1));
3338 correct = False;
3341 sleep(4);
3343 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3344 printf("unlink failed (%s)\n", cli_errstr(cli1));
3345 correct = False;
3348 if (!torture_close_connection(cli1)) {
3349 correct = False;
3352 if (!*shared_correct) {
3353 correct = False;
3356 printf("finished oplock test 2\n");
3358 return correct;
3361 /* handler for oplock 3 tests */
3362 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3364 printf("got oplock break fnum=%d level=%d\n",
3365 fnum, level);
3366 return cli_oplock_ack(cli, fnum, level);
3369 static bool run_oplock3(int dummy)
3371 struct cli_state *cli;
3372 const char *fname = "\\oplockt3.dat";
3373 uint16_t fnum;
3374 char buf[4] = "abcd";
3375 bool correct = True;
3376 volatile bool *shared_correct;
3378 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3379 *shared_correct = True;
3381 printf("starting oplock test 3\n");
3383 if (fork() == 0) {
3384 /* Child code */
3385 use_oplocks = True;
3386 use_level_II_oplocks = True;
3387 if (!torture_open_connection(&cli, 0)) {
3388 *shared_correct = False;
3389 exit(0);
3391 sleep(2);
3392 /* try to trigger a oplock break in parent */
3393 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3394 cli_write(cli, fnum, 0, buf, 0, 4);
3395 exit(0);
3398 /* parent code */
3399 use_oplocks = True;
3400 use_level_II_oplocks = True;
3401 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3402 return False;
3404 cli_oplock_handler(cli, oplock3_handler);
3405 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3406 cli_write(cli, fnum, 0, buf, 0, 4);
3407 cli_close(cli, fnum);
3408 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3409 cli->timeout = 20000;
3410 cli_receive_smb(cli);
3411 printf("finished oplock test 3\n");
3413 return (correct && *shared_correct);
3415 /* What are we looking for here? What's sucess and what's FAILURE? */
3418 /* handler for oplock 4 tests */
3419 bool *oplock4_shared_correct;
3421 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3423 printf("got oplock break fnum=%d level=%d\n",
3424 fnum, level);
3425 *oplock4_shared_correct = true;
3426 cli_oplock_ack(cli, fnum, level);
3427 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3430 static bool run_oplock4(int dummy)
3432 struct cli_state *cli1, *cli2;
3433 const char *fname = "\\lockt4.lck";
3434 const char *fname_ln = "\\lockt4_ln.lck";
3435 uint16_t fnum1, fnum2;
3436 int saved_use_oplocks = use_oplocks;
3437 NTSTATUS status;
3438 bool correct = true;
3440 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3441 *oplock4_shared_correct = false;
3443 printf("starting oplock test 4\n");
3445 if (!torture_open_connection(&cli1, 0)) {
3446 use_level_II_oplocks = false;
3447 use_oplocks = saved_use_oplocks;
3448 return false;
3451 if (!torture_open_connection(&cli2, 1)) {
3452 use_level_II_oplocks = false;
3453 use_oplocks = saved_use_oplocks;
3454 return false;
3457 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3458 cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN);
3460 cli_sockopt(cli1, sockops);
3461 cli_sockopt(cli2, sockops);
3463 /* Create the file. */
3464 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3465 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3466 return false;
3469 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3470 printf("close1 failed (%s)\n", cli_errstr(cli1));
3471 return false;
3474 /* Now create a hardlink. */
3475 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3476 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3477 return false;
3480 /* Prove that opening hardlinks cause deny modes to conflict. */
3481 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3482 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3483 return false;
3486 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3487 if (NT_STATUS_IS_OK(status)) {
3488 printf("open of %s succeeded - should fail with sharing violation.\n",
3489 fname_ln);
3490 return false;
3493 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3494 printf("open of %s should fail with sharing violation. Got %s\n",
3495 fname_ln, nt_errstr(status));
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 cli1->use_oplocks = true;
3505 cli1->use_level_II_oplocks = true;
3507 cli2->use_oplocks = true;
3508 cli2->use_level_II_oplocks = true;
3510 cli_oplock_handler(cli1, oplock4_handler);
3511 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3512 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3513 return false;
3516 if (fork() == 0) {
3517 /* Child code */
3518 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3519 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3520 *oplock4_shared_correct = false;
3521 exit(0);
3524 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3525 printf("close2 failed (%s)\n", cli_errstr(cli1));
3526 *oplock4_shared_correct = false;
3529 exit(0);
3532 sleep(2);
3534 /* Process the oplock break. */
3535 cli_receive_smb(cli1);
3537 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3538 printf("close1 failed (%s)\n", cli_errstr(cli1));
3539 correct = false;
3542 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3543 printf("unlink failed (%s)\n", cli_errstr(cli1));
3544 correct = false;
3546 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN))) {
3547 printf("unlink failed (%s)\n", cli_errstr(cli1));
3548 correct = false;
3551 if (!torture_close_connection(cli1)) {
3552 correct = false;
3555 if (!*oplock4_shared_correct) {
3556 correct = false;
3559 printf("finished oplock test 4\n");
3561 return correct;
3566 Test delete on close semantics.
3568 static bool run_deletetest(int dummy)
3570 struct cli_state *cli1 = NULL;
3571 struct cli_state *cli2 = NULL;
3572 const char *fname = "\\delete.file";
3573 uint16_t fnum1 = (uint16_t)-1;
3574 uint16_t fnum2 = (uint16_t)-1;
3575 bool correct = True;
3577 printf("starting delete test\n");
3579 if (!torture_open_connection(&cli1, 0)) {
3580 return False;
3583 cli_sockopt(cli1, sockops);
3585 /* Test 1 - this should delete the file on close. */
3587 cli_setatr(cli1, fname, 0, 0);
3588 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3590 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3591 0, FILE_OVERWRITE_IF,
3592 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3593 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3594 correct = False;
3595 goto fail;
3598 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3599 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3600 correct = False;
3601 goto fail;
3604 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3605 printf("[1] open of %s succeeded (should fail)\n", fname);
3606 correct = False;
3607 goto fail;
3610 printf("first delete on close test succeeded.\n");
3612 /* Test 2 - this should delete the file on close. */
3614 cli_setatr(cli1, fname, 0, 0);
3615 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3617 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3618 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3619 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3620 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3621 correct = False;
3622 goto fail;
3625 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3626 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3627 correct = False;
3628 goto fail;
3631 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3632 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3633 correct = False;
3634 goto fail;
3637 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3638 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3639 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3640 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3641 correct = False;
3642 goto fail;
3644 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3645 } else
3646 printf("second delete on close test succeeded.\n");
3648 /* Test 3 - ... */
3649 cli_setatr(cli1, fname, 0, 0);
3650 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3652 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3653 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3654 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3655 correct = False;
3656 goto fail;
3659 /* This should fail with a sharing violation - open for delete is only compatible
3660 with SHARE_DELETE. */
3662 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3663 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3664 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3665 correct = False;
3666 goto fail;
3669 /* This should succeed. */
3671 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3672 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3673 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3674 correct = False;
3675 goto fail;
3678 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3679 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3680 correct = False;
3681 goto fail;
3684 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3685 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3686 correct = False;
3687 goto fail;
3690 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3691 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3692 correct = False;
3693 goto fail;
3696 /* This should fail - file should no longer be there. */
3698 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3699 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3700 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3701 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3703 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3704 correct = False;
3705 goto fail;
3706 } else
3707 printf("third delete on close test succeeded.\n");
3709 /* Test 4 ... */
3710 cli_setatr(cli1, fname, 0, 0);
3711 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3713 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3714 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3715 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3716 correct = False;
3717 goto fail;
3720 /* This should succeed. */
3721 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3722 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3723 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3724 correct = False;
3725 goto fail;
3728 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3729 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3730 correct = False;
3731 goto fail;
3734 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3735 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3736 correct = False;
3737 goto fail;
3740 /* This should fail - no more opens once delete on close set. */
3741 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3742 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3743 FILE_OPEN, 0, 0, &fnum2))) {
3744 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3745 correct = False;
3746 goto fail;
3747 } else
3748 printf("fourth delete on close test succeeded.\n");
3750 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3751 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3752 correct = False;
3753 goto fail;
3756 /* Test 5 ... */
3757 cli_setatr(cli1, fname, 0, 0);
3758 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3760 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3761 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3762 correct = False;
3763 goto fail;
3766 /* This should fail - only allowed on NT opens with DELETE access. */
3768 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3769 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3770 correct = False;
3771 goto fail;
3774 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3775 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3776 correct = False;
3777 goto fail;
3780 printf("fifth delete on close test succeeded.\n");
3782 /* Test 6 ... */
3783 cli_setatr(cli1, fname, 0, 0);
3784 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3786 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3787 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3788 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3789 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3790 correct = False;
3791 goto fail;
3794 /* This should fail - only allowed on NT opens with DELETE access. */
3796 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3797 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3798 correct = False;
3799 goto fail;
3802 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3803 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3804 correct = False;
3805 goto fail;
3808 printf("sixth delete on close test succeeded.\n");
3810 /* Test 7 ... */
3811 cli_setatr(cli1, fname, 0, 0);
3812 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3814 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3815 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3816 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3817 correct = False;
3818 goto fail;
3821 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3822 printf("[7] setting delete_on_close on file failed !\n");
3823 correct = False;
3824 goto fail;
3827 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3828 printf("[7] unsetting delete_on_close on file failed !\n");
3829 correct = False;
3830 goto fail;
3833 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3834 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3835 correct = False;
3836 goto fail;
3839 /* This next open should succeed - we reset the flag. */
3841 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3842 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3843 correct = False;
3844 goto fail;
3847 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3848 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3849 correct = False;
3850 goto fail;
3853 printf("seventh delete on close test succeeded.\n");
3855 /* Test 7 ... */
3856 cli_setatr(cli1, fname, 0, 0);
3857 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3859 if (!torture_open_connection(&cli2, 1)) {
3860 printf("[8] failed to open second connection.\n");
3861 correct = False;
3862 goto fail;
3865 cli_sockopt(cli1, sockops);
3867 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3868 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3869 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3870 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3871 correct = False;
3872 goto fail;
3875 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3876 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3877 FILE_OPEN, 0, 0, &fnum2))) {
3878 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3879 correct = False;
3880 goto fail;
3883 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3884 printf("[8] setting delete_on_close on file failed !\n");
3885 correct = False;
3886 goto fail;
3889 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3890 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3891 correct = False;
3892 goto fail;
3895 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3896 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3897 correct = False;
3898 goto fail;
3901 /* This should fail.. */
3902 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3903 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3904 goto fail;
3905 correct = False;
3906 } else
3907 printf("eighth delete on close test succeeded.\n");
3909 /* This should fail - we need to set DELETE_ACCESS. */
3910 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3911 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3912 printf("[9] open of %s succeeded should have failed!\n", fname);
3913 correct = False;
3914 goto fail;
3917 printf("ninth delete on close test succeeded.\n");
3919 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3920 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3921 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3922 correct = False;
3923 goto fail;
3926 /* This should delete the file. */
3927 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3928 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3929 correct = False;
3930 goto fail;
3933 /* This should fail.. */
3934 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3935 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3936 goto fail;
3937 correct = False;
3938 } else
3939 printf("tenth delete on close test succeeded.\n");
3941 cli_setatr(cli1, fname, 0, 0);
3942 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3944 /* What error do we get when attempting to open a read-only file with
3945 delete access ? */
3947 /* Create a readonly file. */
3948 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3949 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3950 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3951 correct = False;
3952 goto fail;
3955 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3956 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3957 correct = False;
3958 goto fail;
3961 /* Now try open for delete access. */
3962 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3963 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3964 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3965 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3966 cli_close(cli1, fnum1);
3967 goto fail;
3968 correct = False;
3969 } else {
3970 NTSTATUS nterr = cli_nt_error(cli1);
3971 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3972 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3973 goto fail;
3974 correct = False;
3975 } else {
3976 printf("eleventh delete on close test succeeded.\n");
3980 printf("finished delete test\n");
3982 fail:
3983 /* FIXME: This will crash if we aborted before cli2 got
3984 * intialized, because these functions don't handle
3985 * uninitialized connections. */
3987 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3988 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3989 cli_setatr(cli1, fname, 0, 0);
3990 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3992 if (cli1 && !torture_close_connection(cli1)) {
3993 correct = False;
3995 if (cli2 && !torture_close_connection(cli2)) {
3996 correct = False;
3998 return correct;
4001 static bool run_deletetest_ln(int dummy)
4003 struct cli_state *cli;
4004 const char *fname = "\\delete1";
4005 const char *fname_ln = "\\delete1_ln";
4006 uint16_t fnum;
4007 uint16_t fnum1;
4008 NTSTATUS status;
4009 bool correct = true;
4010 time_t t;
4012 printf("starting deletetest-ln\n");
4014 if (!torture_open_connection(&cli, 0)) {
4015 return false;
4018 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4019 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4021 cli_sockopt(cli, sockops);
4023 /* Create the file. */
4024 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4025 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4026 return false;
4029 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4030 printf("close1 failed (%s)\n", cli_errstr(cli));
4031 return false;
4034 /* Now create a hardlink. */
4035 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4036 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4037 return false;
4040 /* Open the original file. */
4041 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4042 FILE_ATTRIBUTE_NORMAL,
4043 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4044 FILE_OPEN_IF, 0, 0, &fnum);
4045 if (!NT_STATUS_IS_OK(status)) {
4046 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4047 return false;
4050 /* Unlink the hard link path. */
4051 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4052 FILE_ATTRIBUTE_NORMAL,
4053 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4054 FILE_OPEN_IF, 0, 0, &fnum1);
4055 if (!NT_STATUS_IS_OK(status)) {
4056 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4057 return false;
4059 status = cli_nt_delete_on_close(cli, fnum1, true);
4060 if (!NT_STATUS_IS_OK(status)) {
4061 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4062 __location__, fname_ln, nt_errstr(status));
4063 return false;
4066 status = cli_close(cli, fnum1);
4067 if (!NT_STATUS_IS_OK(status)) {
4068 printf("close %s failed (%s)\n",
4069 fname_ln, nt_errstr(status));
4070 return false;
4073 status = cli_close(cli, fnum);
4074 if (!NT_STATUS_IS_OK(status)) {
4075 printf("close %s failed (%s)\n",
4076 fname, nt_errstr(status));
4077 return false;
4080 /* Ensure the original file is still there. */
4081 status = cli_getatr(cli, fname, NULL, NULL, &t);
4082 if (!NT_STATUS_IS_OK(status)) {
4083 printf("%s getatr on file %s failed (%s)\n",
4084 __location__,
4085 fname,
4086 nt_errstr(status));
4087 correct = False;
4090 /* Ensure the link path is gone. */
4091 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4092 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4093 printf("%s, getatr for file %s returned wrong error code %s "
4094 "- should have been deleted\n",
4095 __location__,
4096 fname_ln, nt_errstr(status));
4097 correct = False;
4100 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4101 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4103 if (!torture_close_connection(cli)) {
4104 correct = false;
4107 printf("finished deletetest-ln\n");
4109 return correct;
4113 print out server properties
4115 static bool run_properties(int dummy)
4117 struct cli_state *cli;
4118 bool correct = True;
4120 printf("starting properties test\n");
4122 ZERO_STRUCT(cli);
4124 if (!torture_open_connection(&cli, 0)) {
4125 return False;
4128 cli_sockopt(cli, sockops);
4130 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4132 if (!torture_close_connection(cli)) {
4133 correct = False;
4136 return correct;
4141 /* FIRST_DESIRED_ACCESS 0xf019f */
4142 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4143 FILE_READ_EA| /* 0xf */ \
4144 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4145 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4146 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4147 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4148 /* SECOND_DESIRED_ACCESS 0xe0080 */
4149 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4150 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4151 WRITE_OWNER_ACCESS /* 0xe0000 */
4153 #if 0
4154 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4155 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4156 FILE_READ_DATA|\
4157 WRITE_OWNER_ACCESS /* */
4158 #endif
4161 Test ntcreate calls made by xcopy
4163 static bool run_xcopy(int dummy)
4165 static struct cli_state *cli1;
4166 const char *fname = "\\test.txt";
4167 bool correct = True;
4168 uint16_t fnum1, fnum2;
4170 printf("starting xcopy test\n");
4172 if (!torture_open_connection(&cli1, 0)) {
4173 return False;
4176 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4177 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4178 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4179 0x4044, 0, &fnum1))) {
4180 printf("First open failed - %s\n", cli_errstr(cli1));
4181 return False;
4184 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4185 SECOND_DESIRED_ACCESS, 0,
4186 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4187 0x200000, 0, &fnum2))) {
4188 printf("second open failed - %s\n", cli_errstr(cli1));
4189 return False;
4192 if (!torture_close_connection(cli1)) {
4193 correct = False;
4196 return correct;
4200 Test rename on files open with share delete and no share delete.
4202 static bool run_rename(int dummy)
4204 static struct cli_state *cli1;
4205 const char *fname = "\\test.txt";
4206 const char *fname1 = "\\test1.txt";
4207 bool correct = True;
4208 uint16_t fnum1;
4209 uint16_t attr;
4210 NTSTATUS status;
4212 printf("starting rename test\n");
4214 if (!torture_open_connection(&cli1, 0)) {
4215 return False;
4218 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4219 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4220 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4221 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4222 printf("First open failed - %s\n", cli_errstr(cli1));
4223 return False;
4226 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4227 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4228 } else {
4229 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4230 correct = False;
4233 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4234 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4235 return False;
4238 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4239 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4240 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4241 #if 0
4242 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4243 #else
4244 FILE_SHARE_DELETE|FILE_SHARE_READ,
4245 #endif
4246 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4247 if (!NT_STATUS_IS_OK(status)) {
4248 printf("Second open failed - %s\n", cli_errstr(cli1));
4249 return False;
4252 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4253 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4254 correct = False;
4255 } else {
4256 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4259 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4260 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4261 return False;
4264 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4265 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4267 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4268 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4269 printf("Third open failed - %s\n", cli_errstr(cli1));
4270 return False;
4274 #if 0
4276 uint16_t fnum2;
4278 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4279 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4280 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4281 return False;
4283 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4284 printf("[8] setting delete_on_close on file failed !\n");
4285 return False;
4288 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4289 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4290 return False;
4293 #endif
4295 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4296 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4297 correct = False;
4298 } else {
4299 printf("Third rename succeeded (SHARE_NONE)\n");
4302 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4303 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4304 return False;
4307 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4308 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4310 /*----*/
4312 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4313 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4314 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4315 return False;
4318 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4319 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4320 } else {
4321 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4322 correct = False;
4325 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4326 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4327 return False;
4330 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4331 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4333 /*--*/
4335 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4336 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4337 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4338 return False;
4341 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4342 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4343 cli_errstr(cli1));
4344 correct = False;
4345 } else {
4346 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4350 * Now check if the first name still exists ...
4353 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4354 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4355 printf("Opening original file after rename of open file fails: %s\n",
4356 cli_errstr(cli1));
4358 else {
4359 printf("Opening original file after rename of open file works ...\n");
4360 (void)cli_close(cli1, fnum2);
4361 } */
4363 /*--*/
4364 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4365 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4366 return False;
4369 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4370 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4371 printf("getatr on file %s failed - %s ! \n",
4372 fname1,
4373 cli_errstr(cli1));
4374 correct = False;
4375 } else {
4376 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4377 printf("Renamed file %s has wrong attr 0x%x "
4378 "(should be 0x%x)\n",
4379 fname1,
4380 attr,
4381 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4382 correct = False;
4383 } else {
4384 printf("Renamed file %s has archive bit set\n", fname1);
4388 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4389 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4391 if (!torture_close_connection(cli1)) {
4392 correct = False;
4395 return correct;
4398 static bool run_pipe_number(int dummy)
4400 struct cli_state *cli1;
4401 const char *pipe_name = "\\SPOOLSS";
4402 uint16_t fnum;
4403 int num_pipes = 0;
4405 printf("starting pipenumber test\n");
4406 if (!torture_open_connection(&cli1, 0)) {
4407 return False;
4410 cli_sockopt(cli1, sockops);
4411 while(1) {
4412 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4413 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4414 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4415 break;
4417 num_pipes++;
4418 printf("\r%6d", num_pipes);
4421 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4422 torture_close_connection(cli1);
4423 return True;
4427 Test open mode returns on read-only files.
4429 static bool run_opentest(int dummy)
4431 static struct cli_state *cli1;
4432 static struct cli_state *cli2;
4433 const char *fname = "\\readonly.file";
4434 uint16_t fnum1, fnum2;
4435 char buf[20];
4436 SMB_OFF_T fsize;
4437 bool correct = True;
4438 char *tmp_path;
4440 printf("starting open test\n");
4442 if (!torture_open_connection(&cli1, 0)) {
4443 return False;
4446 cli_setatr(cli1, fname, 0, 0);
4447 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4449 cli_sockopt(cli1, sockops);
4451 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4452 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4453 return False;
4456 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4457 printf("close2 failed (%s)\n", cli_errstr(cli1));
4458 return False;
4461 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4462 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4463 return False;
4466 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4467 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4468 return False;
4471 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4472 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4474 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4475 NT_STATUS_ACCESS_DENIED)) {
4476 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4479 printf("finished open test 1\n");
4481 cli_close(cli1, fnum1);
4483 /* Now try not readonly and ensure ERRbadshare is returned. */
4485 cli_setatr(cli1, fname, 0, 0);
4487 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4488 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4489 return False;
4492 /* This will fail - but the error should be ERRshare. */
4493 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4495 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4496 NT_STATUS_SHARING_VIOLATION)) {
4497 printf("correct error code ERRDOS/ERRbadshare returned\n");
4500 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4501 printf("close2 failed (%s)\n", cli_errstr(cli1));
4502 return False;
4505 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4507 printf("finished open test 2\n");
4509 /* Test truncate open disposition on file opened for read. */
4511 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4512 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4513 return False;
4516 /* write 20 bytes. */
4518 memset(buf, '\0', 20);
4520 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4521 printf("write failed (%s)\n", cli_errstr(cli1));
4522 correct = False;
4525 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4526 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4527 return False;
4530 /* Ensure size == 20. */
4531 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4532 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4533 return False;
4536 if (fsize != 20) {
4537 printf("(3) file size != 20\n");
4538 return False;
4541 /* Now test if we can truncate a file opened for readonly. */
4543 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4544 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4545 return False;
4548 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4549 printf("close2 failed (%s)\n", cli_errstr(cli1));
4550 return False;
4553 /* Ensure size == 0. */
4554 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4555 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4556 return False;
4559 if (fsize != 0) {
4560 printf("(3) file size != 0\n");
4561 return False;
4563 printf("finished open test 3\n");
4565 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4567 printf("Do ctemp tests\n");
4568 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4569 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4570 return False;
4572 printf("ctemp gave path %s\n", tmp_path);
4573 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4574 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4576 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4577 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4580 /* Test the non-io opens... */
4582 if (!torture_open_connection(&cli2, 1)) {
4583 return False;
4586 cli_setatr(cli2, fname, 0, 0);
4587 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4589 cli_sockopt(cli2, sockops);
4591 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4593 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4594 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4595 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4596 return False;
4599 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4600 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4601 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4602 return False;
4605 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4606 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4607 return False;
4609 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4610 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4611 return False;
4614 printf("non-io open test #1 passed.\n");
4616 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4618 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4620 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4621 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4622 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4623 return False;
4626 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4627 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4628 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4629 return False;
4632 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4633 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4634 return False;
4636 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4637 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4638 return False;
4641 printf("non-io open test #2 passed.\n");
4643 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4645 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4647 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4648 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4649 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4650 return False;
4653 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4654 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4655 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4656 return False;
4659 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4660 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4661 return False;
4663 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4664 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4665 return False;
4668 printf("non-io open test #3 passed.\n");
4670 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4672 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4674 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4675 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4676 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4677 return False;
4680 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4681 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4682 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4683 return False;
4686 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4688 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4689 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4690 return False;
4693 printf("non-io open test #4 passed.\n");
4695 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4697 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4699 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4700 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4701 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4702 return False;
4705 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4706 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4707 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4708 return False;
4711 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4712 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4713 return False;
4716 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4717 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4718 return False;
4721 printf("non-io open test #5 passed.\n");
4723 printf("TEST #6 testing 1 non-io open, one io open\n");
4725 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4727 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4728 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4729 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4730 return False;
4733 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4734 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4735 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4736 return False;
4739 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4740 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4741 return False;
4744 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4745 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4746 return False;
4749 printf("non-io open test #6 passed.\n");
4751 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4753 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4755 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4756 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4757 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4758 return False;
4761 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4762 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4763 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4764 return False;
4767 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4769 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4770 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4771 return False;
4774 printf("non-io open test #7 passed.\n");
4776 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4778 if (!torture_close_connection(cli1)) {
4779 correct = False;
4781 if (!torture_close_connection(cli2)) {
4782 correct = False;
4785 return correct;
4788 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4790 uint16 major, minor;
4791 uint32 caplow, caphigh;
4792 NTSTATUS status;
4794 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4795 printf("Server doesn't support UNIX CIFS extensions.\n");
4796 return NT_STATUS_NOT_SUPPORTED;
4799 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4800 &caphigh);
4801 if (!NT_STATUS_IS_OK(status)) {
4802 printf("Server didn't return UNIX CIFS extensions: %s\n",
4803 nt_errstr(status));
4804 return status;
4807 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4808 caplow, caphigh);
4809 if (!NT_STATUS_IS_OK(status)) {
4810 printf("Server doesn't support setting UNIX CIFS extensions: "
4811 "%s.\n", nt_errstr(status));
4812 return status;
4815 return NT_STATUS_OK;
4819 Test POSIX open /mkdir calls.
4821 static bool run_simple_posix_open_test(int dummy)
4823 static struct cli_state *cli1;
4824 const char *fname = "posix:file";
4825 const char *hname = "posix:hlink";
4826 const char *sname = "posix:symlink";
4827 const char *dname = "posix:dir";
4828 char buf[10];
4829 char namebuf[11];
4830 uint16_t fnum1 = (uint16_t)-1;
4831 SMB_STRUCT_STAT sbuf;
4832 bool correct = false;
4833 NTSTATUS status;
4835 printf("Starting simple POSIX open test\n");
4837 if (!torture_open_connection(&cli1, 0)) {
4838 return false;
4841 cli_sockopt(cli1, sockops);
4843 status = torture_setup_unix_extensions(cli1);
4844 if (!NT_STATUS_IS_OK(status)) {
4845 return false;
4848 cli_setatr(cli1, fname, 0, 0);
4849 cli_posix_unlink(cli1, fname);
4850 cli_setatr(cli1, dname, 0, 0);
4851 cli_posix_rmdir(cli1, dname);
4852 cli_setatr(cli1, hname, 0, 0);
4853 cli_posix_unlink(cli1, hname);
4854 cli_setatr(cli1, sname, 0, 0);
4855 cli_posix_unlink(cli1, sname);
4857 /* Create a directory. */
4858 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4859 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4860 goto out;
4863 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4864 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4865 goto out;
4868 /* Test ftruncate - set file size. */
4869 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4870 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4871 goto out;
4874 /* Ensure st_size == 1000 */
4875 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4876 printf("stat failed (%s)\n", cli_errstr(cli1));
4877 goto out;
4880 if (sbuf.st_ex_size != 1000) {
4881 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4882 goto out;
4885 /* Test ftruncate - set file size back to zero. */
4886 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4887 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4888 goto out;
4891 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4892 printf("close failed (%s)\n", cli_errstr(cli1));
4893 goto out;
4896 /* Now open the file again for read only. */
4897 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4898 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4899 goto out;
4902 /* Now unlink while open. */
4903 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4904 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4905 goto out;
4908 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4909 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4910 goto out;
4913 /* Ensure the file has gone. */
4914 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4915 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4916 goto out;
4919 /* What happens when we try and POSIX open a directory ? */
4920 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4921 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4922 goto out;
4923 } else {
4924 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4925 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4926 goto out;
4930 /* Create the file. */
4931 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4932 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4933 goto out;
4936 /* Write some data into it. */
4937 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4938 printf("cli_write failed: %s\n", cli_errstr(cli1));
4939 goto out;
4942 cli_close(cli1, fnum1);
4944 /* Now create a hardlink. */
4945 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4946 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4947 goto out;
4950 /* Now create a symlink. */
4951 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4952 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4953 goto out;
4956 /* Open the hardlink for read. */
4957 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4958 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4959 goto out;
4962 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4963 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4964 goto out;
4967 if (memcmp(buf, "TEST DATA\n", 10)) {
4968 printf("invalid data read from hardlink\n");
4969 goto out;
4972 /* Do a POSIX lock/unlock. */
4973 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4974 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4975 goto out;
4978 /* Punch a hole in the locked area. */
4979 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4980 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4981 goto out;
4984 cli_close(cli1, fnum1);
4986 /* Open the symlink for read - this should fail. A POSIX
4987 client should not be doing opens on a symlink. */
4988 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4989 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4990 goto out;
4991 } else {
4992 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4993 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4994 printf("POSIX open of %s should have failed "
4995 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4996 "failed with %s instead.\n",
4997 sname, cli_errstr(cli1));
4998 goto out;
5002 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5003 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5004 goto out;
5007 if (strcmp(namebuf, fname) != 0) {
5008 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5009 sname, fname, namebuf);
5010 goto out;
5013 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5014 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5015 goto out;
5018 printf("Simple POSIX open test passed\n");
5019 correct = true;
5021 out:
5023 if (fnum1 != (uint16_t)-1) {
5024 cli_close(cli1, fnum1);
5025 fnum1 = (uint16_t)-1;
5028 cli_setatr(cli1, sname, 0, 0);
5029 cli_posix_unlink(cli1, sname);
5030 cli_setatr(cli1, hname, 0, 0);
5031 cli_posix_unlink(cli1, hname);
5032 cli_setatr(cli1, fname, 0, 0);
5033 cli_posix_unlink(cli1, fname);
5034 cli_setatr(cli1, dname, 0, 0);
5035 cli_posix_rmdir(cli1, dname);
5037 if (!torture_close_connection(cli1)) {
5038 correct = false;
5041 return correct;
5045 static uint32 open_attrs_table[] = {
5046 FILE_ATTRIBUTE_NORMAL,
5047 FILE_ATTRIBUTE_ARCHIVE,
5048 FILE_ATTRIBUTE_READONLY,
5049 FILE_ATTRIBUTE_HIDDEN,
5050 FILE_ATTRIBUTE_SYSTEM,
5052 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5053 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5054 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5055 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5056 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5057 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5059 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5060 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5061 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5062 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5065 struct trunc_open_results {
5066 unsigned int num;
5067 uint32 init_attr;
5068 uint32 trunc_attr;
5069 uint32 result_attr;
5072 static struct trunc_open_results attr_results[] = {
5073 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5074 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5075 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5076 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5077 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5078 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5079 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5080 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5081 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5082 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5083 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5084 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5085 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5086 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5087 { 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 },
5088 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5089 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5090 { 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 },
5091 { 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 },
5092 { 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 },
5093 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5094 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5095 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5096 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5097 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5098 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5101 static bool run_openattrtest(int dummy)
5103 static struct cli_state *cli1;
5104 const char *fname = "\\openattr.file";
5105 uint16_t fnum1;
5106 bool correct = True;
5107 uint16 attr;
5108 unsigned int i, j, k, l;
5110 printf("starting open attr test\n");
5112 if (!torture_open_connection(&cli1, 0)) {
5113 return False;
5116 cli_sockopt(cli1, sockops);
5118 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5119 cli_setatr(cli1, fname, 0, 0);
5120 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5121 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5122 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5123 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5124 return False;
5127 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5128 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5129 return False;
5132 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5133 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5134 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5135 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5136 if (attr_results[l].num == k) {
5137 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5138 k, open_attrs_table[i],
5139 open_attrs_table[j],
5140 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5141 correct = False;
5144 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5145 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5146 k, open_attrs_table[i], open_attrs_table[j],
5147 cli_errstr(cli1));
5148 correct = False;
5150 #if 0
5151 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5152 #endif
5153 k++;
5154 continue;
5157 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5158 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5159 return False;
5162 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5163 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5164 return False;
5167 #if 0
5168 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5169 k, open_attrs_table[i], open_attrs_table[j], attr );
5170 #endif
5172 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5173 if (attr_results[l].num == k) {
5174 if (attr != attr_results[l].result_attr ||
5175 open_attrs_table[i] != attr_results[l].init_attr ||
5176 open_attrs_table[j] != attr_results[l].trunc_attr) {
5177 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5178 open_attrs_table[i],
5179 open_attrs_table[j],
5180 (unsigned int)attr,
5181 attr_results[l].result_attr);
5182 correct = False;
5184 break;
5187 k++;
5191 cli_setatr(cli1, fname, 0, 0);
5192 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5194 printf("open attr test %s.\n", correct ? "passed" : "failed");
5196 if (!torture_close_connection(cli1)) {
5197 correct = False;
5199 return correct;
5202 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5203 const char *name, void *state)
5205 int *matched = (int *)state;
5206 if (matched != NULL) {
5207 *matched += 1;
5209 return NT_STATUS_OK;
5213 test directory listing speed
5215 static bool run_dirtest(int dummy)
5217 int i;
5218 static struct cli_state *cli;
5219 uint16_t fnum;
5220 struct timeval core_start;
5221 bool correct = True;
5222 int matched;
5224 printf("starting directory test\n");
5226 if (!torture_open_connection(&cli, 0)) {
5227 return False;
5230 cli_sockopt(cli, sockops);
5232 srandom(0);
5233 for (i=0;i<torture_numops;i++) {
5234 fstring fname;
5235 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5236 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5237 fprintf(stderr,"Failed to open %s\n", fname);
5238 return False;
5240 cli_close(cli, fnum);
5243 core_start = timeval_current();
5245 matched = 0;
5246 cli_list(cli, "a*.*", 0, list_fn, &matched);
5247 printf("Matched %d\n", matched);
5249 matched = 0;
5250 cli_list(cli, "b*.*", 0, list_fn, &matched);
5251 printf("Matched %d\n", matched);
5253 matched = 0;
5254 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5255 printf("Matched %d\n", matched);
5257 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5259 srandom(0);
5260 for (i=0;i<torture_numops;i++) {
5261 fstring fname;
5262 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5263 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5266 if (!torture_close_connection(cli)) {
5267 correct = False;
5270 printf("finished dirtest\n");
5272 return correct;
5275 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5276 void *state)
5278 struct cli_state *pcli = (struct cli_state *)state;
5279 fstring fname;
5280 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5282 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5283 return NT_STATUS_OK;
5285 if (finfo->mode & aDIR) {
5286 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5287 printf("del_fn: failed to rmdir %s\n,", fname );
5288 } else {
5289 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5290 printf("del_fn: failed to unlink %s\n,", fname );
5292 return NT_STATUS_OK;
5297 sees what IOCTLs are supported
5299 bool torture_ioctl_test(int dummy)
5301 static struct cli_state *cli;
5302 uint16_t device, function;
5303 uint16_t fnum;
5304 const char *fname = "\\ioctl.dat";
5305 DATA_BLOB blob;
5306 NTSTATUS status;
5308 if (!torture_open_connection(&cli, 0)) {
5309 return False;
5312 printf("starting ioctl test\n");
5314 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5316 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5317 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5318 return False;
5321 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5322 printf("ioctl device info: %s\n", nt_errstr(status));
5324 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5325 printf("ioctl job info: %s\n", nt_errstr(status));
5327 for (device=0;device<0x100;device++) {
5328 printf("ioctl test with device = 0x%x\n", device);
5329 for (function=0;function<0x100;function++) {
5330 uint32 code = (device<<16) | function;
5332 status = cli_raw_ioctl(cli, fnum, code, &blob);
5334 if (NT_STATUS_IS_OK(status)) {
5335 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5336 (int)blob.length);
5337 data_blob_free(&blob);
5342 if (!torture_close_connection(cli)) {
5343 return False;
5346 return True;
5351 tries varients of chkpath
5353 bool torture_chkpath_test(int dummy)
5355 static struct cli_state *cli;
5356 uint16_t fnum;
5357 bool ret;
5359 if (!torture_open_connection(&cli, 0)) {
5360 return False;
5363 printf("starting chkpath test\n");
5365 /* cleanup from an old run */
5366 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5367 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5368 cli_rmdir(cli, "\\chkpath.dir");
5370 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5371 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5372 return False;
5375 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5376 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5377 return False;
5380 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5381 printf("open1 failed (%s)\n", cli_errstr(cli));
5382 return False;
5384 cli_close(cli, fnum);
5386 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5387 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5388 ret = False;
5391 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5392 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5393 ret = False;
5396 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5397 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5398 NT_STATUS_NOT_A_DIRECTORY);
5399 } else {
5400 printf("* chkpath on a file should fail\n");
5401 ret = False;
5404 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5405 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5406 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5407 } else {
5408 printf("* chkpath on a non existant file should fail\n");
5409 ret = False;
5412 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5413 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5414 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5415 } else {
5416 printf("* chkpath on a non existent component should fail\n");
5417 ret = False;
5420 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5421 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5422 cli_rmdir(cli, "\\chkpath.dir");
5424 if (!torture_close_connection(cli)) {
5425 return False;
5428 return ret;
5431 static bool run_eatest(int dummy)
5433 static struct cli_state *cli;
5434 const char *fname = "\\eatest.txt";
5435 bool correct = True;
5436 uint16_t fnum;
5437 int i;
5438 size_t num_eas;
5439 struct ea_struct *ea_list = NULL;
5440 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5441 NTSTATUS status;
5443 printf("starting eatest\n");
5445 if (!torture_open_connection(&cli, 0)) {
5446 talloc_destroy(mem_ctx);
5447 return False;
5450 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5451 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5452 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5453 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5454 0x4044, 0, &fnum))) {
5455 printf("open failed - %s\n", cli_errstr(cli));
5456 talloc_destroy(mem_ctx);
5457 return False;
5460 for (i = 0; i < 10; i++) {
5461 fstring ea_name, ea_val;
5463 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5464 memset(ea_val, (char)i+1, i+1);
5465 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5466 if (!NT_STATUS_IS_OK(status)) {
5467 printf("ea_set of name %s failed - %s\n", ea_name,
5468 nt_errstr(status));
5469 talloc_destroy(mem_ctx);
5470 return False;
5474 cli_close(cli, fnum);
5475 for (i = 0; i < 10; i++) {
5476 fstring ea_name, ea_val;
5478 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5479 memset(ea_val, (char)i+1, i+1);
5480 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5481 if (!NT_STATUS_IS_OK(status)) {
5482 printf("ea_set of name %s failed - %s\n", ea_name,
5483 nt_errstr(status));
5484 talloc_destroy(mem_ctx);
5485 return False;
5489 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5490 if (!NT_STATUS_IS_OK(status)) {
5491 printf("ea_get list failed - %s\n", nt_errstr(status));
5492 correct = False;
5495 printf("num_eas = %d\n", (int)num_eas);
5497 if (num_eas != 20) {
5498 printf("Should be 20 EA's stored... failing.\n");
5499 correct = False;
5502 for (i = 0; i < num_eas; i++) {
5503 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5504 dump_data(0, ea_list[i].value.data,
5505 ea_list[i].value.length);
5508 /* Setting EA's to zero length deletes them. Test this */
5509 printf("Now deleting all EA's - case indepenent....\n");
5511 #if 1
5512 cli_set_ea_path(cli, fname, "", "", 0);
5513 #else
5514 for (i = 0; i < 20; i++) {
5515 fstring ea_name;
5516 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5517 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5518 if (!NT_STATUS_IS_OK(status)) {
5519 printf("ea_set of name %s failed - %s\n", ea_name,
5520 nt_errstr(status));
5521 talloc_destroy(mem_ctx);
5522 return False;
5525 #endif
5527 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5528 if (!NT_STATUS_IS_OK(status)) {
5529 printf("ea_get list failed - %s\n", nt_errstr(status));
5530 correct = False;
5533 printf("num_eas = %d\n", (int)num_eas);
5534 for (i = 0; i < num_eas; i++) {
5535 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5536 dump_data(0, ea_list[i].value.data,
5537 ea_list[i].value.length);
5540 if (num_eas != 0) {
5541 printf("deleting EA's failed.\n");
5542 correct = False;
5545 /* Try and delete a non existant EA. */
5546 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5547 if (!NT_STATUS_IS_OK(status)) {
5548 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5549 nt_errstr(status));
5550 correct = False;
5553 talloc_destroy(mem_ctx);
5554 if (!torture_close_connection(cli)) {
5555 correct = False;
5558 return correct;
5561 static bool run_dirtest1(int dummy)
5563 int i;
5564 static struct cli_state *cli;
5565 uint16_t fnum;
5566 int num_seen;
5567 bool correct = True;
5569 printf("starting directory test\n");
5571 if (!torture_open_connection(&cli, 0)) {
5572 return False;
5575 cli_sockopt(cli, sockops);
5577 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5578 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5579 cli_rmdir(cli, "\\LISTDIR");
5580 cli_mkdir(cli, "\\LISTDIR");
5582 /* Create 1000 files and 1000 directories. */
5583 for (i=0;i<1000;i++) {
5584 fstring fname;
5585 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5586 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5587 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5588 fprintf(stderr,"Failed to open %s\n", fname);
5589 return False;
5591 cli_close(cli, fnum);
5593 for (i=0;i<1000;i++) {
5594 fstring fname;
5595 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5596 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5597 fprintf(stderr,"Failed to open %s\n", fname);
5598 return False;
5602 /* Now ensure that doing an old list sees both files and directories. */
5603 num_seen = 0;
5604 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5605 printf("num_seen = %d\n", num_seen );
5606 /* We should see 100 files + 1000 directories + . and .. */
5607 if (num_seen != 2002)
5608 correct = False;
5610 /* Ensure if we have the "must have" bits we only see the
5611 * relevent entries.
5613 num_seen = 0;
5614 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5615 printf("num_seen = %d\n", num_seen );
5616 if (num_seen != 1002)
5617 correct = False;
5619 num_seen = 0;
5620 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5621 printf("num_seen = %d\n", num_seen );
5622 if (num_seen != 1000)
5623 correct = False;
5625 /* Delete everything. */
5626 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5627 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5628 cli_rmdir(cli, "\\LISTDIR");
5630 #if 0
5631 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5632 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5633 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5634 #endif
5636 if (!torture_close_connection(cli)) {
5637 correct = False;
5640 printf("finished dirtest1\n");
5642 return correct;
5645 static bool run_error_map_extract(int dummy) {
5647 static struct cli_state *c_dos;
5648 static struct cli_state *c_nt;
5649 NTSTATUS status;
5651 uint32 error;
5653 uint32 flgs2, errnum;
5654 uint8 errclass;
5656 NTSTATUS nt_status;
5658 fstring user;
5660 /* NT-Error connection */
5662 if (!(c_nt = open_nbt_connection())) {
5663 return False;
5666 c_nt->use_spnego = False;
5668 status = cli_negprot(c_nt);
5670 if (!NT_STATUS_IS_OK(status)) {
5671 printf("%s rejected the NT-error negprot (%s)\n", host,
5672 nt_errstr(status));
5673 cli_shutdown(c_nt);
5674 return False;
5677 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5678 workgroup))) {
5679 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5680 return False;
5683 /* DOS-Error connection */
5685 if (!(c_dos = open_nbt_connection())) {
5686 return False;
5689 c_dos->use_spnego = False;
5690 c_dos->force_dos_errors = True;
5692 status = cli_negprot(c_dos);
5693 if (!NT_STATUS_IS_OK(status)) {
5694 printf("%s rejected the DOS-error negprot (%s)\n", host,
5695 nt_errstr(status));
5696 cli_shutdown(c_dos);
5697 return False;
5700 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5701 workgroup))) {
5702 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5703 return False;
5706 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5707 fstr_sprintf(user, "%X", error);
5709 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5710 password, strlen(password),
5711 password, strlen(password),
5712 workgroup))) {
5713 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5716 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5718 /* Case #1: 32-bit NT errors */
5719 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5720 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5721 } else {
5722 printf("/** Dos error on NT connection! (%s) */\n",
5723 cli_errstr(c_nt));
5724 nt_status = NT_STATUS(0xc0000000);
5727 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5728 password, strlen(password),
5729 password, strlen(password),
5730 workgroup))) {
5731 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5733 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5735 /* Case #1: 32-bit NT errors */
5736 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5737 printf("/** NT error on DOS connection! (%s) */\n",
5738 cli_errstr(c_nt));
5739 errnum = errclass = 0;
5740 } else {
5741 cli_dos_error(c_dos, &errclass, &errnum);
5744 if (NT_STATUS_V(nt_status) != error) {
5745 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5746 get_nt_error_c_code(NT_STATUS(error)),
5747 get_nt_error_c_code(nt_status));
5750 printf("\t{%s,\t%s,\t%s},\n",
5751 smb_dos_err_class(errclass),
5752 smb_dos_err_name(errclass, errnum),
5753 get_nt_error_c_code(NT_STATUS(error)));
5755 return True;
5758 static bool run_sesssetup_bench(int dummy)
5760 static struct cli_state *c;
5761 const char *fname = "\\file.dat";
5762 uint16_t fnum;
5763 NTSTATUS status;
5764 int i;
5766 if (!torture_open_connection(&c, 0)) {
5767 return false;
5770 if (!NT_STATUS_IS_OK(cli_ntcreate(
5771 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5772 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5773 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5774 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5775 return false;
5778 for (i=0; i<torture_numops; i++) {
5779 status = cli_session_setup(
5780 c, username,
5781 password, strlen(password),
5782 password, strlen(password),
5783 workgroup);
5784 if (!NT_STATUS_IS_OK(status)) {
5785 d_printf("(%s) cli_session_setup failed: %s\n",
5786 __location__, nt_errstr(status));
5787 return false;
5790 d_printf("\r%d ", (int)c->vuid);
5792 status = cli_ulogoff(c);
5793 if (!NT_STATUS_IS_OK(status)) {
5794 d_printf("(%s) cli_ulogoff failed: %s\n",
5795 __location__, nt_errstr(status));
5796 return false;
5798 c->vuid = 0;
5801 return true;
5804 static bool subst_test(const char *str, const char *user, const char *domain,
5805 uid_t uid, gid_t gid, const char *expected)
5807 char *subst;
5808 bool result = true;
5810 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5812 if (strcmp(subst, expected) != 0) {
5813 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5814 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5815 expected);
5816 result = false;
5819 TALLOC_FREE(subst);
5820 return result;
5823 static void chain1_open_completion(struct tevent_req *req)
5825 uint16_t fnum;
5826 NTSTATUS status;
5827 status = cli_open_recv(req, &fnum);
5828 TALLOC_FREE(req);
5830 d_printf("cli_open_recv returned %s: %d\n",
5831 nt_errstr(status),
5832 NT_STATUS_IS_OK(status) ? fnum : -1);
5835 static void chain1_write_completion(struct tevent_req *req)
5837 size_t written;
5838 NTSTATUS status;
5839 status = cli_write_andx_recv(req, &written);
5840 TALLOC_FREE(req);
5842 d_printf("cli_write_andx_recv returned %s: %d\n",
5843 nt_errstr(status),
5844 NT_STATUS_IS_OK(status) ? (int)written : -1);
5847 static void chain1_close_completion(struct tevent_req *req)
5849 NTSTATUS status;
5850 bool *done = (bool *)tevent_req_callback_data_void(req);
5852 status = cli_close_recv(req);
5853 *done = true;
5855 TALLOC_FREE(req);
5857 d_printf("cli_close returned %s\n", nt_errstr(status));
5860 static bool run_chain1(int dummy)
5862 struct cli_state *cli1;
5863 struct event_context *evt = event_context_init(NULL);
5864 struct tevent_req *reqs[3], *smbreqs[3];
5865 bool done = false;
5866 const char *str = "foobar";
5867 NTSTATUS status;
5869 printf("starting chain1 test\n");
5870 if (!torture_open_connection(&cli1, 0)) {
5871 return False;
5874 cli_sockopt(cli1, sockops);
5876 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5877 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5878 if (reqs[0] == NULL) return false;
5879 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5882 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5883 (uint8_t *)str, 0, strlen(str)+1,
5884 smbreqs, 1, &smbreqs[1]);
5885 if (reqs[1] == NULL) return false;
5886 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5888 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5889 if (reqs[2] == NULL) return false;
5890 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5892 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5893 if (!NT_STATUS_IS_OK(status)) {
5894 return false;
5897 while (!done) {
5898 event_loop_once(evt);
5901 torture_close_connection(cli1);
5902 return True;
5905 static void chain2_sesssetup_completion(struct tevent_req *req)
5907 NTSTATUS status;
5908 status = cli_session_setup_guest_recv(req);
5909 d_printf("sesssetup returned %s\n", nt_errstr(status));
5912 static void chain2_tcon_completion(struct tevent_req *req)
5914 bool *done = (bool *)tevent_req_callback_data_void(req);
5915 NTSTATUS status;
5916 status = cli_tcon_andx_recv(req);
5917 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5918 *done = true;
5921 static bool run_chain2(int dummy)
5923 struct cli_state *cli1;
5924 struct event_context *evt = event_context_init(NULL);
5925 struct tevent_req *reqs[2], *smbreqs[2];
5926 bool done = false;
5927 NTSTATUS status;
5929 printf("starting chain2 test\n");
5930 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5931 port_to_use, Undefined, 0);
5932 if (!NT_STATUS_IS_OK(status)) {
5933 return False;
5936 cli_sockopt(cli1, sockops);
5938 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5939 &smbreqs[0]);
5940 if (reqs[0] == NULL) return false;
5941 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5943 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5944 "?????", NULL, 0, &smbreqs[1]);
5945 if (reqs[1] == NULL) return false;
5946 tevent_req_set_callback(reqs[1], chain2_tcon_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;
5962 struct torture_createdel_state {
5963 struct tevent_context *ev;
5964 struct cli_state *cli;
5967 static void torture_createdel_created(struct tevent_req *subreq);
5968 static void torture_createdel_closed(struct tevent_req *subreq);
5970 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5971 struct tevent_context *ev,
5972 struct cli_state *cli,
5973 const char *name)
5975 struct tevent_req *req, *subreq;
5976 struct torture_createdel_state *state;
5978 req = tevent_req_create(mem_ctx, &state,
5979 struct torture_createdel_state);
5980 if (req == NULL) {
5981 return NULL;
5983 state->ev = ev;
5984 state->cli = cli;
5986 subreq = cli_ntcreate_send(
5987 state, ev, cli, name, 0,
5988 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5989 FILE_ATTRIBUTE_NORMAL,
5990 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5991 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5993 if (tevent_req_nomem(subreq, req)) {
5994 return tevent_req_post(req, ev);
5996 tevent_req_set_callback(subreq, torture_createdel_created, req);
5997 return req;
6000 static void torture_createdel_created(struct tevent_req *subreq)
6002 struct tevent_req *req = tevent_req_callback_data(
6003 subreq, struct tevent_req);
6004 struct torture_createdel_state *state = tevent_req_data(
6005 req, struct torture_createdel_state);
6006 NTSTATUS status;
6007 uint16_t fnum;
6009 status = cli_ntcreate_recv(subreq, &fnum);
6010 TALLOC_FREE(subreq);
6011 if (!NT_STATUS_IS_OK(status)) {
6012 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6013 nt_errstr(status)));
6014 tevent_req_nterror(req, status);
6015 return;
6018 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6019 if (tevent_req_nomem(subreq, req)) {
6020 return;
6022 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6025 static void torture_createdel_closed(struct tevent_req *subreq)
6027 struct tevent_req *req = tevent_req_callback_data(
6028 subreq, struct tevent_req);
6029 NTSTATUS status;
6031 status = cli_close_recv(subreq);
6032 if (!NT_STATUS_IS_OK(status)) {
6033 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6034 tevent_req_nterror(req, status);
6035 return;
6037 tevent_req_done(req);
6040 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6042 return tevent_req_simple_recv_ntstatus(req);
6045 struct torture_createdels_state {
6046 struct tevent_context *ev;
6047 struct cli_state *cli;
6048 const char *base_name;
6049 int sent;
6050 int received;
6051 int num_files;
6052 struct tevent_req **reqs;
6055 static void torture_createdels_done(struct tevent_req *subreq);
6057 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6058 struct tevent_context *ev,
6059 struct cli_state *cli,
6060 const char *base_name,
6061 int num_parallel,
6062 int num_files)
6064 struct tevent_req *req;
6065 struct torture_createdels_state *state;
6066 int i;
6068 req = tevent_req_create(mem_ctx, &state,
6069 struct torture_createdels_state);
6070 if (req == NULL) {
6071 return NULL;
6073 state->ev = ev;
6074 state->cli = cli;
6075 state->base_name = talloc_strdup(state, base_name);
6076 if (tevent_req_nomem(state->base_name, req)) {
6077 return tevent_req_post(req, ev);
6079 state->num_files = MAX(num_parallel, num_files);
6080 state->sent = 0;
6081 state->received = 0;
6083 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6084 if (tevent_req_nomem(state->reqs, req)) {
6085 return tevent_req_post(req, ev);
6088 for (i=0; i<num_parallel; i++) {
6089 char *name;
6091 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6092 state->sent);
6093 if (tevent_req_nomem(name, req)) {
6094 return tevent_req_post(req, ev);
6096 state->reqs[i] = torture_createdel_send(
6097 state->reqs, state->ev, state->cli, name);
6098 if (tevent_req_nomem(state->reqs[i], req)) {
6099 return tevent_req_post(req, ev);
6101 name = talloc_move(state->reqs[i], &name);
6102 tevent_req_set_callback(state->reqs[i],
6103 torture_createdels_done, req);
6104 state->sent += 1;
6106 return req;
6109 static void torture_createdels_done(struct tevent_req *subreq)
6111 struct tevent_req *req = tevent_req_callback_data(
6112 subreq, struct tevent_req);
6113 struct torture_createdels_state *state = tevent_req_data(
6114 req, struct torture_createdels_state);
6115 size_t num_parallel = talloc_array_length(state->reqs);
6116 NTSTATUS status;
6117 char *name;
6118 int i;
6120 status = torture_createdel_recv(subreq);
6121 if (!NT_STATUS_IS_OK(status)){
6122 DEBUG(10, ("torture_createdel_recv returned %s\n",
6123 nt_errstr(status)));
6124 TALLOC_FREE(subreq);
6125 tevent_req_nterror(req, status);
6126 return;
6129 for (i=0; i<num_parallel; i++) {
6130 if (subreq == state->reqs[i]) {
6131 break;
6134 if (i == num_parallel) {
6135 DEBUG(10, ("received something we did not send\n"));
6136 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6137 return;
6139 TALLOC_FREE(state->reqs[i]);
6141 if (state->sent >= state->num_files) {
6142 tevent_req_done(req);
6143 return;
6146 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6147 state->sent);
6148 if (tevent_req_nomem(name, req)) {
6149 return;
6151 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6152 state->cli, name);
6153 if (tevent_req_nomem(state->reqs[i], req)) {
6154 return;
6156 name = talloc_move(state->reqs[i], &name);
6157 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6158 state->sent += 1;
6161 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6163 return tevent_req_simple_recv_ntstatus(req);
6166 struct swallow_notify_state {
6167 struct tevent_context *ev;
6168 struct cli_state *cli;
6169 uint16_t fnum;
6170 uint32_t completion_filter;
6171 bool recursive;
6172 bool (*fn)(uint32_t action, const char *name, void *priv);
6173 void *priv;
6176 static void swallow_notify_done(struct tevent_req *subreq);
6178 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6179 struct tevent_context *ev,
6180 struct cli_state *cli,
6181 uint16_t fnum,
6182 uint32_t completion_filter,
6183 bool recursive,
6184 bool (*fn)(uint32_t action,
6185 const char *name,
6186 void *priv),
6187 void *priv)
6189 struct tevent_req *req, *subreq;
6190 struct swallow_notify_state *state;
6192 req = tevent_req_create(mem_ctx, &state,
6193 struct swallow_notify_state);
6194 if (req == NULL) {
6195 return NULL;
6197 state->ev = ev;
6198 state->cli = cli;
6199 state->fnum = fnum;
6200 state->completion_filter = completion_filter;
6201 state->recursive = recursive;
6202 state->fn = fn;
6203 state->priv = priv;
6205 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6206 0xffff, state->completion_filter,
6207 state->recursive);
6208 if (tevent_req_nomem(subreq, req)) {
6209 return tevent_req_post(req, ev);
6211 tevent_req_set_callback(subreq, swallow_notify_done, req);
6212 return req;
6215 static void swallow_notify_done(struct tevent_req *subreq)
6217 struct tevent_req *req = tevent_req_callback_data(
6218 subreq, struct tevent_req);
6219 struct swallow_notify_state *state = tevent_req_data(
6220 req, struct swallow_notify_state);
6221 NTSTATUS status;
6222 uint32_t i, num_changes;
6223 struct notify_change *changes;
6225 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6226 TALLOC_FREE(subreq);
6227 if (!NT_STATUS_IS_OK(status)) {
6228 DEBUG(10, ("cli_notify_recv returned %s\n",
6229 nt_errstr(status)));
6230 tevent_req_nterror(req, status);
6231 return;
6234 for (i=0; i<num_changes; i++) {
6235 state->fn(changes[i].action, changes[i].name, state->priv);
6237 TALLOC_FREE(changes);
6239 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6240 0xffff, state->completion_filter,
6241 state->recursive);
6242 if (tevent_req_nomem(subreq, req)) {
6243 return;
6245 tevent_req_set_callback(subreq, swallow_notify_done, req);
6248 static bool print_notifies(uint32_t action, const char *name, void *priv)
6250 if (DEBUGLEVEL > 5) {
6251 d_printf("%d %s\n", (int)action, name);
6253 return true;
6256 static void notify_bench_done(struct tevent_req *req)
6258 int *num_finished = (int *)tevent_req_callback_data_void(req);
6259 *num_finished += 1;
6262 static bool run_notify_bench(int dummy)
6264 const char *dname = "\\notify-bench";
6265 struct tevent_context *ev;
6266 NTSTATUS status;
6267 uint16_t dnum;
6268 struct tevent_req *req1;
6269 struct tevent_req *req2 = NULL;
6270 int i, num_unc_names;
6271 int num_finished = 0;
6273 printf("starting notify-bench test\n");
6275 if (use_multishare_conn) {
6276 char **unc_list;
6277 unc_list = file_lines_load(multishare_conn_fname,
6278 &num_unc_names, 0, NULL);
6279 if (!unc_list || num_unc_names <= 0) {
6280 d_printf("Failed to load unc names list from '%s'\n",
6281 multishare_conn_fname);
6282 return false;
6284 TALLOC_FREE(unc_list);
6285 } else {
6286 num_unc_names = 1;
6289 ev = tevent_context_init(talloc_tos());
6290 if (ev == NULL) {
6291 d_printf("tevent_context_init failed\n");
6292 return false;
6295 for (i=0; i<num_unc_names; i++) {
6296 struct cli_state *cli;
6297 char *base_fname;
6299 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6300 dname, i);
6301 if (base_fname == NULL) {
6302 return false;
6305 if (!torture_open_connection(&cli, i)) {
6306 return false;
6309 status = cli_ntcreate(cli, dname, 0,
6310 MAXIMUM_ALLOWED_ACCESS,
6311 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6312 FILE_SHARE_DELETE,
6313 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6314 &dnum);
6316 if (!NT_STATUS_IS_OK(status)) {
6317 d_printf("Could not create %s: %s\n", dname,
6318 nt_errstr(status));
6319 return false;
6322 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6323 FILE_NOTIFY_CHANGE_FILE_NAME |
6324 FILE_NOTIFY_CHANGE_DIR_NAME |
6325 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6326 FILE_NOTIFY_CHANGE_LAST_WRITE,
6327 false, print_notifies, NULL);
6328 if (req1 == NULL) {
6329 d_printf("Could not create notify request\n");
6330 return false;
6333 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6334 base_fname, 10, torture_numops);
6335 if (req2 == NULL) {
6336 d_printf("Could not create createdels request\n");
6337 return false;
6339 TALLOC_FREE(base_fname);
6341 tevent_req_set_callback(req2, notify_bench_done,
6342 &num_finished);
6345 while (num_finished < num_unc_names) {
6346 int ret;
6347 ret = tevent_loop_once(ev);
6348 if (ret != 0) {
6349 d_printf("tevent_loop_once failed\n");
6350 return false;
6354 if (!tevent_req_poll(req2, ev)) {
6355 d_printf("tevent_req_poll failed\n");
6358 status = torture_createdels_recv(req2);
6359 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6361 return true;
6364 static bool run_mangle1(int dummy)
6366 struct cli_state *cli;
6367 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6368 uint16_t fnum;
6369 fstring alt_name;
6370 NTSTATUS status;
6371 time_t change_time, access_time, write_time;
6372 SMB_OFF_T size;
6373 uint16_t mode;
6375 printf("starting mangle1 test\n");
6376 if (!torture_open_connection(&cli, 0)) {
6377 return False;
6380 cli_sockopt(cli, sockops);
6382 if (!NT_STATUS_IS_OK(cli_ntcreate(
6383 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6384 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6385 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6386 return false;
6388 cli_close(cli, fnum);
6390 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6391 if (!NT_STATUS_IS_OK(status)) {
6392 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6393 nt_errstr(status));
6394 return false;
6396 d_printf("alt_name: %s\n", alt_name);
6398 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6399 d_printf("cli_open(%s) failed: %s\n", alt_name,
6400 cli_errstr(cli));
6401 return false;
6403 cli_close(cli, fnum);
6405 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6406 &write_time, &size, &mode);
6407 if (!NT_STATUS_IS_OK(status)) {
6408 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6409 nt_errstr(status));
6410 return false;
6413 return true;
6416 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6418 size_t *to_pull = (size_t *)priv;
6419 size_t thistime = *to_pull;
6421 thistime = MIN(thistime, n);
6422 if (thistime == 0) {
6423 return 0;
6426 memset(buf, 0, thistime);
6427 *to_pull -= thistime;
6428 return thistime;
6431 static bool run_windows_write(int dummy)
6433 struct cli_state *cli1;
6434 uint16_t fnum;
6435 int i;
6436 bool ret = false;
6437 const char *fname = "\\writetest.txt";
6438 struct timeval start_time;
6439 double seconds;
6440 double kbytes;
6442 printf("starting windows_write test\n");
6443 if (!torture_open_connection(&cli1, 0)) {
6444 return False;
6447 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6448 printf("open failed (%s)\n", cli_errstr(cli1));
6449 return False;
6452 cli_sockopt(cli1, sockops);
6454 start_time = timeval_current();
6456 for (i=0; i<torture_numops; i++) {
6457 char c = 0;
6458 off_t start = i * torture_blocksize;
6459 NTSTATUS status;
6460 size_t to_pull = torture_blocksize - 1;
6462 if (cli_write(cli1, fnum, 0, &c,
6463 start + torture_blocksize - 1, 1) != 1) {
6464 printf("cli_write failed: %s\n", cli_errstr(cli1));
6465 goto fail;
6468 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6469 null_source, &to_pull);
6470 if (!NT_STATUS_IS_OK(status)) {
6471 printf("cli_push returned: %s\n", nt_errstr(status));
6472 goto fail;
6476 seconds = timeval_elapsed(&start_time);
6477 kbytes = (double)torture_blocksize * torture_numops;
6478 kbytes /= 1024;
6480 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6481 (double)seconds, (int)(kbytes/seconds));
6483 ret = true;
6484 fail:
6485 cli_close(cli1, fnum);
6486 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6487 torture_close_connection(cli1);
6488 return ret;
6491 static bool run_cli_echo(int dummy)
6493 struct cli_state *cli;
6494 NTSTATUS status;
6496 printf("starting cli_echo test\n");
6497 if (!torture_open_connection(&cli, 0)) {
6498 return false;
6500 cli_sockopt(cli, sockops);
6502 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6504 d_printf("cli_echo returned %s\n", nt_errstr(status));
6506 torture_close_connection(cli);
6507 return NT_STATUS_IS_OK(status);
6510 static bool run_uid_regression_test(int dummy)
6512 static struct cli_state *cli;
6513 int16_t old_vuid;
6514 int16_t old_cnum;
6515 bool correct = True;
6516 NTSTATUS status;
6518 printf("starting uid regression test\n");
6520 if (!torture_open_connection(&cli, 0)) {
6521 return False;
6524 cli_sockopt(cli, sockops);
6526 /* Ok - now save then logoff our current user. */
6527 old_vuid = cli->vuid;
6529 status = cli_ulogoff(cli);
6530 if (!NT_STATUS_IS_OK(status)) {
6531 d_printf("(%s) cli_ulogoff failed: %s\n",
6532 __location__, nt_errstr(status));
6533 correct = false;
6534 goto out;
6537 cli->vuid = old_vuid;
6539 /* Try an operation. */
6540 status = cli_mkdir(cli, "\\uid_reg_test");
6541 if (NT_STATUS_IS_OK(status)) {
6542 d_printf("(%s) cli_mkdir succeeded\n",
6543 __location__);
6544 correct = false;
6545 goto out;
6546 } else {
6547 /* Should be bad uid. */
6548 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6549 NT_STATUS_USER_SESSION_DELETED)) {
6550 correct = false;
6551 goto out;
6555 old_cnum = cli->cnum;
6557 /* Now try a SMBtdis with the invald vuid set to zero. */
6558 cli->vuid = 0;
6560 /* This should succeed. */
6561 status = cli_tdis(cli);
6563 if (NT_STATUS_IS_OK(status)) {
6564 d_printf("First tdis with invalid vuid should succeed.\n");
6565 } else {
6566 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6567 correct = false;
6568 goto out;
6571 cli->vuid = old_vuid;
6572 cli->cnum = old_cnum;
6574 /* This should fail. */
6575 status = cli_tdis(cli);
6576 if (NT_STATUS_IS_OK(status)) {
6577 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6578 correct = false;
6579 goto out;
6580 } else {
6581 /* Should be bad tid. */
6582 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6583 NT_STATUS_NETWORK_NAME_DELETED)) {
6584 correct = false;
6585 goto out;
6589 cli_rmdir(cli, "\\uid_reg_test");
6591 out:
6593 cli_shutdown(cli);
6594 return correct;
6598 static const char *illegal_chars = "*\\/?<>|\":";
6599 static char force_shortname_chars[] = " +,.[];=\177";
6601 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6602 const char *mask, void *state)
6604 struct cli_state *pcli = (struct cli_state *)state;
6605 fstring fname;
6606 NTSTATUS status = NT_STATUS_OK;
6608 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6610 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6611 return NT_STATUS_OK;
6613 if (finfo->mode & aDIR) {
6614 status = cli_rmdir(pcli, fname);
6615 if (!NT_STATUS_IS_OK(status)) {
6616 printf("del_fn: failed to rmdir %s\n,", fname );
6618 } else {
6619 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6620 if (!NT_STATUS_IS_OK(status)) {
6621 printf("del_fn: failed to unlink %s\n,", fname );
6624 return status;
6627 struct sn_state {
6628 int matched;
6629 int i;
6630 bool val;
6633 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6634 const char *name, void *state)
6636 struct sn_state *s = (struct sn_state *)state;
6637 int i = s->i;
6639 #if 0
6640 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6641 i, finfo->name, finfo->short_name);
6642 #endif
6644 if (strchr(force_shortname_chars, i)) {
6645 if (!finfo->short_name[0]) {
6646 /* Shortname not created when it should be. */
6647 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6648 __location__, finfo->name, i);
6649 s->val = true;
6651 } else if (finfo->short_name[0]){
6652 /* Shortname created when it should not be. */
6653 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6654 __location__, finfo->short_name, finfo->name);
6655 s->val = true;
6657 s->matched += 1;
6658 return NT_STATUS_OK;
6661 static bool run_shortname_test(int dummy)
6663 static struct cli_state *cli;
6664 bool correct = True;
6665 int i;
6666 struct sn_state s;
6667 char fname[20];
6669 printf("starting shortname test\n");
6671 if (!torture_open_connection(&cli, 0)) {
6672 return False;
6675 cli_sockopt(cli, sockops);
6677 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6678 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6679 cli_rmdir(cli, "\\shortname");
6681 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6682 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6683 __location__, cli_errstr(cli));
6684 correct = false;
6685 goto out;
6688 strlcpy(fname, "\\shortname\\", sizeof(fname));
6689 strlcat(fname, "test .txt", sizeof(fname));
6691 s.val = false;
6693 for (i = 32; i < 128; i++) {
6694 NTSTATUS status;
6695 uint16_t fnum = (uint16_t)-1;
6697 s.i = i;
6699 if (strchr(illegal_chars, i)) {
6700 continue;
6702 fname[15] = i;
6704 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6705 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6706 if (!NT_STATUS_IS_OK(status)) {
6707 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6708 __location__, fname, cli_errstr(cli));
6709 correct = false;
6710 goto out;
6712 cli_close(cli, fnum);
6714 s.matched = 0;
6715 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6716 &s);
6717 if (s.matched != 1) {
6718 d_printf("(%s) failed to list %s: %s\n",
6719 __location__, fname, cli_errstr(cli));
6720 correct = false;
6721 goto out;
6723 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6724 d_printf("(%s) failed to delete %s: %s\n",
6725 __location__, fname, cli_errstr(cli));
6726 correct = false;
6727 goto out;
6730 if (s.val) {
6731 correct = false;
6732 goto out;
6736 out:
6738 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6739 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6740 cli_rmdir(cli, "\\shortname");
6741 torture_close_connection(cli);
6742 return correct;
6745 static void pagedsearch_cb(struct tevent_req *req)
6747 int rc;
6748 struct tldap_message *msg;
6749 char *dn;
6751 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6752 if (rc != TLDAP_SUCCESS) {
6753 d_printf("tldap_search_paged_recv failed: %s\n",
6754 tldap_err2string(rc));
6755 return;
6757 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6758 TALLOC_FREE(msg);
6759 return;
6761 if (!tldap_entry_dn(msg, &dn)) {
6762 d_printf("tldap_entry_dn failed\n");
6763 return;
6765 d_printf("%s\n", dn);
6766 TALLOC_FREE(msg);
6769 static bool run_tldap(int dummy)
6771 struct tldap_context *ld;
6772 int fd, rc;
6773 NTSTATUS status;
6774 struct sockaddr_storage addr;
6775 struct tevent_context *ev;
6776 struct tevent_req *req;
6777 char *basedn;
6778 const char *filter;
6780 if (!resolve_name(host, &addr, 0, false)) {
6781 d_printf("could not find host %s\n", host);
6782 return false;
6784 status = open_socket_out(&addr, 389, 9999, &fd);
6785 if (!NT_STATUS_IS_OK(status)) {
6786 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6787 return false;
6790 ld = tldap_context_create(talloc_tos(), fd);
6791 if (ld == NULL) {
6792 close(fd);
6793 d_printf("tldap_context_create failed\n");
6794 return false;
6797 rc = tldap_fetch_rootdse(ld);
6798 if (rc != TLDAP_SUCCESS) {
6799 d_printf("tldap_fetch_rootdse failed: %s\n",
6800 tldap_errstr(talloc_tos(), ld, rc));
6801 return false;
6804 basedn = tldap_talloc_single_attribute(
6805 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6806 if (basedn == NULL) {
6807 d_printf("no defaultNamingContext\n");
6808 return false;
6810 d_printf("defaultNamingContext: %s\n", basedn);
6812 ev = tevent_context_init(talloc_tos());
6813 if (ev == NULL) {
6814 d_printf("tevent_context_init failed\n");
6815 return false;
6818 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6819 TLDAP_SCOPE_SUB, "(objectclass=*)",
6820 NULL, 0, 0,
6821 NULL, 0, NULL, 0, 0, 0, 0, 5);
6822 if (req == NULL) {
6823 d_printf("tldap_search_paged_send failed\n");
6824 return false;
6826 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6828 tevent_req_poll(req, ev);
6830 TALLOC_FREE(req);
6832 /* test search filters against rootDSE */
6833 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6834 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6836 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6837 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6838 talloc_tos(), NULL, NULL);
6839 if (rc != TLDAP_SUCCESS) {
6840 d_printf("tldap_search with complex filter failed: %s\n",
6841 tldap_errstr(talloc_tos(), ld, rc));
6842 return false;
6845 TALLOC_FREE(ld);
6846 return true;
6849 /* Torture test to ensure no regression of :
6850 https://bugzilla.samba.org/show_bug.cgi?id=7084
6853 static bool run_dir_createtime(int dummy)
6855 struct cli_state *cli;
6856 const char *dname = "\\testdir";
6857 const char *fname = "\\testdir\\testfile";
6858 NTSTATUS status;
6859 struct timespec create_time;
6860 struct timespec create_time1;
6861 uint16_t fnum;
6862 bool ret = false;
6864 if (!torture_open_connection(&cli, 0)) {
6865 return false;
6868 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6869 cli_rmdir(cli, dname);
6871 status = cli_mkdir(cli, dname);
6872 if (!NT_STATUS_IS_OK(status)) {
6873 printf("mkdir failed: %s\n", nt_errstr(status));
6874 goto out;
6877 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6878 NULL, NULL, NULL);
6879 if (!NT_STATUS_IS_OK(status)) {
6880 printf("cli_qpathinfo2 returned %s\n",
6881 nt_errstr(status));
6882 goto out;
6885 /* Sleep 3 seconds, then create a file. */
6886 sleep(3);
6888 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6889 DENY_NONE, &fnum);
6890 if (!NT_STATUS_IS_OK(status)) {
6891 printf("cli_open failed: %s\n", nt_errstr(status));
6892 goto out;
6895 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6896 NULL, NULL, NULL);
6897 if (!NT_STATUS_IS_OK(status)) {
6898 printf("cli_qpathinfo2 (2) returned %s\n",
6899 nt_errstr(status));
6900 goto out;
6903 if (timespec_compare(&create_time1, &create_time)) {
6904 printf("run_dir_createtime: create time was updated (error)\n");
6905 } else {
6906 printf("run_dir_createtime: create time was not updated (correct)\n");
6907 ret = true;
6910 out:
6912 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6913 cli_rmdir(cli, dname);
6914 if (!torture_close_connection(cli)) {
6915 ret = false;
6917 return ret;
6921 static bool run_streamerror(int dummy)
6923 struct cli_state *cli;
6924 const char *dname = "\\testdir";
6925 const char *streamname =
6926 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6927 NTSTATUS status;
6928 time_t change_time, access_time, write_time;
6929 SMB_OFF_T size;
6930 uint16_t mode, fnum;
6931 bool ret = true;
6933 if (!torture_open_connection(&cli, 0)) {
6934 return false;
6937 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6938 cli_rmdir(cli, dname);
6940 status = cli_mkdir(cli, dname);
6941 if (!NT_STATUS_IS_OK(status)) {
6942 printf("mkdir failed: %s\n", nt_errstr(status));
6943 return false;
6946 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6947 &size, &mode);
6948 status = cli_nt_error(cli);
6950 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6951 printf("pathinfo returned %s, expected "
6952 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6953 nt_errstr(status));
6954 ret = false;
6957 status = cli_ntcreate(cli, streamname, 0x16,
6958 FILE_READ_DATA|FILE_READ_EA|
6959 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6960 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6961 FILE_OPEN, 0, 0, &fnum);
6963 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6964 printf("ntcreate returned %s, expected "
6965 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6966 nt_errstr(status));
6967 ret = false;
6971 cli_rmdir(cli, dname);
6972 return ret;
6975 static bool run_local_substitute(int dummy)
6977 bool ok = true;
6979 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6980 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6981 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6982 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6983 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6984 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6985 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6986 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6988 /* Different captialization rules in sub_basic... */
6990 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6991 "blaDOM") == 0);
6993 return ok;
6996 static bool run_local_base64(int dummy)
6998 int i;
6999 bool ret = true;
7001 for (i=1; i<2000; i++) {
7002 DATA_BLOB blob1, blob2;
7003 char *b64;
7005 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7006 blob1.length = i;
7007 generate_random_buffer(blob1.data, blob1.length);
7009 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7010 if (b64 == NULL) {
7011 d_fprintf(stderr, "base64_encode_data_blob failed "
7012 "for %d bytes\n", i);
7013 ret = false;
7015 blob2 = base64_decode_data_blob(b64);
7016 TALLOC_FREE(b64);
7018 if (data_blob_cmp(&blob1, &blob2)) {
7019 d_fprintf(stderr, "data_blob_cmp failed for %d "
7020 "bytes\n", i);
7021 ret = false;
7023 TALLOC_FREE(blob1.data);
7024 data_blob_free(&blob2);
7026 return ret;
7029 static bool run_local_gencache(int dummy)
7031 char *val;
7032 time_t tm;
7033 DATA_BLOB blob;
7035 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7036 d_printf("%s: gencache_set() failed\n", __location__);
7037 return False;
7040 if (!gencache_get("foo", NULL, NULL)) {
7041 d_printf("%s: gencache_get() failed\n", __location__);
7042 return False;
7045 if (!gencache_get("foo", &val, &tm)) {
7046 d_printf("%s: gencache_get() failed\n", __location__);
7047 return False;
7050 if (strcmp(val, "bar") != 0) {
7051 d_printf("%s: gencache_get() returned %s, expected %s\n",
7052 __location__, val, "bar");
7053 SAFE_FREE(val);
7054 return False;
7057 SAFE_FREE(val);
7059 if (!gencache_del("foo")) {
7060 d_printf("%s: gencache_del() failed\n", __location__);
7061 return False;
7063 if (gencache_del("foo")) {
7064 d_printf("%s: second gencache_del() succeeded\n",
7065 __location__);
7066 return False;
7069 if (gencache_get("foo", &val, &tm)) {
7070 d_printf("%s: gencache_get() on deleted entry "
7071 "succeeded\n", __location__);
7072 return False;
7075 blob = data_blob_string_const_null("bar");
7076 tm = time(NULL) + 60;
7078 if (!gencache_set_data_blob("foo", &blob, tm)) {
7079 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7080 return False;
7083 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7084 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7085 return False;
7088 if (strcmp((const char *)blob.data, "bar") != 0) {
7089 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7090 __location__, (const char *)blob.data, "bar");
7091 data_blob_free(&blob);
7092 return False;
7095 data_blob_free(&blob);
7097 if (!gencache_del("foo")) {
7098 d_printf("%s: gencache_del() failed\n", __location__);
7099 return False;
7101 if (gencache_del("foo")) {
7102 d_printf("%s: second gencache_del() succeeded\n",
7103 __location__);
7104 return False;
7107 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7108 d_printf("%s: gencache_get_data_blob() on deleted entry "
7109 "succeeded\n", __location__);
7110 return False;
7113 return True;
7116 static bool rbt_testval(struct db_context *db, const char *key,
7117 const char *value)
7119 struct db_record *rec;
7120 TDB_DATA data = string_tdb_data(value);
7121 bool ret = false;
7122 NTSTATUS status;
7124 rec = db->fetch_locked(db, db, string_tdb_data(key));
7125 if (rec == NULL) {
7126 d_fprintf(stderr, "fetch_locked failed\n");
7127 goto done;
7129 status = rec->store(rec, data, 0);
7130 if (!NT_STATUS_IS_OK(status)) {
7131 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7132 goto done;
7134 TALLOC_FREE(rec);
7136 rec = db->fetch_locked(db, db, string_tdb_data(key));
7137 if (rec == NULL) {
7138 d_fprintf(stderr, "second fetch_locked failed\n");
7139 goto done;
7141 if ((rec->value.dsize != data.dsize)
7142 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7143 d_fprintf(stderr, "Got wrong data back\n");
7144 goto done;
7147 ret = true;
7148 done:
7149 TALLOC_FREE(rec);
7150 return ret;
7153 static bool run_local_rbtree(int dummy)
7155 struct db_context *db;
7156 bool ret = false;
7157 int i;
7159 db = db_open_rbt(NULL);
7161 if (db == NULL) {
7162 d_fprintf(stderr, "db_open_rbt failed\n");
7163 return false;
7166 for (i=0; i<1000; i++) {
7167 char *key, *value;
7169 if (asprintf(&key, "key%ld", random()) == -1) {
7170 goto done;
7172 if (asprintf(&value, "value%ld", random()) == -1) {
7173 SAFE_FREE(key);
7174 goto done;
7177 if (!rbt_testval(db, key, value)) {
7178 SAFE_FREE(key);
7179 SAFE_FREE(value);
7180 goto done;
7183 SAFE_FREE(value);
7184 if (asprintf(&value, "value%ld", random()) == -1) {
7185 SAFE_FREE(key);
7186 goto done;
7189 if (!rbt_testval(db, key, value)) {
7190 SAFE_FREE(key);
7191 SAFE_FREE(value);
7192 goto done;
7195 SAFE_FREE(key);
7196 SAFE_FREE(value);
7199 ret = true;
7201 done:
7202 TALLOC_FREE(db);
7203 return ret;
7206 struct talloc_dict_test {
7207 int content;
7210 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7212 int *count = (int *)priv;
7213 *count += 1;
7214 return 0;
7217 static bool run_local_talloc_dict(int dummy)
7219 struct talloc_dict *dict;
7220 struct talloc_dict_test *t;
7221 int key, count;
7223 dict = talloc_dict_init(talloc_tos());
7224 if (dict == NULL) {
7225 return false;
7228 t = talloc(talloc_tos(), struct talloc_dict_test);
7229 if (t == NULL) {
7230 return false;
7233 key = 1;
7234 t->content = 1;
7235 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7236 return false;
7239 count = 0;
7240 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7241 return false;
7244 if (count != 1) {
7245 return false;
7248 TALLOC_FREE(dict);
7250 return true;
7253 static bool run_local_string_to_sid(int dummy) {
7254 struct dom_sid sid;
7256 if (string_to_sid(&sid, "S--1-5-32-545")) {
7257 printf("allowing S--1-5-32-545\n");
7258 return false;
7260 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7261 printf("allowing S-1-5-32-+545\n");
7262 return false;
7264 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")) {
7265 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7266 return false;
7268 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7269 printf("allowing S-1-5-32-545-abc\n");
7270 return false;
7272 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7273 printf("could not parse S-1-5-32-545\n");
7274 return false;
7276 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7277 printf("mis-parsed S-1-5-32-545 as %s\n",
7278 sid_string_tos(&sid));
7279 return false;
7281 return true;
7284 static bool run_local_binary_to_sid(int dummy) {
7285 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7286 static const char good_binary_sid[] = {
7287 0x1, /* revision number */
7288 15, /* num auths */
7289 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7290 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7291 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7292 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7293 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7294 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7295 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7296 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7297 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7298 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7299 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7300 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7301 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7302 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7303 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7304 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7307 static const char long_binary_sid[] = {
7308 0x1, /* revision number */
7309 15, /* num auths */
7310 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7311 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7312 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7313 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7314 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7315 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7316 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7317 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7318 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7319 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7320 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7321 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7322 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7323 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7324 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7325 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7326 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7327 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7328 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7331 static const char long_binary_sid2[] = {
7332 0x1, /* revision number */
7333 32, /* num auths */
7334 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7335 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7336 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7337 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7338 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7339 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7340 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7341 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7342 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7343 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7344 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7345 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7346 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7347 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7348 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7349 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7350 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7351 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7352 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7353 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7354 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7355 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7356 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7357 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7358 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7359 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7360 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7361 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7362 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7363 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7364 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7365 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7366 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7369 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7370 return false;
7372 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7373 return false;
7375 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7376 return false;
7378 return true;
7381 /* Split a path name into filename and stream name components. Canonicalise
7382 * such that an implicit $DATA token is always explicit.
7384 * The "specification" of this function can be found in the
7385 * run_local_stream_name() function in torture.c, I've tried those
7386 * combinations against a W2k3 server.
7389 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7390 char **pbase, char **pstream)
7392 char *base = NULL;
7393 char *stream = NULL;
7394 char *sname; /* stream name */
7395 const char *stype; /* stream type */
7397 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7399 sname = strchr_m(fname, ':');
7401 if (lp_posix_pathnames() || (sname == NULL)) {
7402 if (pbase != NULL) {
7403 base = talloc_strdup(mem_ctx, fname);
7404 NT_STATUS_HAVE_NO_MEMORY(base);
7406 goto done;
7409 if (pbase != NULL) {
7410 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7411 NT_STATUS_HAVE_NO_MEMORY(base);
7414 sname += 1;
7416 stype = strchr_m(sname, ':');
7418 if (stype == NULL) {
7419 sname = talloc_strdup(mem_ctx, sname);
7420 stype = "$DATA";
7422 else {
7423 if (StrCaseCmp(stype, ":$DATA") != 0) {
7425 * If there is an explicit stream type, so far we only
7426 * allow $DATA. Is there anything else allowed? -- vl
7428 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7429 TALLOC_FREE(base);
7430 return NT_STATUS_OBJECT_NAME_INVALID;
7432 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7433 stype += 1;
7436 if (sname == NULL) {
7437 TALLOC_FREE(base);
7438 return NT_STATUS_NO_MEMORY;
7441 if (sname[0] == '\0') {
7443 * no stream name, so no stream
7445 goto done;
7448 if (pstream != NULL) {
7449 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7450 if (stream == NULL) {
7451 TALLOC_FREE(sname);
7452 TALLOC_FREE(base);
7453 return NT_STATUS_NO_MEMORY;
7456 * upper-case the type field
7458 strupper_m(strchr_m(stream, ':')+1);
7461 done:
7462 if (pbase != NULL) {
7463 *pbase = base;
7465 if (pstream != NULL) {
7466 *pstream = stream;
7468 return NT_STATUS_OK;
7471 static bool test_stream_name(const char *fname, const char *expected_base,
7472 const char *expected_stream,
7473 NTSTATUS expected_status)
7475 NTSTATUS status;
7476 char *base = NULL;
7477 char *stream = NULL;
7479 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7480 if (!NT_STATUS_EQUAL(status, expected_status)) {
7481 goto error;
7484 if (!NT_STATUS_IS_OK(status)) {
7485 return true;
7488 if (base == NULL) goto error;
7490 if (strcmp(expected_base, base) != 0) goto error;
7492 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7493 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7495 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7496 goto error;
7498 TALLOC_FREE(base);
7499 TALLOC_FREE(stream);
7500 return true;
7502 error:
7503 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7504 fname, expected_base ? expected_base : "<NULL>",
7505 expected_stream ? expected_stream : "<NULL>",
7506 nt_errstr(expected_status));
7507 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7508 base ? base : "<NULL>", stream ? stream : "<NULL>",
7509 nt_errstr(status));
7510 TALLOC_FREE(base);
7511 TALLOC_FREE(stream);
7512 return false;
7515 static bool run_local_stream_name(int dummy)
7517 bool ret = true;
7519 ret &= test_stream_name(
7520 "bla", "bla", NULL, NT_STATUS_OK);
7521 ret &= test_stream_name(
7522 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7523 ret &= test_stream_name(
7524 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7525 ret &= test_stream_name(
7526 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7527 ret &= test_stream_name(
7528 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7529 ret &= test_stream_name(
7530 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7531 ret &= test_stream_name(
7532 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7533 ret &= test_stream_name(
7534 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7536 return ret;
7539 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7541 if (a.length != b.length) {
7542 printf("a.length=%d != b.length=%d\n",
7543 (int)a.length, (int)b.length);
7544 return false;
7546 if (memcmp(a.data, b.data, a.length) != 0) {
7547 printf("a.data and b.data differ\n");
7548 return false;
7550 return true;
7553 static bool run_local_memcache(int dummy)
7555 struct memcache *cache;
7556 DATA_BLOB k1, k2;
7557 DATA_BLOB d1, d2, d3;
7558 DATA_BLOB v1, v2, v3;
7560 TALLOC_CTX *mem_ctx;
7561 char *str1, *str2;
7562 size_t size1, size2;
7563 bool ret = false;
7565 cache = memcache_init(NULL, 100);
7567 if (cache == NULL) {
7568 printf("memcache_init failed\n");
7569 return false;
7572 d1 = data_blob_const("d1", 2);
7573 d2 = data_blob_const("d2", 2);
7574 d3 = data_blob_const("d3", 2);
7576 k1 = data_blob_const("d1", 2);
7577 k2 = data_blob_const("d2", 2);
7579 memcache_add(cache, STAT_CACHE, k1, d1);
7580 memcache_add(cache, GETWD_CACHE, k2, d2);
7582 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7583 printf("could not find k1\n");
7584 return false;
7586 if (!data_blob_equal(d1, v1)) {
7587 return false;
7590 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7591 printf("could not find k2\n");
7592 return false;
7594 if (!data_blob_equal(d2, v2)) {
7595 return false;
7598 memcache_add(cache, STAT_CACHE, k1, d3);
7600 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7601 printf("could not find replaced k1\n");
7602 return false;
7604 if (!data_blob_equal(d3, v3)) {
7605 return false;
7608 memcache_add(cache, GETWD_CACHE, k1, d1);
7610 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7611 printf("Did find k2, should have been purged\n");
7612 return false;
7615 TALLOC_FREE(cache);
7617 cache = memcache_init(NULL, 0);
7619 mem_ctx = talloc_init("foo");
7621 str1 = talloc_strdup(mem_ctx, "string1");
7622 str2 = talloc_strdup(mem_ctx, "string2");
7624 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7625 data_blob_string_const("torture"), &str1);
7626 size1 = talloc_total_size(cache);
7628 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7629 data_blob_string_const("torture"), &str2);
7630 size2 = talloc_total_size(cache);
7632 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7634 if (size2 > size1) {
7635 printf("memcache leaks memory!\n");
7636 goto fail;
7639 ret = true;
7640 fail:
7641 TALLOC_FREE(cache);
7642 return ret;
7645 static void wbclient_done(struct tevent_req *req)
7647 wbcErr wbc_err;
7648 struct winbindd_response *wb_resp;
7649 int *i = (int *)tevent_req_callback_data_void(req);
7651 wbc_err = wb_trans_recv(req, req, &wb_resp);
7652 TALLOC_FREE(req);
7653 *i += 1;
7654 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7657 static bool run_local_wbclient(int dummy)
7659 struct event_context *ev;
7660 struct wb_context **wb_ctx;
7661 struct winbindd_request wb_req;
7662 bool result = false;
7663 int i, j;
7665 BlockSignals(True, SIGPIPE);
7667 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7668 if (ev == NULL) {
7669 goto fail;
7672 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7673 if (wb_ctx == NULL) {
7674 goto fail;
7677 ZERO_STRUCT(wb_req);
7678 wb_req.cmd = WINBINDD_PING;
7680 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7682 for (i=0; i<nprocs; i++) {
7683 wb_ctx[i] = wb_context_init(ev, NULL);
7684 if (wb_ctx[i] == NULL) {
7685 goto fail;
7687 for (j=0; j<torture_numops; j++) {
7688 struct tevent_req *req;
7689 req = wb_trans_send(ev, ev, wb_ctx[i],
7690 (j % 2) == 0, &wb_req);
7691 if (req == NULL) {
7692 goto fail;
7694 tevent_req_set_callback(req, wbclient_done, &i);
7698 i = 0;
7700 while (i < nprocs * torture_numops) {
7701 event_loop_once(ev);
7704 result = true;
7705 fail:
7706 TALLOC_FREE(ev);
7707 return result;
7710 static void getaddrinfo_finished(struct tevent_req *req)
7712 char *name = (char *)tevent_req_callback_data_void(req);
7713 struct addrinfo *ainfo;
7714 int res;
7716 res = getaddrinfo_recv(req, &ainfo);
7717 if (res != 0) {
7718 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7719 return;
7721 d_printf("gai(%s) succeeded\n", name);
7722 freeaddrinfo(ainfo);
7725 static bool run_getaddrinfo_send(int dummy)
7727 TALLOC_CTX *frame = talloc_stackframe();
7728 struct fncall_context *ctx;
7729 struct tevent_context *ev;
7730 bool result = false;
7731 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7732 "www.slashdot.org", "heise.de" };
7733 struct tevent_req *reqs[4];
7734 int i;
7736 ev = event_context_init(frame);
7737 if (ev == NULL) {
7738 goto fail;
7741 ctx = fncall_context_init(frame, 4);
7743 for (i=0; i<ARRAY_SIZE(names); i++) {
7744 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7745 NULL);
7746 if (reqs[i] == NULL) {
7747 goto fail;
7749 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7750 (void *)names[i]);
7753 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7754 tevent_loop_once(ev);
7757 result = true;
7758 fail:
7759 TALLOC_FREE(frame);
7760 return result;
7763 static bool dbtrans_inc(struct db_context *db)
7765 struct db_record *rec;
7766 uint32_t *val;
7767 bool ret = false;
7768 NTSTATUS status;
7770 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7771 if (rec == NULL) {
7772 printf(__location__ "fetch_lock failed\n");
7773 return false;
7776 if (rec->value.dsize != sizeof(uint32_t)) {
7777 printf(__location__ "value.dsize = %d\n",
7778 (int)rec->value.dsize);
7779 goto fail;
7782 val = (uint32_t *)rec->value.dptr;
7783 *val += 1;
7785 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7786 sizeof(uint32_t)),
7788 if (!NT_STATUS_IS_OK(status)) {
7789 printf(__location__ "store failed: %s\n",
7790 nt_errstr(status));
7791 goto fail;
7794 ret = true;
7795 fail:
7796 TALLOC_FREE(rec);
7797 return ret;
7800 static bool run_local_dbtrans(int dummy)
7802 struct db_context *db;
7803 struct db_record *rec;
7804 NTSTATUS status;
7805 uint32_t initial;
7806 int res;
7808 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7809 O_RDWR|O_CREAT, 0600);
7810 if (db == NULL) {
7811 printf("Could not open transtest.db\n");
7812 return false;
7815 res = db->transaction_start(db);
7816 if (res == -1) {
7817 printf(__location__ "transaction_start failed\n");
7818 return false;
7821 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7822 if (rec == NULL) {
7823 printf(__location__ "fetch_lock failed\n");
7824 return false;
7827 if (rec->value.dptr == NULL) {
7828 initial = 0;
7829 status = rec->store(
7830 rec, make_tdb_data((uint8_t *)&initial,
7831 sizeof(initial)),
7833 if (!NT_STATUS_IS_OK(status)) {
7834 printf(__location__ "store returned %s\n",
7835 nt_errstr(status));
7836 return false;
7840 TALLOC_FREE(rec);
7842 res = db->transaction_commit(db);
7843 if (res == -1) {
7844 printf(__location__ "transaction_commit failed\n");
7845 return false;
7848 while (true) {
7849 uint32_t val, val2;
7850 int i;
7852 res = db->transaction_start(db);
7853 if (res == -1) {
7854 printf(__location__ "transaction_start failed\n");
7855 break;
7858 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7859 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7860 break;
7863 for (i=0; i<10; i++) {
7864 if (!dbtrans_inc(db)) {
7865 return false;
7869 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7870 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7871 break;
7874 if (val2 != val + 10) {
7875 printf(__location__ "val=%d, val2=%d\n",
7876 (int)val, (int)val2);
7877 break;
7880 printf("val2=%d\r", val2);
7882 res = db->transaction_commit(db);
7883 if (res == -1) {
7884 printf(__location__ "transaction_commit failed\n");
7885 break;
7889 TALLOC_FREE(db);
7890 return true;
7894 * Just a dummy test to be run under a debugger. There's no real way
7895 * to inspect the tevent_select specific function from outside of
7896 * tevent_select.c.
7899 static bool run_local_tevent_select(int dummy)
7901 struct tevent_context *ev;
7902 struct tevent_fd *fd1, *fd2;
7903 bool result = false;
7905 ev = tevent_context_init_byname(NULL, "select");
7906 if (ev == NULL) {
7907 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7908 goto fail;
7911 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7912 if (fd1 == NULL) {
7913 d_fprintf(stderr, "tevent_add_fd failed\n");
7914 goto fail;
7916 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7917 if (fd2 == NULL) {
7918 d_fprintf(stderr, "tevent_add_fd failed\n");
7919 goto fail;
7921 TALLOC_FREE(fd2);
7923 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7924 if (fd2 == NULL) {
7925 d_fprintf(stderr, "tevent_add_fd failed\n");
7926 goto fail;
7929 result = true;
7930 fail:
7931 TALLOC_FREE(ev);
7932 return result;
7935 static double create_procs(bool (*fn)(int), bool *result)
7937 int i, status;
7938 volatile pid_t *child_status;
7939 volatile bool *child_status_out;
7940 int synccount;
7941 int tries = 8;
7942 struct timeval start;
7944 synccount = 0;
7946 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7947 if (!child_status) {
7948 printf("Failed to setup shared memory\n");
7949 return -1;
7952 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7953 if (!child_status_out) {
7954 printf("Failed to setup result status shared memory\n");
7955 return -1;
7958 for (i = 0; i < nprocs; i++) {
7959 child_status[i] = 0;
7960 child_status_out[i] = True;
7963 start = timeval_current();
7965 for (i=0;i<nprocs;i++) {
7966 procnum = i;
7967 if (fork() == 0) {
7968 pid_t mypid = getpid();
7969 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7971 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7973 while (1) {
7974 if (torture_open_connection(&current_cli, i)) break;
7975 if (tries-- == 0) {
7976 printf("pid %d failed to start\n", (int)getpid());
7977 _exit(1);
7979 smb_msleep(10);
7982 child_status[i] = getpid();
7984 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7986 child_status_out[i] = fn(i);
7987 _exit(0);
7991 do {
7992 synccount = 0;
7993 for (i=0;i<nprocs;i++) {
7994 if (child_status[i]) synccount++;
7996 if (synccount == nprocs) break;
7997 smb_msleep(10);
7998 } while (timeval_elapsed(&start) < 30);
8000 if (synccount != nprocs) {
8001 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8002 *result = False;
8003 return timeval_elapsed(&start);
8006 /* start the client load */
8007 start = timeval_current();
8009 for (i=0;i<nprocs;i++) {
8010 child_status[i] = 0;
8013 printf("%d clients started\n", nprocs);
8015 for (i=0;i<nprocs;i++) {
8016 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8019 printf("\n");
8021 for (i=0;i<nprocs;i++) {
8022 if (!child_status_out[i]) {
8023 *result = False;
8026 return timeval_elapsed(&start);
8029 #define FLAG_MULTIPROC 1
8031 static struct {
8032 const char *name;
8033 bool (*fn)(int);
8034 unsigned flags;
8035 } torture_ops[] = {
8036 {"FDPASS", run_fdpasstest, 0},
8037 {"LOCK1", run_locktest1, 0},
8038 {"LOCK2", run_locktest2, 0},
8039 {"LOCK3", run_locktest3, 0},
8040 {"LOCK4", run_locktest4, 0},
8041 {"LOCK5", run_locktest5, 0},
8042 {"LOCK6", run_locktest6, 0},
8043 {"LOCK7", run_locktest7, 0},
8044 {"LOCK8", run_locktest8, 0},
8045 {"LOCK9", run_locktest9, 0},
8046 {"UNLINK", run_unlinktest, 0},
8047 {"BROWSE", run_browsetest, 0},
8048 {"ATTR", run_attrtest, 0},
8049 {"TRANS2", run_trans2test, 0},
8050 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8051 {"TORTURE",run_torture, FLAG_MULTIPROC},
8052 {"RANDOMIPC", run_randomipc, 0},
8053 {"NEGNOWAIT", run_negprot_nowait, 0},
8054 {"NBENCH", run_nbench, 0},
8055 {"NBENCH2", run_nbench2, 0},
8056 {"OPLOCK1", run_oplock1, 0},
8057 {"OPLOCK2", run_oplock2, 0},
8058 {"OPLOCK3", run_oplock3, 0},
8059 {"OPLOCK4", run_oplock4, 0},
8060 {"DIR", run_dirtest, 0},
8061 {"DIR1", run_dirtest1, 0},
8062 {"DIR-CREATETIME", run_dir_createtime, 0},
8063 {"DENY1", torture_denytest1, 0},
8064 {"DENY2", torture_denytest2, 0},
8065 {"TCON", run_tcon_test, 0},
8066 {"TCONDEV", run_tcon_devtype_test, 0},
8067 {"RW1", run_readwritetest, 0},
8068 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8069 {"RW3", run_readwritelarge, 0},
8070 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8071 {"OPEN", run_opentest, 0},
8072 {"POSIX", run_simple_posix_open_test, 0},
8073 {"POSIX-APPEND", run_posix_append, 0},
8074 {"ASYNC-ECHO", run_async_echo, 0},
8075 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8076 { "SHORTNAME-TEST", run_shortname_test, 0},
8077 { "ADDRCHANGE", run_addrchange, 0},
8078 #if 1
8079 {"OPENATTR", run_openattrtest, 0},
8080 #endif
8081 {"XCOPY", run_xcopy, 0},
8082 {"RENAME", run_rename, 0},
8083 {"DELETE", run_deletetest, 0},
8084 {"DELETE-LN", run_deletetest_ln, 0},
8085 {"PROPERTIES", run_properties, 0},
8086 {"MANGLE", torture_mangle, 0},
8087 {"MANGLE1", run_mangle1, 0},
8088 {"W2K", run_w2ktest, 0},
8089 {"TRANS2SCAN", torture_trans2_scan, 0},
8090 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8091 {"UTABLE", torture_utable, 0},
8092 {"CASETABLE", torture_casetable, 0},
8093 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8094 {"PIPE_NUMBER", run_pipe_number, 0},
8095 {"TCON2", run_tcon2_test, 0},
8096 {"IOCTL", torture_ioctl_test, 0},
8097 {"CHKPATH", torture_chkpath_test, 0},
8098 {"FDSESS", run_fdsesstest, 0},
8099 { "EATEST", run_eatest, 0},
8100 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8101 { "CHAIN1", run_chain1, 0},
8102 { "CHAIN2", run_chain2, 0},
8103 { "WINDOWS-WRITE", run_windows_write, 0},
8104 { "CLI_ECHO", run_cli_echo, 0},
8105 { "GETADDRINFO", run_getaddrinfo_send, 0},
8106 { "TLDAP", run_tldap },
8107 { "STREAMERROR", run_streamerror },
8108 { "NOTIFY-BENCH", run_notify_bench },
8109 { "BAD-NBT-SESSION", run_bad_nbt_session },
8110 { "SMB-ANY-CONNECT", run_smb_any_connect },
8111 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8112 { "LOCAL-GENCACHE", run_local_gencache, 0},
8113 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8114 { "LOCAL-BASE64", run_local_base64, 0},
8115 { "LOCAL-RBTREE", run_local_rbtree, 0},
8116 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8117 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8118 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8119 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8120 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8121 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8122 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8123 {NULL, NULL, 0}};
8127 /****************************************************************************
8128 run a specified test or "ALL"
8129 ****************************************************************************/
8130 static bool run_test(const char *name)
8132 bool ret = True;
8133 bool result = True;
8134 bool found = False;
8135 int i;
8136 double t;
8137 if (strequal(name,"ALL")) {
8138 for (i=0;torture_ops[i].name;i++) {
8139 run_test(torture_ops[i].name);
8141 found = True;
8144 for (i=0;torture_ops[i].name;i++) {
8145 fstr_sprintf(randomfname, "\\XX%x",
8146 (unsigned)random());
8148 if (strequal(name, torture_ops[i].name)) {
8149 found = True;
8150 printf("Running %s\n", name);
8151 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8152 t = create_procs(torture_ops[i].fn, &result);
8153 if (!result) {
8154 ret = False;
8155 printf("TEST %s FAILED!\n", name);
8157 } else {
8158 struct timeval start;
8159 start = timeval_current();
8160 if (!torture_ops[i].fn(0)) {
8161 ret = False;
8162 printf("TEST %s FAILED!\n", name);
8164 t = timeval_elapsed(&start);
8166 printf("%s took %g secs\n\n", name, t);
8170 if (!found) {
8171 printf("Did not find a test named %s\n", name);
8172 ret = False;
8175 return ret;
8179 static void usage(void)
8181 int i;
8183 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8184 printf("Please use samba4 torture.\n\n");
8186 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8188 printf("\t-d debuglevel\n");
8189 printf("\t-U user%%pass\n");
8190 printf("\t-k use kerberos\n");
8191 printf("\t-N numprocs\n");
8192 printf("\t-n my_netbios_name\n");
8193 printf("\t-W workgroup\n");
8194 printf("\t-o num_operations\n");
8195 printf("\t-O socket_options\n");
8196 printf("\t-m maximum protocol\n");
8197 printf("\t-L use oplocks\n");
8198 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8199 printf("\t-A showall\n");
8200 printf("\t-p port\n");
8201 printf("\t-s seed\n");
8202 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8203 printf("\n\n");
8205 printf("tests are:");
8206 for (i=0;torture_ops[i].name;i++) {
8207 printf(" %s", torture_ops[i].name);
8209 printf("\n");
8211 printf("default test is ALL\n");
8213 exit(1);
8216 /****************************************************************************
8217 main program
8218 ****************************************************************************/
8219 int main(int argc,char *argv[])
8221 int opt, i;
8222 char *p;
8223 int gotuser = 0;
8224 int gotpass = 0;
8225 bool correct = True;
8226 TALLOC_CTX *frame = talloc_stackframe();
8227 int seed = time(NULL);
8229 #ifdef HAVE_SETBUFFER
8230 setbuffer(stdout, NULL, 0);
8231 #endif
8233 setup_logging("smbtorture", DEBUG_STDOUT);
8235 load_case_tables();
8237 if (is_default_dyn_CONFIGFILE()) {
8238 if(getenv("SMB_CONF_PATH")) {
8239 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8242 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8243 load_interfaces();
8245 if (argc < 2) {
8246 usage();
8249 for(p = argv[1]; *p; p++)
8250 if(*p == '\\')
8251 *p = '/';
8253 if (strncmp(argv[1], "//", 2)) {
8254 usage();
8257 fstrcpy(host, &argv[1][2]);
8258 p = strchr_m(&host[2],'/');
8259 if (!p) {
8260 usage();
8262 *p = 0;
8263 fstrcpy(share, p+1);
8265 fstrcpy(myname, get_myname(talloc_tos()));
8266 if (!*myname) {
8267 fprintf(stderr, "Failed to get my hostname.\n");
8268 return 1;
8271 if (*username == 0 && getenv("LOGNAME")) {
8272 fstrcpy(username,getenv("LOGNAME"));
8275 argc--;
8276 argv++;
8278 fstrcpy(workgroup, lp_workgroup());
8280 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8281 switch (opt) {
8282 case 'p':
8283 port_to_use = atoi(optarg);
8284 break;
8285 case 's':
8286 seed = atoi(optarg);
8287 break;
8288 case 'W':
8289 fstrcpy(workgroup,optarg);
8290 break;
8291 case 'm':
8292 max_protocol = interpret_protocol(optarg, max_protocol);
8293 break;
8294 case 'N':
8295 nprocs = atoi(optarg);
8296 break;
8297 case 'o':
8298 torture_numops = atoi(optarg);
8299 break;
8300 case 'd':
8301 lp_set_cmdline("log level", optarg);
8302 break;
8303 case 'O':
8304 sockops = optarg;
8305 break;
8306 case 'L':
8307 use_oplocks = True;
8308 break;
8309 case 'l':
8310 local_path = optarg;
8311 break;
8312 case 'A':
8313 torture_showall = True;
8314 break;
8315 case 'n':
8316 fstrcpy(myname, optarg);
8317 break;
8318 case 'c':
8319 client_txt = optarg;
8320 break;
8321 case 'e':
8322 do_encrypt = true;
8323 break;
8324 case 'k':
8325 #ifdef HAVE_KRB5
8326 use_kerberos = True;
8327 #else
8328 d_printf("No kerberos support compiled in\n");
8329 exit(1);
8330 #endif
8331 break;
8332 case 'U':
8333 gotuser = 1;
8334 fstrcpy(username,optarg);
8335 p = strchr_m(username,'%');
8336 if (p) {
8337 *p = 0;
8338 fstrcpy(password, p+1);
8339 gotpass = 1;
8341 break;
8342 case 'b':
8343 fstrcpy(multishare_conn_fname, optarg);
8344 use_multishare_conn = True;
8345 break;
8346 case 'B':
8347 torture_blocksize = atoi(optarg);
8348 break;
8349 default:
8350 printf("Unknown option %c (%d)\n", (char)opt, opt);
8351 usage();
8355 d_printf("using seed %d\n", seed);
8357 srandom(seed);
8359 if(use_kerberos && !gotuser) gotpass = True;
8361 while (!gotpass) {
8362 p = getpass("Password:");
8363 if (p) {
8364 fstrcpy(password, p);
8365 gotpass = 1;
8369 printf("host=%s share=%s user=%s myname=%s\n",
8370 host, share, username, myname);
8372 if (argc == optind) {
8373 correct = run_test("ALL");
8374 } else {
8375 for (i=optind;i<argc;i++) {
8376 if (!run_test(argv[i])) {
8377 correct = False;
8382 TALLOC_FREE(frame);
8384 if (correct) {
8385 return(0);
8386 } else {
8387 return(1);