Remove fstrings from client struct. Properly talloc strings (ensuring we never end...
[Samba.git] / source3 / torture / torture.c
blob216eef46b12b3ada7d360f70bb6d9ae0b6d80c4a
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "includes.h"
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
26 #include "tldap.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
29 #include "memcache.h"
30 #include "nsswitch/winbind_client.h"
31 #include "dbwrap.h"
32 #include "talloc_dict.h"
33 #include "async_smb.h"
34 #include "libsmb/clirap.h"
35 #include "trans2.h"
36 #include "libsmb/nmblib.h"
38 extern char *optarg;
39 extern int optind;
41 static fstring host, workgroup, share, password, username, myname;
42 static int max_protocol = PROTOCOL_NT1;
43 static const char *sockops="TCP_NODELAY";
44 static int nprocs=1;
45 static int port_to_use=0;
46 int torture_numops=100;
47 int torture_blocksize=1024*1024;
48 static int procnum; /* records process count number when forking */
49 static struct cli_state *current_cli;
50 static fstring randomfname;
51 static bool use_oplocks;
52 static bool use_level_II_oplocks;
53 static const char *client_txt = "client_oplocks.txt";
54 static bool use_kerberos;
55 static fstring multishare_conn_fname;
56 static bool use_multishare_conn = False;
57 static bool do_encrypt;
58 static const char *local_path = NULL;
59 static int signing_state = Undefined;
61 bool torture_showall = False;
63 static double create_procs(bool (*fn)(int), bool *result);
66 /* return a pointer to a anonymous shared memory segment of size "size"
67 which will persist across fork() but will disappear when all processes
68 exit
70 The memory is not zeroed
72 This function uses system5 shared memory. It takes advantage of a property
73 that the memory is not destroyed if it is attached when the id is removed
75 void *shm_setup(int size)
77 int shmid;
78 void *ret;
80 #ifdef __QNXNTO__
81 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
82 if (shmid == -1) {
83 printf("can't get shared memory\n");
84 exit(1);
86 shm_unlink("private");
87 if (ftruncate(shmid, size) == -1) {
88 printf("can't set shared memory size\n");
89 exit(1);
91 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
92 if (ret == MAP_FAILED) {
93 printf("can't map shared memory\n");
94 exit(1);
96 #else
97 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
98 if (shmid == -1) {
99 printf("can't get shared memory\n");
100 exit(1);
102 ret = (void *)shmat(shmid, 0, 0);
103 if (!ret || ret == (void *)-1) {
104 printf("can't attach to shared memory\n");
105 return NULL;
107 /* the following releases the ipc, but note that this process
108 and all its children will still have access to the memory, its
109 just that the shmid is no longer valid for other shm calls. This
110 means we don't leave behind lots of shm segments after we exit
112 See Stevens "advanced programming in unix env" for details
114 shmctl(shmid, IPC_RMID, 0);
115 #endif
117 return ret;
120 /********************************************************************
121 Ensure a connection is encrypted.
122 ********************************************************************/
124 static bool force_cli_encryption(struct cli_state *c,
125 const char *sharename)
127 uint16 major, minor;
128 uint32 caplow, caphigh;
129 NTSTATUS status;
131 if (!SERVER_HAS_UNIX_CIFS(c)) {
132 d_printf("Encryption required and "
133 "server that doesn't support "
134 "UNIX extensions - failing connect\n");
135 return false;
138 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
139 &caphigh);
140 if (!NT_STATUS_IS_OK(status)) {
141 d_printf("Encryption required and "
142 "can't get UNIX CIFS extensions "
143 "version from server: %s\n", nt_errstr(status));
144 return false;
147 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
148 d_printf("Encryption required and "
149 "share %s doesn't support "
150 "encryption.\n", sharename);
151 return false;
154 if (c->use_kerberos) {
155 status = cli_gss_smb_encryption_start(c);
156 } else {
157 status = cli_raw_ntlm_smb_encryption_start(c,
158 username,
159 password,
160 workgroup);
163 if (!NT_STATUS_IS_OK(status)) {
164 d_printf("Encryption required and "
165 "setup failed with error %s.\n",
166 nt_errstr(status));
167 return false;
170 return true;
174 static struct cli_state *open_nbt_connection(void)
176 struct nmb_name called, calling;
177 struct sockaddr_storage ss;
178 struct cli_state *c;
179 NTSTATUS status;
181 make_nmb_name(&calling, myname, 0x0);
182 make_nmb_name(&called , host, 0x20);
184 zero_sockaddr(&ss);
186 if (!(c = cli_initialise_ex(signing_state))) {
187 printf("Failed initialize cli_struct to connect with %s\n", host);
188 return NULL;
191 c->port = port_to_use;
193 status = cli_connect(c, host, &ss);
194 if (!NT_STATUS_IS_OK(status)) {
195 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
196 return NULL;
199 c->use_kerberos = use_kerberos;
201 c->timeout = 120000; /* set a really long timeout (2 minutes) */
202 if (use_oplocks) c->use_oplocks = True;
203 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
205 if (!cli_session_request(c, &calling, &called)) {
207 * Well, that failed, try *SMBSERVER ...
208 * However, we must reconnect as well ...
210 status = cli_connect(c, host, &ss);
211 if (!NT_STATUS_IS_OK(status)) {
212 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
213 return NULL;
216 make_nmb_name(&called, "*SMBSERVER", 0x20);
217 if (!cli_session_request(c, &calling, &called)) {
218 printf("%s rejected the session\n",host);
219 printf("We tried with a called name of %s & %s\n",
220 host, "*SMBSERVER");
221 cli_shutdown(c);
222 return NULL;
226 return c;
229 /****************************************************************************
230 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
231 ****************************************************************************/
233 static bool cli_bad_session_request(struct cli_state *cli,
234 struct nmb_name *calling, struct nmb_name *called)
236 char *p;
237 int len = 4;
238 int namelen = 0;
239 char *tmp;
241 memcpy(&(cli->calling), calling, sizeof(*calling));
242 memcpy(&(cli->called ), called , sizeof(*called ));
244 /* put in the destination name */
246 tmp = name_mangle(talloc_tos(), cli->called.name,
247 cli->called.name_type);
248 if (tmp == NULL) {
249 return false;
252 p = cli->outbuf+len;
253 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
254 if (namelen > 0) {
255 memcpy(p, tmp, namelen);
256 len += namelen;
258 TALLOC_FREE(tmp);
260 /* Deliberately corrupt the name len (first byte) */
261 *p = 100;
263 /* and my name */
265 tmp = name_mangle(talloc_tos(), cli->calling.name,
266 cli->calling.name_type);
267 if (tmp == NULL) {
268 return false;
271 p = cli->outbuf+len;
272 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
273 if (namelen > 0) {
274 memcpy(p, tmp, namelen);
275 len += namelen;
277 TALLOC_FREE(tmp);
278 /* Deliberately corrupt the name len (first byte) */
279 *p = 100;
281 /* send a session request (RFC 1002) */
282 /* setup the packet length
283 * Remove four bytes from the length count, since the length
284 * field in the NBT Session Service header counts the number
285 * of bytes which follow. The cli_send_smb() function knows
286 * about this and accounts for those four bytes.
287 * CRH.
289 len -= 4;
290 _smb_setlen(cli->outbuf,len);
291 SCVAL(cli->outbuf,0,0x81);
293 cli_send_smb(cli);
294 DEBUG(5,("Sent session request\n"));
296 if (!cli_receive_smb(cli))
297 return False;
299 if (CVAL(cli->inbuf,0) != 0x82) {
300 /* This is the wrong place to put the error... JRA. */
301 cli->rap_error = CVAL(cli->inbuf,4);
302 return False;
304 return(True);
307 static struct cli_state *open_bad_nbt_connection(void)
309 struct nmb_name called, calling;
310 struct sockaddr_storage ss;
311 struct cli_state *c;
312 NTSTATUS status;
314 make_nmb_name(&calling, myname, 0x0);
315 make_nmb_name(&called , host, 0x20);
317 zero_sockaddr(&ss);
319 if (!(c = cli_initialise_ex(signing_state))) {
320 printf("Failed initialize cli_struct to connect with %s\n", host);
321 return NULL;
324 c->port = 139;
326 status = cli_connect(c, host, &ss);
327 if (!NT_STATUS_IS_OK(status)) {
328 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
329 return NULL;
332 c->timeout = 4000; /* set a short timeout (4 seconds) */
334 if (!cli_bad_session_request(c, &calling, &called)) {
335 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
336 return NULL;
339 return c;
343 /* Insert a NULL at the first separator of the given path and return a pointer
344 * to the remainder of the string.
346 static char *
347 terminate_path_at_separator(char * path)
349 char * p;
351 if (!path) {
352 return NULL;
355 if ((p = strchr_m(path, '/'))) {
356 *p = '\0';
357 return p + 1;
360 if ((p = strchr_m(path, '\\'))) {
361 *p = '\0';
362 return p + 1;
365 /* No separator. */
366 return NULL;
370 parse a //server/share type UNC name
372 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
373 char **hostname, char **sharename)
375 char *p;
377 *hostname = *sharename = NULL;
379 if (strncmp(unc_name, "\\\\", 2) &&
380 strncmp(unc_name, "//", 2)) {
381 return False;
384 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
385 p = terminate_path_at_separator(*hostname);
387 if (p && *p) {
388 *sharename = talloc_strdup(mem_ctx, p);
389 terminate_path_at_separator(*sharename);
392 if (*hostname && *sharename) {
393 return True;
396 TALLOC_FREE(*hostname);
397 TALLOC_FREE(*sharename);
398 return False;
401 static bool torture_open_connection_share(struct cli_state **c,
402 const char *hostname,
403 const char *sharename)
405 int flags = 0;
406 NTSTATUS status;
408 if (use_kerberos)
409 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
410 if (use_oplocks)
411 flags |= CLI_FULL_CONNECTION_OPLOCKS;
412 if (use_level_II_oplocks)
413 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
415 status = cli_full_connection(c, myname,
416 hostname, NULL, port_to_use,
417 sharename, "?????",
418 username, workgroup,
419 password, flags, signing_state);
420 if (!NT_STATUS_IS_OK(status)) {
421 printf("failed to open share connection: //%s/%s port:%d - %s\n",
422 hostname, sharename, port_to_use, nt_errstr(status));
423 return False;
426 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
428 if (do_encrypt) {
429 return force_cli_encryption(*c,
430 sharename);
432 return True;
435 bool torture_open_connection(struct cli_state **c, int conn_index)
437 char **unc_list = NULL;
438 int num_unc_names = 0;
439 bool result;
441 if (use_multishare_conn==True) {
442 char *h, *s;
443 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
444 if (!unc_list || num_unc_names <= 0) {
445 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
446 exit(1);
449 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
450 NULL, &h, &s)) {
451 printf("Failed to parse UNC name %s\n",
452 unc_list[conn_index % num_unc_names]);
453 TALLOC_FREE(unc_list);
454 exit(1);
457 result = torture_open_connection_share(c, h, s);
459 /* h, s were copied earlier */
460 TALLOC_FREE(unc_list);
461 return result;
464 return torture_open_connection_share(c, host, share);
467 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
469 uint16 old_vuid = cli->vuid;
470 fstring old_user_name;
471 size_t passlen = strlen(password);
472 NTSTATUS status;
473 bool ret;
475 fstrcpy(old_user_name, cli->user_name);
476 cli->vuid = 0;
477 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
478 password, passlen,
479 password, passlen,
480 workgroup));
481 *new_vuid = cli->vuid;
482 cli->vuid = old_vuid;
483 status = cli_set_username(cli, old_user_name);
484 if (!NT_STATUS_IS_OK(status)) {
485 return false;
487 return ret;
491 bool torture_close_connection(struct cli_state *c)
493 bool ret = True;
494 NTSTATUS status;
496 status = cli_tdis(c);
497 if (!NT_STATUS_IS_OK(status)) {
498 printf("tdis failed (%s)\n", nt_errstr(status));
499 ret = False;
502 cli_shutdown(c);
504 return ret;
508 /* check if the server produced the expected error code */
509 static bool check_error(int line, struct cli_state *c,
510 uint8 eclass, uint32 ecode, NTSTATUS nterr)
512 if (cli_is_dos_error(c)) {
513 uint8 cclass;
514 uint32 num;
516 /* Check DOS error */
518 cli_dos_error(c, &cclass, &num);
520 if (eclass != cclass || ecode != num) {
521 printf("unexpected error code class=%d code=%d\n",
522 (int)cclass, (int)num);
523 printf(" expected %d/%d %s (line=%d)\n",
524 (int)eclass, (int)ecode, nt_errstr(nterr), line);
525 return False;
528 } else {
529 NTSTATUS status;
531 /* Check NT error */
533 status = cli_nt_error(c);
535 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
536 printf("unexpected error code %s\n", nt_errstr(status));
537 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
538 return False;
542 return True;
546 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
548 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
549 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
551 return True;
555 static bool rw_torture(struct cli_state *c)
557 const char *lockfname = "\\torture.lck";
558 fstring fname;
559 uint16_t fnum;
560 uint16_t fnum2;
561 pid_t pid2, pid = getpid();
562 int i, j;
563 char buf[1024];
564 bool correct = True;
565 NTSTATUS status;
567 memset(buf, '\0', sizeof(buf));
569 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
570 DENY_NONE, &fnum2);
571 if (!NT_STATUS_IS_OK(status)) {
572 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
574 if (!NT_STATUS_IS_OK(status)) {
575 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
576 return False;
579 for (i=0;i<torture_numops;i++) {
580 unsigned n = (unsigned)sys_random()%10;
582 if (i % 10 == 0) {
583 printf("%d\r", i); fflush(stdout);
585 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
587 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
588 return False;
591 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
592 printf("open failed (%s)\n", cli_errstr(c));
593 correct = False;
594 break;
597 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
598 sizeof(pid), NULL);
599 if (!NT_STATUS_IS_OK(status)) {
600 printf("write failed (%s)\n", nt_errstr(status));
601 correct = False;
604 for (j=0;j<50;j++) {
605 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
606 sizeof(pid)+(j*sizeof(buf)),
607 sizeof(buf), NULL);
608 if (!NT_STATUS_IS_OK(status)) {
609 printf("write failed (%s)\n",
610 nt_errstr(status));
611 correct = False;
615 pid2 = 0;
617 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
618 printf("read failed (%s)\n", cli_errstr(c));
619 correct = False;
622 if (pid2 != pid) {
623 printf("data corruption!\n");
624 correct = False;
627 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
628 printf("close failed (%s)\n", cli_errstr(c));
629 correct = False;
632 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
633 printf("unlink failed (%s)\n", cli_errstr(c));
634 correct = False;
637 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
638 printf("unlock failed (%s)\n", cli_errstr(c));
639 correct = False;
643 cli_close(c, fnum2);
644 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
646 printf("%d\n", i);
648 return correct;
651 static bool run_torture(int dummy)
653 struct cli_state *cli;
654 bool ret;
656 cli = current_cli;
658 cli_sockopt(cli, sockops);
660 ret = rw_torture(cli);
662 if (!torture_close_connection(cli)) {
663 ret = False;
666 return ret;
669 static bool rw_torture3(struct cli_state *c, char *lockfname)
671 uint16_t fnum = (uint16_t)-1;
672 unsigned int i = 0;
673 char buf[131072];
674 char buf_rd[131072];
675 unsigned count;
676 unsigned countprev = 0;
677 ssize_t sent = 0;
678 bool correct = True;
679 NTSTATUS status = NT_STATUS_OK;
681 srandom(1);
682 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
684 SIVAL(buf, i, sys_random());
687 if (procnum == 0)
689 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, aSYSTEM | aHIDDEN))) {
690 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
693 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
694 DENY_NONE, &fnum))) {
695 printf("first open read/write of %s failed (%s)\n",
696 lockfname, cli_errstr(c));
697 return False;
700 else
702 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
704 status = cli_open(c, lockfname, O_RDONLY,
705 DENY_NONE, &fnum);
706 if (!NT_STATUS_IS_OK(status)) {
707 break;
709 smb_msleep(10);
711 if (!NT_STATUS_IS_OK(status)) {
712 printf("second open read-only of %s failed (%s)\n",
713 lockfname, cli_errstr(c));
714 return False;
718 i = 0;
719 for (count = 0; count < sizeof(buf); count += sent)
721 if (count >= countprev) {
722 printf("%d %8d\r", i, count);
723 fflush(stdout);
724 i++;
725 countprev += (sizeof(buf) / 20);
728 if (procnum == 0)
730 sent = ((unsigned)sys_random()%(20))+ 1;
731 if (sent > sizeof(buf) - count)
733 sent = sizeof(buf) - count;
736 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
737 count, (size_t)sent, NULL);
738 if (!NT_STATUS_IS_OK(status)) {
739 printf("write failed (%s)\n",
740 nt_errstr(status));
741 correct = False;
744 else
746 sent = cli_read(c, fnum, buf_rd+count, count,
747 sizeof(buf)-count);
748 if (sent < 0)
750 printf("read failed offset:%d size:%ld (%s)\n",
751 count, (unsigned long)sizeof(buf)-count,
752 cli_errstr(c));
753 correct = False;
754 sent = 0;
756 if (sent > 0)
758 if (memcmp(buf_rd+count, buf+count, sent) != 0)
760 printf("read/write compare failed\n");
761 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
762 correct = False;
763 break;
770 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
771 printf("close failed (%s)\n", cli_errstr(c));
772 correct = False;
775 return correct;
778 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
780 const char *lockfname = "\\torture2.lck";
781 uint16_t fnum1;
782 uint16_t fnum2;
783 int i;
784 char buf[131072];
785 char buf_rd[131072];
786 bool correct = True;
787 ssize_t bytes_read;
789 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
790 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
793 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
794 DENY_NONE, &fnum1))) {
795 printf("first open read/write of %s failed (%s)\n",
796 lockfname, cli_errstr(c1));
797 return False;
799 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
800 DENY_NONE, &fnum2))) {
801 printf("second open read-only of %s failed (%s)\n",
802 lockfname, cli_errstr(c2));
803 cli_close(c1, fnum1);
804 return False;
807 for (i=0;i<torture_numops;i++)
809 NTSTATUS status;
810 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
811 if (i % 10 == 0) {
812 printf("%d\r", i); fflush(stdout);
815 generate_random_buffer((unsigned char *)buf, buf_size);
817 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
818 buf_size, NULL);
819 if (!NT_STATUS_IS_OK(status)) {
820 printf("write failed (%s)\n", nt_errstr(status));
821 correct = False;
822 break;
825 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
826 printf("read failed (%s)\n", cli_errstr(c2));
827 printf("read %d, expected %ld\n", (int)bytes_read,
828 (unsigned long)buf_size);
829 correct = False;
830 break;
833 if (memcmp(buf_rd, buf, buf_size) != 0)
835 printf("read/write compare failed\n");
836 correct = False;
837 break;
841 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
842 printf("close failed (%s)\n", cli_errstr(c2));
843 correct = False;
845 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
846 printf("close failed (%s)\n", cli_errstr(c1));
847 correct = False;
850 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
851 printf("unlink failed (%s)\n", cli_errstr(c1));
852 correct = False;
855 return correct;
858 static bool run_readwritetest(int dummy)
860 struct cli_state *cli1, *cli2;
861 bool test1, test2 = False;
863 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
864 return False;
866 cli_sockopt(cli1, sockops);
867 cli_sockopt(cli2, sockops);
869 printf("starting readwritetest\n");
871 test1 = rw_torture2(cli1, cli2);
872 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
874 if (test1) {
875 test2 = rw_torture2(cli1, cli1);
876 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
879 if (!torture_close_connection(cli1)) {
880 test1 = False;
883 if (!torture_close_connection(cli2)) {
884 test2 = False;
887 return (test1 && test2);
890 static bool run_readwritemulti(int dummy)
892 struct cli_state *cli;
893 bool test;
895 cli = current_cli;
897 cli_sockopt(cli, sockops);
899 printf("run_readwritemulti: fname %s\n", randomfname);
900 test = rw_torture3(cli, randomfname);
902 if (!torture_close_connection(cli)) {
903 test = False;
906 return test;
909 static bool run_readwritelarge_internal(int max_xmit_k)
911 static struct cli_state *cli1;
912 uint16_t fnum1;
913 const char *lockfname = "\\large.dat";
914 SMB_OFF_T fsize;
915 char buf[126*1024];
916 bool correct = True;
918 if (!torture_open_connection(&cli1, 0)) {
919 return False;
921 cli_sockopt(cli1, sockops);
922 memset(buf,'\0',sizeof(buf));
924 cli1->max_xmit = max_xmit_k*1024;
926 if (signing_state == Required) {
927 /* Horrible cheat to force
928 multiple signed outstanding
929 packets against a Samba server.
931 cli1->is_samba = false;
934 printf("starting readwritelarge_internal\n");
936 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
938 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
939 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
940 return False;
943 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
945 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
946 cli1, fnum1, NULL, &fsize, NULL, NULL,
947 NULL, NULL, NULL))) {
948 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
949 correct = False;
952 if (fsize == sizeof(buf))
953 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
954 (unsigned long)fsize);
955 else {
956 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
957 (unsigned long)fsize);
958 correct = False;
961 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
962 printf("close failed (%s)\n", cli_errstr(cli1));
963 correct = False;
966 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
967 printf("unlink failed (%s)\n", cli_errstr(cli1));
968 correct = False;
971 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
972 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
973 return False;
976 cli1->max_xmit = 4*1024;
978 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
980 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
981 cli1, fnum1, NULL, &fsize, NULL, NULL,
982 NULL, NULL, NULL))) {
983 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
984 correct = False;
987 if (fsize == sizeof(buf))
988 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
989 (unsigned long)fsize);
990 else {
991 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
992 (unsigned long)fsize);
993 correct = False;
996 #if 0
997 /* ToDo - set allocation. JRA */
998 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
999 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1000 return False;
1002 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1003 NULL, NULL)) {
1004 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1005 correct = False;
1007 if (fsize != 0)
1008 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1009 #endif
1011 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1012 printf("close failed (%s)\n", cli_errstr(cli1));
1013 correct = False;
1016 if (!torture_close_connection(cli1)) {
1017 correct = False;
1019 return correct;
1022 static bool run_readwritelarge(int dummy)
1024 return run_readwritelarge_internal(128);
1027 static bool run_readwritelarge_signtest(int dummy)
1029 bool ret;
1030 signing_state = Required;
1031 ret = run_readwritelarge_internal(2);
1032 signing_state = Undefined;
1033 return ret;
1036 int line_count = 0;
1037 int nbio_id;
1039 #define ival(s) strtol(s, NULL, 0)
1041 /* run a test that simulates an approximate netbench client load */
1042 static bool run_netbench(int client)
1044 struct cli_state *cli;
1045 int i;
1046 char line[1024];
1047 char cname[20];
1048 FILE *f;
1049 const char *params[20];
1050 bool correct = True;
1052 cli = current_cli;
1054 nbio_id = client;
1056 cli_sockopt(cli, sockops);
1058 nb_setup(cli);
1060 slprintf(cname,sizeof(cname)-1, "client%d", client);
1062 f = fopen(client_txt, "r");
1064 if (!f) {
1065 perror(client_txt);
1066 return False;
1069 while (fgets(line, sizeof(line)-1, f)) {
1070 char *saveptr;
1071 line_count++;
1073 line[strlen(line)-1] = 0;
1075 /* printf("[%d] %s\n", line_count, line); */
1077 all_string_sub(line,"client1", cname, sizeof(line));
1079 /* parse the command parameters */
1080 params[0] = strtok_r(line, " ", &saveptr);
1081 i = 0;
1082 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1084 params[i] = "";
1086 if (i < 2) continue;
1088 if (!strncmp(params[0],"SMB", 3)) {
1089 printf("ERROR: You are using a dbench 1 load file\n");
1090 exit(1);
1093 if (!strcmp(params[0],"NTCreateX")) {
1094 nb_createx(params[1], ival(params[2]), ival(params[3]),
1095 ival(params[4]));
1096 } else if (!strcmp(params[0],"Close")) {
1097 nb_close(ival(params[1]));
1098 } else if (!strcmp(params[0],"Rename")) {
1099 nb_rename(params[1], params[2]);
1100 } else if (!strcmp(params[0],"Unlink")) {
1101 nb_unlink(params[1]);
1102 } else if (!strcmp(params[0],"Deltree")) {
1103 nb_deltree(params[1]);
1104 } else if (!strcmp(params[0],"Rmdir")) {
1105 nb_rmdir(params[1]);
1106 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1107 nb_qpathinfo(params[1]);
1108 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1109 nb_qfileinfo(ival(params[1]));
1110 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1111 nb_qfsinfo(ival(params[1]));
1112 } else if (!strcmp(params[0],"FIND_FIRST")) {
1113 nb_findfirst(params[1]);
1114 } else if (!strcmp(params[0],"WriteX")) {
1115 nb_writex(ival(params[1]),
1116 ival(params[2]), ival(params[3]), ival(params[4]));
1117 } else if (!strcmp(params[0],"ReadX")) {
1118 nb_readx(ival(params[1]),
1119 ival(params[2]), ival(params[3]), ival(params[4]));
1120 } else if (!strcmp(params[0],"Flush")) {
1121 nb_flush(ival(params[1]));
1122 } else {
1123 printf("Unknown operation %s\n", params[0]);
1124 exit(1);
1127 fclose(f);
1129 nb_cleanup();
1131 if (!torture_close_connection(cli)) {
1132 correct = False;
1135 return correct;
1139 /* run a test that simulates an approximate netbench client load */
1140 static bool run_nbench(int dummy)
1142 double t;
1143 bool correct = True;
1145 nbio_shmem(nprocs);
1147 nbio_id = -1;
1149 signal(SIGALRM, nb_alarm);
1150 alarm(1);
1151 t = create_procs(run_netbench, &correct);
1152 alarm(0);
1154 printf("\nThroughput %g MB/sec\n",
1155 1.0e-6 * nbio_total() / t);
1156 return correct;
1161 This test checks for two things:
1163 1) correct support for retaining locks over a close (ie. the server
1164 must not use posix semantics)
1165 2) support for lock timeouts
1167 static bool run_locktest1(int dummy)
1169 struct cli_state *cli1, *cli2;
1170 const char *fname = "\\lockt1.lck";
1171 uint16_t fnum1, fnum2, fnum3;
1172 time_t t1, t2;
1173 unsigned lock_timeout;
1175 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1176 return False;
1178 cli_sockopt(cli1, sockops);
1179 cli_sockopt(cli2, sockops);
1181 printf("starting locktest1\n");
1183 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1185 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1186 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1187 return False;
1189 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1190 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1191 return False;
1193 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1194 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1195 return False;
1198 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1199 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1200 return False;
1204 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1205 printf("lock2 succeeded! This is a locking bug\n");
1206 return False;
1207 } else {
1208 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1209 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1213 lock_timeout = (1 + (random() % 20));
1214 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1215 t1 = time(NULL);
1216 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1217 printf("lock3 succeeded! This is a locking bug\n");
1218 return False;
1219 } else {
1220 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1221 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1223 t2 = time(NULL);
1225 if (ABS(t2 - t1) < lock_timeout-1) {
1226 printf("error: This server appears not to support timed lock requests\n");
1229 printf("server slept for %u seconds for a %u second timeout\n",
1230 (unsigned int)(t2-t1), lock_timeout);
1232 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1233 printf("close1 failed (%s)\n", cli_errstr(cli1));
1234 return False;
1237 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1238 printf("lock4 succeeded! This is a locking bug\n");
1239 return False;
1240 } else {
1241 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1242 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1245 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1246 printf("close2 failed (%s)\n", cli_errstr(cli1));
1247 return False;
1250 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1251 printf("close3 failed (%s)\n", cli_errstr(cli2));
1252 return False;
1255 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1256 printf("unlink failed (%s)\n", cli_errstr(cli1));
1257 return False;
1261 if (!torture_close_connection(cli1)) {
1262 return False;
1265 if (!torture_close_connection(cli2)) {
1266 return False;
1269 printf("Passed locktest1\n");
1270 return True;
1274 this checks to see if a secondary tconx can use open files from an
1275 earlier tconx
1277 static bool run_tcon_test(int dummy)
1279 static struct cli_state *cli;
1280 const char *fname = "\\tcontest.tmp";
1281 uint16 fnum1;
1282 uint16 cnum1, cnum2, cnum3;
1283 uint16 vuid1, vuid2;
1284 char buf[4];
1285 bool ret = True;
1286 NTSTATUS status;
1288 memset(buf, '\0', sizeof(buf));
1290 if (!torture_open_connection(&cli, 0)) {
1291 return False;
1293 cli_sockopt(cli, sockops);
1295 printf("starting tcontest\n");
1297 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1299 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1300 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1301 return False;
1304 cnum1 = cli->cnum;
1305 vuid1 = cli->vuid;
1307 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1308 if (!NT_STATUS_IS_OK(status)) {
1309 printf("initial write failed (%s)", nt_errstr(status));
1310 return False;
1313 status = cli_tcon_andx(cli, share, "?????",
1314 password, strlen(password)+1);
1315 if (!NT_STATUS_IS_OK(status)) {
1316 printf("%s refused 2nd tree connect (%s)\n", host,
1317 nt_errstr(status));
1318 cli_shutdown(cli);
1319 return False;
1322 cnum2 = cli->cnum;
1323 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1324 vuid2 = cli->vuid + 1;
1326 /* try a write with the wrong tid */
1327 cli->cnum = cnum2;
1329 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1330 if (NT_STATUS_IS_OK(status)) {
1331 printf("* server allows write with wrong TID\n");
1332 ret = False;
1333 } else {
1334 printf("server fails write with wrong TID : %s\n",
1335 nt_errstr(status));
1339 /* try a write with an invalid tid */
1340 cli->cnum = cnum3;
1342 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1343 if (NT_STATUS_IS_OK(status)) {
1344 printf("* server allows write with invalid TID\n");
1345 ret = False;
1346 } else {
1347 printf("server fails write with invalid TID : %s\n",
1348 nt_errstr(status));
1351 /* try a write with an invalid vuid */
1352 cli->vuid = vuid2;
1353 cli->cnum = cnum1;
1355 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1356 if (NT_STATUS_IS_OK(status)) {
1357 printf("* server allows write with invalid VUID\n");
1358 ret = False;
1359 } else {
1360 printf("server fails write with invalid VUID : %s\n",
1361 nt_errstr(status));
1364 cli->cnum = cnum1;
1365 cli->vuid = vuid1;
1367 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1368 printf("close failed (%s)\n", cli_errstr(cli));
1369 return False;
1372 cli->cnum = cnum2;
1374 status = cli_tdis(cli);
1375 if (!NT_STATUS_IS_OK(status)) {
1376 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1377 return False;
1380 cli->cnum = cnum1;
1382 if (!torture_close_connection(cli)) {
1383 return False;
1386 return ret;
1391 checks for old style tcon support
1393 static bool run_tcon2_test(int dummy)
1395 static struct cli_state *cli;
1396 uint16 cnum, max_xmit;
1397 char *service;
1398 NTSTATUS status;
1400 if (!torture_open_connection(&cli, 0)) {
1401 return False;
1403 cli_sockopt(cli, sockops);
1405 printf("starting tcon2 test\n");
1407 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1408 return false;
1411 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1413 SAFE_FREE(service);
1415 if (!NT_STATUS_IS_OK(status)) {
1416 printf("tcon2 failed : %s\n", nt_errstr(status));
1417 } else {
1418 printf("tcon OK : max_xmit=%d cnum=%d\n",
1419 (int)max_xmit, (int)cnum);
1422 if (!torture_close_connection(cli)) {
1423 return False;
1426 printf("Passed tcon2 test\n");
1427 return True;
1430 static bool tcon_devtest(struct cli_state *cli,
1431 const char *myshare, const char *devtype,
1432 const char *return_devtype,
1433 NTSTATUS expected_error)
1435 NTSTATUS status;
1436 bool ret;
1438 status = cli_tcon_andx(cli, myshare, devtype,
1439 password, strlen(password)+1);
1441 if (NT_STATUS_IS_OK(expected_error)) {
1442 if (NT_STATUS_IS_OK(status)) {
1443 if (strcmp(cli->dev, return_devtype) == 0) {
1444 ret = True;
1445 } else {
1446 printf("tconX to share %s with type %s "
1447 "succeeded but returned the wrong "
1448 "device type (got [%s] but should have got [%s])\n",
1449 myshare, devtype, cli->dev, return_devtype);
1450 ret = False;
1452 } else {
1453 printf("tconX to share %s with type %s "
1454 "should have succeeded but failed\n",
1455 myshare, devtype);
1456 ret = False;
1458 cli_tdis(cli);
1459 } else {
1460 if (NT_STATUS_IS_OK(status)) {
1461 printf("tconx to share %s with type %s "
1462 "should have failed but succeeded\n",
1463 myshare, devtype);
1464 ret = False;
1465 } else {
1466 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1467 expected_error)) {
1468 ret = True;
1469 } else {
1470 printf("Returned unexpected error\n");
1471 ret = False;
1475 return ret;
1479 checks for correct tconX support
1481 static bool run_tcon_devtype_test(int dummy)
1483 static struct cli_state *cli1 = NULL;
1484 int flags = 0;
1485 NTSTATUS status;
1486 bool ret = True;
1488 status = cli_full_connection(&cli1, myname,
1489 host, NULL, port_to_use,
1490 NULL, NULL,
1491 username, workgroup,
1492 password, flags, signing_state);
1494 if (!NT_STATUS_IS_OK(status)) {
1495 printf("could not open connection\n");
1496 return False;
1499 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1500 ret = False;
1502 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1503 ret = False;
1505 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1506 ret = False;
1508 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1509 ret = False;
1511 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1512 ret = False;
1514 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1515 ret = False;
1517 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1518 ret = False;
1520 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1521 ret = False;
1523 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1524 ret = False;
1526 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1527 ret = False;
1529 cli_shutdown(cli1);
1531 if (ret)
1532 printf("Passed tcondevtest\n");
1534 return ret;
1539 This test checks that
1541 1) the server supports multiple locking contexts on the one SMB
1542 connection, distinguished by PID.
1544 2) the server correctly fails overlapping locks made by the same PID (this
1545 goes against POSIX behaviour, which is why it is tricky to implement)
1547 3) the server denies unlock requests by an incorrect client PID
1549 static bool run_locktest2(int dummy)
1551 static struct cli_state *cli;
1552 const char *fname = "\\lockt2.lck";
1553 uint16_t fnum1, fnum2, fnum3;
1554 bool correct = True;
1556 if (!torture_open_connection(&cli, 0)) {
1557 return False;
1560 cli_sockopt(cli, sockops);
1562 printf("starting locktest2\n");
1564 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1566 cli_setpid(cli, 1);
1568 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1569 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1570 return False;
1573 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1574 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1575 return False;
1578 cli_setpid(cli, 2);
1580 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1581 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1582 return False;
1585 cli_setpid(cli, 1);
1587 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1588 printf("lock1 failed (%s)\n", cli_errstr(cli));
1589 return False;
1592 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1593 printf("WRITE lock1 succeeded! This is a locking bug\n");
1594 correct = False;
1595 } else {
1596 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1597 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1600 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1601 printf("WRITE lock2 succeeded! This is a locking bug\n");
1602 correct = False;
1603 } else {
1604 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1605 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1608 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1609 printf("READ lock2 succeeded! This is a locking bug\n");
1610 correct = False;
1611 } else {
1612 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1613 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1616 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1617 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1619 cli_setpid(cli, 2);
1620 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1621 printf("unlock at 100 succeeded! This is a locking bug\n");
1622 correct = False;
1625 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1626 printf("unlock1 succeeded! This is a locking bug\n");
1627 correct = False;
1628 } else {
1629 if (!check_error(__LINE__, cli,
1630 ERRDOS, ERRlock,
1631 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1634 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1635 printf("unlock2 succeeded! This is a locking bug\n");
1636 correct = False;
1637 } else {
1638 if (!check_error(__LINE__, cli,
1639 ERRDOS, ERRlock,
1640 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1643 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1644 printf("lock3 succeeded! This is a locking bug\n");
1645 correct = False;
1646 } else {
1647 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1650 cli_setpid(cli, 1);
1652 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1653 printf("close1 failed (%s)\n", cli_errstr(cli));
1654 return False;
1657 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1658 printf("close2 failed (%s)\n", cli_errstr(cli));
1659 return False;
1662 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1663 printf("close3 failed (%s)\n", cli_errstr(cli));
1664 return False;
1667 if (!torture_close_connection(cli)) {
1668 correct = False;
1671 printf("locktest2 finished\n");
1673 return correct;
1678 This test checks that
1680 1) the server supports the full offset range in lock requests
1682 static bool run_locktest3(int dummy)
1684 static struct cli_state *cli1, *cli2;
1685 const char *fname = "\\lockt3.lck";
1686 uint16_t fnum1, fnum2;
1687 int i;
1688 uint32 offset;
1689 bool correct = True;
1691 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1693 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1694 return False;
1696 cli_sockopt(cli1, sockops);
1697 cli_sockopt(cli2, sockops);
1699 printf("starting locktest3\n");
1701 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1703 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1704 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1705 return False;
1707 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1708 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1709 return False;
1712 for (offset=i=0;i<torture_numops;i++) {
1713 NEXT_OFFSET;
1714 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1715 printf("lock1 %d failed (%s)\n",
1717 cli_errstr(cli1));
1718 return False;
1721 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1722 printf("lock2 %d failed (%s)\n",
1724 cli_errstr(cli1));
1725 return False;
1729 for (offset=i=0;i<torture_numops;i++) {
1730 NEXT_OFFSET;
1732 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1733 printf("error: lock1 %d succeeded!\n", i);
1734 return False;
1737 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1738 printf("error: lock2 %d succeeded!\n", i);
1739 return False;
1742 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1743 printf("error: lock3 %d succeeded!\n", i);
1744 return False;
1747 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1748 printf("error: lock4 %d succeeded!\n", i);
1749 return False;
1753 for (offset=i=0;i<torture_numops;i++) {
1754 NEXT_OFFSET;
1756 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1757 printf("unlock1 %d failed (%s)\n",
1759 cli_errstr(cli1));
1760 return False;
1763 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1764 printf("unlock2 %d failed (%s)\n",
1766 cli_errstr(cli1));
1767 return False;
1771 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1772 printf("close1 failed (%s)\n", cli_errstr(cli1));
1773 return False;
1776 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1777 printf("close2 failed (%s)\n", cli_errstr(cli2));
1778 return False;
1781 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1782 printf("unlink failed (%s)\n", cli_errstr(cli1));
1783 return False;
1786 if (!torture_close_connection(cli1)) {
1787 correct = False;
1790 if (!torture_close_connection(cli2)) {
1791 correct = False;
1794 printf("finished locktest3\n");
1796 return correct;
1799 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1800 printf("** "); correct = False; \
1804 looks at overlapping locks
1806 static bool run_locktest4(int dummy)
1808 static struct cli_state *cli1, *cli2;
1809 const char *fname = "\\lockt4.lck";
1810 uint16_t fnum1, fnum2, f;
1811 bool ret;
1812 char buf[1000];
1813 bool correct = True;
1814 NTSTATUS status;
1816 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1817 return False;
1820 cli_sockopt(cli1, sockops);
1821 cli_sockopt(cli2, sockops);
1823 printf("starting locktest4\n");
1825 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1827 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1828 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1830 memset(buf, 0, sizeof(buf));
1832 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1833 NULL);
1834 if (!NT_STATUS_IS_OK(status)) {
1835 printf("Failed to create file: %s\n", nt_errstr(status));
1836 correct = False;
1837 goto fail;
1840 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1841 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1842 EXPECTED(ret, False);
1843 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1845 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1846 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1847 EXPECTED(ret, True);
1848 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1850 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1851 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1852 EXPECTED(ret, False);
1853 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1855 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1856 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1857 EXPECTED(ret, True);
1858 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1860 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1861 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1862 EXPECTED(ret, False);
1863 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1865 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1866 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1867 EXPECTED(ret, True);
1868 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1870 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1871 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1872 EXPECTED(ret, True);
1873 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1875 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1876 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1877 EXPECTED(ret, False);
1878 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1880 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1881 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1882 EXPECTED(ret, False);
1883 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1885 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1886 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1887 EXPECTED(ret, True);
1888 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1890 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1891 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1892 EXPECTED(ret, False);
1893 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1895 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1896 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1897 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1898 EXPECTED(ret, False);
1899 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1902 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1903 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1904 EXPECTED(ret, False);
1905 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1907 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1908 if (ret) {
1909 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1910 NULL);
1911 ret = NT_STATUS_IS_OK(status);
1913 EXPECTED(ret, False);
1914 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1917 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1918 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1919 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1920 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1921 EXPECTED(ret, True);
1922 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1925 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1926 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1927 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1928 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1929 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1930 150, 4, NULL))) &&
1931 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1932 EXPECTED(ret, True);
1933 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1935 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1936 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1937 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1938 160, 4, NULL)) &&
1939 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1940 EXPECTED(ret, True);
1941 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1943 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1944 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1945 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1946 170, 4, NULL)) &&
1947 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1948 EXPECTED(ret, True);
1949 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1951 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1952 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1953 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1954 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1955 190, 4, NULL)) &&
1956 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1957 EXPECTED(ret, True);
1958 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1960 cli_close(cli1, fnum1);
1961 cli_close(cli2, fnum2);
1962 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1963 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1964 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1965 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1966 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1967 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1968 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1969 cli_close(cli1, f);
1970 cli_close(cli1, fnum1);
1971 EXPECTED(ret, True);
1972 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1974 fail:
1975 cli_close(cli1, fnum1);
1976 cli_close(cli2, fnum2);
1977 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1978 torture_close_connection(cli1);
1979 torture_close_connection(cli2);
1981 printf("finished locktest4\n");
1982 return correct;
1986 looks at lock upgrade/downgrade.
1988 static bool run_locktest5(int dummy)
1990 static struct cli_state *cli1, *cli2;
1991 const char *fname = "\\lockt5.lck";
1992 uint16_t fnum1, fnum2, fnum3;
1993 bool ret;
1994 char buf[1000];
1995 bool correct = True;
1996 NTSTATUS status;
1998 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1999 return False;
2002 cli_sockopt(cli1, sockops);
2003 cli_sockopt(cli2, sockops);
2005 printf("starting locktest5\n");
2007 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2009 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2010 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2011 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2013 memset(buf, 0, sizeof(buf));
2015 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2016 NULL);
2017 if (!NT_STATUS_IS_OK(status)) {
2018 printf("Failed to create file: %s\n", nt_errstr(status));
2019 correct = False;
2020 goto fail;
2023 /* Check for NT bug... */
2024 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2025 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2026 cli_close(cli1, fnum1);
2027 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2028 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2029 EXPECTED(ret, True);
2030 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2031 cli_close(cli1, fnum1);
2032 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2033 cli_unlock(cli1, fnum3, 0, 1);
2035 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2036 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2037 EXPECTED(ret, True);
2038 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2040 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2041 EXPECTED(ret, False);
2043 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2045 /* Unlock the process 2 lock. */
2046 cli_unlock(cli2, fnum2, 0, 4);
2048 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2049 EXPECTED(ret, False);
2051 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2053 /* Unlock the process 1 fnum3 lock. */
2054 cli_unlock(cli1, fnum3, 0, 4);
2056 /* Stack 2 more locks here. */
2057 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2058 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2060 EXPECTED(ret, True);
2061 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2063 /* Unlock the first process lock, then check this was the WRITE lock that was
2064 removed. */
2066 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2067 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2069 EXPECTED(ret, True);
2070 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2072 /* Unlock the process 2 lock. */
2073 cli_unlock(cli2, fnum2, 0, 4);
2075 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2077 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2078 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2079 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2081 EXPECTED(ret, True);
2082 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2084 /* Ensure the next unlock fails. */
2085 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2086 EXPECTED(ret, False);
2087 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2089 /* Ensure connection 2 can get a write lock. */
2090 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2091 EXPECTED(ret, True);
2093 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2096 fail:
2097 cli_close(cli1, fnum1);
2098 cli_close(cli2, fnum2);
2099 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2100 if (!torture_close_connection(cli1)) {
2101 correct = False;
2103 if (!torture_close_connection(cli2)) {
2104 correct = False;
2107 printf("finished locktest5\n");
2109 return correct;
2113 tries the unusual lockingX locktype bits
2115 static bool run_locktest6(int dummy)
2117 static struct cli_state *cli;
2118 const char *fname[1] = { "\\lock6.txt" };
2119 int i;
2120 uint16_t fnum;
2121 NTSTATUS status;
2123 if (!torture_open_connection(&cli, 0)) {
2124 return False;
2127 cli_sockopt(cli, sockops);
2129 printf("starting locktest6\n");
2131 for (i=0;i<1;i++) {
2132 printf("Testing %s\n", fname[i]);
2134 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2136 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2137 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2138 cli_close(cli, fnum);
2139 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2141 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2142 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2143 cli_close(cli, fnum);
2144 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2146 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2149 torture_close_connection(cli);
2151 printf("finished locktest6\n");
2152 return True;
2155 static bool run_locktest7(int dummy)
2157 struct cli_state *cli1;
2158 const char *fname = "\\lockt7.lck";
2159 uint16_t fnum1;
2160 char buf[200];
2161 bool correct = False;
2162 NTSTATUS status;
2164 if (!torture_open_connection(&cli1, 0)) {
2165 return False;
2168 cli_sockopt(cli1, sockops);
2170 printf("starting locktest7\n");
2172 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2174 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2176 memset(buf, 0, sizeof(buf));
2178 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2179 NULL);
2180 if (!NT_STATUS_IS_OK(status)) {
2181 printf("Failed to create file: %s\n", nt_errstr(status));
2182 goto fail;
2185 cli_setpid(cli1, 1);
2187 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2188 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2189 goto fail;
2190 } else {
2191 printf("pid1 successfully locked range 130:4 for READ\n");
2194 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2195 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2196 goto fail;
2197 } else {
2198 printf("pid1 successfully read the range 130:4\n");
2201 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2202 if (!NT_STATUS_IS_OK(status)) {
2203 printf("pid1 unable to write to the range 130:4, error was "
2204 "%s\n", nt_errstr(status));
2205 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2206 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2207 goto fail;
2209 } else {
2210 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2211 goto fail;
2214 cli_setpid(cli1, 2);
2216 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2217 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2218 } else {
2219 printf("pid2 successfully read the range 130:4\n");
2222 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2223 if (!NT_STATUS_IS_OK(status)) {
2224 printf("pid2 unable to write to the range 130:4, error was "
2225 "%s\n", nt_errstr(status));
2226 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2227 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2228 goto fail;
2230 } else {
2231 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2232 goto fail;
2235 cli_setpid(cli1, 1);
2236 cli_unlock(cli1, fnum1, 130, 4);
2238 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2239 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2240 goto fail;
2241 } else {
2242 printf("pid1 successfully locked range 130:4 for WRITE\n");
2245 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2246 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2247 goto fail;
2248 } else {
2249 printf("pid1 successfully read the range 130:4\n");
2252 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2253 if (!NT_STATUS_IS_OK(status)) {
2254 printf("pid1 unable to write to the range 130:4, error was "
2255 "%s\n", nt_errstr(status));
2256 goto fail;
2257 } else {
2258 printf("pid1 successfully wrote to the range 130:4\n");
2261 cli_setpid(cli1, 2);
2263 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2264 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2265 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2266 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2267 goto fail;
2269 } else {
2270 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2271 goto fail;
2274 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2275 if (!NT_STATUS_IS_OK(status)) {
2276 printf("pid2 unable to write to the range 130:4, error was "
2277 "%s\n", nt_errstr(status));
2278 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2279 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2280 goto fail;
2282 } else {
2283 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2284 goto fail;
2287 cli_unlock(cli1, fnum1, 130, 0);
2288 correct = True;
2290 fail:
2291 cli_close(cli1, fnum1);
2292 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2293 torture_close_connection(cli1);
2295 printf("finished locktest7\n");
2296 return correct;
2300 * This demonstrates a problem with our use of GPFS share modes: A file
2301 * descriptor sitting in the pending close queue holding a GPFS share mode
2302 * blocks opening a file another time. Happens with Word 2007 temp files.
2303 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2304 * open is denied with NT_STATUS_SHARING_VIOLATION.
2307 static bool run_locktest8(int dummy)
2309 struct cli_state *cli1;
2310 const char *fname = "\\lockt8.lck";
2311 uint16_t fnum1, fnum2;
2312 char buf[200];
2313 bool correct = False;
2314 NTSTATUS status;
2316 if (!torture_open_connection(&cli1, 0)) {
2317 return False;
2320 cli_sockopt(cli1, sockops);
2322 printf("starting locktest8\n");
2324 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2326 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2327 &fnum1);
2328 if (!NT_STATUS_IS_OK(status)) {
2329 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2330 return false;
2333 memset(buf, 0, sizeof(buf));
2335 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2336 if (!NT_STATUS_IS_OK(status)) {
2337 d_fprintf(stderr, "cli_open second time returned %s\n",
2338 cli_errstr(cli1));
2339 goto fail;
2342 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2343 printf("Unable to apply read lock on range 1:1, error was "
2344 "%s\n", cli_errstr(cli1));
2345 goto fail;
2348 status = cli_close(cli1, fnum1);
2349 if (!NT_STATUS_IS_OK(status)) {
2350 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2351 goto fail;
2354 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2355 if (!NT_STATUS_IS_OK(status)) {
2356 d_fprintf(stderr, "cli_open third time returned %s\n",
2357 cli_errstr(cli1));
2358 goto fail;
2361 correct = true;
2363 fail:
2364 cli_close(cli1, fnum1);
2365 cli_close(cli1, fnum2);
2366 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2367 torture_close_connection(cli1);
2369 printf("finished locktest8\n");
2370 return correct;
2374 * This test is designed to be run in conjunction with
2375 * external NFS or POSIX locks taken in the filesystem.
2376 * It checks that the smbd server will block until the
2377 * lock is released and then acquire it. JRA.
2380 static bool got_alarm;
2381 static int alarm_fd;
2383 static void alarm_handler(int dummy)
2385 got_alarm = True;
2388 static void alarm_handler_parent(int dummy)
2390 close(alarm_fd);
2393 static void do_local_lock(int read_fd, int write_fd)
2395 int fd;
2396 char c = '\0';
2397 struct flock lock;
2398 const char *local_pathname = NULL;
2399 int ret;
2401 local_pathname = talloc_asprintf(talloc_tos(),
2402 "%s/lockt9.lck", local_path);
2403 if (!local_pathname) {
2404 printf("child: alloc fail\n");
2405 exit(1);
2408 unlink(local_pathname);
2409 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2410 if (fd == -1) {
2411 printf("child: open of %s failed %s.\n",
2412 local_pathname, strerror(errno));
2413 exit(1);
2416 /* Now take a fcntl lock. */
2417 lock.l_type = F_WRLCK;
2418 lock.l_whence = SEEK_SET;
2419 lock.l_start = 0;
2420 lock.l_len = 4;
2421 lock.l_pid = getpid();
2423 ret = fcntl(fd,F_SETLK,&lock);
2424 if (ret == -1) {
2425 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2426 local_pathname, strerror(errno));
2427 exit(1);
2428 } else {
2429 printf("child: got lock 0:4 on file %s.\n",
2430 local_pathname );
2431 fflush(stdout);
2434 CatchSignal(SIGALRM, alarm_handler);
2435 alarm(5);
2436 /* Signal the parent. */
2437 if (write(write_fd, &c, 1) != 1) {
2438 printf("child: start signal fail %s.\n",
2439 strerror(errno));
2440 exit(1);
2442 alarm(0);
2444 alarm(10);
2445 /* Wait for the parent to be ready. */
2446 if (read(read_fd, &c, 1) != 1) {
2447 printf("child: reply signal fail %s.\n",
2448 strerror(errno));
2449 exit(1);
2451 alarm(0);
2453 sleep(5);
2454 close(fd);
2455 printf("child: released lock 0:4 on file %s.\n",
2456 local_pathname );
2457 fflush(stdout);
2458 exit(0);
2461 static bool run_locktest9(int dummy)
2463 struct cli_state *cli1;
2464 const char *fname = "\\lockt9.lck";
2465 uint16_t fnum;
2466 bool correct = False;
2467 int pipe_in[2], pipe_out[2];
2468 pid_t child_pid;
2469 char c = '\0';
2470 int ret;
2471 struct timeval start;
2472 double seconds;
2473 NTSTATUS status;
2475 printf("starting locktest9\n");
2477 if (local_path == NULL) {
2478 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2479 return false;
2482 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2483 return false;
2486 child_pid = fork();
2487 if (child_pid == -1) {
2488 return false;
2491 if (child_pid == 0) {
2492 /* Child. */
2493 do_local_lock(pipe_out[0], pipe_in[1]);
2494 exit(0);
2497 close(pipe_out[0]);
2498 close(pipe_in[1]);
2499 pipe_out[0] = -1;
2500 pipe_in[1] = -1;
2502 /* Parent. */
2503 ret = read(pipe_in[0], &c, 1);
2504 if (ret != 1) {
2505 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2506 strerror(errno));
2507 return false;
2510 if (!torture_open_connection(&cli1, 0)) {
2511 return false;
2514 cli_sockopt(cli1, sockops);
2516 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2517 &fnum);
2518 if (!NT_STATUS_IS_OK(status)) {
2519 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2520 return false;
2523 /* Ensure the child has the lock. */
2524 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2525 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2526 goto fail;
2527 } else {
2528 d_printf("Child has the lock.\n");
2531 /* Tell the child to wait 5 seconds then exit. */
2532 ret = write(pipe_out[1], &c, 1);
2533 if (ret != 1) {
2534 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2535 strerror(errno));
2536 goto fail;
2539 /* Wait 20 seconds for the lock. */
2540 alarm_fd = cli1->fd;
2541 CatchSignal(SIGALRM, alarm_handler_parent);
2542 alarm(20);
2544 start = timeval_current();
2546 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2547 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2548 "%s\n", cli_errstr(cli1));
2549 goto fail_nofd;
2551 alarm(0);
2553 seconds = timeval_elapsed(&start);
2555 printf("Parent got the lock after %.2f seconds.\n",
2556 seconds);
2558 status = cli_close(cli1, fnum);
2559 if (!NT_STATUS_IS_OK(status)) {
2560 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2561 goto fail;
2564 correct = true;
2566 fail:
2567 cli_close(cli1, fnum);
2568 torture_close_connection(cli1);
2570 fail_nofd:
2572 printf("finished locktest9\n");
2573 return correct;
2577 test whether fnums and tids open on one VC are available on another (a major
2578 security hole)
2580 static bool run_fdpasstest(int dummy)
2582 struct cli_state *cli1, *cli2;
2583 const char *fname = "\\fdpass.tst";
2584 uint16_t fnum1;
2585 char buf[1024];
2586 NTSTATUS status;
2588 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2589 return False;
2591 cli_sockopt(cli1, sockops);
2592 cli_sockopt(cli2, sockops);
2594 printf("starting fdpasstest\n");
2596 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2598 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2599 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2600 return False;
2603 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"hello world\n", 0,
2604 13, NULL);
2605 if (!NT_STATUS_IS_OK(status)) {
2606 printf("write failed (%s)\n", nt_errstr(status));
2607 return False;
2610 cli2->vuid = cli1->vuid;
2611 cli2->cnum = cli1->cnum;
2612 cli2->pid = cli1->pid;
2614 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2615 printf("read succeeded! nasty security hole [%s]\n",
2616 buf);
2617 return False;
2620 cli_close(cli1, fnum1);
2621 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2623 torture_close_connection(cli1);
2624 torture_close_connection(cli2);
2626 printf("finished fdpasstest\n");
2627 return True;
2630 static bool run_fdsesstest(int dummy)
2632 struct cli_state *cli;
2633 uint16 new_vuid;
2634 uint16 saved_vuid;
2635 uint16 new_cnum;
2636 uint16 saved_cnum;
2637 const char *fname = "\\fdsess.tst";
2638 const char *fname1 = "\\fdsess1.tst";
2639 uint16_t fnum1;
2640 uint16_t fnum2;
2641 char buf[1024];
2642 bool ret = True;
2643 NTSTATUS status;
2645 if (!torture_open_connection(&cli, 0))
2646 return False;
2647 cli_sockopt(cli, sockops);
2649 if (!torture_cli_session_setup2(cli, &new_vuid))
2650 return False;
2652 saved_cnum = cli->cnum;
2653 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2654 return False;
2655 new_cnum = cli->cnum;
2656 cli->cnum = saved_cnum;
2658 printf("starting fdsesstest\n");
2660 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2661 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2663 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2664 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2665 return False;
2668 status = cli_writeall(cli, fnum1, 0, (uint8_t *)"hello world\n", 0, 13,
2669 NULL);
2670 if (!NT_STATUS_IS_OK(status)) {
2671 printf("write failed (%s)\n", nt_errstr(status));
2672 return False;
2675 saved_vuid = cli->vuid;
2676 cli->vuid = new_vuid;
2678 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2679 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2680 buf);
2681 ret = False;
2683 /* Try to open a file with different vuid, samba cnum. */
2684 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2685 printf("create with different vuid, same cnum succeeded.\n");
2686 cli_close(cli, fnum2);
2687 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2688 } else {
2689 printf("create with different vuid, same cnum failed.\n");
2690 printf("This will cause problems with service clients.\n");
2691 ret = False;
2694 cli->vuid = saved_vuid;
2696 /* Try with same vuid, different cnum. */
2697 cli->cnum = new_cnum;
2699 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2700 printf("read succeeded with different cnum![%s]\n",
2701 buf);
2702 ret = False;
2705 cli->cnum = saved_cnum;
2706 cli_close(cli, fnum1);
2707 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2709 torture_close_connection(cli);
2711 printf("finished fdsesstest\n");
2712 return ret;
2716 This test checks that
2718 1) the server does not allow an unlink on a file that is open
2720 static bool run_unlinktest(int dummy)
2722 struct cli_state *cli;
2723 const char *fname = "\\unlink.tst";
2724 uint16_t fnum;
2725 bool correct = True;
2727 if (!torture_open_connection(&cli, 0)) {
2728 return False;
2731 cli_sockopt(cli, sockops);
2733 printf("starting unlink test\n");
2735 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2737 cli_setpid(cli, 1);
2739 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2740 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2741 return False;
2744 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2745 printf("error: server allowed unlink on an open file\n");
2746 correct = False;
2747 } else {
2748 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2749 NT_STATUS_SHARING_VIOLATION);
2752 cli_close(cli, fnum);
2753 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2755 if (!torture_close_connection(cli)) {
2756 correct = False;
2759 printf("unlink test finished\n");
2761 return correct;
2766 test how many open files this server supports on the one socket
2768 static bool run_maxfidtest(int dummy)
2770 struct cli_state *cli;
2771 const char *ftemplate = "\\maxfid.%d.%d";
2772 fstring fname;
2773 uint16_t fnums[0x11000];
2774 int i;
2775 int retries=4;
2776 bool correct = True;
2778 cli = current_cli;
2780 if (retries <= 0) {
2781 printf("failed to connect\n");
2782 return False;
2785 cli_sockopt(cli, sockops);
2787 for (i=0; i<0x11000; i++) {
2788 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2789 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2790 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2791 printf("open of %s failed (%s)\n",
2792 fname, cli_errstr(cli));
2793 printf("maximum fnum is %d\n", i);
2794 break;
2796 printf("%6d\r", i);
2798 printf("%6d\n", i);
2799 i--;
2801 printf("cleaning up\n");
2802 for (;i>=0;i--) {
2803 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2804 cli_close(cli, fnums[i]);
2805 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2806 printf("unlink of %s failed (%s)\n",
2807 fname, cli_errstr(cli));
2808 correct = False;
2810 printf("%6d\r", i);
2812 printf("%6d\n", 0);
2814 printf("maxfid test finished\n");
2815 if (!torture_close_connection(cli)) {
2816 correct = False;
2818 return correct;
2821 /* generate a random buffer */
2822 static void rand_buf(char *buf, int len)
2824 while (len--) {
2825 *buf = (char)sys_random();
2826 buf++;
2830 /* send smb negprot commands, not reading the response */
2831 static bool run_negprot_nowait(int dummy)
2833 struct tevent_context *ev;
2834 int i;
2835 struct cli_state *cli;
2836 bool correct = True;
2838 printf("starting negprot nowait test\n");
2840 ev = tevent_context_init(talloc_tos());
2841 if (ev == NULL) {
2842 return false;
2845 if (!(cli = open_nbt_connection())) {
2846 TALLOC_FREE(ev);
2847 return False;
2850 for (i=0;i<50000;i++) {
2851 struct tevent_req *req;
2853 req = cli_negprot_send(ev, ev, cli);
2854 if (req == NULL) {
2855 TALLOC_FREE(ev);
2856 return false;
2858 if (!tevent_req_poll(req, ev)) {
2859 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2860 strerror(errno));
2861 TALLOC_FREE(ev);
2862 return false;
2864 TALLOC_FREE(req);
2867 if (torture_close_connection(cli)) {
2868 correct = False;
2871 printf("finished negprot nowait test\n");
2873 return correct;
2876 /* send smb negprot commands, not reading the response */
2877 static bool run_bad_nbt_session(int dummy)
2879 static struct cli_state *cli;
2881 printf("starting bad nbt session test\n");
2883 if (!(cli = open_bad_nbt_connection())) {
2884 return False;
2887 cli_shutdown(cli);
2888 printf("finished bad nbt session test\n");
2889 return true;
2892 /* send random IPC commands */
2893 static bool run_randomipc(int dummy)
2895 char *rparam = NULL;
2896 char *rdata = NULL;
2897 unsigned int rdrcnt,rprcnt;
2898 char param[1024];
2899 int api, param_len, i;
2900 struct cli_state *cli;
2901 bool correct = True;
2902 int count = 50000;
2904 printf("starting random ipc test\n");
2906 if (!torture_open_connection(&cli, 0)) {
2907 return False;
2910 for (i=0;i<count;i++) {
2911 api = sys_random() % 500;
2912 param_len = (sys_random() % 64);
2914 rand_buf(param, param_len);
2916 SSVAL(param,0,api);
2918 cli_api(cli,
2919 param, param_len, 8,
2920 NULL, 0, BUFFER_SIZE,
2921 &rparam, &rprcnt,
2922 &rdata, &rdrcnt);
2923 if (i % 100 == 0) {
2924 printf("%d/%d\r", i,count);
2927 printf("%d/%d\n", i, count);
2929 if (!torture_close_connection(cli)) {
2930 correct = False;
2933 printf("finished random ipc test\n");
2935 return correct;
2940 static void browse_callback(const char *sname, uint32 stype,
2941 const char *comment, void *state)
2943 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2949 This test checks the browse list code
2952 static bool run_browsetest(int dummy)
2954 static struct cli_state *cli;
2955 bool correct = True;
2957 printf("starting browse test\n");
2959 if (!torture_open_connection(&cli, 0)) {
2960 return False;
2963 printf("domain list:\n");
2964 cli_NetServerEnum(cli, cli->server_domain,
2965 SV_TYPE_DOMAIN_ENUM,
2966 browse_callback, NULL);
2968 printf("machine list:\n");
2969 cli_NetServerEnum(cli, cli->server_domain,
2970 SV_TYPE_ALL,
2971 browse_callback, NULL);
2973 if (!torture_close_connection(cli)) {
2974 correct = False;
2977 printf("browse test finished\n");
2979 return correct;
2985 This checks how the getatr calls works
2987 static bool run_attrtest(int dummy)
2989 struct cli_state *cli;
2990 uint16_t fnum;
2991 time_t t, t2;
2992 const char *fname = "\\attrib123456789.tst";
2993 bool correct = True;
2995 printf("starting attrib test\n");
2997 if (!torture_open_connection(&cli, 0)) {
2998 return False;
3001 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3002 cli_open(cli, fname,
3003 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3004 cli_close(cli, fnum);
3005 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3006 printf("getatr failed (%s)\n", cli_errstr(cli));
3007 correct = False;
3010 if (abs(t - time(NULL)) > 60*60*24*10) {
3011 printf("ERROR: SMBgetatr bug. time is %s",
3012 ctime(&t));
3013 t = time(NULL);
3014 correct = True;
3017 t2 = t-60*60*24; /* 1 day ago */
3019 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
3020 printf("setatr failed (%s)\n", cli_errstr(cli));
3021 correct = True;
3024 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3025 printf("getatr failed (%s)\n", cli_errstr(cli));
3026 correct = True;
3029 if (t != t2) {
3030 printf("ERROR: getatr/setatr bug. times are\n%s",
3031 ctime(&t));
3032 printf("%s", ctime(&t2));
3033 correct = True;
3036 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3038 if (!torture_close_connection(cli)) {
3039 correct = False;
3042 printf("attrib test finished\n");
3044 return correct;
3049 This checks a couple of trans2 calls
3051 static bool run_trans2test(int dummy)
3053 struct cli_state *cli;
3054 uint16_t fnum;
3055 SMB_OFF_T size;
3056 time_t c_time, a_time, m_time;
3057 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3058 const char *fname = "\\trans2.tst";
3059 const char *dname = "\\trans2";
3060 const char *fname2 = "\\trans2\\trans2.tst";
3061 char pname[1024];
3062 bool correct = True;
3063 NTSTATUS status;
3064 uint32_t fs_attr;
3066 printf("starting trans2 test\n");
3068 if (!torture_open_connection(&cli, 0)) {
3069 return False;
3072 status = cli_get_fs_attr_info(cli, &fs_attr);
3073 if (!NT_STATUS_IS_OK(status)) {
3074 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3075 nt_errstr(status));
3076 correct = false;
3079 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3080 cli_open(cli, fname,
3081 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3082 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3083 cli, fnum, NULL, &size, &c_time_ts,
3084 &a_time_ts, &w_time_ts,
3085 &m_time_ts, NULL))) {
3086 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3087 correct = False;
3090 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3091 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3092 correct = False;
3095 if (strcmp(pname, fname)) {
3096 printf("qfilename gave different name? [%s] [%s]\n",
3097 fname, pname);
3098 correct = False;
3101 cli_close(cli, fnum);
3103 sleep(2);
3105 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3106 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3107 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3108 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3109 return False;
3111 cli_close(cli, fnum);
3113 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3114 NULL);
3115 if (!NT_STATUS_IS_OK(status)) {
3116 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3117 correct = False;
3118 } else {
3119 if (c_time != m_time) {
3120 printf("create time=%s", ctime(&c_time));
3121 printf("modify time=%s", ctime(&m_time));
3122 printf("This system appears to have sticky create times\n");
3124 if (a_time % (60*60) == 0) {
3125 printf("access time=%s", ctime(&a_time));
3126 printf("This system appears to set a midnight access time\n");
3127 correct = False;
3130 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3131 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3132 correct = False;
3137 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3138 cli_open(cli, fname,
3139 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3140 cli_close(cli, fnum);
3141 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3142 &m_time_ts, &size, NULL, NULL);
3143 if (!NT_STATUS_IS_OK(status)) {
3144 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3145 correct = False;
3146 } else {
3147 if (w_time_ts.tv_sec < 60*60*24*2) {
3148 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3149 printf("This system appears to set a initial 0 write time\n");
3150 correct = False;
3154 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3157 /* check if the server updates the directory modification time
3158 when creating a new file */
3159 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3160 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3161 correct = False;
3163 sleep(3);
3164 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3165 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3166 if (!NT_STATUS_IS_OK(status)) {
3167 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3168 correct = False;
3171 cli_open(cli, fname2,
3172 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3173 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3174 cli_close(cli, fnum);
3175 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3176 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3177 if (!NT_STATUS_IS_OK(status)) {
3178 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3179 correct = False;
3180 } else {
3181 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3182 == 0) {
3183 printf("This system does not update directory modification times\n");
3184 correct = False;
3187 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3188 cli_rmdir(cli, dname);
3190 if (!torture_close_connection(cli)) {
3191 correct = False;
3194 printf("trans2 test finished\n");
3196 return correct;
3200 This checks new W2K calls.
3203 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3205 uint8_t *buf = NULL;
3206 uint32 len;
3207 NTSTATUS status;
3209 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3210 pcli->max_xmit, &buf, &len);
3211 if (!NT_STATUS_IS_OK(status)) {
3212 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3213 nt_errstr(status));
3214 } else {
3215 printf("qfileinfo: level %d, len = %u\n", level, len);
3216 dump_data(0, (uint8 *)buf, len);
3217 printf("\n");
3219 TALLOC_FREE(buf);
3220 return status;
3223 static bool run_w2ktest(int dummy)
3225 struct cli_state *cli;
3226 uint16_t fnum;
3227 const char *fname = "\\w2ktest\\w2k.tst";
3228 int level;
3229 bool correct = True;
3231 printf("starting w2k test\n");
3233 if (!torture_open_connection(&cli, 0)) {
3234 return False;
3237 cli_open(cli, fname,
3238 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3240 for (level = 1004; level < 1040; level++) {
3241 new_trans(cli, fnum, level);
3244 cli_close(cli, fnum);
3246 if (!torture_close_connection(cli)) {
3247 correct = False;
3250 printf("w2k test finished\n");
3252 return correct;
3257 this is a harness for some oplock tests
3259 static bool run_oplock1(int dummy)
3261 struct cli_state *cli1;
3262 const char *fname = "\\lockt1.lck";
3263 uint16_t fnum1;
3264 bool correct = True;
3266 printf("starting oplock test 1\n");
3268 if (!torture_open_connection(&cli1, 0)) {
3269 return False;
3272 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3274 cli_sockopt(cli1, sockops);
3276 cli1->use_oplocks = True;
3278 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3279 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3280 return False;
3283 cli1->use_oplocks = False;
3285 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3286 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3288 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3289 printf("close2 failed (%s)\n", cli_errstr(cli1));
3290 return False;
3293 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3294 printf("unlink failed (%s)\n", cli_errstr(cli1));
3295 return False;
3298 if (!torture_close_connection(cli1)) {
3299 correct = False;
3302 printf("finished oplock test 1\n");
3304 return correct;
3307 static bool run_oplock2(int dummy)
3309 struct cli_state *cli1, *cli2;
3310 const char *fname = "\\lockt2.lck";
3311 uint16_t fnum1, fnum2;
3312 int saved_use_oplocks = use_oplocks;
3313 char buf[4];
3314 bool correct = True;
3315 volatile bool *shared_correct;
3317 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3318 *shared_correct = True;
3320 use_level_II_oplocks = True;
3321 use_oplocks = True;
3323 printf("starting oplock test 2\n");
3325 if (!torture_open_connection(&cli1, 0)) {
3326 use_level_II_oplocks = False;
3327 use_oplocks = saved_use_oplocks;
3328 return False;
3331 cli1->use_oplocks = True;
3332 cli1->use_level_II_oplocks = True;
3334 if (!torture_open_connection(&cli2, 1)) {
3335 use_level_II_oplocks = False;
3336 use_oplocks = saved_use_oplocks;
3337 return False;
3340 cli2->use_oplocks = True;
3341 cli2->use_level_II_oplocks = True;
3343 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3345 cli_sockopt(cli1, sockops);
3346 cli_sockopt(cli2, sockops);
3348 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3349 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3350 return False;
3353 /* Don't need the globals any more. */
3354 use_level_II_oplocks = False;
3355 use_oplocks = saved_use_oplocks;
3357 if (fork() == 0) {
3358 /* Child code */
3359 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3360 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3361 *shared_correct = False;
3362 exit(0);
3365 sleep(2);
3367 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3368 printf("close2 failed (%s)\n", cli_errstr(cli1));
3369 *shared_correct = False;
3372 exit(0);
3375 sleep(2);
3377 /* Ensure cli1 processes the break. Empty file should always return 0
3378 * bytes. */
3380 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3381 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3382 correct = False;
3385 /* Should now be at level II. */
3386 /* Test if sending a write locks causes a break to none. */
3388 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3389 printf("lock failed (%s)\n", cli_errstr(cli1));
3390 correct = False;
3393 cli_unlock(cli1, fnum1, 0, 4);
3395 sleep(2);
3397 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3398 printf("lock failed (%s)\n", cli_errstr(cli1));
3399 correct = False;
3402 cli_unlock(cli1, fnum1, 0, 4);
3404 sleep(2);
3406 cli_read(cli1, fnum1, buf, 0, 4);
3408 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3409 printf("close1 failed (%s)\n", cli_errstr(cli1));
3410 correct = False;
3413 sleep(4);
3415 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3416 printf("unlink failed (%s)\n", cli_errstr(cli1));
3417 correct = False;
3420 if (!torture_close_connection(cli1)) {
3421 correct = False;
3424 if (!*shared_correct) {
3425 correct = False;
3428 printf("finished oplock test 2\n");
3430 return correct;
3433 /* handler for oplock 3 tests */
3434 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3436 printf("got oplock break fnum=%d level=%d\n",
3437 fnum, level);
3438 return cli_oplock_ack(cli, fnum, level);
3441 static bool run_oplock3(int dummy)
3443 struct cli_state *cli;
3444 const char *fname = "\\oplockt3.dat";
3445 uint16_t fnum;
3446 char buf[4] = "abcd";
3447 bool correct = True;
3448 volatile bool *shared_correct;
3450 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3451 *shared_correct = True;
3453 printf("starting oplock test 3\n");
3455 if (fork() == 0) {
3456 /* Child code */
3457 use_oplocks = True;
3458 use_level_II_oplocks = True;
3459 if (!torture_open_connection(&cli, 0)) {
3460 *shared_correct = False;
3461 exit(0);
3463 sleep(2);
3464 /* try to trigger a oplock break in parent */
3465 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3466 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3467 exit(0);
3470 /* parent code */
3471 use_oplocks = True;
3472 use_level_II_oplocks = True;
3473 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3474 return False;
3476 cli_oplock_handler(cli, oplock3_handler);
3477 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3478 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3479 cli_close(cli, fnum);
3480 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3481 cli->timeout = 20000;
3482 cli_receive_smb(cli);
3483 printf("finished oplock test 3\n");
3485 return (correct && *shared_correct);
3487 /* What are we looking for here? What's sucess and what's FAILURE? */
3490 /* handler for oplock 4 tests */
3491 bool *oplock4_shared_correct;
3493 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3495 printf("got oplock break fnum=%d level=%d\n",
3496 fnum, level);
3497 *oplock4_shared_correct = true;
3498 cli_oplock_ack(cli, fnum, level);
3499 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3502 static bool run_oplock4(int dummy)
3504 struct cli_state *cli1, *cli2;
3505 const char *fname = "\\lockt4.lck";
3506 const char *fname_ln = "\\lockt4_ln.lck";
3507 uint16_t fnum1, fnum2;
3508 int saved_use_oplocks = use_oplocks;
3509 NTSTATUS status;
3510 bool correct = true;
3512 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3513 *oplock4_shared_correct = false;
3515 printf("starting oplock test 4\n");
3517 if (!torture_open_connection(&cli1, 0)) {
3518 use_level_II_oplocks = false;
3519 use_oplocks = saved_use_oplocks;
3520 return false;
3523 if (!torture_open_connection(&cli2, 1)) {
3524 use_level_II_oplocks = false;
3525 use_oplocks = saved_use_oplocks;
3526 return false;
3529 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3530 cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN);
3532 cli_sockopt(cli1, sockops);
3533 cli_sockopt(cli2, sockops);
3535 /* Create the file. */
3536 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3537 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3538 return false;
3541 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3542 printf("close1 failed (%s)\n", cli_errstr(cli1));
3543 return false;
3546 /* Now create a hardlink. */
3547 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3548 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3549 return false;
3552 /* Prove that opening hardlinks cause deny modes to conflict. */
3553 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3554 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3555 return false;
3558 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3559 if (NT_STATUS_IS_OK(status)) {
3560 printf("open of %s succeeded - should fail with sharing violation.\n",
3561 fname_ln);
3562 return false;
3565 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3566 printf("open of %s should fail with sharing violation. Got %s\n",
3567 fname_ln, nt_errstr(status));
3568 return false;
3571 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3572 printf("close1 failed (%s)\n", cli_errstr(cli1));
3573 return false;
3576 cli1->use_oplocks = true;
3577 cli1->use_level_II_oplocks = true;
3579 cli2->use_oplocks = true;
3580 cli2->use_level_II_oplocks = true;
3582 cli_oplock_handler(cli1, oplock4_handler);
3583 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3584 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3585 return false;
3588 if (fork() == 0) {
3589 /* Child code */
3590 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3591 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3592 *oplock4_shared_correct = false;
3593 exit(0);
3596 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3597 printf("close2 failed (%s)\n", cli_errstr(cli1));
3598 *oplock4_shared_correct = false;
3601 exit(0);
3604 sleep(2);
3606 /* Process the oplock break. */
3607 cli_receive_smb(cli1);
3609 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3610 printf("close1 failed (%s)\n", cli_errstr(cli1));
3611 correct = false;
3614 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3615 printf("unlink failed (%s)\n", cli_errstr(cli1));
3616 correct = false;
3618 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN))) {
3619 printf("unlink failed (%s)\n", cli_errstr(cli1));
3620 correct = false;
3623 if (!torture_close_connection(cli1)) {
3624 correct = false;
3627 if (!*oplock4_shared_correct) {
3628 correct = false;
3631 printf("finished oplock test 4\n");
3633 return correct;
3638 Test delete on close semantics.
3640 static bool run_deletetest(int dummy)
3642 struct cli_state *cli1 = NULL;
3643 struct cli_state *cli2 = NULL;
3644 const char *fname = "\\delete.file";
3645 uint16_t fnum1 = (uint16_t)-1;
3646 uint16_t fnum2 = (uint16_t)-1;
3647 bool correct = True;
3649 printf("starting delete test\n");
3651 if (!torture_open_connection(&cli1, 0)) {
3652 return False;
3655 cli_sockopt(cli1, sockops);
3657 /* Test 1 - this should delete the file on close. */
3659 cli_setatr(cli1, fname, 0, 0);
3660 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3662 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3663 0, FILE_OVERWRITE_IF,
3664 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3665 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3666 correct = False;
3667 goto fail;
3670 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3671 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3672 correct = False;
3673 goto fail;
3676 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3677 printf("[1] open of %s succeeded (should fail)\n", fname);
3678 correct = False;
3679 goto fail;
3682 printf("first delete on close test succeeded.\n");
3684 /* Test 2 - this should delete the file on close. */
3686 cli_setatr(cli1, fname, 0, 0);
3687 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3689 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3690 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3691 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3692 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3693 correct = False;
3694 goto fail;
3697 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3698 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3699 correct = False;
3700 goto fail;
3703 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3704 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3705 correct = False;
3706 goto fail;
3709 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3710 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3711 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3712 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3713 correct = False;
3714 goto fail;
3716 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3717 } else
3718 printf("second delete on close test succeeded.\n");
3720 /* Test 3 - ... */
3721 cli_setatr(cli1, fname, 0, 0);
3722 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3724 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3725 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3726 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3727 correct = False;
3728 goto fail;
3731 /* This should fail with a sharing violation - open for delete is only compatible
3732 with SHARE_DELETE. */
3734 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3735 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3736 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3737 correct = False;
3738 goto fail;
3741 /* This should succeed. */
3743 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3744 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3745 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3746 correct = False;
3747 goto fail;
3750 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3751 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3752 correct = False;
3753 goto fail;
3756 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3757 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3758 correct = False;
3759 goto fail;
3762 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3763 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3764 correct = False;
3765 goto fail;
3768 /* This should fail - file should no longer be there. */
3770 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3771 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3772 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3773 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3775 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3776 correct = False;
3777 goto fail;
3778 } else
3779 printf("third delete on close test succeeded.\n");
3781 /* Test 4 ... */
3782 cli_setatr(cli1, fname, 0, 0);
3783 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3785 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3786 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3787 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3788 correct = False;
3789 goto fail;
3792 /* This should succeed. */
3793 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3794 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3795 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3796 correct = False;
3797 goto fail;
3800 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3801 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3802 correct = False;
3803 goto fail;
3806 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3807 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3808 correct = False;
3809 goto fail;
3812 /* This should fail - no more opens once delete on close set. */
3813 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3814 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3815 FILE_OPEN, 0, 0, &fnum2))) {
3816 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3817 correct = False;
3818 goto fail;
3819 } else
3820 printf("fourth delete on close test succeeded.\n");
3822 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3823 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3824 correct = False;
3825 goto fail;
3828 /* Test 5 ... */
3829 cli_setatr(cli1, fname, 0, 0);
3830 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3832 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3833 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3834 correct = False;
3835 goto fail;
3838 /* This should fail - only allowed on NT opens with DELETE access. */
3840 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3841 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3842 correct = False;
3843 goto fail;
3846 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3847 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3848 correct = False;
3849 goto fail;
3852 printf("fifth delete on close test succeeded.\n");
3854 /* Test 6 ... */
3855 cli_setatr(cli1, fname, 0, 0);
3856 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3858 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3859 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3860 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3861 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3862 correct = False;
3863 goto fail;
3866 /* This should fail - only allowed on NT opens with DELETE access. */
3868 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3869 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3870 correct = False;
3871 goto fail;
3874 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3875 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3876 correct = False;
3877 goto fail;
3880 printf("sixth delete on close test succeeded.\n");
3882 /* Test 7 ... */
3883 cli_setatr(cli1, fname, 0, 0);
3884 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3886 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3887 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3888 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3889 correct = False;
3890 goto fail;
3893 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3894 printf("[7] setting delete_on_close on file failed !\n");
3895 correct = False;
3896 goto fail;
3899 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3900 printf("[7] unsetting delete_on_close on file failed !\n");
3901 correct = False;
3902 goto fail;
3905 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3906 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3907 correct = False;
3908 goto fail;
3911 /* This next open should succeed - we reset the flag. */
3913 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3914 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3915 correct = False;
3916 goto fail;
3919 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3920 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3921 correct = False;
3922 goto fail;
3925 printf("seventh delete on close test succeeded.\n");
3927 /* Test 7 ... */
3928 cli_setatr(cli1, fname, 0, 0);
3929 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3931 if (!torture_open_connection(&cli2, 1)) {
3932 printf("[8] failed to open second connection.\n");
3933 correct = False;
3934 goto fail;
3937 cli_sockopt(cli1, sockops);
3939 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3940 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3941 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3942 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3943 correct = False;
3944 goto fail;
3947 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3948 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3949 FILE_OPEN, 0, 0, &fnum2))) {
3950 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3951 correct = False;
3952 goto fail;
3955 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3956 printf("[8] setting delete_on_close on file failed !\n");
3957 correct = False;
3958 goto fail;
3961 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3962 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3963 correct = False;
3964 goto fail;
3967 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3968 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3969 correct = False;
3970 goto fail;
3973 /* This should fail.. */
3974 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3975 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3976 goto fail;
3977 correct = False;
3978 } else
3979 printf("eighth delete on close test succeeded.\n");
3981 /* This should fail - we need to set DELETE_ACCESS. */
3982 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3983 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3984 printf("[9] open of %s succeeded should have failed!\n", fname);
3985 correct = False;
3986 goto fail;
3989 printf("ninth delete on close test succeeded.\n");
3991 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3992 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3993 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3994 correct = False;
3995 goto fail;
3998 /* This should delete the file. */
3999 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4000 printf("[10] close failed (%s)\n", cli_errstr(cli1));
4001 correct = False;
4002 goto fail;
4005 /* This should fail.. */
4006 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4007 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4008 goto fail;
4009 correct = False;
4010 } else
4011 printf("tenth delete on close test succeeded.\n");
4013 cli_setatr(cli1, fname, 0, 0);
4014 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4016 /* What error do we get when attempting to open a read-only file with
4017 delete access ? */
4019 /* Create a readonly file. */
4020 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4021 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4022 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
4023 correct = False;
4024 goto fail;
4027 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4028 printf("[11] close failed (%s)\n", cli_errstr(cli1));
4029 correct = False;
4030 goto fail;
4033 /* Now try open for delete access. */
4034 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4035 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4036 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4037 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4038 cli_close(cli1, fnum1);
4039 goto fail;
4040 correct = False;
4041 } else {
4042 NTSTATUS nterr = cli_nt_error(cli1);
4043 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4044 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4045 goto fail;
4046 correct = False;
4047 } else {
4048 printf("eleventh delete on close test succeeded.\n");
4052 printf("finished delete test\n");
4054 fail:
4055 /* FIXME: This will crash if we aborted before cli2 got
4056 * intialized, because these functions don't handle
4057 * uninitialized connections. */
4059 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4060 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4061 cli_setatr(cli1, fname, 0, 0);
4062 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4064 if (cli1 && !torture_close_connection(cli1)) {
4065 correct = False;
4067 if (cli2 && !torture_close_connection(cli2)) {
4068 correct = False;
4070 return correct;
4073 static bool run_deletetest_ln(int dummy)
4075 struct cli_state *cli;
4076 const char *fname = "\\delete1";
4077 const char *fname_ln = "\\delete1_ln";
4078 uint16_t fnum;
4079 uint16_t fnum1;
4080 NTSTATUS status;
4081 bool correct = true;
4082 time_t t;
4084 printf("starting deletetest-ln\n");
4086 if (!torture_open_connection(&cli, 0)) {
4087 return false;
4090 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4091 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4093 cli_sockopt(cli, sockops);
4095 /* Create the file. */
4096 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4097 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4098 return false;
4101 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4102 printf("close1 failed (%s)\n", cli_errstr(cli));
4103 return false;
4106 /* Now create a hardlink. */
4107 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4108 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4109 return false;
4112 /* Open the original file. */
4113 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4114 FILE_ATTRIBUTE_NORMAL,
4115 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4116 FILE_OPEN_IF, 0, 0, &fnum);
4117 if (!NT_STATUS_IS_OK(status)) {
4118 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4119 return false;
4122 /* Unlink the hard link path. */
4123 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4124 FILE_ATTRIBUTE_NORMAL,
4125 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4126 FILE_OPEN_IF, 0, 0, &fnum1);
4127 if (!NT_STATUS_IS_OK(status)) {
4128 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4129 return false;
4131 status = cli_nt_delete_on_close(cli, fnum1, true);
4132 if (!NT_STATUS_IS_OK(status)) {
4133 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4134 __location__, fname_ln, nt_errstr(status));
4135 return false;
4138 status = cli_close(cli, fnum1);
4139 if (!NT_STATUS_IS_OK(status)) {
4140 printf("close %s failed (%s)\n",
4141 fname_ln, nt_errstr(status));
4142 return false;
4145 status = cli_close(cli, fnum);
4146 if (!NT_STATUS_IS_OK(status)) {
4147 printf("close %s failed (%s)\n",
4148 fname, nt_errstr(status));
4149 return false;
4152 /* Ensure the original file is still there. */
4153 status = cli_getatr(cli, fname, NULL, NULL, &t);
4154 if (!NT_STATUS_IS_OK(status)) {
4155 printf("%s getatr on file %s failed (%s)\n",
4156 __location__,
4157 fname,
4158 nt_errstr(status));
4159 correct = False;
4162 /* Ensure the link path is gone. */
4163 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4164 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4165 printf("%s, getatr for file %s returned wrong error code %s "
4166 "- should have been deleted\n",
4167 __location__,
4168 fname_ln, nt_errstr(status));
4169 correct = False;
4172 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4173 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4175 if (!torture_close_connection(cli)) {
4176 correct = false;
4179 printf("finished deletetest-ln\n");
4181 return correct;
4185 print out server properties
4187 static bool run_properties(int dummy)
4189 struct cli_state *cli;
4190 bool correct = True;
4192 printf("starting properties test\n");
4194 ZERO_STRUCT(cli);
4196 if (!torture_open_connection(&cli, 0)) {
4197 return False;
4200 cli_sockopt(cli, sockops);
4202 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4204 if (!torture_close_connection(cli)) {
4205 correct = False;
4208 return correct;
4213 /* FIRST_DESIRED_ACCESS 0xf019f */
4214 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4215 FILE_READ_EA| /* 0xf */ \
4216 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4217 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4218 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4219 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4220 /* SECOND_DESIRED_ACCESS 0xe0080 */
4221 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4222 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4223 WRITE_OWNER_ACCESS /* 0xe0000 */
4225 #if 0
4226 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4227 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4228 FILE_READ_DATA|\
4229 WRITE_OWNER_ACCESS /* */
4230 #endif
4233 Test ntcreate calls made by xcopy
4235 static bool run_xcopy(int dummy)
4237 static struct cli_state *cli1;
4238 const char *fname = "\\test.txt";
4239 bool correct = True;
4240 uint16_t fnum1, fnum2;
4242 printf("starting xcopy test\n");
4244 if (!torture_open_connection(&cli1, 0)) {
4245 return False;
4248 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4249 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4250 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4251 0x4044, 0, &fnum1))) {
4252 printf("First open failed - %s\n", cli_errstr(cli1));
4253 return False;
4256 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4257 SECOND_DESIRED_ACCESS, 0,
4258 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4259 0x200000, 0, &fnum2))) {
4260 printf("second open failed - %s\n", cli_errstr(cli1));
4261 return False;
4264 if (!torture_close_connection(cli1)) {
4265 correct = False;
4268 return correct;
4272 Test rename on files open with share delete and no share delete.
4274 static bool run_rename(int dummy)
4276 static struct cli_state *cli1;
4277 const char *fname = "\\test.txt";
4278 const char *fname1 = "\\test1.txt";
4279 bool correct = True;
4280 uint16_t fnum1;
4281 uint16_t attr;
4282 NTSTATUS status;
4284 printf("starting rename test\n");
4286 if (!torture_open_connection(&cli1, 0)) {
4287 return False;
4290 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4291 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4292 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4293 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4294 printf("First open failed - %s\n", cli_errstr(cli1));
4295 return False;
4298 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4299 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4300 } else {
4301 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4302 correct = False;
4305 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4306 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4307 return False;
4310 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4311 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4312 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4313 #if 0
4314 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4315 #else
4316 FILE_SHARE_DELETE|FILE_SHARE_READ,
4317 #endif
4318 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4319 if (!NT_STATUS_IS_OK(status)) {
4320 printf("Second open failed - %s\n", cli_errstr(cli1));
4321 return False;
4324 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4325 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4326 correct = False;
4327 } else {
4328 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4331 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4332 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4333 return False;
4336 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4337 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4339 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4340 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4341 printf("Third open failed - %s\n", cli_errstr(cli1));
4342 return False;
4346 #if 0
4348 uint16_t fnum2;
4350 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4351 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4352 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4353 return False;
4355 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4356 printf("[8] setting delete_on_close on file failed !\n");
4357 return False;
4360 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4361 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4362 return False;
4365 #endif
4367 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4368 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4369 correct = False;
4370 } else {
4371 printf("Third rename succeeded (SHARE_NONE)\n");
4374 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4375 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4376 return False;
4379 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4380 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4382 /*----*/
4384 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4385 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4386 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4387 return False;
4390 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4391 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4392 } else {
4393 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4394 correct = False;
4397 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4398 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4399 return False;
4402 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4403 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4405 /*--*/
4407 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4408 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4409 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4410 return False;
4413 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4414 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4415 cli_errstr(cli1));
4416 correct = False;
4417 } else {
4418 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4422 * Now check if the first name still exists ...
4425 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4426 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4427 printf("Opening original file after rename of open file fails: %s\n",
4428 cli_errstr(cli1));
4430 else {
4431 printf("Opening original file after rename of open file works ...\n");
4432 (void)cli_close(cli1, fnum2);
4433 } */
4435 /*--*/
4436 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4437 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4438 return False;
4441 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4442 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4443 printf("getatr on file %s failed - %s ! \n",
4444 fname1,
4445 cli_errstr(cli1));
4446 correct = False;
4447 } else {
4448 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4449 printf("Renamed file %s has wrong attr 0x%x "
4450 "(should be 0x%x)\n",
4451 fname1,
4452 attr,
4453 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4454 correct = False;
4455 } else {
4456 printf("Renamed file %s has archive bit set\n", fname1);
4460 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4461 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4463 if (!torture_close_connection(cli1)) {
4464 correct = False;
4467 return correct;
4470 static bool run_pipe_number(int dummy)
4472 struct cli_state *cli1;
4473 const char *pipe_name = "\\SPOOLSS";
4474 uint16_t fnum;
4475 int num_pipes = 0;
4477 printf("starting pipenumber test\n");
4478 if (!torture_open_connection(&cli1, 0)) {
4479 return False;
4482 cli_sockopt(cli1, sockops);
4483 while(1) {
4484 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4485 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4486 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4487 break;
4489 num_pipes++;
4490 printf("\r%6d", num_pipes);
4493 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4494 torture_close_connection(cli1);
4495 return True;
4499 Test open mode returns on read-only files.
4501 static bool run_opentest(int dummy)
4503 static struct cli_state *cli1;
4504 static struct cli_state *cli2;
4505 const char *fname = "\\readonly.file";
4506 uint16_t fnum1, fnum2;
4507 char buf[20];
4508 SMB_OFF_T fsize;
4509 bool correct = True;
4510 char *tmp_path;
4511 NTSTATUS status;
4513 printf("starting open test\n");
4515 if (!torture_open_connection(&cli1, 0)) {
4516 return False;
4519 cli_setatr(cli1, fname, 0, 0);
4520 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4522 cli_sockopt(cli1, sockops);
4524 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4525 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4526 return False;
4529 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4530 printf("close2 failed (%s)\n", cli_errstr(cli1));
4531 return False;
4534 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4535 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4536 return False;
4539 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4540 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4541 return False;
4544 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4545 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4547 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4548 NT_STATUS_ACCESS_DENIED)) {
4549 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4552 printf("finished open test 1\n");
4554 cli_close(cli1, fnum1);
4556 /* Now try not readonly and ensure ERRbadshare is returned. */
4558 cli_setatr(cli1, fname, 0, 0);
4560 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4561 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4562 return False;
4565 /* This will fail - but the error should be ERRshare. */
4566 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4568 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4569 NT_STATUS_SHARING_VIOLATION)) {
4570 printf("correct error code ERRDOS/ERRbadshare returned\n");
4573 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4574 printf("close2 failed (%s)\n", cli_errstr(cli1));
4575 return False;
4578 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4580 printf("finished open test 2\n");
4582 /* Test truncate open disposition on file opened for read. */
4584 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4585 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4586 return False;
4589 /* write 20 bytes. */
4591 memset(buf, '\0', 20);
4593 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4594 if (!NT_STATUS_IS_OK(status)) {
4595 printf("write failed (%s)\n", nt_errstr(status));
4596 correct = False;
4599 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4600 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4601 return False;
4604 /* Ensure size == 20. */
4605 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4606 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4607 return False;
4610 if (fsize != 20) {
4611 printf("(3) file size != 20\n");
4612 return False;
4615 /* Now test if we can truncate a file opened for readonly. */
4617 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4618 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4619 return False;
4622 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4623 printf("close2 failed (%s)\n", cli_errstr(cli1));
4624 return False;
4627 /* Ensure size == 0. */
4628 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4629 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4630 return False;
4633 if (fsize != 0) {
4634 printf("(3) file size != 0\n");
4635 return False;
4637 printf("finished open test 3\n");
4639 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4641 printf("Do ctemp tests\n");
4642 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4643 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4644 return False;
4646 printf("ctemp gave path %s\n", tmp_path);
4647 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4648 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4650 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4651 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4654 /* Test the non-io opens... */
4656 if (!torture_open_connection(&cli2, 1)) {
4657 return False;
4660 cli_setatr(cli2, fname, 0, 0);
4661 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4663 cli_sockopt(cli2, sockops);
4665 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4667 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4668 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4669 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4670 return False;
4673 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4674 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4675 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4676 return False;
4679 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4680 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4681 return False;
4683 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4684 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4685 return False;
4688 printf("non-io open test #1 passed.\n");
4690 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4692 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4694 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4695 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4696 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4697 return False;
4700 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4701 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4702 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4703 return False;
4706 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4707 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4708 return False;
4710 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4711 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4712 return False;
4715 printf("non-io open test #2 passed.\n");
4717 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4719 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4721 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4722 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4723 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4724 return False;
4727 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4728 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4729 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4730 return False;
4733 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4734 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4735 return False;
4737 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4738 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4739 return False;
4742 printf("non-io open test #3 passed.\n");
4744 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4746 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4748 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4749 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4750 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4751 return False;
4754 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4755 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4756 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4757 return False;
4760 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4762 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4763 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4764 return False;
4767 printf("non-io open test #4 passed.\n");
4769 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4771 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4773 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4774 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4775 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4776 return False;
4779 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4780 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4781 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4782 return False;
4785 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4786 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4787 return False;
4790 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4791 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4792 return False;
4795 printf("non-io open test #5 passed.\n");
4797 printf("TEST #6 testing 1 non-io open, one io open\n");
4799 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4801 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4802 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4803 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4804 return False;
4807 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4808 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4809 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4810 return False;
4813 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4814 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4815 return False;
4818 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4819 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4820 return False;
4823 printf("non-io open test #6 passed.\n");
4825 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4827 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4829 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4830 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4831 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4832 return False;
4835 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4836 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4837 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4838 return False;
4841 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4843 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4844 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4845 return False;
4848 printf("non-io open test #7 passed.\n");
4850 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4852 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4853 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4854 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4855 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4856 if (!NT_STATUS_IS_OK(status)) {
4857 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4858 correct = false;
4859 goto out;
4862 /* Write to ensure we have to update the file time. */
4863 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
4864 NULL);
4865 if (!NT_STATUS_IS_OK(status)) {
4866 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
4867 correct = false;
4868 goto out;
4871 status = cli_close(cli1, fnum1);
4872 if (!NT_STATUS_IS_OK(status)) {
4873 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4874 correct = false;
4877 out:
4879 if (!torture_close_connection(cli1)) {
4880 correct = False;
4882 if (!torture_close_connection(cli2)) {
4883 correct = False;
4886 return correct;
4889 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4891 uint16 major, minor;
4892 uint32 caplow, caphigh;
4893 NTSTATUS status;
4895 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4896 printf("Server doesn't support UNIX CIFS extensions.\n");
4897 return NT_STATUS_NOT_SUPPORTED;
4900 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4901 &caphigh);
4902 if (!NT_STATUS_IS_OK(status)) {
4903 printf("Server didn't return UNIX CIFS extensions: %s\n",
4904 nt_errstr(status));
4905 return status;
4908 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4909 caplow, caphigh);
4910 if (!NT_STATUS_IS_OK(status)) {
4911 printf("Server doesn't support setting UNIX CIFS extensions: "
4912 "%s.\n", nt_errstr(status));
4913 return status;
4916 return NT_STATUS_OK;
4920 Test POSIX open /mkdir calls.
4922 static bool run_simple_posix_open_test(int dummy)
4924 static struct cli_state *cli1;
4925 const char *fname = "posix:file";
4926 const char *hname = "posix:hlink";
4927 const char *sname = "posix:symlink";
4928 const char *dname = "posix:dir";
4929 char buf[10];
4930 char namebuf[11];
4931 uint16_t fnum1 = (uint16_t)-1;
4932 SMB_STRUCT_STAT sbuf;
4933 bool correct = false;
4934 NTSTATUS status;
4936 printf("Starting simple POSIX open test\n");
4938 if (!torture_open_connection(&cli1, 0)) {
4939 return false;
4942 cli_sockopt(cli1, sockops);
4944 status = torture_setup_unix_extensions(cli1);
4945 if (!NT_STATUS_IS_OK(status)) {
4946 return false;
4949 cli_setatr(cli1, fname, 0, 0);
4950 cli_posix_unlink(cli1, fname);
4951 cli_setatr(cli1, dname, 0, 0);
4952 cli_posix_rmdir(cli1, dname);
4953 cli_setatr(cli1, hname, 0, 0);
4954 cli_posix_unlink(cli1, hname);
4955 cli_setatr(cli1, sname, 0, 0);
4956 cli_posix_unlink(cli1, sname);
4958 /* Create a directory. */
4959 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4960 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4961 goto out;
4964 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4965 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4966 goto out;
4969 /* Test ftruncate - set file size. */
4970 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4971 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4972 goto out;
4975 /* Ensure st_size == 1000 */
4976 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4977 printf("stat failed (%s)\n", cli_errstr(cli1));
4978 goto out;
4981 if (sbuf.st_ex_size != 1000) {
4982 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4983 goto out;
4986 /* Test ftruncate - set file size back to zero. */
4987 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4988 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4989 goto out;
4992 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4993 printf("close failed (%s)\n", cli_errstr(cli1));
4994 goto out;
4997 /* Now open the file again for read only. */
4998 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4999 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
5000 goto out;
5003 /* Now unlink while open. */
5004 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5005 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5006 goto out;
5009 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5010 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5011 goto out;
5014 /* Ensure the file has gone. */
5015 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5016 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5017 goto out;
5020 /* What happens when we try and POSIX open a directory ? */
5021 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5022 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5023 goto out;
5024 } else {
5025 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5026 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5027 goto out;
5031 /* Create the file. */
5032 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5033 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5034 goto out;
5037 /* Write some data into it. */
5038 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
5039 NULL);
5040 if (!NT_STATUS_IS_OK(status)) {
5041 printf("cli_write failed: %s\n", nt_errstr(status));
5042 goto out;
5045 cli_close(cli1, fnum1);
5047 /* Now create a hardlink. */
5048 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5049 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5050 goto out;
5053 /* Now create a symlink. */
5054 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5055 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5056 goto out;
5059 /* Open the hardlink for read. */
5060 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5061 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5062 goto out;
5065 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5066 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5067 goto out;
5070 if (memcmp(buf, "TEST DATA\n", 10)) {
5071 printf("invalid data read from hardlink\n");
5072 goto out;
5075 /* Do a POSIX lock/unlock. */
5076 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5077 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5078 goto out;
5081 /* Punch a hole in the locked area. */
5082 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5083 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5084 goto out;
5087 cli_close(cli1, fnum1);
5089 /* Open the symlink for read - this should fail. A POSIX
5090 client should not be doing opens on a symlink. */
5091 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5092 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5093 goto out;
5094 } else {
5095 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5096 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5097 printf("POSIX open of %s should have failed "
5098 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5099 "failed with %s instead.\n",
5100 sname, cli_errstr(cli1));
5101 goto out;
5105 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5106 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5107 goto out;
5110 if (strcmp(namebuf, fname) != 0) {
5111 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5112 sname, fname, namebuf);
5113 goto out;
5116 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5117 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5118 goto out;
5121 printf("Simple POSIX open test passed\n");
5122 correct = true;
5124 out:
5126 if (fnum1 != (uint16_t)-1) {
5127 cli_close(cli1, fnum1);
5128 fnum1 = (uint16_t)-1;
5131 cli_setatr(cli1, sname, 0, 0);
5132 cli_posix_unlink(cli1, sname);
5133 cli_setatr(cli1, hname, 0, 0);
5134 cli_posix_unlink(cli1, hname);
5135 cli_setatr(cli1, fname, 0, 0);
5136 cli_posix_unlink(cli1, fname);
5137 cli_setatr(cli1, dname, 0, 0);
5138 cli_posix_rmdir(cli1, dname);
5140 if (!torture_close_connection(cli1)) {
5141 correct = false;
5144 return correct;
5148 static uint32 open_attrs_table[] = {
5149 FILE_ATTRIBUTE_NORMAL,
5150 FILE_ATTRIBUTE_ARCHIVE,
5151 FILE_ATTRIBUTE_READONLY,
5152 FILE_ATTRIBUTE_HIDDEN,
5153 FILE_ATTRIBUTE_SYSTEM,
5155 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5156 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5157 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5158 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5159 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5160 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5162 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5163 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5164 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5165 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5168 struct trunc_open_results {
5169 unsigned int num;
5170 uint32 init_attr;
5171 uint32 trunc_attr;
5172 uint32 result_attr;
5175 static struct trunc_open_results attr_results[] = {
5176 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5177 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5178 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5179 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5180 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5181 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5182 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5183 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5184 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5185 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5186 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5187 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5188 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5189 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5190 { 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 },
5191 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5192 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5193 { 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 },
5194 { 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 },
5195 { 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 },
5196 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5197 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5198 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5199 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5200 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5201 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5204 static bool run_openattrtest(int dummy)
5206 static struct cli_state *cli1;
5207 const char *fname = "\\openattr.file";
5208 uint16_t fnum1;
5209 bool correct = True;
5210 uint16 attr;
5211 unsigned int i, j, k, l;
5213 printf("starting open attr test\n");
5215 if (!torture_open_connection(&cli1, 0)) {
5216 return False;
5219 cli_sockopt(cli1, sockops);
5221 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5222 cli_setatr(cli1, fname, 0, 0);
5223 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5224 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5225 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5226 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5227 return False;
5230 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5231 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5232 return False;
5235 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5236 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5237 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5238 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5239 if (attr_results[l].num == k) {
5240 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5241 k, open_attrs_table[i],
5242 open_attrs_table[j],
5243 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5244 correct = False;
5247 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5248 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5249 k, open_attrs_table[i], open_attrs_table[j],
5250 cli_errstr(cli1));
5251 correct = False;
5253 #if 0
5254 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5255 #endif
5256 k++;
5257 continue;
5260 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5261 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5262 return False;
5265 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5266 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5267 return False;
5270 #if 0
5271 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5272 k, open_attrs_table[i], open_attrs_table[j], attr );
5273 #endif
5275 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5276 if (attr_results[l].num == k) {
5277 if (attr != attr_results[l].result_attr ||
5278 open_attrs_table[i] != attr_results[l].init_attr ||
5279 open_attrs_table[j] != attr_results[l].trunc_attr) {
5280 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5281 open_attrs_table[i],
5282 open_attrs_table[j],
5283 (unsigned int)attr,
5284 attr_results[l].result_attr);
5285 correct = False;
5287 break;
5290 k++;
5294 cli_setatr(cli1, fname, 0, 0);
5295 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5297 printf("open attr test %s.\n", correct ? "passed" : "failed");
5299 if (!torture_close_connection(cli1)) {
5300 correct = False;
5302 return correct;
5305 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5306 const char *name, void *state)
5308 int *matched = (int *)state;
5309 if (matched != NULL) {
5310 *matched += 1;
5312 return NT_STATUS_OK;
5316 test directory listing speed
5318 static bool run_dirtest(int dummy)
5320 int i;
5321 static struct cli_state *cli;
5322 uint16_t fnum;
5323 struct timeval core_start;
5324 bool correct = True;
5325 int matched;
5327 printf("starting directory test\n");
5329 if (!torture_open_connection(&cli, 0)) {
5330 return False;
5333 cli_sockopt(cli, sockops);
5335 srandom(0);
5336 for (i=0;i<torture_numops;i++) {
5337 fstring fname;
5338 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5339 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5340 fprintf(stderr,"Failed to open %s\n", fname);
5341 return False;
5343 cli_close(cli, fnum);
5346 core_start = timeval_current();
5348 matched = 0;
5349 cli_list(cli, "a*.*", 0, list_fn, &matched);
5350 printf("Matched %d\n", matched);
5352 matched = 0;
5353 cli_list(cli, "b*.*", 0, list_fn, &matched);
5354 printf("Matched %d\n", matched);
5356 matched = 0;
5357 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5358 printf("Matched %d\n", matched);
5360 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5362 srandom(0);
5363 for (i=0;i<torture_numops;i++) {
5364 fstring fname;
5365 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5366 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5369 if (!torture_close_connection(cli)) {
5370 correct = False;
5373 printf("finished dirtest\n");
5375 return correct;
5378 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5379 void *state)
5381 struct cli_state *pcli = (struct cli_state *)state;
5382 fstring fname;
5383 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5385 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5386 return NT_STATUS_OK;
5388 if (finfo->mode & aDIR) {
5389 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5390 printf("del_fn: failed to rmdir %s\n,", fname );
5391 } else {
5392 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5393 printf("del_fn: failed to unlink %s\n,", fname );
5395 return NT_STATUS_OK;
5400 sees what IOCTLs are supported
5402 bool torture_ioctl_test(int dummy)
5404 static struct cli_state *cli;
5405 uint16_t device, function;
5406 uint16_t fnum;
5407 const char *fname = "\\ioctl.dat";
5408 DATA_BLOB blob;
5409 NTSTATUS status;
5411 if (!torture_open_connection(&cli, 0)) {
5412 return False;
5415 printf("starting ioctl test\n");
5417 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5419 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5420 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5421 return False;
5424 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5425 printf("ioctl device info: %s\n", nt_errstr(status));
5427 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5428 printf("ioctl job info: %s\n", nt_errstr(status));
5430 for (device=0;device<0x100;device++) {
5431 printf("ioctl test with device = 0x%x\n", device);
5432 for (function=0;function<0x100;function++) {
5433 uint32 code = (device<<16) | function;
5435 status = cli_raw_ioctl(cli, fnum, code, &blob);
5437 if (NT_STATUS_IS_OK(status)) {
5438 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5439 (int)blob.length);
5440 data_blob_free(&blob);
5445 if (!torture_close_connection(cli)) {
5446 return False;
5449 return True;
5454 tries varients of chkpath
5456 bool torture_chkpath_test(int dummy)
5458 static struct cli_state *cli;
5459 uint16_t fnum;
5460 bool ret;
5462 if (!torture_open_connection(&cli, 0)) {
5463 return False;
5466 printf("starting chkpath test\n");
5468 /* cleanup from an old run */
5469 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5470 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5471 cli_rmdir(cli, "\\chkpath.dir");
5473 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5474 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5475 return False;
5478 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5479 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5480 return False;
5483 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5484 printf("open1 failed (%s)\n", cli_errstr(cli));
5485 return False;
5487 cli_close(cli, fnum);
5489 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5490 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5491 ret = False;
5494 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5495 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5496 ret = False;
5499 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5500 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5501 NT_STATUS_NOT_A_DIRECTORY);
5502 } else {
5503 printf("* chkpath on a file should fail\n");
5504 ret = False;
5507 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5508 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5509 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5510 } else {
5511 printf("* chkpath on a non existant file should fail\n");
5512 ret = False;
5515 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5516 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5517 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5518 } else {
5519 printf("* chkpath on a non existent component should fail\n");
5520 ret = False;
5523 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5524 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5525 cli_rmdir(cli, "\\chkpath.dir");
5527 if (!torture_close_connection(cli)) {
5528 return False;
5531 return ret;
5534 static bool run_eatest(int dummy)
5536 static struct cli_state *cli;
5537 const char *fname = "\\eatest.txt";
5538 bool correct = True;
5539 uint16_t fnum;
5540 int i;
5541 size_t num_eas;
5542 struct ea_struct *ea_list = NULL;
5543 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5544 NTSTATUS status;
5546 printf("starting eatest\n");
5548 if (!torture_open_connection(&cli, 0)) {
5549 talloc_destroy(mem_ctx);
5550 return False;
5553 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5554 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5555 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5556 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5557 0x4044, 0, &fnum))) {
5558 printf("open failed - %s\n", cli_errstr(cli));
5559 talloc_destroy(mem_ctx);
5560 return False;
5563 for (i = 0; i < 10; i++) {
5564 fstring ea_name, ea_val;
5566 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5567 memset(ea_val, (char)i+1, i+1);
5568 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5569 if (!NT_STATUS_IS_OK(status)) {
5570 printf("ea_set of name %s failed - %s\n", ea_name,
5571 nt_errstr(status));
5572 talloc_destroy(mem_ctx);
5573 return False;
5577 cli_close(cli, fnum);
5578 for (i = 0; i < 10; i++) {
5579 fstring ea_name, ea_val;
5581 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5582 memset(ea_val, (char)i+1, i+1);
5583 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5584 if (!NT_STATUS_IS_OK(status)) {
5585 printf("ea_set of name %s failed - %s\n", ea_name,
5586 nt_errstr(status));
5587 talloc_destroy(mem_ctx);
5588 return False;
5592 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5593 if (!NT_STATUS_IS_OK(status)) {
5594 printf("ea_get list failed - %s\n", nt_errstr(status));
5595 correct = False;
5598 printf("num_eas = %d\n", (int)num_eas);
5600 if (num_eas != 20) {
5601 printf("Should be 20 EA's stored... failing.\n");
5602 correct = False;
5605 for (i = 0; i < num_eas; i++) {
5606 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5607 dump_data(0, ea_list[i].value.data,
5608 ea_list[i].value.length);
5611 /* Setting EA's to zero length deletes them. Test this */
5612 printf("Now deleting all EA's - case indepenent....\n");
5614 #if 1
5615 cli_set_ea_path(cli, fname, "", "", 0);
5616 #else
5617 for (i = 0; i < 20; i++) {
5618 fstring ea_name;
5619 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5620 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5621 if (!NT_STATUS_IS_OK(status)) {
5622 printf("ea_set of name %s failed - %s\n", ea_name,
5623 nt_errstr(status));
5624 talloc_destroy(mem_ctx);
5625 return False;
5628 #endif
5630 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5631 if (!NT_STATUS_IS_OK(status)) {
5632 printf("ea_get list failed - %s\n", nt_errstr(status));
5633 correct = False;
5636 printf("num_eas = %d\n", (int)num_eas);
5637 for (i = 0; i < num_eas; i++) {
5638 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5639 dump_data(0, ea_list[i].value.data,
5640 ea_list[i].value.length);
5643 if (num_eas != 0) {
5644 printf("deleting EA's failed.\n");
5645 correct = False;
5648 /* Try and delete a non existant EA. */
5649 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5650 if (!NT_STATUS_IS_OK(status)) {
5651 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5652 nt_errstr(status));
5653 correct = False;
5656 talloc_destroy(mem_ctx);
5657 if (!torture_close_connection(cli)) {
5658 correct = False;
5661 return correct;
5664 static bool run_dirtest1(int dummy)
5666 int i;
5667 static struct cli_state *cli;
5668 uint16_t fnum;
5669 int num_seen;
5670 bool correct = True;
5672 printf("starting directory test\n");
5674 if (!torture_open_connection(&cli, 0)) {
5675 return False;
5678 cli_sockopt(cli, sockops);
5680 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5681 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5682 cli_rmdir(cli, "\\LISTDIR");
5683 cli_mkdir(cli, "\\LISTDIR");
5685 /* Create 1000 files and 1000 directories. */
5686 for (i=0;i<1000;i++) {
5687 fstring fname;
5688 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5689 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5690 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5691 fprintf(stderr,"Failed to open %s\n", fname);
5692 return False;
5694 cli_close(cli, fnum);
5696 for (i=0;i<1000;i++) {
5697 fstring fname;
5698 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5699 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5700 fprintf(stderr,"Failed to open %s\n", fname);
5701 return False;
5705 /* Now ensure that doing an old list sees both files and directories. */
5706 num_seen = 0;
5707 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5708 printf("num_seen = %d\n", num_seen );
5709 /* We should see 100 files + 1000 directories + . and .. */
5710 if (num_seen != 2002)
5711 correct = False;
5713 /* Ensure if we have the "must have" bits we only see the
5714 * relevent entries.
5716 num_seen = 0;
5717 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5718 printf("num_seen = %d\n", num_seen );
5719 if (num_seen != 1002)
5720 correct = False;
5722 num_seen = 0;
5723 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5724 printf("num_seen = %d\n", num_seen );
5725 if (num_seen != 1000)
5726 correct = False;
5728 /* Delete everything. */
5729 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5730 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5731 cli_rmdir(cli, "\\LISTDIR");
5733 #if 0
5734 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5735 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5736 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5737 #endif
5739 if (!torture_close_connection(cli)) {
5740 correct = False;
5743 printf("finished dirtest1\n");
5745 return correct;
5748 static bool run_error_map_extract(int dummy) {
5750 static struct cli_state *c_dos;
5751 static struct cli_state *c_nt;
5752 NTSTATUS status;
5754 uint32 error;
5756 uint32 flgs2, errnum;
5757 uint8 errclass;
5759 NTSTATUS nt_status;
5761 fstring user;
5763 /* NT-Error connection */
5765 if (!(c_nt = open_nbt_connection())) {
5766 return False;
5769 c_nt->use_spnego = False;
5771 status = cli_negprot(c_nt);
5773 if (!NT_STATUS_IS_OK(status)) {
5774 printf("%s rejected the NT-error negprot (%s)\n", host,
5775 nt_errstr(status));
5776 cli_shutdown(c_nt);
5777 return False;
5780 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5781 workgroup))) {
5782 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5783 return False;
5786 /* DOS-Error connection */
5788 if (!(c_dos = open_nbt_connection())) {
5789 return False;
5792 c_dos->use_spnego = False;
5793 c_dos->force_dos_errors = True;
5795 status = cli_negprot(c_dos);
5796 if (!NT_STATUS_IS_OK(status)) {
5797 printf("%s rejected the DOS-error negprot (%s)\n", host,
5798 nt_errstr(status));
5799 cli_shutdown(c_dos);
5800 return False;
5803 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5804 workgroup))) {
5805 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5806 return False;
5809 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5810 fstr_sprintf(user, "%X", error);
5812 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5813 password, strlen(password),
5814 password, strlen(password),
5815 workgroup))) {
5816 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5819 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5821 /* Case #1: 32-bit NT errors */
5822 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5823 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5824 } else {
5825 printf("/** Dos error on NT connection! (%s) */\n",
5826 cli_errstr(c_nt));
5827 nt_status = NT_STATUS(0xc0000000);
5830 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5831 password, strlen(password),
5832 password, strlen(password),
5833 workgroup))) {
5834 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5836 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5838 /* Case #1: 32-bit NT errors */
5839 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5840 printf("/** NT error on DOS connection! (%s) */\n",
5841 cli_errstr(c_nt));
5842 errnum = errclass = 0;
5843 } else {
5844 cli_dos_error(c_dos, &errclass, &errnum);
5847 if (NT_STATUS_V(nt_status) != error) {
5848 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5849 get_nt_error_c_code(NT_STATUS(error)),
5850 get_nt_error_c_code(nt_status));
5853 printf("\t{%s,\t%s,\t%s},\n",
5854 smb_dos_err_class(errclass),
5855 smb_dos_err_name(errclass, errnum),
5856 get_nt_error_c_code(NT_STATUS(error)));
5858 return True;
5861 static bool run_sesssetup_bench(int dummy)
5863 static struct cli_state *c;
5864 const char *fname = "\\file.dat";
5865 uint16_t fnum;
5866 NTSTATUS status;
5867 int i;
5869 if (!torture_open_connection(&c, 0)) {
5870 return false;
5873 if (!NT_STATUS_IS_OK(cli_ntcreate(
5874 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5875 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5876 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5877 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5878 return false;
5881 for (i=0; i<torture_numops; i++) {
5882 status = cli_session_setup(
5883 c, username,
5884 password, strlen(password),
5885 password, strlen(password),
5886 workgroup);
5887 if (!NT_STATUS_IS_OK(status)) {
5888 d_printf("(%s) cli_session_setup failed: %s\n",
5889 __location__, nt_errstr(status));
5890 return false;
5893 d_printf("\r%d ", (int)c->vuid);
5895 status = cli_ulogoff(c);
5896 if (!NT_STATUS_IS_OK(status)) {
5897 d_printf("(%s) cli_ulogoff failed: %s\n",
5898 __location__, nt_errstr(status));
5899 return false;
5901 c->vuid = 0;
5904 return true;
5907 static bool subst_test(const char *str, const char *user, const char *domain,
5908 uid_t uid, gid_t gid, const char *expected)
5910 char *subst;
5911 bool result = true;
5913 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5915 if (strcmp(subst, expected) != 0) {
5916 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5917 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5918 expected);
5919 result = false;
5922 TALLOC_FREE(subst);
5923 return result;
5926 static void chain1_open_completion(struct tevent_req *req)
5928 uint16_t fnum;
5929 NTSTATUS status;
5930 status = cli_open_recv(req, &fnum);
5931 TALLOC_FREE(req);
5933 d_printf("cli_open_recv returned %s: %d\n",
5934 nt_errstr(status),
5935 NT_STATUS_IS_OK(status) ? fnum : -1);
5938 static void chain1_write_completion(struct tevent_req *req)
5940 size_t written;
5941 NTSTATUS status;
5942 status = cli_write_andx_recv(req, &written);
5943 TALLOC_FREE(req);
5945 d_printf("cli_write_andx_recv returned %s: %d\n",
5946 nt_errstr(status),
5947 NT_STATUS_IS_OK(status) ? (int)written : -1);
5950 static void chain1_close_completion(struct tevent_req *req)
5952 NTSTATUS status;
5953 bool *done = (bool *)tevent_req_callback_data_void(req);
5955 status = cli_close_recv(req);
5956 *done = true;
5958 TALLOC_FREE(req);
5960 d_printf("cli_close returned %s\n", nt_errstr(status));
5963 static bool run_chain1(int dummy)
5965 struct cli_state *cli1;
5966 struct event_context *evt = event_context_init(NULL);
5967 struct tevent_req *reqs[3], *smbreqs[3];
5968 bool done = false;
5969 const char *str = "foobar";
5970 NTSTATUS status;
5972 printf("starting chain1 test\n");
5973 if (!torture_open_connection(&cli1, 0)) {
5974 return False;
5977 cli_sockopt(cli1, sockops);
5979 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5980 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5981 if (reqs[0] == NULL) return false;
5982 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5985 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5986 (uint8_t *)str, 0, strlen(str)+1,
5987 smbreqs, 1, &smbreqs[1]);
5988 if (reqs[1] == NULL) return false;
5989 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5991 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5992 if (reqs[2] == NULL) return false;
5993 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5995 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5996 if (!NT_STATUS_IS_OK(status)) {
5997 return false;
6000 while (!done) {
6001 event_loop_once(evt);
6004 torture_close_connection(cli1);
6005 return True;
6008 static void chain2_sesssetup_completion(struct tevent_req *req)
6010 NTSTATUS status;
6011 status = cli_session_setup_guest_recv(req);
6012 d_printf("sesssetup returned %s\n", nt_errstr(status));
6015 static void chain2_tcon_completion(struct tevent_req *req)
6017 bool *done = (bool *)tevent_req_callback_data_void(req);
6018 NTSTATUS status;
6019 status = cli_tcon_andx_recv(req);
6020 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6021 *done = true;
6024 static bool run_chain2(int dummy)
6026 struct cli_state *cli1;
6027 struct event_context *evt = event_context_init(NULL);
6028 struct tevent_req *reqs[2], *smbreqs[2];
6029 bool done = false;
6030 NTSTATUS status;
6032 printf("starting chain2 test\n");
6033 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6034 port_to_use, Undefined, 0);
6035 if (!NT_STATUS_IS_OK(status)) {
6036 return False;
6039 cli_sockopt(cli1, sockops);
6041 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6042 &smbreqs[0]);
6043 if (reqs[0] == NULL) return false;
6044 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6046 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6047 "?????", NULL, 0, &smbreqs[1]);
6048 if (reqs[1] == NULL) return false;
6049 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6051 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6052 if (!NT_STATUS_IS_OK(status)) {
6053 return false;
6056 while (!done) {
6057 event_loop_once(evt);
6060 torture_close_connection(cli1);
6061 return True;
6065 struct torture_createdel_state {
6066 struct tevent_context *ev;
6067 struct cli_state *cli;
6070 static void torture_createdel_created(struct tevent_req *subreq);
6071 static void torture_createdel_closed(struct tevent_req *subreq);
6073 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6074 struct tevent_context *ev,
6075 struct cli_state *cli,
6076 const char *name)
6078 struct tevent_req *req, *subreq;
6079 struct torture_createdel_state *state;
6081 req = tevent_req_create(mem_ctx, &state,
6082 struct torture_createdel_state);
6083 if (req == NULL) {
6084 return NULL;
6086 state->ev = ev;
6087 state->cli = cli;
6089 subreq = cli_ntcreate_send(
6090 state, ev, cli, name, 0,
6091 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6092 FILE_ATTRIBUTE_NORMAL,
6093 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6094 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6096 if (tevent_req_nomem(subreq, req)) {
6097 return tevent_req_post(req, ev);
6099 tevent_req_set_callback(subreq, torture_createdel_created, req);
6100 return req;
6103 static void torture_createdel_created(struct tevent_req *subreq)
6105 struct tevent_req *req = tevent_req_callback_data(
6106 subreq, struct tevent_req);
6107 struct torture_createdel_state *state = tevent_req_data(
6108 req, struct torture_createdel_state);
6109 NTSTATUS status;
6110 uint16_t fnum;
6112 status = cli_ntcreate_recv(subreq, &fnum);
6113 TALLOC_FREE(subreq);
6114 if (!NT_STATUS_IS_OK(status)) {
6115 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6116 nt_errstr(status)));
6117 tevent_req_nterror(req, status);
6118 return;
6121 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6122 if (tevent_req_nomem(subreq, req)) {
6123 return;
6125 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6128 static void torture_createdel_closed(struct tevent_req *subreq)
6130 struct tevent_req *req = tevent_req_callback_data(
6131 subreq, struct tevent_req);
6132 NTSTATUS status;
6134 status = cli_close_recv(subreq);
6135 if (!NT_STATUS_IS_OK(status)) {
6136 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6137 tevent_req_nterror(req, status);
6138 return;
6140 tevent_req_done(req);
6143 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6145 return tevent_req_simple_recv_ntstatus(req);
6148 struct torture_createdels_state {
6149 struct tevent_context *ev;
6150 struct cli_state *cli;
6151 const char *base_name;
6152 int sent;
6153 int received;
6154 int num_files;
6155 struct tevent_req **reqs;
6158 static void torture_createdels_done(struct tevent_req *subreq);
6160 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6161 struct tevent_context *ev,
6162 struct cli_state *cli,
6163 const char *base_name,
6164 int num_parallel,
6165 int num_files)
6167 struct tevent_req *req;
6168 struct torture_createdels_state *state;
6169 int i;
6171 req = tevent_req_create(mem_ctx, &state,
6172 struct torture_createdels_state);
6173 if (req == NULL) {
6174 return NULL;
6176 state->ev = ev;
6177 state->cli = cli;
6178 state->base_name = talloc_strdup(state, base_name);
6179 if (tevent_req_nomem(state->base_name, req)) {
6180 return tevent_req_post(req, ev);
6182 state->num_files = MAX(num_parallel, num_files);
6183 state->sent = 0;
6184 state->received = 0;
6186 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6187 if (tevent_req_nomem(state->reqs, req)) {
6188 return tevent_req_post(req, ev);
6191 for (i=0; i<num_parallel; i++) {
6192 char *name;
6194 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6195 state->sent);
6196 if (tevent_req_nomem(name, req)) {
6197 return tevent_req_post(req, ev);
6199 state->reqs[i] = torture_createdel_send(
6200 state->reqs, state->ev, state->cli, name);
6201 if (tevent_req_nomem(state->reqs[i], req)) {
6202 return tevent_req_post(req, ev);
6204 name = talloc_move(state->reqs[i], &name);
6205 tevent_req_set_callback(state->reqs[i],
6206 torture_createdels_done, req);
6207 state->sent += 1;
6209 return req;
6212 static void torture_createdels_done(struct tevent_req *subreq)
6214 struct tevent_req *req = tevent_req_callback_data(
6215 subreq, struct tevent_req);
6216 struct torture_createdels_state *state = tevent_req_data(
6217 req, struct torture_createdels_state);
6218 size_t num_parallel = talloc_array_length(state->reqs);
6219 NTSTATUS status;
6220 char *name;
6221 int i;
6223 status = torture_createdel_recv(subreq);
6224 if (!NT_STATUS_IS_OK(status)){
6225 DEBUG(10, ("torture_createdel_recv returned %s\n",
6226 nt_errstr(status)));
6227 TALLOC_FREE(subreq);
6228 tevent_req_nterror(req, status);
6229 return;
6232 for (i=0; i<num_parallel; i++) {
6233 if (subreq == state->reqs[i]) {
6234 break;
6237 if (i == num_parallel) {
6238 DEBUG(10, ("received something we did not send\n"));
6239 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6240 return;
6242 TALLOC_FREE(state->reqs[i]);
6244 if (state->sent >= state->num_files) {
6245 tevent_req_done(req);
6246 return;
6249 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6250 state->sent);
6251 if (tevent_req_nomem(name, req)) {
6252 return;
6254 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6255 state->cli, name);
6256 if (tevent_req_nomem(state->reqs[i], req)) {
6257 return;
6259 name = talloc_move(state->reqs[i], &name);
6260 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6261 state->sent += 1;
6264 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6266 return tevent_req_simple_recv_ntstatus(req);
6269 struct swallow_notify_state {
6270 struct tevent_context *ev;
6271 struct cli_state *cli;
6272 uint16_t fnum;
6273 uint32_t completion_filter;
6274 bool recursive;
6275 bool (*fn)(uint32_t action, const char *name, void *priv);
6276 void *priv;
6279 static void swallow_notify_done(struct tevent_req *subreq);
6281 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6282 struct tevent_context *ev,
6283 struct cli_state *cli,
6284 uint16_t fnum,
6285 uint32_t completion_filter,
6286 bool recursive,
6287 bool (*fn)(uint32_t action,
6288 const char *name,
6289 void *priv),
6290 void *priv)
6292 struct tevent_req *req, *subreq;
6293 struct swallow_notify_state *state;
6295 req = tevent_req_create(mem_ctx, &state,
6296 struct swallow_notify_state);
6297 if (req == NULL) {
6298 return NULL;
6300 state->ev = ev;
6301 state->cli = cli;
6302 state->fnum = fnum;
6303 state->completion_filter = completion_filter;
6304 state->recursive = recursive;
6305 state->fn = fn;
6306 state->priv = priv;
6308 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6309 0xffff, state->completion_filter,
6310 state->recursive);
6311 if (tevent_req_nomem(subreq, req)) {
6312 return tevent_req_post(req, ev);
6314 tevent_req_set_callback(subreq, swallow_notify_done, req);
6315 return req;
6318 static void swallow_notify_done(struct tevent_req *subreq)
6320 struct tevent_req *req = tevent_req_callback_data(
6321 subreq, struct tevent_req);
6322 struct swallow_notify_state *state = tevent_req_data(
6323 req, struct swallow_notify_state);
6324 NTSTATUS status;
6325 uint32_t i, num_changes;
6326 struct notify_change *changes;
6328 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6329 TALLOC_FREE(subreq);
6330 if (!NT_STATUS_IS_OK(status)) {
6331 DEBUG(10, ("cli_notify_recv returned %s\n",
6332 nt_errstr(status)));
6333 tevent_req_nterror(req, status);
6334 return;
6337 for (i=0; i<num_changes; i++) {
6338 state->fn(changes[i].action, changes[i].name, state->priv);
6340 TALLOC_FREE(changes);
6342 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6343 0xffff, state->completion_filter,
6344 state->recursive);
6345 if (tevent_req_nomem(subreq, req)) {
6346 return;
6348 tevent_req_set_callback(subreq, swallow_notify_done, req);
6351 static bool print_notifies(uint32_t action, const char *name, void *priv)
6353 if (DEBUGLEVEL > 5) {
6354 d_printf("%d %s\n", (int)action, name);
6356 return true;
6359 static void notify_bench_done(struct tevent_req *req)
6361 int *num_finished = (int *)tevent_req_callback_data_void(req);
6362 *num_finished += 1;
6365 static bool run_notify_bench(int dummy)
6367 const char *dname = "\\notify-bench";
6368 struct tevent_context *ev;
6369 NTSTATUS status;
6370 uint16_t dnum;
6371 struct tevent_req *req1;
6372 struct tevent_req *req2 = NULL;
6373 int i, num_unc_names;
6374 int num_finished = 0;
6376 printf("starting notify-bench test\n");
6378 if (use_multishare_conn) {
6379 char **unc_list;
6380 unc_list = file_lines_load(multishare_conn_fname,
6381 &num_unc_names, 0, NULL);
6382 if (!unc_list || num_unc_names <= 0) {
6383 d_printf("Failed to load unc names list from '%s'\n",
6384 multishare_conn_fname);
6385 return false;
6387 TALLOC_FREE(unc_list);
6388 } else {
6389 num_unc_names = 1;
6392 ev = tevent_context_init(talloc_tos());
6393 if (ev == NULL) {
6394 d_printf("tevent_context_init failed\n");
6395 return false;
6398 for (i=0; i<num_unc_names; i++) {
6399 struct cli_state *cli;
6400 char *base_fname;
6402 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6403 dname, i);
6404 if (base_fname == NULL) {
6405 return false;
6408 if (!torture_open_connection(&cli, i)) {
6409 return false;
6412 status = cli_ntcreate(cli, dname, 0,
6413 MAXIMUM_ALLOWED_ACCESS,
6414 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6415 FILE_SHARE_DELETE,
6416 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6417 &dnum);
6419 if (!NT_STATUS_IS_OK(status)) {
6420 d_printf("Could not create %s: %s\n", dname,
6421 nt_errstr(status));
6422 return false;
6425 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6426 FILE_NOTIFY_CHANGE_FILE_NAME |
6427 FILE_NOTIFY_CHANGE_DIR_NAME |
6428 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6429 FILE_NOTIFY_CHANGE_LAST_WRITE,
6430 false, print_notifies, NULL);
6431 if (req1 == NULL) {
6432 d_printf("Could not create notify request\n");
6433 return false;
6436 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6437 base_fname, 10, torture_numops);
6438 if (req2 == NULL) {
6439 d_printf("Could not create createdels request\n");
6440 return false;
6442 TALLOC_FREE(base_fname);
6444 tevent_req_set_callback(req2, notify_bench_done,
6445 &num_finished);
6448 while (num_finished < num_unc_names) {
6449 int ret;
6450 ret = tevent_loop_once(ev);
6451 if (ret != 0) {
6452 d_printf("tevent_loop_once failed\n");
6453 return false;
6457 if (!tevent_req_poll(req2, ev)) {
6458 d_printf("tevent_req_poll failed\n");
6461 status = torture_createdels_recv(req2);
6462 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6464 return true;
6467 static bool run_mangle1(int dummy)
6469 struct cli_state *cli;
6470 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6471 uint16_t fnum;
6472 fstring alt_name;
6473 NTSTATUS status;
6474 time_t change_time, access_time, write_time;
6475 SMB_OFF_T size;
6476 uint16_t mode;
6478 printf("starting mangle1 test\n");
6479 if (!torture_open_connection(&cli, 0)) {
6480 return False;
6483 cli_sockopt(cli, sockops);
6485 if (!NT_STATUS_IS_OK(cli_ntcreate(
6486 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6487 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6488 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6489 return false;
6491 cli_close(cli, fnum);
6493 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6494 if (!NT_STATUS_IS_OK(status)) {
6495 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6496 nt_errstr(status));
6497 return false;
6499 d_printf("alt_name: %s\n", alt_name);
6501 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6502 d_printf("cli_open(%s) failed: %s\n", alt_name,
6503 cli_errstr(cli));
6504 return false;
6506 cli_close(cli, fnum);
6508 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6509 &write_time, &size, &mode);
6510 if (!NT_STATUS_IS_OK(status)) {
6511 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6512 nt_errstr(status));
6513 return false;
6516 return true;
6519 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6521 size_t *to_pull = (size_t *)priv;
6522 size_t thistime = *to_pull;
6524 thistime = MIN(thistime, n);
6525 if (thistime == 0) {
6526 return 0;
6529 memset(buf, 0, thistime);
6530 *to_pull -= thistime;
6531 return thistime;
6534 static bool run_windows_write(int dummy)
6536 struct cli_state *cli1;
6537 uint16_t fnum;
6538 int i;
6539 bool ret = false;
6540 const char *fname = "\\writetest.txt";
6541 struct timeval start_time;
6542 double seconds;
6543 double kbytes;
6545 printf("starting windows_write test\n");
6546 if (!torture_open_connection(&cli1, 0)) {
6547 return False;
6550 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6551 printf("open failed (%s)\n", cli_errstr(cli1));
6552 return False;
6555 cli_sockopt(cli1, sockops);
6557 start_time = timeval_current();
6559 for (i=0; i<torture_numops; i++) {
6560 uint8_t c = 0;
6561 off_t start = i * torture_blocksize;
6562 NTSTATUS status;
6563 size_t to_pull = torture_blocksize - 1;
6565 status = cli_writeall(cli1, fnum, 0, &c,
6566 start + torture_blocksize - 1, 1, NULL);
6567 if (!NT_STATUS_IS_OK(status)) {
6568 printf("cli_write failed: %s\n", nt_errstr(status));
6569 goto fail;
6572 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6573 null_source, &to_pull);
6574 if (!NT_STATUS_IS_OK(status)) {
6575 printf("cli_push returned: %s\n", nt_errstr(status));
6576 goto fail;
6580 seconds = timeval_elapsed(&start_time);
6581 kbytes = (double)torture_blocksize * torture_numops;
6582 kbytes /= 1024;
6584 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6585 (double)seconds, (int)(kbytes/seconds));
6587 ret = true;
6588 fail:
6589 cli_close(cli1, fnum);
6590 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6591 torture_close_connection(cli1);
6592 return ret;
6595 static bool run_cli_echo(int dummy)
6597 struct cli_state *cli;
6598 NTSTATUS status;
6600 printf("starting cli_echo test\n");
6601 if (!torture_open_connection(&cli, 0)) {
6602 return false;
6604 cli_sockopt(cli, sockops);
6606 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6608 d_printf("cli_echo returned %s\n", nt_errstr(status));
6610 torture_close_connection(cli);
6611 return NT_STATUS_IS_OK(status);
6614 static bool run_uid_regression_test(int dummy)
6616 static struct cli_state *cli;
6617 int16_t old_vuid;
6618 int16_t old_cnum;
6619 bool correct = True;
6620 NTSTATUS status;
6622 printf("starting uid regression test\n");
6624 if (!torture_open_connection(&cli, 0)) {
6625 return False;
6628 cli_sockopt(cli, sockops);
6630 /* Ok - now save then logoff our current user. */
6631 old_vuid = cli->vuid;
6633 status = cli_ulogoff(cli);
6634 if (!NT_STATUS_IS_OK(status)) {
6635 d_printf("(%s) cli_ulogoff failed: %s\n",
6636 __location__, nt_errstr(status));
6637 correct = false;
6638 goto out;
6641 cli->vuid = old_vuid;
6643 /* Try an operation. */
6644 status = cli_mkdir(cli, "\\uid_reg_test");
6645 if (NT_STATUS_IS_OK(status)) {
6646 d_printf("(%s) cli_mkdir succeeded\n",
6647 __location__);
6648 correct = false;
6649 goto out;
6650 } else {
6651 /* Should be bad uid. */
6652 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6653 NT_STATUS_USER_SESSION_DELETED)) {
6654 correct = false;
6655 goto out;
6659 old_cnum = cli->cnum;
6661 /* Now try a SMBtdis with the invald vuid set to zero. */
6662 cli->vuid = 0;
6664 /* This should succeed. */
6665 status = cli_tdis(cli);
6667 if (NT_STATUS_IS_OK(status)) {
6668 d_printf("First tdis with invalid vuid should succeed.\n");
6669 } else {
6670 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6671 correct = false;
6672 goto out;
6675 cli->vuid = old_vuid;
6676 cli->cnum = old_cnum;
6678 /* This should fail. */
6679 status = cli_tdis(cli);
6680 if (NT_STATUS_IS_OK(status)) {
6681 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6682 correct = false;
6683 goto out;
6684 } else {
6685 /* Should be bad tid. */
6686 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6687 NT_STATUS_NETWORK_NAME_DELETED)) {
6688 correct = false;
6689 goto out;
6693 cli_rmdir(cli, "\\uid_reg_test");
6695 out:
6697 cli_shutdown(cli);
6698 return correct;
6702 static const char *illegal_chars = "*\\/?<>|\":";
6703 static char force_shortname_chars[] = " +,.[];=\177";
6705 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6706 const char *mask, void *state)
6708 struct cli_state *pcli = (struct cli_state *)state;
6709 fstring fname;
6710 NTSTATUS status = NT_STATUS_OK;
6712 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6714 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6715 return NT_STATUS_OK;
6717 if (finfo->mode & aDIR) {
6718 status = cli_rmdir(pcli, fname);
6719 if (!NT_STATUS_IS_OK(status)) {
6720 printf("del_fn: failed to rmdir %s\n,", fname );
6722 } else {
6723 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6724 if (!NT_STATUS_IS_OK(status)) {
6725 printf("del_fn: failed to unlink %s\n,", fname );
6728 return status;
6731 struct sn_state {
6732 int matched;
6733 int i;
6734 bool val;
6737 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6738 const char *name, void *state)
6740 struct sn_state *s = (struct sn_state *)state;
6741 int i = s->i;
6743 #if 0
6744 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6745 i, finfo->name, finfo->short_name);
6746 #endif
6748 if (strchr(force_shortname_chars, i)) {
6749 if (!finfo->short_name[0]) {
6750 /* Shortname not created when it should be. */
6751 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6752 __location__, finfo->name, i);
6753 s->val = true;
6755 } else if (finfo->short_name[0]){
6756 /* Shortname created when it should not be. */
6757 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6758 __location__, finfo->short_name, finfo->name);
6759 s->val = true;
6761 s->matched += 1;
6762 return NT_STATUS_OK;
6765 static bool run_shortname_test(int dummy)
6767 static struct cli_state *cli;
6768 bool correct = True;
6769 int i;
6770 struct sn_state s;
6771 char fname[20];
6773 printf("starting shortname test\n");
6775 if (!torture_open_connection(&cli, 0)) {
6776 return False;
6779 cli_sockopt(cli, sockops);
6781 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6782 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6783 cli_rmdir(cli, "\\shortname");
6785 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6786 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6787 __location__, cli_errstr(cli));
6788 correct = false;
6789 goto out;
6792 strlcpy(fname, "\\shortname\\", sizeof(fname));
6793 strlcat(fname, "test .txt", sizeof(fname));
6795 s.val = false;
6797 for (i = 32; i < 128; i++) {
6798 NTSTATUS status;
6799 uint16_t fnum = (uint16_t)-1;
6801 s.i = i;
6803 if (strchr(illegal_chars, i)) {
6804 continue;
6806 fname[15] = i;
6808 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6809 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6810 if (!NT_STATUS_IS_OK(status)) {
6811 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6812 __location__, fname, cli_errstr(cli));
6813 correct = false;
6814 goto out;
6816 cli_close(cli, fnum);
6818 s.matched = 0;
6819 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6820 &s);
6821 if (s.matched != 1) {
6822 d_printf("(%s) failed to list %s: %s\n",
6823 __location__, fname, cli_errstr(cli));
6824 correct = false;
6825 goto out;
6827 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6828 d_printf("(%s) failed to delete %s: %s\n",
6829 __location__, fname, cli_errstr(cli));
6830 correct = false;
6831 goto out;
6834 if (s.val) {
6835 correct = false;
6836 goto out;
6840 out:
6842 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6843 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6844 cli_rmdir(cli, "\\shortname");
6845 torture_close_connection(cli);
6846 return correct;
6849 static void pagedsearch_cb(struct tevent_req *req)
6851 int rc;
6852 struct tldap_message *msg;
6853 char *dn;
6855 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6856 if (rc != TLDAP_SUCCESS) {
6857 d_printf("tldap_search_paged_recv failed: %s\n",
6858 tldap_err2string(rc));
6859 return;
6861 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6862 TALLOC_FREE(msg);
6863 return;
6865 if (!tldap_entry_dn(msg, &dn)) {
6866 d_printf("tldap_entry_dn failed\n");
6867 return;
6869 d_printf("%s\n", dn);
6870 TALLOC_FREE(msg);
6873 static bool run_tldap(int dummy)
6875 struct tldap_context *ld;
6876 int fd, rc;
6877 NTSTATUS status;
6878 struct sockaddr_storage addr;
6879 struct tevent_context *ev;
6880 struct tevent_req *req;
6881 char *basedn;
6882 const char *filter;
6884 if (!resolve_name(host, &addr, 0, false)) {
6885 d_printf("could not find host %s\n", host);
6886 return false;
6888 status = open_socket_out(&addr, 389, 9999, &fd);
6889 if (!NT_STATUS_IS_OK(status)) {
6890 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6891 return false;
6894 ld = tldap_context_create(talloc_tos(), fd);
6895 if (ld == NULL) {
6896 close(fd);
6897 d_printf("tldap_context_create failed\n");
6898 return false;
6901 rc = tldap_fetch_rootdse(ld);
6902 if (rc != TLDAP_SUCCESS) {
6903 d_printf("tldap_fetch_rootdse failed: %s\n",
6904 tldap_errstr(talloc_tos(), ld, rc));
6905 return false;
6908 basedn = tldap_talloc_single_attribute(
6909 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6910 if (basedn == NULL) {
6911 d_printf("no defaultNamingContext\n");
6912 return false;
6914 d_printf("defaultNamingContext: %s\n", basedn);
6916 ev = tevent_context_init(talloc_tos());
6917 if (ev == NULL) {
6918 d_printf("tevent_context_init failed\n");
6919 return false;
6922 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6923 TLDAP_SCOPE_SUB, "(objectclass=*)",
6924 NULL, 0, 0,
6925 NULL, 0, NULL, 0, 0, 0, 0, 5);
6926 if (req == NULL) {
6927 d_printf("tldap_search_paged_send failed\n");
6928 return false;
6930 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6932 tevent_req_poll(req, ev);
6934 TALLOC_FREE(req);
6936 /* test search filters against rootDSE */
6937 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6938 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6940 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6941 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6942 talloc_tos(), NULL, NULL);
6943 if (rc != TLDAP_SUCCESS) {
6944 d_printf("tldap_search with complex filter failed: %s\n",
6945 tldap_errstr(talloc_tos(), ld, rc));
6946 return false;
6949 TALLOC_FREE(ld);
6950 return true;
6953 /* Torture test to ensure no regression of :
6954 https://bugzilla.samba.org/show_bug.cgi?id=7084
6957 static bool run_dir_createtime(int dummy)
6959 struct cli_state *cli;
6960 const char *dname = "\\testdir";
6961 const char *fname = "\\testdir\\testfile";
6962 NTSTATUS status;
6963 struct timespec create_time;
6964 struct timespec create_time1;
6965 uint16_t fnum;
6966 bool ret = false;
6968 if (!torture_open_connection(&cli, 0)) {
6969 return false;
6972 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6973 cli_rmdir(cli, dname);
6975 status = cli_mkdir(cli, dname);
6976 if (!NT_STATUS_IS_OK(status)) {
6977 printf("mkdir failed: %s\n", nt_errstr(status));
6978 goto out;
6981 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6982 NULL, NULL, NULL);
6983 if (!NT_STATUS_IS_OK(status)) {
6984 printf("cli_qpathinfo2 returned %s\n",
6985 nt_errstr(status));
6986 goto out;
6989 /* Sleep 3 seconds, then create a file. */
6990 sleep(3);
6992 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6993 DENY_NONE, &fnum);
6994 if (!NT_STATUS_IS_OK(status)) {
6995 printf("cli_open failed: %s\n", nt_errstr(status));
6996 goto out;
6999 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7000 NULL, NULL, NULL);
7001 if (!NT_STATUS_IS_OK(status)) {
7002 printf("cli_qpathinfo2 (2) returned %s\n",
7003 nt_errstr(status));
7004 goto out;
7007 if (timespec_compare(&create_time1, &create_time)) {
7008 printf("run_dir_createtime: create time was updated (error)\n");
7009 } else {
7010 printf("run_dir_createtime: create time was not updated (correct)\n");
7011 ret = true;
7014 out:
7016 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
7017 cli_rmdir(cli, dname);
7018 if (!torture_close_connection(cli)) {
7019 ret = false;
7021 return ret;
7025 static bool run_streamerror(int dummy)
7027 struct cli_state *cli;
7028 const char *dname = "\\testdir";
7029 const char *streamname =
7030 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7031 NTSTATUS status;
7032 time_t change_time, access_time, write_time;
7033 SMB_OFF_T size;
7034 uint16_t mode, fnum;
7035 bool ret = true;
7037 if (!torture_open_connection(&cli, 0)) {
7038 return false;
7041 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
7042 cli_rmdir(cli, dname);
7044 status = cli_mkdir(cli, dname);
7045 if (!NT_STATUS_IS_OK(status)) {
7046 printf("mkdir failed: %s\n", nt_errstr(status));
7047 return false;
7050 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7051 &size, &mode);
7052 status = cli_nt_error(cli);
7054 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7055 printf("pathinfo returned %s, expected "
7056 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7057 nt_errstr(status));
7058 ret = false;
7061 status = cli_ntcreate(cli, streamname, 0x16,
7062 FILE_READ_DATA|FILE_READ_EA|
7063 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7064 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7065 FILE_OPEN, 0, 0, &fnum);
7067 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7068 printf("ntcreate returned %s, expected "
7069 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7070 nt_errstr(status));
7071 ret = false;
7075 cli_rmdir(cli, dname);
7076 return ret;
7079 static bool run_local_substitute(int dummy)
7081 bool ok = true;
7083 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7084 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7085 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7086 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7087 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7088 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7089 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7090 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7092 /* Different captialization rules in sub_basic... */
7094 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7095 "blaDOM") == 0);
7097 return ok;
7100 static bool run_local_base64(int dummy)
7102 int i;
7103 bool ret = true;
7105 for (i=1; i<2000; i++) {
7106 DATA_BLOB blob1, blob2;
7107 char *b64;
7109 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7110 blob1.length = i;
7111 generate_random_buffer(blob1.data, blob1.length);
7113 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7114 if (b64 == NULL) {
7115 d_fprintf(stderr, "base64_encode_data_blob failed "
7116 "for %d bytes\n", i);
7117 ret = false;
7119 blob2 = base64_decode_data_blob(b64);
7120 TALLOC_FREE(b64);
7122 if (data_blob_cmp(&blob1, &blob2)) {
7123 d_fprintf(stderr, "data_blob_cmp failed for %d "
7124 "bytes\n", i);
7125 ret = false;
7127 TALLOC_FREE(blob1.data);
7128 data_blob_free(&blob2);
7130 return ret;
7133 static bool run_local_gencache(int dummy)
7135 char *val;
7136 time_t tm;
7137 DATA_BLOB blob;
7139 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7140 d_printf("%s: gencache_set() failed\n", __location__);
7141 return False;
7144 if (!gencache_get("foo", NULL, NULL)) {
7145 d_printf("%s: gencache_get() failed\n", __location__);
7146 return False;
7149 if (!gencache_get("foo", &val, &tm)) {
7150 d_printf("%s: gencache_get() failed\n", __location__);
7151 return False;
7154 if (strcmp(val, "bar") != 0) {
7155 d_printf("%s: gencache_get() returned %s, expected %s\n",
7156 __location__, val, "bar");
7157 SAFE_FREE(val);
7158 return False;
7161 SAFE_FREE(val);
7163 if (!gencache_del("foo")) {
7164 d_printf("%s: gencache_del() failed\n", __location__);
7165 return False;
7167 if (gencache_del("foo")) {
7168 d_printf("%s: second gencache_del() succeeded\n",
7169 __location__);
7170 return False;
7173 if (gencache_get("foo", &val, &tm)) {
7174 d_printf("%s: gencache_get() on deleted entry "
7175 "succeeded\n", __location__);
7176 return False;
7179 blob = data_blob_string_const_null("bar");
7180 tm = time(NULL) + 60;
7182 if (!gencache_set_data_blob("foo", &blob, tm)) {
7183 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7184 return False;
7187 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7188 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7189 return False;
7192 if (strcmp((const char *)blob.data, "bar") != 0) {
7193 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7194 __location__, (const char *)blob.data, "bar");
7195 data_blob_free(&blob);
7196 return False;
7199 data_blob_free(&blob);
7201 if (!gencache_del("foo")) {
7202 d_printf("%s: gencache_del() failed\n", __location__);
7203 return False;
7205 if (gencache_del("foo")) {
7206 d_printf("%s: second gencache_del() succeeded\n",
7207 __location__);
7208 return False;
7211 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7212 d_printf("%s: gencache_get_data_blob() on deleted entry "
7213 "succeeded\n", __location__);
7214 return False;
7217 return True;
7220 static bool rbt_testval(struct db_context *db, const char *key,
7221 const char *value)
7223 struct db_record *rec;
7224 TDB_DATA data = string_tdb_data(value);
7225 bool ret = false;
7226 NTSTATUS status;
7228 rec = db->fetch_locked(db, db, string_tdb_data(key));
7229 if (rec == NULL) {
7230 d_fprintf(stderr, "fetch_locked failed\n");
7231 goto done;
7233 status = rec->store(rec, data, 0);
7234 if (!NT_STATUS_IS_OK(status)) {
7235 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7236 goto done;
7238 TALLOC_FREE(rec);
7240 rec = db->fetch_locked(db, db, string_tdb_data(key));
7241 if (rec == NULL) {
7242 d_fprintf(stderr, "second fetch_locked failed\n");
7243 goto done;
7245 if ((rec->value.dsize != data.dsize)
7246 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7247 d_fprintf(stderr, "Got wrong data back\n");
7248 goto done;
7251 ret = true;
7252 done:
7253 TALLOC_FREE(rec);
7254 return ret;
7257 static bool run_local_rbtree(int dummy)
7259 struct db_context *db;
7260 bool ret = false;
7261 int i;
7263 db = db_open_rbt(NULL);
7265 if (db == NULL) {
7266 d_fprintf(stderr, "db_open_rbt failed\n");
7267 return false;
7270 for (i=0; i<1000; i++) {
7271 char *key, *value;
7273 if (asprintf(&key, "key%ld", random()) == -1) {
7274 goto done;
7276 if (asprintf(&value, "value%ld", random()) == -1) {
7277 SAFE_FREE(key);
7278 goto done;
7281 if (!rbt_testval(db, key, value)) {
7282 SAFE_FREE(key);
7283 SAFE_FREE(value);
7284 goto done;
7287 SAFE_FREE(value);
7288 if (asprintf(&value, "value%ld", random()) == -1) {
7289 SAFE_FREE(key);
7290 goto done;
7293 if (!rbt_testval(db, key, value)) {
7294 SAFE_FREE(key);
7295 SAFE_FREE(value);
7296 goto done;
7299 SAFE_FREE(key);
7300 SAFE_FREE(value);
7303 ret = true;
7305 done:
7306 TALLOC_FREE(db);
7307 return ret;
7310 struct talloc_dict_test {
7311 int content;
7314 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7316 int *count = (int *)priv;
7317 *count += 1;
7318 return 0;
7321 static bool run_local_talloc_dict(int dummy)
7323 struct talloc_dict *dict;
7324 struct talloc_dict_test *t;
7325 int key, count;
7327 dict = talloc_dict_init(talloc_tos());
7328 if (dict == NULL) {
7329 return false;
7332 t = talloc(talloc_tos(), struct talloc_dict_test);
7333 if (t == NULL) {
7334 return false;
7337 key = 1;
7338 t->content = 1;
7339 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7340 return false;
7343 count = 0;
7344 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7345 return false;
7348 if (count != 1) {
7349 return false;
7352 TALLOC_FREE(dict);
7354 return true;
7357 static bool run_local_string_to_sid(int dummy) {
7358 struct dom_sid sid;
7360 if (string_to_sid(&sid, "S--1-5-32-545")) {
7361 printf("allowing S--1-5-32-545\n");
7362 return false;
7364 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7365 printf("allowing S-1-5-32-+545\n");
7366 return false;
7368 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")) {
7369 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7370 return false;
7372 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7373 printf("allowing S-1-5-32-545-abc\n");
7374 return false;
7376 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7377 printf("could not parse S-1-5-32-545\n");
7378 return false;
7380 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7381 printf("mis-parsed S-1-5-32-545 as %s\n",
7382 sid_string_tos(&sid));
7383 return false;
7385 return true;
7388 static bool run_local_binary_to_sid(int dummy) {
7389 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7390 static const char good_binary_sid[] = {
7391 0x1, /* revision number */
7392 15, /* num auths */
7393 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7394 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7395 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7396 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7397 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7398 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7399 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7400 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7401 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7402 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7403 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7404 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7405 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7406 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7407 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7408 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7411 static const char long_binary_sid[] = {
7412 0x1, /* revision number */
7413 15, /* num auths */
7414 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7415 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7416 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7417 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7418 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7419 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7420 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7421 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7422 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7423 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7424 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7425 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7426 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7427 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7428 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7429 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7430 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7431 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7432 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7435 static const char long_binary_sid2[] = {
7436 0x1, /* revision number */
7437 32, /* num auths */
7438 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7439 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7440 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7441 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7442 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7443 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7444 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7445 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7446 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7447 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7448 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7449 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7450 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7451 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7452 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7453 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7454 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7455 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7456 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7457 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7458 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7459 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7460 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7461 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7462 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7463 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7464 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7465 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7466 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7467 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7468 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7469 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7470 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7473 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7474 return false;
7476 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7477 return false;
7479 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7480 return false;
7482 return true;
7485 /* Split a path name into filename and stream name components. Canonicalise
7486 * such that an implicit $DATA token is always explicit.
7488 * The "specification" of this function can be found in the
7489 * run_local_stream_name() function in torture.c, I've tried those
7490 * combinations against a W2k3 server.
7493 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7494 char **pbase, char **pstream)
7496 char *base = NULL;
7497 char *stream = NULL;
7498 char *sname; /* stream name */
7499 const char *stype; /* stream type */
7501 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7503 sname = strchr_m(fname, ':');
7505 if (lp_posix_pathnames() || (sname == NULL)) {
7506 if (pbase != NULL) {
7507 base = talloc_strdup(mem_ctx, fname);
7508 NT_STATUS_HAVE_NO_MEMORY(base);
7510 goto done;
7513 if (pbase != NULL) {
7514 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7515 NT_STATUS_HAVE_NO_MEMORY(base);
7518 sname += 1;
7520 stype = strchr_m(sname, ':');
7522 if (stype == NULL) {
7523 sname = talloc_strdup(mem_ctx, sname);
7524 stype = "$DATA";
7526 else {
7527 if (StrCaseCmp(stype, ":$DATA") != 0) {
7529 * If there is an explicit stream type, so far we only
7530 * allow $DATA. Is there anything else allowed? -- vl
7532 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7533 TALLOC_FREE(base);
7534 return NT_STATUS_OBJECT_NAME_INVALID;
7536 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7537 stype += 1;
7540 if (sname == NULL) {
7541 TALLOC_FREE(base);
7542 return NT_STATUS_NO_MEMORY;
7545 if (sname[0] == '\0') {
7547 * no stream name, so no stream
7549 goto done;
7552 if (pstream != NULL) {
7553 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7554 if (stream == NULL) {
7555 TALLOC_FREE(sname);
7556 TALLOC_FREE(base);
7557 return NT_STATUS_NO_MEMORY;
7560 * upper-case the type field
7562 strupper_m(strchr_m(stream, ':')+1);
7565 done:
7566 if (pbase != NULL) {
7567 *pbase = base;
7569 if (pstream != NULL) {
7570 *pstream = stream;
7572 return NT_STATUS_OK;
7575 static bool test_stream_name(const char *fname, const char *expected_base,
7576 const char *expected_stream,
7577 NTSTATUS expected_status)
7579 NTSTATUS status;
7580 char *base = NULL;
7581 char *stream = NULL;
7583 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7584 if (!NT_STATUS_EQUAL(status, expected_status)) {
7585 goto error;
7588 if (!NT_STATUS_IS_OK(status)) {
7589 return true;
7592 if (base == NULL) goto error;
7594 if (strcmp(expected_base, base) != 0) goto error;
7596 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7597 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7599 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7600 goto error;
7602 TALLOC_FREE(base);
7603 TALLOC_FREE(stream);
7604 return true;
7606 error:
7607 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7608 fname, expected_base ? expected_base : "<NULL>",
7609 expected_stream ? expected_stream : "<NULL>",
7610 nt_errstr(expected_status));
7611 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7612 base ? base : "<NULL>", stream ? stream : "<NULL>",
7613 nt_errstr(status));
7614 TALLOC_FREE(base);
7615 TALLOC_FREE(stream);
7616 return false;
7619 static bool run_local_stream_name(int dummy)
7621 bool ret = true;
7623 ret &= test_stream_name(
7624 "bla", "bla", NULL, NT_STATUS_OK);
7625 ret &= test_stream_name(
7626 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7627 ret &= test_stream_name(
7628 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7629 ret &= test_stream_name(
7630 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7631 ret &= test_stream_name(
7632 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7633 ret &= test_stream_name(
7634 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7635 ret &= test_stream_name(
7636 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7637 ret &= test_stream_name(
7638 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7640 return ret;
7643 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7645 if (a.length != b.length) {
7646 printf("a.length=%d != b.length=%d\n",
7647 (int)a.length, (int)b.length);
7648 return false;
7650 if (memcmp(a.data, b.data, a.length) != 0) {
7651 printf("a.data and b.data differ\n");
7652 return false;
7654 return true;
7657 static bool run_local_memcache(int dummy)
7659 struct memcache *cache;
7660 DATA_BLOB k1, k2;
7661 DATA_BLOB d1, d2, d3;
7662 DATA_BLOB v1, v2, v3;
7664 TALLOC_CTX *mem_ctx;
7665 char *str1, *str2;
7666 size_t size1, size2;
7667 bool ret = false;
7669 cache = memcache_init(NULL, 100);
7671 if (cache == NULL) {
7672 printf("memcache_init failed\n");
7673 return false;
7676 d1 = data_blob_const("d1", 2);
7677 d2 = data_blob_const("d2", 2);
7678 d3 = data_blob_const("d3", 2);
7680 k1 = data_blob_const("d1", 2);
7681 k2 = data_blob_const("d2", 2);
7683 memcache_add(cache, STAT_CACHE, k1, d1);
7684 memcache_add(cache, GETWD_CACHE, k2, d2);
7686 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7687 printf("could not find k1\n");
7688 return false;
7690 if (!data_blob_equal(d1, v1)) {
7691 return false;
7694 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7695 printf("could not find k2\n");
7696 return false;
7698 if (!data_blob_equal(d2, v2)) {
7699 return false;
7702 memcache_add(cache, STAT_CACHE, k1, d3);
7704 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7705 printf("could not find replaced k1\n");
7706 return false;
7708 if (!data_blob_equal(d3, v3)) {
7709 return false;
7712 memcache_add(cache, GETWD_CACHE, k1, d1);
7714 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7715 printf("Did find k2, should have been purged\n");
7716 return false;
7719 TALLOC_FREE(cache);
7721 cache = memcache_init(NULL, 0);
7723 mem_ctx = talloc_init("foo");
7725 str1 = talloc_strdup(mem_ctx, "string1");
7726 str2 = talloc_strdup(mem_ctx, "string2");
7728 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7729 data_blob_string_const("torture"), &str1);
7730 size1 = talloc_total_size(cache);
7732 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7733 data_blob_string_const("torture"), &str2);
7734 size2 = talloc_total_size(cache);
7736 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7738 if (size2 > size1) {
7739 printf("memcache leaks memory!\n");
7740 goto fail;
7743 ret = true;
7744 fail:
7745 TALLOC_FREE(cache);
7746 return ret;
7749 static void wbclient_done(struct tevent_req *req)
7751 wbcErr wbc_err;
7752 struct winbindd_response *wb_resp;
7753 int *i = (int *)tevent_req_callback_data_void(req);
7755 wbc_err = wb_trans_recv(req, req, &wb_resp);
7756 TALLOC_FREE(req);
7757 *i += 1;
7758 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7761 static bool run_local_wbclient(int dummy)
7763 struct event_context *ev;
7764 struct wb_context **wb_ctx;
7765 struct winbindd_request wb_req;
7766 bool result = false;
7767 int i, j;
7769 BlockSignals(True, SIGPIPE);
7771 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7772 if (ev == NULL) {
7773 goto fail;
7776 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7777 if (wb_ctx == NULL) {
7778 goto fail;
7781 ZERO_STRUCT(wb_req);
7782 wb_req.cmd = WINBINDD_PING;
7784 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7786 for (i=0; i<nprocs; i++) {
7787 wb_ctx[i] = wb_context_init(ev, NULL);
7788 if (wb_ctx[i] == NULL) {
7789 goto fail;
7791 for (j=0; j<torture_numops; j++) {
7792 struct tevent_req *req;
7793 req = wb_trans_send(ev, ev, wb_ctx[i],
7794 (j % 2) == 0, &wb_req);
7795 if (req == NULL) {
7796 goto fail;
7798 tevent_req_set_callback(req, wbclient_done, &i);
7802 i = 0;
7804 while (i < nprocs * torture_numops) {
7805 event_loop_once(ev);
7808 result = true;
7809 fail:
7810 TALLOC_FREE(ev);
7811 return result;
7814 static void getaddrinfo_finished(struct tevent_req *req)
7816 char *name = (char *)tevent_req_callback_data_void(req);
7817 struct addrinfo *ainfo;
7818 int res;
7820 res = getaddrinfo_recv(req, &ainfo);
7821 if (res != 0) {
7822 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7823 return;
7825 d_printf("gai(%s) succeeded\n", name);
7826 freeaddrinfo(ainfo);
7829 static bool run_getaddrinfo_send(int dummy)
7831 TALLOC_CTX *frame = talloc_stackframe();
7832 struct fncall_context *ctx;
7833 struct tevent_context *ev;
7834 bool result = false;
7835 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7836 "www.slashdot.org", "heise.de" };
7837 struct tevent_req *reqs[4];
7838 int i;
7840 ev = event_context_init(frame);
7841 if (ev == NULL) {
7842 goto fail;
7845 ctx = fncall_context_init(frame, 4);
7847 for (i=0; i<ARRAY_SIZE(names); i++) {
7848 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7849 NULL);
7850 if (reqs[i] == NULL) {
7851 goto fail;
7853 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7854 (void *)names[i]);
7857 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7858 tevent_loop_once(ev);
7861 result = true;
7862 fail:
7863 TALLOC_FREE(frame);
7864 return result;
7867 static bool dbtrans_inc(struct db_context *db)
7869 struct db_record *rec;
7870 uint32_t *val;
7871 bool ret = false;
7872 NTSTATUS status;
7874 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7875 if (rec == NULL) {
7876 printf(__location__ "fetch_lock failed\n");
7877 return false;
7880 if (rec->value.dsize != sizeof(uint32_t)) {
7881 printf(__location__ "value.dsize = %d\n",
7882 (int)rec->value.dsize);
7883 goto fail;
7886 val = (uint32_t *)rec->value.dptr;
7887 *val += 1;
7889 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7890 sizeof(uint32_t)),
7892 if (!NT_STATUS_IS_OK(status)) {
7893 printf(__location__ "store failed: %s\n",
7894 nt_errstr(status));
7895 goto fail;
7898 ret = true;
7899 fail:
7900 TALLOC_FREE(rec);
7901 return ret;
7904 static bool run_local_dbtrans(int dummy)
7906 struct db_context *db;
7907 struct db_record *rec;
7908 NTSTATUS status;
7909 uint32_t initial;
7910 int res;
7912 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7913 O_RDWR|O_CREAT, 0600);
7914 if (db == NULL) {
7915 printf("Could not open transtest.db\n");
7916 return false;
7919 res = db->transaction_start(db);
7920 if (res == -1) {
7921 printf(__location__ "transaction_start failed\n");
7922 return false;
7925 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7926 if (rec == NULL) {
7927 printf(__location__ "fetch_lock failed\n");
7928 return false;
7931 if (rec->value.dptr == NULL) {
7932 initial = 0;
7933 status = rec->store(
7934 rec, make_tdb_data((uint8_t *)&initial,
7935 sizeof(initial)),
7937 if (!NT_STATUS_IS_OK(status)) {
7938 printf(__location__ "store returned %s\n",
7939 nt_errstr(status));
7940 return false;
7944 TALLOC_FREE(rec);
7946 res = db->transaction_commit(db);
7947 if (res == -1) {
7948 printf(__location__ "transaction_commit failed\n");
7949 return false;
7952 while (true) {
7953 uint32_t val, val2;
7954 int i;
7956 res = db->transaction_start(db);
7957 if (res == -1) {
7958 printf(__location__ "transaction_start failed\n");
7959 break;
7962 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7963 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7964 break;
7967 for (i=0; i<10; i++) {
7968 if (!dbtrans_inc(db)) {
7969 return false;
7973 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7974 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7975 break;
7978 if (val2 != val + 10) {
7979 printf(__location__ "val=%d, val2=%d\n",
7980 (int)val, (int)val2);
7981 break;
7984 printf("val2=%d\r", val2);
7986 res = db->transaction_commit(db);
7987 if (res == -1) {
7988 printf(__location__ "transaction_commit failed\n");
7989 break;
7993 TALLOC_FREE(db);
7994 return true;
7998 * Just a dummy test to be run under a debugger. There's no real way
7999 * to inspect the tevent_select specific function from outside of
8000 * tevent_select.c.
8003 static bool run_local_tevent_select(int dummy)
8005 struct tevent_context *ev;
8006 struct tevent_fd *fd1, *fd2;
8007 bool result = false;
8009 ev = tevent_context_init_byname(NULL, "select");
8010 if (ev == NULL) {
8011 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8012 goto fail;
8015 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8016 if (fd1 == NULL) {
8017 d_fprintf(stderr, "tevent_add_fd failed\n");
8018 goto fail;
8020 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8021 if (fd2 == NULL) {
8022 d_fprintf(stderr, "tevent_add_fd failed\n");
8023 goto fail;
8025 TALLOC_FREE(fd2);
8027 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8028 if (fd2 == NULL) {
8029 d_fprintf(stderr, "tevent_add_fd failed\n");
8030 goto fail;
8033 result = true;
8034 fail:
8035 TALLOC_FREE(ev);
8036 return result;
8039 static double create_procs(bool (*fn)(int), bool *result)
8041 int i, status;
8042 volatile pid_t *child_status;
8043 volatile bool *child_status_out;
8044 int synccount;
8045 int tries = 8;
8046 struct timeval start;
8048 synccount = 0;
8050 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8051 if (!child_status) {
8052 printf("Failed to setup shared memory\n");
8053 return -1;
8056 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8057 if (!child_status_out) {
8058 printf("Failed to setup result status shared memory\n");
8059 return -1;
8062 for (i = 0; i < nprocs; i++) {
8063 child_status[i] = 0;
8064 child_status_out[i] = True;
8067 start = timeval_current();
8069 for (i=0;i<nprocs;i++) {
8070 procnum = i;
8071 if (fork() == 0) {
8072 pid_t mypid = getpid();
8073 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8075 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8077 while (1) {
8078 if (torture_open_connection(&current_cli, i)) break;
8079 if (tries-- == 0) {
8080 printf("pid %d failed to start\n", (int)getpid());
8081 _exit(1);
8083 smb_msleep(10);
8086 child_status[i] = getpid();
8088 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8090 child_status_out[i] = fn(i);
8091 _exit(0);
8095 do {
8096 synccount = 0;
8097 for (i=0;i<nprocs;i++) {
8098 if (child_status[i]) synccount++;
8100 if (synccount == nprocs) break;
8101 smb_msleep(10);
8102 } while (timeval_elapsed(&start) < 30);
8104 if (synccount != nprocs) {
8105 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8106 *result = False;
8107 return timeval_elapsed(&start);
8110 /* start the client load */
8111 start = timeval_current();
8113 for (i=0;i<nprocs;i++) {
8114 child_status[i] = 0;
8117 printf("%d clients started\n", nprocs);
8119 for (i=0;i<nprocs;i++) {
8120 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8123 printf("\n");
8125 for (i=0;i<nprocs;i++) {
8126 if (!child_status_out[i]) {
8127 *result = False;
8130 return timeval_elapsed(&start);
8133 #define FLAG_MULTIPROC 1
8135 static struct {
8136 const char *name;
8137 bool (*fn)(int);
8138 unsigned flags;
8139 } torture_ops[] = {
8140 {"FDPASS", run_fdpasstest, 0},
8141 {"LOCK1", run_locktest1, 0},
8142 {"LOCK2", run_locktest2, 0},
8143 {"LOCK3", run_locktest3, 0},
8144 {"LOCK4", run_locktest4, 0},
8145 {"LOCK5", run_locktest5, 0},
8146 {"LOCK6", run_locktest6, 0},
8147 {"LOCK7", run_locktest7, 0},
8148 {"LOCK8", run_locktest8, 0},
8149 {"LOCK9", run_locktest9, 0},
8150 {"UNLINK", run_unlinktest, 0},
8151 {"BROWSE", run_browsetest, 0},
8152 {"ATTR", run_attrtest, 0},
8153 {"TRANS2", run_trans2test, 0},
8154 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8155 {"TORTURE",run_torture, FLAG_MULTIPROC},
8156 {"RANDOMIPC", run_randomipc, 0},
8157 {"NEGNOWAIT", run_negprot_nowait, 0},
8158 {"NBENCH", run_nbench, 0},
8159 {"NBENCH2", run_nbench2, 0},
8160 {"OPLOCK1", run_oplock1, 0},
8161 {"OPLOCK2", run_oplock2, 0},
8162 {"OPLOCK3", run_oplock3, 0},
8163 {"OPLOCK4", run_oplock4, 0},
8164 {"DIR", run_dirtest, 0},
8165 {"DIR1", run_dirtest1, 0},
8166 {"DIR-CREATETIME", run_dir_createtime, 0},
8167 {"DENY1", torture_denytest1, 0},
8168 {"DENY2", torture_denytest2, 0},
8169 {"TCON", run_tcon_test, 0},
8170 {"TCONDEV", run_tcon_devtype_test, 0},
8171 {"RW1", run_readwritetest, 0},
8172 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8173 {"RW3", run_readwritelarge, 0},
8174 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8175 {"OPEN", run_opentest, 0},
8176 {"POSIX", run_simple_posix_open_test, 0},
8177 {"POSIX-APPEND", run_posix_append, 0},
8178 {"ASYNC-ECHO", run_async_echo, 0},
8179 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8180 { "SHORTNAME-TEST", run_shortname_test, 0},
8181 { "ADDRCHANGE", run_addrchange, 0},
8182 #if 1
8183 {"OPENATTR", run_openattrtest, 0},
8184 #endif
8185 {"XCOPY", run_xcopy, 0},
8186 {"RENAME", run_rename, 0},
8187 {"DELETE", run_deletetest, 0},
8188 {"DELETE-LN", run_deletetest_ln, 0},
8189 {"PROPERTIES", run_properties, 0},
8190 {"MANGLE", torture_mangle, 0},
8191 {"MANGLE1", run_mangle1, 0},
8192 {"W2K", run_w2ktest, 0},
8193 {"TRANS2SCAN", torture_trans2_scan, 0},
8194 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8195 {"UTABLE", torture_utable, 0},
8196 {"CASETABLE", torture_casetable, 0},
8197 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8198 {"PIPE_NUMBER", run_pipe_number, 0},
8199 {"TCON2", run_tcon2_test, 0},
8200 {"IOCTL", torture_ioctl_test, 0},
8201 {"CHKPATH", torture_chkpath_test, 0},
8202 {"FDSESS", run_fdsesstest, 0},
8203 { "EATEST", run_eatest, 0},
8204 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8205 { "CHAIN1", run_chain1, 0},
8206 { "CHAIN2", run_chain2, 0},
8207 { "WINDOWS-WRITE", run_windows_write, 0},
8208 { "CLI_ECHO", run_cli_echo, 0},
8209 { "GETADDRINFO", run_getaddrinfo_send, 0},
8210 { "TLDAP", run_tldap },
8211 { "STREAMERROR", run_streamerror },
8212 { "NOTIFY-BENCH", run_notify_bench },
8213 { "BAD-NBT-SESSION", run_bad_nbt_session },
8214 { "SMB-ANY-CONNECT", run_smb_any_connect },
8215 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8216 { "LOCAL-GENCACHE", run_local_gencache, 0},
8217 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8218 { "LOCAL-BASE64", run_local_base64, 0},
8219 { "LOCAL-RBTREE", run_local_rbtree, 0},
8220 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8221 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8222 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8223 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8224 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8225 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8226 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8227 {NULL, NULL, 0}};
8231 /****************************************************************************
8232 run a specified test or "ALL"
8233 ****************************************************************************/
8234 static bool run_test(const char *name)
8236 bool ret = True;
8237 bool result = True;
8238 bool found = False;
8239 int i;
8240 double t;
8241 if (strequal(name,"ALL")) {
8242 for (i=0;torture_ops[i].name;i++) {
8243 run_test(torture_ops[i].name);
8245 found = True;
8248 for (i=0;torture_ops[i].name;i++) {
8249 fstr_sprintf(randomfname, "\\XX%x",
8250 (unsigned)random());
8252 if (strequal(name, torture_ops[i].name)) {
8253 found = True;
8254 printf("Running %s\n", name);
8255 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8256 t = create_procs(torture_ops[i].fn, &result);
8257 if (!result) {
8258 ret = False;
8259 printf("TEST %s FAILED!\n", name);
8261 } else {
8262 struct timeval start;
8263 start = timeval_current();
8264 if (!torture_ops[i].fn(0)) {
8265 ret = False;
8266 printf("TEST %s FAILED!\n", name);
8268 t = timeval_elapsed(&start);
8270 printf("%s took %g secs\n\n", name, t);
8274 if (!found) {
8275 printf("Did not find a test named %s\n", name);
8276 ret = False;
8279 return ret;
8283 static void usage(void)
8285 int i;
8287 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8288 printf("Please use samba4 torture.\n\n");
8290 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8292 printf("\t-d debuglevel\n");
8293 printf("\t-U user%%pass\n");
8294 printf("\t-k use kerberos\n");
8295 printf("\t-N numprocs\n");
8296 printf("\t-n my_netbios_name\n");
8297 printf("\t-W workgroup\n");
8298 printf("\t-o num_operations\n");
8299 printf("\t-O socket_options\n");
8300 printf("\t-m maximum protocol\n");
8301 printf("\t-L use oplocks\n");
8302 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8303 printf("\t-A showall\n");
8304 printf("\t-p port\n");
8305 printf("\t-s seed\n");
8306 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8307 printf("\n\n");
8309 printf("tests are:");
8310 for (i=0;torture_ops[i].name;i++) {
8311 printf(" %s", torture_ops[i].name);
8313 printf("\n");
8315 printf("default test is ALL\n");
8317 exit(1);
8320 /****************************************************************************
8321 main program
8322 ****************************************************************************/
8323 int main(int argc,char *argv[])
8325 int opt, i;
8326 char *p;
8327 int gotuser = 0;
8328 int gotpass = 0;
8329 bool correct = True;
8330 TALLOC_CTX *frame = talloc_stackframe();
8331 int seed = time(NULL);
8333 #ifdef HAVE_SETBUFFER
8334 setbuffer(stdout, NULL, 0);
8335 #endif
8337 setup_logging("smbtorture", DEBUG_STDOUT);
8339 load_case_tables();
8341 if (is_default_dyn_CONFIGFILE()) {
8342 if(getenv("SMB_CONF_PATH")) {
8343 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8346 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8347 load_interfaces();
8349 if (argc < 2) {
8350 usage();
8353 for(p = argv[1]; *p; p++)
8354 if(*p == '\\')
8355 *p = '/';
8357 if (strncmp(argv[1], "//", 2)) {
8358 usage();
8361 fstrcpy(host, &argv[1][2]);
8362 p = strchr_m(&host[2],'/');
8363 if (!p) {
8364 usage();
8366 *p = 0;
8367 fstrcpy(share, p+1);
8369 fstrcpy(myname, get_myname(talloc_tos()));
8370 if (!*myname) {
8371 fprintf(stderr, "Failed to get my hostname.\n");
8372 return 1;
8375 if (*username == 0 && getenv("LOGNAME")) {
8376 fstrcpy(username,getenv("LOGNAME"));
8379 argc--;
8380 argv++;
8382 fstrcpy(workgroup, lp_workgroup());
8384 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8385 switch (opt) {
8386 case 'p':
8387 port_to_use = atoi(optarg);
8388 break;
8389 case 's':
8390 seed = atoi(optarg);
8391 break;
8392 case 'W':
8393 fstrcpy(workgroup,optarg);
8394 break;
8395 case 'm':
8396 max_protocol = interpret_protocol(optarg, max_protocol);
8397 break;
8398 case 'N':
8399 nprocs = atoi(optarg);
8400 break;
8401 case 'o':
8402 torture_numops = atoi(optarg);
8403 break;
8404 case 'd':
8405 lp_set_cmdline("log level", optarg);
8406 break;
8407 case 'O':
8408 sockops = optarg;
8409 break;
8410 case 'L':
8411 use_oplocks = True;
8412 break;
8413 case 'l':
8414 local_path = optarg;
8415 break;
8416 case 'A':
8417 torture_showall = True;
8418 break;
8419 case 'n':
8420 fstrcpy(myname, optarg);
8421 break;
8422 case 'c':
8423 client_txt = optarg;
8424 break;
8425 case 'e':
8426 do_encrypt = true;
8427 break;
8428 case 'k':
8429 #ifdef HAVE_KRB5
8430 use_kerberos = True;
8431 #else
8432 d_printf("No kerberos support compiled in\n");
8433 exit(1);
8434 #endif
8435 break;
8436 case 'U':
8437 gotuser = 1;
8438 fstrcpy(username,optarg);
8439 p = strchr_m(username,'%');
8440 if (p) {
8441 *p = 0;
8442 fstrcpy(password, p+1);
8443 gotpass = 1;
8445 break;
8446 case 'b':
8447 fstrcpy(multishare_conn_fname, optarg);
8448 use_multishare_conn = True;
8449 break;
8450 case 'B':
8451 torture_blocksize = atoi(optarg);
8452 break;
8453 default:
8454 printf("Unknown option %c (%d)\n", (char)opt, opt);
8455 usage();
8459 d_printf("using seed %d\n", seed);
8461 srandom(seed);
8463 if(use_kerberos && !gotuser) gotpass = True;
8465 while (!gotpass) {
8466 p = getpass("Password:");
8467 if (p) {
8468 fstrcpy(password, p);
8469 gotpass = 1;
8473 printf("host=%s share=%s user=%s myname=%s\n",
8474 host, share, username, myname);
8476 if (argc == optind) {
8477 correct = run_test("ALL");
8478 } else {
8479 for (i=optind;i<argc;i++) {
8480 if (!run_test(argv[i])) {
8481 correct = False;
8486 TALLOC_FREE(frame);
8488 if (correct) {
8489 return(0);
8490 } else {
8491 return(1);