s3-smb Use FILE_ATTRIBUTE_HIDDEN intead of aHIDDEN
[Samba.git] / source3 / torture / torture.c
blobb560040c5e167db2b19b28602077f934989c048b
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"
37 #include "../lib/util/tevent_ntstatus.h"
39 extern char *optarg;
40 extern int optind;
42 static fstring host, workgroup, share, password, username, myname;
43 static int max_protocol = PROTOCOL_NT1;
44 static const char *sockops="TCP_NODELAY";
45 static int nprocs=1;
46 static int port_to_use=0;
47 int torture_numops=100;
48 int torture_blocksize=1024*1024;
49 static int procnum; /* records process count number when forking */
50 static struct cli_state *current_cli;
51 static fstring randomfname;
52 static bool use_oplocks;
53 static bool use_level_II_oplocks;
54 static const char *client_txt = "client_oplocks.txt";
55 static bool use_kerberos;
56 static fstring multishare_conn_fname;
57 static bool use_multishare_conn = False;
58 static bool do_encrypt;
59 static const char *local_path = NULL;
60 static int signing_state = Undefined;
62 bool torture_showall = False;
64 static double create_procs(bool (*fn)(int), bool *result);
67 /* return a pointer to a anonymous shared memory segment of size "size"
68 which will persist across fork() but will disappear when all processes
69 exit
71 The memory is not zeroed
73 This function uses system5 shared memory. It takes advantage of a property
74 that the memory is not destroyed if it is attached when the id is removed
76 void *shm_setup(int size)
78 int shmid;
79 void *ret;
81 #ifdef __QNXNTO__
82 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
83 if (shmid == -1) {
84 printf("can't get shared memory\n");
85 exit(1);
87 shm_unlink("private");
88 if (ftruncate(shmid, size) == -1) {
89 printf("can't set shared memory size\n");
90 exit(1);
92 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
93 if (ret == MAP_FAILED) {
94 printf("can't map shared memory\n");
95 exit(1);
97 #else
98 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
99 if (shmid == -1) {
100 printf("can't get shared memory\n");
101 exit(1);
103 ret = (void *)shmat(shmid, 0, 0);
104 if (!ret || ret == (void *)-1) {
105 printf("can't attach to shared memory\n");
106 return NULL;
108 /* the following releases the ipc, but note that this process
109 and all its children will still have access to the memory, its
110 just that the shmid is no longer valid for other shm calls. This
111 means we don't leave behind lots of shm segments after we exit
113 See Stevens "advanced programming in unix env" for details
115 shmctl(shmid, IPC_RMID, 0);
116 #endif
118 return ret;
121 /********************************************************************
122 Ensure a connection is encrypted.
123 ********************************************************************/
125 static bool force_cli_encryption(struct cli_state *c,
126 const char *sharename)
128 uint16 major, minor;
129 uint32 caplow, caphigh;
130 NTSTATUS status;
132 if (!SERVER_HAS_UNIX_CIFS(c)) {
133 d_printf("Encryption required and "
134 "server that doesn't support "
135 "UNIX extensions - failing connect\n");
136 return false;
139 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
140 &caphigh);
141 if (!NT_STATUS_IS_OK(status)) {
142 d_printf("Encryption required and "
143 "can't get UNIX CIFS extensions "
144 "version from server: %s\n", nt_errstr(status));
145 return false;
148 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
149 d_printf("Encryption required and "
150 "share %s doesn't support "
151 "encryption.\n", sharename);
152 return false;
155 if (c->use_kerberos) {
156 status = cli_gss_smb_encryption_start(c);
157 } else {
158 status = cli_raw_ntlm_smb_encryption_start(c,
159 username,
160 password,
161 workgroup);
164 if (!NT_STATUS_IS_OK(status)) {
165 d_printf("Encryption required and "
166 "setup failed with error %s.\n",
167 nt_errstr(status));
168 return false;
171 return true;
175 static struct cli_state *open_nbt_connection(void)
177 struct nmb_name called, calling;
178 struct sockaddr_storage ss;
179 struct cli_state *c;
180 NTSTATUS status;
182 make_nmb_name(&calling, myname, 0x0);
183 make_nmb_name(&called , host, 0x20);
185 zero_sockaddr(&ss);
187 if (!(c = cli_initialise_ex(signing_state))) {
188 printf("Failed initialize cli_struct to connect with %s\n", host);
189 return NULL;
192 c->port = port_to_use;
194 status = cli_connect(c, host, &ss);
195 if (!NT_STATUS_IS_OK(status)) {
196 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
197 return NULL;
200 c->use_kerberos = use_kerberos;
202 c->timeout = 120000; /* set a really long timeout (2 minutes) */
203 if (use_oplocks) c->use_oplocks = True;
204 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
206 if (!cli_session_request(c, &calling, &called)) {
208 * Well, that failed, try *SMBSERVER ...
209 * However, we must reconnect as well ...
211 status = cli_connect(c, host, &ss);
212 if (!NT_STATUS_IS_OK(status)) {
213 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
214 return NULL;
217 make_nmb_name(&called, "*SMBSERVER", 0x20);
218 if (!cli_session_request(c, &calling, &called)) {
219 printf("%s rejected the session\n",host);
220 printf("We tried with a called name of %s & %s\n",
221 host, "*SMBSERVER");
222 cli_shutdown(c);
223 return NULL;
227 return c;
230 /****************************************************************************
231 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
232 ****************************************************************************/
234 static bool cli_bad_session_request(struct cli_state *cli,
235 struct nmb_name *calling, struct nmb_name *called)
237 char *p;
238 int len = 4;
239 int namelen = 0;
240 char *tmp;
242 memcpy(&(cli->calling), calling, sizeof(*calling));
243 memcpy(&(cli->called ), called , sizeof(*called ));
245 /* put in the destination name */
247 tmp = name_mangle(talloc_tos(), cli->called.name,
248 cli->called.name_type);
249 if (tmp == NULL) {
250 return false;
253 p = cli->outbuf+len;
254 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
255 if (namelen > 0) {
256 memcpy(p, tmp, namelen);
257 len += namelen;
259 TALLOC_FREE(tmp);
261 /* Deliberately corrupt the name len (first byte) */
262 *p = 100;
264 /* and my name */
266 tmp = name_mangle(talloc_tos(), cli->calling.name,
267 cli->calling.name_type);
268 if (tmp == NULL) {
269 return false;
272 p = cli->outbuf+len;
273 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
274 if (namelen > 0) {
275 memcpy(p, tmp, namelen);
276 len += namelen;
278 TALLOC_FREE(tmp);
279 /* Deliberately corrupt the name len (first byte) */
280 *p = 100;
282 /* send a session request (RFC 1002) */
283 /* setup the packet length
284 * Remove four bytes from the length count, since the length
285 * field in the NBT Session Service header counts the number
286 * of bytes which follow. The cli_send_smb() function knows
287 * about this and accounts for those four bytes.
288 * CRH.
290 len -= 4;
291 _smb_setlen(cli->outbuf,len);
292 SCVAL(cli->outbuf,0,0x81);
294 cli_send_smb(cli);
295 DEBUG(5,("Sent session request\n"));
297 if (!cli_receive_smb(cli))
298 return False;
300 if (CVAL(cli->inbuf,0) != 0x82) {
301 /* This is the wrong place to put the error... JRA. */
302 cli->rap_error = CVAL(cli->inbuf,4);
303 return False;
305 return(True);
308 static struct cli_state *open_bad_nbt_connection(void)
310 struct nmb_name called, calling;
311 struct sockaddr_storage ss;
312 struct cli_state *c;
313 NTSTATUS status;
315 make_nmb_name(&calling, myname, 0x0);
316 make_nmb_name(&called , host, 0x20);
318 zero_sockaddr(&ss);
320 if (!(c = cli_initialise_ex(signing_state))) {
321 printf("Failed initialize cli_struct to connect with %s\n", host);
322 return NULL;
325 c->port = 139;
327 status = cli_connect(c, host, &ss);
328 if (!NT_STATUS_IS_OK(status)) {
329 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
330 return NULL;
333 c->timeout = 4000; /* set a short timeout (4 seconds) */
335 if (!cli_bad_session_request(c, &calling, &called)) {
336 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
337 return NULL;
340 return c;
344 /* Insert a NULL at the first separator of the given path and return a pointer
345 * to the remainder of the string.
347 static char *
348 terminate_path_at_separator(char * path)
350 char * p;
352 if (!path) {
353 return NULL;
356 if ((p = strchr_m(path, '/'))) {
357 *p = '\0';
358 return p + 1;
361 if ((p = strchr_m(path, '\\'))) {
362 *p = '\0';
363 return p + 1;
366 /* No separator. */
367 return NULL;
371 parse a //server/share type UNC name
373 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
374 char **hostname, char **sharename)
376 char *p;
378 *hostname = *sharename = NULL;
380 if (strncmp(unc_name, "\\\\", 2) &&
381 strncmp(unc_name, "//", 2)) {
382 return False;
385 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
386 p = terminate_path_at_separator(*hostname);
388 if (p && *p) {
389 *sharename = talloc_strdup(mem_ctx, p);
390 terminate_path_at_separator(*sharename);
393 if (*hostname && *sharename) {
394 return True;
397 TALLOC_FREE(*hostname);
398 TALLOC_FREE(*sharename);
399 return False;
402 static bool torture_open_connection_share(struct cli_state **c,
403 const char *hostname,
404 const char *sharename)
406 int flags = 0;
407 NTSTATUS status;
409 if (use_kerberos)
410 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
411 if (use_oplocks)
412 flags |= CLI_FULL_CONNECTION_OPLOCKS;
413 if (use_level_II_oplocks)
414 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
416 status = cli_full_connection(c, myname,
417 hostname, NULL, port_to_use,
418 sharename, "?????",
419 username, workgroup,
420 password, flags, signing_state);
421 if (!NT_STATUS_IS_OK(status)) {
422 printf("failed to open share connection: //%s/%s port:%d - %s\n",
423 hostname, sharename, port_to_use, nt_errstr(status));
424 return False;
427 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
429 if (do_encrypt) {
430 return force_cli_encryption(*c,
431 sharename);
433 return True;
436 bool torture_open_connection(struct cli_state **c, int conn_index)
438 char **unc_list = NULL;
439 int num_unc_names = 0;
440 bool result;
442 if (use_multishare_conn==True) {
443 char *h, *s;
444 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
445 if (!unc_list || num_unc_names <= 0) {
446 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
447 exit(1);
450 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
451 NULL, &h, &s)) {
452 printf("Failed to parse UNC name %s\n",
453 unc_list[conn_index % num_unc_names]);
454 TALLOC_FREE(unc_list);
455 exit(1);
458 result = torture_open_connection_share(c, h, s);
460 /* h, s were copied earlier */
461 TALLOC_FREE(unc_list);
462 return result;
465 return torture_open_connection_share(c, host, share);
468 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
470 uint16 old_vuid = cli->vuid;
471 fstring old_user_name;
472 size_t passlen = strlen(password);
473 NTSTATUS status;
474 bool ret;
476 fstrcpy(old_user_name, cli->user_name);
477 cli->vuid = 0;
478 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
479 password, passlen,
480 password, passlen,
481 workgroup));
482 *new_vuid = cli->vuid;
483 cli->vuid = old_vuid;
484 status = cli_set_username(cli, old_user_name);
485 if (!NT_STATUS_IS_OK(status)) {
486 return false;
488 return ret;
492 bool torture_close_connection(struct cli_state *c)
494 bool ret = True;
495 NTSTATUS status;
497 status = cli_tdis(c);
498 if (!NT_STATUS_IS_OK(status)) {
499 printf("tdis failed (%s)\n", nt_errstr(status));
500 ret = False;
503 cli_shutdown(c);
505 return ret;
509 /* check if the server produced the expected error code */
510 static bool check_error(int line, struct cli_state *c,
511 uint8 eclass, uint32 ecode, NTSTATUS nterr)
513 if (cli_is_dos_error(c)) {
514 uint8 cclass;
515 uint32 num;
517 /* Check DOS error */
519 cli_dos_error(c, &cclass, &num);
521 if (eclass != cclass || ecode != num) {
522 printf("unexpected error code class=%d code=%d\n",
523 (int)cclass, (int)num);
524 printf(" expected %d/%d %s (line=%d)\n",
525 (int)eclass, (int)ecode, nt_errstr(nterr), line);
526 return False;
529 } else {
530 NTSTATUS status;
532 /* Check NT error */
534 status = cli_nt_error(c);
536 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
537 printf("unexpected error code %s\n", nt_errstr(status));
538 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
539 return False;
543 return True;
547 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
549 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
550 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
552 return True;
556 static bool rw_torture(struct cli_state *c)
558 const char *lockfname = "\\torture.lck";
559 fstring fname;
560 uint16_t fnum;
561 uint16_t fnum2;
562 pid_t pid2, pid = getpid();
563 int i, j;
564 char buf[1024];
565 bool correct = True;
566 NTSTATUS status;
568 memset(buf, '\0', sizeof(buf));
570 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
571 DENY_NONE, &fnum2);
572 if (!NT_STATUS_IS_OK(status)) {
573 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
575 if (!NT_STATUS_IS_OK(status)) {
576 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
577 return False;
580 for (i=0;i<torture_numops;i++) {
581 unsigned n = (unsigned)sys_random()%10;
583 if (i % 10 == 0) {
584 printf("%d\r", i); fflush(stdout);
586 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
588 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
589 return False;
592 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
593 printf("open failed (%s)\n", cli_errstr(c));
594 correct = False;
595 break;
598 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
599 sizeof(pid), NULL);
600 if (!NT_STATUS_IS_OK(status)) {
601 printf("write failed (%s)\n", nt_errstr(status));
602 correct = False;
605 for (j=0;j<50;j++) {
606 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
607 sizeof(pid)+(j*sizeof(buf)),
608 sizeof(buf), NULL);
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("write failed (%s)\n",
611 nt_errstr(status));
612 correct = False;
616 pid2 = 0;
618 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
619 printf("read failed (%s)\n", cli_errstr(c));
620 correct = False;
623 if (pid2 != pid) {
624 printf("data corruption!\n");
625 correct = False;
628 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
629 printf("close failed (%s)\n", cli_errstr(c));
630 correct = False;
633 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
634 printf("unlink failed (%s)\n", cli_errstr(c));
635 correct = False;
638 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
639 printf("unlock failed (%s)\n", cli_errstr(c));
640 correct = False;
644 cli_close(c, fnum2);
645 cli_unlink(c, lockfname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
647 printf("%d\n", i);
649 return correct;
652 static bool run_torture(int dummy)
654 struct cli_state *cli;
655 bool ret;
657 cli = current_cli;
659 cli_sockopt(cli, sockops);
661 ret = rw_torture(cli);
663 if (!torture_close_connection(cli)) {
664 ret = False;
667 return ret;
670 static bool rw_torture3(struct cli_state *c, char *lockfname)
672 uint16_t fnum = (uint16_t)-1;
673 unsigned int i = 0;
674 char buf[131072];
675 char buf_rd[131072];
676 unsigned count;
677 unsigned countprev = 0;
678 ssize_t sent = 0;
679 bool correct = True;
680 NTSTATUS status = NT_STATUS_OK;
682 srandom(1);
683 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
685 SIVAL(buf, i, sys_random());
688 if (procnum == 0)
690 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
691 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
694 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
695 DENY_NONE, &fnum))) {
696 printf("first open read/write of %s failed (%s)\n",
697 lockfname, cli_errstr(c));
698 return False;
701 else
703 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
705 status = cli_open(c, lockfname, O_RDONLY,
706 DENY_NONE, &fnum);
707 if (!NT_STATUS_IS_OK(status)) {
708 break;
710 smb_msleep(10);
712 if (!NT_STATUS_IS_OK(status)) {
713 printf("second open read-only of %s failed (%s)\n",
714 lockfname, cli_errstr(c));
715 return False;
719 i = 0;
720 for (count = 0; count < sizeof(buf); count += sent)
722 if (count >= countprev) {
723 printf("%d %8d\r", i, count);
724 fflush(stdout);
725 i++;
726 countprev += (sizeof(buf) / 20);
729 if (procnum == 0)
731 sent = ((unsigned)sys_random()%(20))+ 1;
732 if (sent > sizeof(buf) - count)
734 sent = sizeof(buf) - count;
737 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
738 count, (size_t)sent, NULL);
739 if (!NT_STATUS_IS_OK(status)) {
740 printf("write failed (%s)\n",
741 nt_errstr(status));
742 correct = False;
745 else
747 sent = cli_read(c, fnum, buf_rd+count, count,
748 sizeof(buf)-count);
749 if (sent < 0)
751 printf("read failed offset:%d size:%ld (%s)\n",
752 count, (unsigned long)sizeof(buf)-count,
753 cli_errstr(c));
754 correct = False;
755 sent = 0;
757 if (sent > 0)
759 if (memcmp(buf_rd+count, buf+count, sent) != 0)
761 printf("read/write compare failed\n");
762 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
763 correct = False;
764 break;
771 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
772 printf("close failed (%s)\n", cli_errstr(c));
773 correct = False;
776 return correct;
779 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
781 const char *lockfname = "\\torture2.lck";
782 uint16_t fnum1;
783 uint16_t fnum2;
784 int i;
785 char buf[131072];
786 char buf_rd[131072];
787 bool correct = True;
788 ssize_t bytes_read;
790 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
791 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
794 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
795 DENY_NONE, &fnum1))) {
796 printf("first open read/write of %s failed (%s)\n",
797 lockfname, cli_errstr(c1));
798 return False;
800 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
801 DENY_NONE, &fnum2))) {
802 printf("second open read-only of %s failed (%s)\n",
803 lockfname, cli_errstr(c2));
804 cli_close(c1, fnum1);
805 return False;
808 for (i=0;i<torture_numops;i++)
810 NTSTATUS status;
811 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
812 if (i % 10 == 0) {
813 printf("%d\r", i); fflush(stdout);
816 generate_random_buffer((unsigned char *)buf, buf_size);
818 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
819 buf_size, NULL);
820 if (!NT_STATUS_IS_OK(status)) {
821 printf("write failed (%s)\n", nt_errstr(status));
822 correct = False;
823 break;
826 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
827 printf("read failed (%s)\n", cli_errstr(c2));
828 printf("read %d, expected %ld\n", (int)bytes_read,
829 (unsigned long)buf_size);
830 correct = False;
831 break;
834 if (memcmp(buf_rd, buf, buf_size) != 0)
836 printf("read/write compare failed\n");
837 correct = False;
838 break;
842 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
843 printf("close failed (%s)\n", cli_errstr(c2));
844 correct = False;
846 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
847 printf("close failed (%s)\n", cli_errstr(c1));
848 correct = False;
851 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
852 printf("unlink failed (%s)\n", cli_errstr(c1));
853 correct = False;
856 return correct;
859 static bool run_readwritetest(int dummy)
861 struct cli_state *cli1, *cli2;
862 bool test1, test2 = False;
864 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
865 return False;
867 cli_sockopt(cli1, sockops);
868 cli_sockopt(cli2, sockops);
870 printf("starting readwritetest\n");
872 test1 = rw_torture2(cli1, cli2);
873 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
875 if (test1) {
876 test2 = rw_torture2(cli1, cli1);
877 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
880 if (!torture_close_connection(cli1)) {
881 test1 = False;
884 if (!torture_close_connection(cli2)) {
885 test2 = False;
888 return (test1 && test2);
891 static bool run_readwritemulti(int dummy)
893 struct cli_state *cli;
894 bool test;
896 cli = current_cli;
898 cli_sockopt(cli, sockops);
900 printf("run_readwritemulti: fname %s\n", randomfname);
901 test = rw_torture3(cli, randomfname);
903 if (!torture_close_connection(cli)) {
904 test = False;
907 return test;
910 static bool run_readwritelarge_internal(int max_xmit_k)
912 static struct cli_state *cli1;
913 uint16_t fnum1;
914 const char *lockfname = "\\large.dat";
915 SMB_OFF_T fsize;
916 char buf[126*1024];
917 bool correct = True;
919 if (!torture_open_connection(&cli1, 0)) {
920 return False;
922 cli_sockopt(cli1, sockops);
923 memset(buf,'\0',sizeof(buf));
925 cli1->max_xmit = max_xmit_k*1024;
927 if (signing_state == Required) {
928 /* Horrible cheat to force
929 multiple signed outstanding
930 packets against a Samba server.
932 cli1->is_samba = false;
935 printf("starting readwritelarge_internal\n");
937 cli_unlink(cli1, lockfname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
939 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
940 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
941 return False;
944 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
946 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
947 cli1, fnum1, NULL, &fsize, NULL, NULL,
948 NULL, NULL, NULL))) {
949 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
950 correct = False;
953 if (fsize == sizeof(buf))
954 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
955 (unsigned long)fsize);
956 else {
957 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
958 (unsigned long)fsize);
959 correct = False;
962 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
963 printf("close failed (%s)\n", cli_errstr(cli1));
964 correct = False;
967 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
968 printf("unlink failed (%s)\n", cli_errstr(cli1));
969 correct = False;
972 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
973 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
974 return False;
977 cli1->max_xmit = 4*1024;
979 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
981 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
982 cli1, fnum1, NULL, &fsize, NULL, NULL,
983 NULL, NULL, NULL))) {
984 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
985 correct = False;
988 if (fsize == sizeof(buf))
989 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
990 (unsigned long)fsize);
991 else {
992 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
993 (unsigned long)fsize);
994 correct = False;
997 #if 0
998 /* ToDo - set allocation. JRA */
999 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1000 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1001 return False;
1003 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1004 NULL, NULL)) {
1005 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1006 correct = False;
1008 if (fsize != 0)
1009 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1010 #endif
1012 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1013 printf("close failed (%s)\n", cli_errstr(cli1));
1014 correct = False;
1017 if (!torture_close_connection(cli1)) {
1018 correct = False;
1020 return correct;
1023 static bool run_readwritelarge(int dummy)
1025 return run_readwritelarge_internal(128);
1028 static bool run_readwritelarge_signtest(int dummy)
1030 bool ret;
1031 signing_state = Required;
1032 ret = run_readwritelarge_internal(2);
1033 signing_state = Undefined;
1034 return ret;
1037 int line_count = 0;
1038 int nbio_id;
1040 #define ival(s) strtol(s, NULL, 0)
1042 /* run a test that simulates an approximate netbench client load */
1043 static bool run_netbench(int client)
1045 struct cli_state *cli;
1046 int i;
1047 char line[1024];
1048 char cname[20];
1049 FILE *f;
1050 const char *params[20];
1051 bool correct = True;
1053 cli = current_cli;
1055 nbio_id = client;
1057 cli_sockopt(cli, sockops);
1059 nb_setup(cli);
1061 slprintf(cname,sizeof(cname)-1, "client%d", client);
1063 f = fopen(client_txt, "r");
1065 if (!f) {
1066 perror(client_txt);
1067 return False;
1070 while (fgets(line, sizeof(line)-1, f)) {
1071 char *saveptr;
1072 line_count++;
1074 line[strlen(line)-1] = 0;
1076 /* printf("[%d] %s\n", line_count, line); */
1078 all_string_sub(line,"client1", cname, sizeof(line));
1080 /* parse the command parameters */
1081 params[0] = strtok_r(line, " ", &saveptr);
1082 i = 0;
1083 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1085 params[i] = "";
1087 if (i < 2) continue;
1089 if (!strncmp(params[0],"SMB", 3)) {
1090 printf("ERROR: You are using a dbench 1 load file\n");
1091 exit(1);
1094 if (!strcmp(params[0],"NTCreateX")) {
1095 nb_createx(params[1], ival(params[2]), ival(params[3]),
1096 ival(params[4]));
1097 } else if (!strcmp(params[0],"Close")) {
1098 nb_close(ival(params[1]));
1099 } else if (!strcmp(params[0],"Rename")) {
1100 nb_rename(params[1], params[2]);
1101 } else if (!strcmp(params[0],"Unlink")) {
1102 nb_unlink(params[1]);
1103 } else if (!strcmp(params[0],"Deltree")) {
1104 nb_deltree(params[1]);
1105 } else if (!strcmp(params[0],"Rmdir")) {
1106 nb_rmdir(params[1]);
1107 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1108 nb_qpathinfo(params[1]);
1109 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1110 nb_qfileinfo(ival(params[1]));
1111 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1112 nb_qfsinfo(ival(params[1]));
1113 } else if (!strcmp(params[0],"FIND_FIRST")) {
1114 nb_findfirst(params[1]);
1115 } else if (!strcmp(params[0],"WriteX")) {
1116 nb_writex(ival(params[1]),
1117 ival(params[2]), ival(params[3]), ival(params[4]));
1118 } else if (!strcmp(params[0],"ReadX")) {
1119 nb_readx(ival(params[1]),
1120 ival(params[2]), ival(params[3]), ival(params[4]));
1121 } else if (!strcmp(params[0],"Flush")) {
1122 nb_flush(ival(params[1]));
1123 } else {
1124 printf("Unknown operation %s\n", params[0]);
1125 exit(1);
1128 fclose(f);
1130 nb_cleanup();
1132 if (!torture_close_connection(cli)) {
1133 correct = False;
1136 return correct;
1140 /* run a test that simulates an approximate netbench client load */
1141 static bool run_nbench(int dummy)
1143 double t;
1144 bool correct = True;
1146 nbio_shmem(nprocs);
1148 nbio_id = -1;
1150 signal(SIGALRM, nb_alarm);
1151 alarm(1);
1152 t = create_procs(run_netbench, &correct);
1153 alarm(0);
1155 printf("\nThroughput %g MB/sec\n",
1156 1.0e-6 * nbio_total() / t);
1157 return correct;
1162 This test checks for two things:
1164 1) correct support for retaining locks over a close (ie. the server
1165 must not use posix semantics)
1166 2) support for lock timeouts
1168 static bool run_locktest1(int dummy)
1170 struct cli_state *cli1, *cli2;
1171 const char *fname = "\\lockt1.lck";
1172 uint16_t fnum1, fnum2, fnum3;
1173 time_t t1, t2;
1174 unsigned lock_timeout;
1176 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1177 return False;
1179 cli_sockopt(cli1, sockops);
1180 cli_sockopt(cli2, sockops);
1182 printf("starting locktest1\n");
1184 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
1186 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1187 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1188 return False;
1190 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1191 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1192 return False;
1194 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1195 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1196 return False;
1199 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1200 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1201 return False;
1205 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1206 printf("lock2 succeeded! This is a locking bug\n");
1207 return False;
1208 } else {
1209 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1210 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1214 lock_timeout = (1 + (random() % 20));
1215 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1216 t1 = time(NULL);
1217 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1218 printf("lock3 succeeded! This is a locking bug\n");
1219 return False;
1220 } else {
1221 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1222 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1224 t2 = time(NULL);
1226 if (ABS(t2 - t1) < lock_timeout-1) {
1227 printf("error: This server appears not to support timed lock requests\n");
1230 printf("server slept for %u seconds for a %u second timeout\n",
1231 (unsigned int)(t2-t1), lock_timeout);
1233 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1234 printf("close1 failed (%s)\n", cli_errstr(cli1));
1235 return False;
1238 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1239 printf("lock4 succeeded! This is a locking bug\n");
1240 return False;
1241 } else {
1242 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1243 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1246 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1247 printf("close2 failed (%s)\n", cli_errstr(cli1));
1248 return False;
1251 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1252 printf("close3 failed (%s)\n", cli_errstr(cli2));
1253 return False;
1256 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1257 printf("unlink failed (%s)\n", cli_errstr(cli1));
1258 return False;
1262 if (!torture_close_connection(cli1)) {
1263 return False;
1266 if (!torture_close_connection(cli2)) {
1267 return False;
1270 printf("Passed locktest1\n");
1271 return True;
1275 this checks to see if a secondary tconx can use open files from an
1276 earlier tconx
1278 static bool run_tcon_test(int dummy)
1280 static struct cli_state *cli;
1281 const char *fname = "\\tcontest.tmp";
1282 uint16 fnum1;
1283 uint16 cnum1, cnum2, cnum3;
1284 uint16 vuid1, vuid2;
1285 char buf[4];
1286 bool ret = True;
1287 NTSTATUS status;
1289 memset(buf, '\0', sizeof(buf));
1291 if (!torture_open_connection(&cli, 0)) {
1292 return False;
1294 cli_sockopt(cli, sockops);
1296 printf("starting tcontest\n");
1298 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
1300 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1301 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1302 return False;
1305 cnum1 = cli->cnum;
1306 vuid1 = cli->vuid;
1308 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1309 if (!NT_STATUS_IS_OK(status)) {
1310 printf("initial write failed (%s)", nt_errstr(status));
1311 return False;
1314 status = cli_tcon_andx(cli, share, "?????",
1315 password, strlen(password)+1);
1316 if (!NT_STATUS_IS_OK(status)) {
1317 printf("%s refused 2nd tree connect (%s)\n", host,
1318 nt_errstr(status));
1319 cli_shutdown(cli);
1320 return False;
1323 cnum2 = cli->cnum;
1324 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1325 vuid2 = cli->vuid + 1;
1327 /* try a write with the wrong tid */
1328 cli->cnum = cnum2;
1330 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1331 if (NT_STATUS_IS_OK(status)) {
1332 printf("* server allows write with wrong TID\n");
1333 ret = False;
1334 } else {
1335 printf("server fails write with wrong TID : %s\n",
1336 nt_errstr(status));
1340 /* try a write with an invalid tid */
1341 cli->cnum = cnum3;
1343 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1344 if (NT_STATUS_IS_OK(status)) {
1345 printf("* server allows write with invalid TID\n");
1346 ret = False;
1347 } else {
1348 printf("server fails write with invalid TID : %s\n",
1349 nt_errstr(status));
1352 /* try a write with an invalid vuid */
1353 cli->vuid = vuid2;
1354 cli->cnum = cnum1;
1356 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1357 if (NT_STATUS_IS_OK(status)) {
1358 printf("* server allows write with invalid VUID\n");
1359 ret = False;
1360 } else {
1361 printf("server fails write with invalid VUID : %s\n",
1362 nt_errstr(status));
1365 cli->cnum = cnum1;
1366 cli->vuid = vuid1;
1368 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1369 printf("close failed (%s)\n", cli_errstr(cli));
1370 return False;
1373 cli->cnum = cnum2;
1375 status = cli_tdis(cli);
1376 if (!NT_STATUS_IS_OK(status)) {
1377 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1378 return False;
1381 cli->cnum = cnum1;
1383 if (!torture_close_connection(cli)) {
1384 return False;
1387 return ret;
1392 checks for old style tcon support
1394 static bool run_tcon2_test(int dummy)
1396 static struct cli_state *cli;
1397 uint16 cnum, max_xmit;
1398 char *service;
1399 NTSTATUS status;
1401 if (!torture_open_connection(&cli, 0)) {
1402 return False;
1404 cli_sockopt(cli, sockops);
1406 printf("starting tcon2 test\n");
1408 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1409 return false;
1412 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1414 SAFE_FREE(service);
1416 if (!NT_STATUS_IS_OK(status)) {
1417 printf("tcon2 failed : %s\n", nt_errstr(status));
1418 } else {
1419 printf("tcon OK : max_xmit=%d cnum=%d\n",
1420 (int)max_xmit, (int)cnum);
1423 if (!torture_close_connection(cli)) {
1424 return False;
1427 printf("Passed tcon2 test\n");
1428 return True;
1431 static bool tcon_devtest(struct cli_state *cli,
1432 const char *myshare, const char *devtype,
1433 const char *return_devtype,
1434 NTSTATUS expected_error)
1436 NTSTATUS status;
1437 bool ret;
1439 status = cli_tcon_andx(cli, myshare, devtype,
1440 password, strlen(password)+1);
1442 if (NT_STATUS_IS_OK(expected_error)) {
1443 if (NT_STATUS_IS_OK(status)) {
1444 if (strcmp(cli->dev, return_devtype) == 0) {
1445 ret = True;
1446 } else {
1447 printf("tconX to share %s with type %s "
1448 "succeeded but returned the wrong "
1449 "device type (got [%s] but should have got [%s])\n",
1450 myshare, devtype, cli->dev, return_devtype);
1451 ret = False;
1453 } else {
1454 printf("tconX to share %s with type %s "
1455 "should have succeeded but failed\n",
1456 myshare, devtype);
1457 ret = False;
1459 cli_tdis(cli);
1460 } else {
1461 if (NT_STATUS_IS_OK(status)) {
1462 printf("tconx to share %s with type %s "
1463 "should have failed but succeeded\n",
1464 myshare, devtype);
1465 ret = False;
1466 } else {
1467 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1468 expected_error)) {
1469 ret = True;
1470 } else {
1471 printf("Returned unexpected error\n");
1472 ret = False;
1476 return ret;
1480 checks for correct tconX support
1482 static bool run_tcon_devtype_test(int dummy)
1484 static struct cli_state *cli1 = NULL;
1485 int flags = 0;
1486 NTSTATUS status;
1487 bool ret = True;
1489 status = cli_full_connection(&cli1, myname,
1490 host, NULL, port_to_use,
1491 NULL, NULL,
1492 username, workgroup,
1493 password, flags, signing_state);
1495 if (!NT_STATUS_IS_OK(status)) {
1496 printf("could not open connection\n");
1497 return False;
1500 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1501 ret = False;
1503 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1504 ret = False;
1506 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1507 ret = False;
1509 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1510 ret = False;
1512 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1513 ret = False;
1515 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1516 ret = False;
1518 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1519 ret = False;
1521 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1522 ret = False;
1524 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1525 ret = False;
1527 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1528 ret = False;
1530 cli_shutdown(cli1);
1532 if (ret)
1533 printf("Passed tcondevtest\n");
1535 return ret;
1540 This test checks that
1542 1) the server supports multiple locking contexts on the one SMB
1543 connection, distinguished by PID.
1545 2) the server correctly fails overlapping locks made by the same PID (this
1546 goes against POSIX behaviour, which is why it is tricky to implement)
1548 3) the server denies unlock requests by an incorrect client PID
1550 static bool run_locktest2(int dummy)
1552 static struct cli_state *cli;
1553 const char *fname = "\\lockt2.lck";
1554 uint16_t fnum1, fnum2, fnum3;
1555 bool correct = True;
1557 if (!torture_open_connection(&cli, 0)) {
1558 return False;
1561 cli_sockopt(cli, sockops);
1563 printf("starting locktest2\n");
1565 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
1567 cli_setpid(cli, 1);
1569 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1570 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1571 return False;
1574 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1575 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1576 return False;
1579 cli_setpid(cli, 2);
1581 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1582 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1583 return False;
1586 cli_setpid(cli, 1);
1588 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1589 printf("lock1 failed (%s)\n", cli_errstr(cli));
1590 return False;
1593 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1594 printf("WRITE lock1 succeeded! This is a locking bug\n");
1595 correct = False;
1596 } else {
1597 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1598 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1601 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1602 printf("WRITE lock2 succeeded! This is a locking bug\n");
1603 correct = False;
1604 } else {
1605 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1606 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1609 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1610 printf("READ lock2 succeeded! This is a locking bug\n");
1611 correct = False;
1612 } else {
1613 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1614 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1617 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1618 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1620 cli_setpid(cli, 2);
1621 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1622 printf("unlock at 100 succeeded! This is a locking bug\n");
1623 correct = False;
1626 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1627 printf("unlock1 succeeded! This is a locking bug\n");
1628 correct = False;
1629 } else {
1630 if (!check_error(__LINE__, cli,
1631 ERRDOS, ERRlock,
1632 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1635 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1636 printf("unlock2 succeeded! This is a locking bug\n");
1637 correct = False;
1638 } else {
1639 if (!check_error(__LINE__, cli,
1640 ERRDOS, ERRlock,
1641 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1644 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1645 printf("lock3 succeeded! This is a locking bug\n");
1646 correct = False;
1647 } else {
1648 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1651 cli_setpid(cli, 1);
1653 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1654 printf("close1 failed (%s)\n", cli_errstr(cli));
1655 return False;
1658 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1659 printf("close2 failed (%s)\n", cli_errstr(cli));
1660 return False;
1663 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1664 printf("close3 failed (%s)\n", cli_errstr(cli));
1665 return False;
1668 if (!torture_close_connection(cli)) {
1669 correct = False;
1672 printf("locktest2 finished\n");
1674 return correct;
1679 This test checks that
1681 1) the server supports the full offset range in lock requests
1683 static bool run_locktest3(int dummy)
1685 static struct cli_state *cli1, *cli2;
1686 const char *fname = "\\lockt3.lck";
1687 uint16_t fnum1, fnum2;
1688 int i;
1689 uint32 offset;
1690 bool correct = True;
1692 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1694 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1695 return False;
1697 cli_sockopt(cli1, sockops);
1698 cli_sockopt(cli2, sockops);
1700 printf("starting locktest3\n");
1702 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
1704 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1705 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1706 return False;
1708 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1709 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1710 return False;
1713 for (offset=i=0;i<torture_numops;i++) {
1714 NEXT_OFFSET;
1715 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1716 printf("lock1 %d failed (%s)\n",
1718 cli_errstr(cli1));
1719 return False;
1722 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1723 printf("lock2 %d failed (%s)\n",
1725 cli_errstr(cli1));
1726 return False;
1730 for (offset=i=0;i<torture_numops;i++) {
1731 NEXT_OFFSET;
1733 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1734 printf("error: lock1 %d succeeded!\n", i);
1735 return False;
1738 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1739 printf("error: lock2 %d succeeded!\n", i);
1740 return False;
1743 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1744 printf("error: lock3 %d succeeded!\n", i);
1745 return False;
1748 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1749 printf("error: lock4 %d succeeded!\n", i);
1750 return False;
1754 for (offset=i=0;i<torture_numops;i++) {
1755 NEXT_OFFSET;
1757 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1758 printf("unlock1 %d failed (%s)\n",
1760 cli_errstr(cli1));
1761 return False;
1764 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1765 printf("unlock2 %d failed (%s)\n",
1767 cli_errstr(cli1));
1768 return False;
1772 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1773 printf("close1 failed (%s)\n", cli_errstr(cli1));
1774 return False;
1777 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1778 printf("close2 failed (%s)\n", cli_errstr(cli2));
1779 return False;
1782 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1783 printf("unlink failed (%s)\n", cli_errstr(cli1));
1784 return False;
1787 if (!torture_close_connection(cli1)) {
1788 correct = False;
1791 if (!torture_close_connection(cli2)) {
1792 correct = False;
1795 printf("finished locktest3\n");
1797 return correct;
1800 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1801 printf("** "); correct = False; \
1805 looks at overlapping locks
1807 static bool run_locktest4(int dummy)
1809 static struct cli_state *cli1, *cli2;
1810 const char *fname = "\\lockt4.lck";
1811 uint16_t fnum1, fnum2, f;
1812 bool ret;
1813 char buf[1000];
1814 bool correct = True;
1815 NTSTATUS status;
1817 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1818 return False;
1821 cli_sockopt(cli1, sockops);
1822 cli_sockopt(cli2, sockops);
1824 printf("starting locktest4\n");
1826 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
1828 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1829 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1831 memset(buf, 0, sizeof(buf));
1833 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1834 NULL);
1835 if (!NT_STATUS_IS_OK(status)) {
1836 printf("Failed to create file: %s\n", nt_errstr(status));
1837 correct = False;
1838 goto fail;
1841 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1842 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1843 EXPECTED(ret, False);
1844 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1846 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1847 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1848 EXPECTED(ret, True);
1849 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1851 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1852 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1853 EXPECTED(ret, False);
1854 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1856 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1857 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1858 EXPECTED(ret, True);
1859 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1861 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1862 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1863 EXPECTED(ret, False);
1864 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1866 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1867 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1868 EXPECTED(ret, True);
1869 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1871 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1872 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1873 EXPECTED(ret, True);
1874 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1876 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1877 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1878 EXPECTED(ret, False);
1879 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1881 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1882 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1883 EXPECTED(ret, False);
1884 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1886 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1887 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1888 EXPECTED(ret, True);
1889 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1891 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1892 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1893 EXPECTED(ret, False);
1894 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1896 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1897 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1898 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1899 EXPECTED(ret, False);
1900 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1903 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1904 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1905 EXPECTED(ret, False);
1906 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1908 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1909 if (ret) {
1910 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1911 NULL);
1912 ret = NT_STATUS_IS_OK(status);
1914 EXPECTED(ret, False);
1915 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1918 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1919 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1920 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1921 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1922 EXPECTED(ret, True);
1923 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1926 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1927 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1928 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1929 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1930 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1931 150, 4, NULL))) &&
1932 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1933 EXPECTED(ret, True);
1934 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1936 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1937 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1938 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1939 160, 4, NULL)) &&
1940 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1941 EXPECTED(ret, True);
1942 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1944 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1945 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1946 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1947 170, 4, NULL)) &&
1948 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1949 EXPECTED(ret, True);
1950 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1952 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1953 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1954 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1955 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1956 190, 4, NULL)) &&
1957 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1958 EXPECTED(ret, True);
1959 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1961 cli_close(cli1, fnum1);
1962 cli_close(cli2, fnum2);
1963 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1964 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1965 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1966 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1967 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1968 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1969 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1970 cli_close(cli1, f);
1971 cli_close(cli1, fnum1);
1972 EXPECTED(ret, True);
1973 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1975 fail:
1976 cli_close(cli1, fnum1);
1977 cli_close(cli2, fnum2);
1978 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
1979 torture_close_connection(cli1);
1980 torture_close_connection(cli2);
1982 printf("finished locktest4\n");
1983 return correct;
1987 looks at lock upgrade/downgrade.
1989 static bool run_locktest5(int dummy)
1991 static struct cli_state *cli1, *cli2;
1992 const char *fname = "\\lockt5.lck";
1993 uint16_t fnum1, fnum2, fnum3;
1994 bool ret;
1995 char buf[1000];
1996 bool correct = True;
1997 NTSTATUS status;
1999 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2000 return False;
2003 cli_sockopt(cli1, sockops);
2004 cli_sockopt(cli2, sockops);
2006 printf("starting locktest5\n");
2008 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2010 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2011 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2012 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2014 memset(buf, 0, sizeof(buf));
2016 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2017 NULL);
2018 if (!NT_STATUS_IS_OK(status)) {
2019 printf("Failed to create file: %s\n", nt_errstr(status));
2020 correct = False;
2021 goto fail;
2024 /* Check for NT bug... */
2025 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2026 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2027 cli_close(cli1, fnum1);
2028 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2029 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2030 EXPECTED(ret, True);
2031 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2032 cli_close(cli1, fnum1);
2033 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2034 cli_unlock(cli1, fnum3, 0, 1);
2036 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2037 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2038 EXPECTED(ret, True);
2039 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2041 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2042 EXPECTED(ret, False);
2044 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2046 /* Unlock the process 2 lock. */
2047 cli_unlock(cli2, fnum2, 0, 4);
2049 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2050 EXPECTED(ret, False);
2052 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2054 /* Unlock the process 1 fnum3 lock. */
2055 cli_unlock(cli1, fnum3, 0, 4);
2057 /* Stack 2 more locks here. */
2058 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2059 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2061 EXPECTED(ret, True);
2062 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2064 /* Unlock the first process lock, then check this was the WRITE lock that was
2065 removed. */
2067 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2068 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2070 EXPECTED(ret, True);
2071 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2073 /* Unlock the process 2 lock. */
2074 cli_unlock(cli2, fnum2, 0, 4);
2076 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2078 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2079 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2080 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2082 EXPECTED(ret, True);
2083 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2085 /* Ensure the next unlock fails. */
2086 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2087 EXPECTED(ret, False);
2088 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2090 /* Ensure connection 2 can get a write lock. */
2091 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2092 EXPECTED(ret, True);
2094 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2097 fail:
2098 cli_close(cli1, fnum1);
2099 cli_close(cli2, fnum2);
2100 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2101 if (!torture_close_connection(cli1)) {
2102 correct = False;
2104 if (!torture_close_connection(cli2)) {
2105 correct = False;
2108 printf("finished locktest5\n");
2110 return correct;
2114 tries the unusual lockingX locktype bits
2116 static bool run_locktest6(int dummy)
2118 static struct cli_state *cli;
2119 const char *fname[1] = { "\\lock6.txt" };
2120 int i;
2121 uint16_t fnum;
2122 NTSTATUS status;
2124 if (!torture_open_connection(&cli, 0)) {
2125 return False;
2128 cli_sockopt(cli, sockops);
2130 printf("starting locktest6\n");
2132 for (i=0;i<1;i++) {
2133 printf("Testing %s\n", fname[i]);
2135 cli_unlink(cli, fname[i], aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2137 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2138 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2139 cli_close(cli, fnum);
2140 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2142 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2143 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2144 cli_close(cli, fnum);
2145 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2147 cli_unlink(cli, fname[i], aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2150 torture_close_connection(cli);
2152 printf("finished locktest6\n");
2153 return True;
2156 static bool run_locktest7(int dummy)
2158 struct cli_state *cli1;
2159 const char *fname = "\\lockt7.lck";
2160 uint16_t fnum1;
2161 char buf[200];
2162 bool correct = False;
2163 NTSTATUS status;
2165 if (!torture_open_connection(&cli1, 0)) {
2166 return False;
2169 cli_sockopt(cli1, sockops);
2171 printf("starting locktest7\n");
2173 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2175 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2177 memset(buf, 0, sizeof(buf));
2179 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2180 NULL);
2181 if (!NT_STATUS_IS_OK(status)) {
2182 printf("Failed to create file: %s\n", nt_errstr(status));
2183 goto fail;
2186 cli_setpid(cli1, 1);
2188 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2189 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2190 goto fail;
2191 } else {
2192 printf("pid1 successfully locked range 130:4 for READ\n");
2195 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2196 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2197 goto fail;
2198 } else {
2199 printf("pid1 successfully read the range 130:4\n");
2202 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2203 if (!NT_STATUS_IS_OK(status)) {
2204 printf("pid1 unable to write to the range 130:4, error was "
2205 "%s\n", nt_errstr(status));
2206 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2207 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2208 goto fail;
2210 } else {
2211 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2212 goto fail;
2215 cli_setpid(cli1, 2);
2217 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2218 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2219 } else {
2220 printf("pid2 successfully read the range 130:4\n");
2223 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2224 if (!NT_STATUS_IS_OK(status)) {
2225 printf("pid2 unable to write to the range 130:4, error was "
2226 "%s\n", nt_errstr(status));
2227 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2228 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2229 goto fail;
2231 } else {
2232 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2233 goto fail;
2236 cli_setpid(cli1, 1);
2237 cli_unlock(cli1, fnum1, 130, 4);
2239 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2240 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2241 goto fail;
2242 } else {
2243 printf("pid1 successfully locked range 130:4 for WRITE\n");
2246 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2247 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2248 goto fail;
2249 } else {
2250 printf("pid1 successfully read the range 130:4\n");
2253 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2254 if (!NT_STATUS_IS_OK(status)) {
2255 printf("pid1 unable to write to the range 130:4, error was "
2256 "%s\n", nt_errstr(status));
2257 goto fail;
2258 } else {
2259 printf("pid1 successfully wrote to the range 130:4\n");
2262 cli_setpid(cli1, 2);
2264 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2265 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2266 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2267 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2268 goto fail;
2270 } else {
2271 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2272 goto fail;
2275 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2276 if (!NT_STATUS_IS_OK(status)) {
2277 printf("pid2 unable to write to the range 130:4, error was "
2278 "%s\n", nt_errstr(status));
2279 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2280 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2281 goto fail;
2283 } else {
2284 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2285 goto fail;
2288 cli_unlock(cli1, fnum1, 130, 0);
2289 correct = True;
2291 fail:
2292 cli_close(cli1, fnum1);
2293 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2294 torture_close_connection(cli1);
2296 printf("finished locktest7\n");
2297 return correct;
2301 * This demonstrates a problem with our use of GPFS share modes: A file
2302 * descriptor sitting in the pending close queue holding a GPFS share mode
2303 * blocks opening a file another time. Happens with Word 2007 temp files.
2304 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2305 * open is denied with NT_STATUS_SHARING_VIOLATION.
2308 static bool run_locktest8(int dummy)
2310 struct cli_state *cli1;
2311 const char *fname = "\\lockt8.lck";
2312 uint16_t fnum1, fnum2;
2313 char buf[200];
2314 bool correct = False;
2315 NTSTATUS status;
2317 if (!torture_open_connection(&cli1, 0)) {
2318 return False;
2321 cli_sockopt(cli1, sockops);
2323 printf("starting locktest8\n");
2325 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2327 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2328 &fnum1);
2329 if (!NT_STATUS_IS_OK(status)) {
2330 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2331 return false;
2334 memset(buf, 0, sizeof(buf));
2336 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2337 if (!NT_STATUS_IS_OK(status)) {
2338 d_fprintf(stderr, "cli_open second time returned %s\n",
2339 cli_errstr(cli1));
2340 goto fail;
2343 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2344 printf("Unable to apply read lock on range 1:1, error was "
2345 "%s\n", cli_errstr(cli1));
2346 goto fail;
2349 status = cli_close(cli1, fnum1);
2350 if (!NT_STATUS_IS_OK(status)) {
2351 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2352 goto fail;
2355 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 d_fprintf(stderr, "cli_open third time returned %s\n",
2358 cli_errstr(cli1));
2359 goto fail;
2362 correct = true;
2364 fail:
2365 cli_close(cli1, fnum1);
2366 cli_close(cli1, fnum2);
2367 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2368 torture_close_connection(cli1);
2370 printf("finished locktest8\n");
2371 return correct;
2375 * This test is designed to be run in conjunction with
2376 * external NFS or POSIX locks taken in the filesystem.
2377 * It checks that the smbd server will block until the
2378 * lock is released and then acquire it. JRA.
2381 static bool got_alarm;
2382 static int alarm_fd;
2384 static void alarm_handler(int dummy)
2386 got_alarm = True;
2389 static void alarm_handler_parent(int dummy)
2391 close(alarm_fd);
2394 static void do_local_lock(int read_fd, int write_fd)
2396 int fd;
2397 char c = '\0';
2398 struct flock lock;
2399 const char *local_pathname = NULL;
2400 int ret;
2402 local_pathname = talloc_asprintf(talloc_tos(),
2403 "%s/lockt9.lck", local_path);
2404 if (!local_pathname) {
2405 printf("child: alloc fail\n");
2406 exit(1);
2409 unlink(local_pathname);
2410 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2411 if (fd == -1) {
2412 printf("child: open of %s failed %s.\n",
2413 local_pathname, strerror(errno));
2414 exit(1);
2417 /* Now take a fcntl lock. */
2418 lock.l_type = F_WRLCK;
2419 lock.l_whence = SEEK_SET;
2420 lock.l_start = 0;
2421 lock.l_len = 4;
2422 lock.l_pid = getpid();
2424 ret = fcntl(fd,F_SETLK,&lock);
2425 if (ret == -1) {
2426 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2427 local_pathname, strerror(errno));
2428 exit(1);
2429 } else {
2430 printf("child: got lock 0:4 on file %s.\n",
2431 local_pathname );
2432 fflush(stdout);
2435 CatchSignal(SIGALRM, alarm_handler);
2436 alarm(5);
2437 /* Signal the parent. */
2438 if (write(write_fd, &c, 1) != 1) {
2439 printf("child: start signal fail %s.\n",
2440 strerror(errno));
2441 exit(1);
2443 alarm(0);
2445 alarm(10);
2446 /* Wait for the parent to be ready. */
2447 if (read(read_fd, &c, 1) != 1) {
2448 printf("child: reply signal fail %s.\n",
2449 strerror(errno));
2450 exit(1);
2452 alarm(0);
2454 sleep(5);
2455 close(fd);
2456 printf("child: released lock 0:4 on file %s.\n",
2457 local_pathname );
2458 fflush(stdout);
2459 exit(0);
2462 static bool run_locktest9(int dummy)
2464 struct cli_state *cli1;
2465 const char *fname = "\\lockt9.lck";
2466 uint16_t fnum;
2467 bool correct = False;
2468 int pipe_in[2], pipe_out[2];
2469 pid_t child_pid;
2470 char c = '\0';
2471 int ret;
2472 struct timeval start;
2473 double seconds;
2474 NTSTATUS status;
2476 printf("starting locktest9\n");
2478 if (local_path == NULL) {
2479 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2480 return false;
2483 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2484 return false;
2487 child_pid = fork();
2488 if (child_pid == -1) {
2489 return false;
2492 if (child_pid == 0) {
2493 /* Child. */
2494 do_local_lock(pipe_out[0], pipe_in[1]);
2495 exit(0);
2498 close(pipe_out[0]);
2499 close(pipe_in[1]);
2500 pipe_out[0] = -1;
2501 pipe_in[1] = -1;
2503 /* Parent. */
2504 ret = read(pipe_in[0], &c, 1);
2505 if (ret != 1) {
2506 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2507 strerror(errno));
2508 return false;
2511 if (!torture_open_connection(&cli1, 0)) {
2512 return false;
2515 cli_sockopt(cli1, sockops);
2517 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2518 &fnum);
2519 if (!NT_STATUS_IS_OK(status)) {
2520 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2521 return false;
2524 /* Ensure the child has the lock. */
2525 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2526 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2527 goto fail;
2528 } else {
2529 d_printf("Child has the lock.\n");
2532 /* Tell the child to wait 5 seconds then exit. */
2533 ret = write(pipe_out[1], &c, 1);
2534 if (ret != 1) {
2535 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2536 strerror(errno));
2537 goto fail;
2540 /* Wait 20 seconds for the lock. */
2541 alarm_fd = cli1->fd;
2542 CatchSignal(SIGALRM, alarm_handler_parent);
2543 alarm(20);
2545 start = timeval_current();
2547 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2548 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2549 "%s\n", cli_errstr(cli1));
2550 goto fail_nofd;
2552 alarm(0);
2554 seconds = timeval_elapsed(&start);
2556 printf("Parent got the lock after %.2f seconds.\n",
2557 seconds);
2559 status = cli_close(cli1, fnum);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2562 goto fail;
2565 correct = true;
2567 fail:
2568 cli_close(cli1, fnum);
2569 torture_close_connection(cli1);
2571 fail_nofd:
2573 printf("finished locktest9\n");
2574 return correct;
2578 test whether fnums and tids open on one VC are available on another (a major
2579 security hole)
2581 static bool run_fdpasstest(int dummy)
2583 struct cli_state *cli1, *cli2;
2584 const char *fname = "\\fdpass.tst";
2585 uint16_t fnum1;
2586 char buf[1024];
2587 NTSTATUS status;
2589 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2590 return False;
2592 cli_sockopt(cli1, sockops);
2593 cli_sockopt(cli2, sockops);
2595 printf("starting fdpasstest\n");
2597 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2599 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2600 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2601 return False;
2604 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"hello world\n", 0,
2605 13, NULL);
2606 if (!NT_STATUS_IS_OK(status)) {
2607 printf("write failed (%s)\n", nt_errstr(status));
2608 return False;
2611 cli2->vuid = cli1->vuid;
2612 cli2->cnum = cli1->cnum;
2613 cli2->pid = cli1->pid;
2615 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2616 printf("read succeeded! nasty security hole [%s]\n",
2617 buf);
2618 return False;
2621 cli_close(cli1, fnum1);
2622 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2624 torture_close_connection(cli1);
2625 torture_close_connection(cli2);
2627 printf("finished fdpasstest\n");
2628 return True;
2631 static bool run_fdsesstest(int dummy)
2633 struct cli_state *cli;
2634 uint16 new_vuid;
2635 uint16 saved_vuid;
2636 uint16 new_cnum;
2637 uint16 saved_cnum;
2638 const char *fname = "\\fdsess.tst";
2639 const char *fname1 = "\\fdsess1.tst";
2640 uint16_t fnum1;
2641 uint16_t fnum2;
2642 char buf[1024];
2643 bool ret = True;
2644 NTSTATUS status;
2646 if (!torture_open_connection(&cli, 0))
2647 return False;
2648 cli_sockopt(cli, sockops);
2650 if (!torture_cli_session_setup2(cli, &new_vuid))
2651 return False;
2653 saved_cnum = cli->cnum;
2654 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2655 return False;
2656 new_cnum = cli->cnum;
2657 cli->cnum = saved_cnum;
2659 printf("starting fdsesstest\n");
2661 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2662 cli_unlink(cli, fname1, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2664 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2665 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2666 return False;
2669 status = cli_writeall(cli, fnum1, 0, (uint8_t *)"hello world\n", 0, 13,
2670 NULL);
2671 if (!NT_STATUS_IS_OK(status)) {
2672 printf("write failed (%s)\n", nt_errstr(status));
2673 return False;
2676 saved_vuid = cli->vuid;
2677 cli->vuid = new_vuid;
2679 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2680 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2681 buf);
2682 ret = False;
2684 /* Try to open a file with different vuid, samba cnum. */
2685 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2686 printf("create with different vuid, same cnum succeeded.\n");
2687 cli_close(cli, fnum2);
2688 cli_unlink(cli, fname1, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2689 } else {
2690 printf("create with different vuid, same cnum failed.\n");
2691 printf("This will cause problems with service clients.\n");
2692 ret = False;
2695 cli->vuid = saved_vuid;
2697 /* Try with same vuid, different cnum. */
2698 cli->cnum = new_cnum;
2700 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2701 printf("read succeeded with different cnum![%s]\n",
2702 buf);
2703 ret = False;
2706 cli->cnum = saved_cnum;
2707 cli_close(cli, fnum1);
2708 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2710 torture_close_connection(cli);
2712 printf("finished fdsesstest\n");
2713 return ret;
2717 This test checks that
2719 1) the server does not allow an unlink on a file that is open
2721 static bool run_unlinktest(int dummy)
2723 struct cli_state *cli;
2724 const char *fname = "\\unlink.tst";
2725 uint16_t fnum;
2726 bool correct = True;
2728 if (!torture_open_connection(&cli, 0)) {
2729 return False;
2732 cli_sockopt(cli, sockops);
2734 printf("starting unlink test\n");
2736 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2738 cli_setpid(cli, 1);
2740 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2741 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2742 return False;
2745 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2746 printf("error: server allowed unlink on an open file\n");
2747 correct = False;
2748 } else {
2749 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2750 NT_STATUS_SHARING_VIOLATION);
2753 cli_close(cli, fnum);
2754 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
2756 if (!torture_close_connection(cli)) {
2757 correct = False;
2760 printf("unlink test finished\n");
2762 return correct;
2767 test how many open files this server supports on the one socket
2769 static bool run_maxfidtest(int dummy)
2771 struct cli_state *cli;
2772 const char *ftemplate = "\\maxfid.%d.%d";
2773 fstring fname;
2774 uint16_t fnums[0x11000];
2775 int i;
2776 int retries=4;
2777 bool correct = True;
2779 cli = current_cli;
2781 if (retries <= 0) {
2782 printf("failed to connect\n");
2783 return False;
2786 cli_sockopt(cli, sockops);
2788 for (i=0; i<0x11000; i++) {
2789 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2790 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2791 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2792 printf("open of %s failed (%s)\n",
2793 fname, cli_errstr(cli));
2794 printf("maximum fnum is %d\n", i);
2795 break;
2797 printf("%6d\r", i);
2799 printf("%6d\n", i);
2800 i--;
2802 printf("cleaning up\n");
2803 for (;i>=0;i--) {
2804 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2805 cli_close(cli, fnums[i]);
2806 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2807 printf("unlink of %s failed (%s)\n",
2808 fname, cli_errstr(cli));
2809 correct = False;
2811 printf("%6d\r", i);
2813 printf("%6d\n", 0);
2815 printf("maxfid test finished\n");
2816 if (!torture_close_connection(cli)) {
2817 correct = False;
2819 return correct;
2822 /* generate a random buffer */
2823 static void rand_buf(char *buf, int len)
2825 while (len--) {
2826 *buf = (char)sys_random();
2827 buf++;
2831 /* send smb negprot commands, not reading the response */
2832 static bool run_negprot_nowait(int dummy)
2834 struct tevent_context *ev;
2835 int i;
2836 struct cli_state *cli;
2837 bool correct = True;
2839 printf("starting negprot nowait test\n");
2841 ev = tevent_context_init(talloc_tos());
2842 if (ev == NULL) {
2843 return false;
2846 if (!(cli = open_nbt_connection())) {
2847 TALLOC_FREE(ev);
2848 return False;
2851 for (i=0;i<50000;i++) {
2852 struct tevent_req *req;
2854 req = cli_negprot_send(ev, ev, cli);
2855 if (req == NULL) {
2856 TALLOC_FREE(ev);
2857 return false;
2859 if (!tevent_req_poll(req, ev)) {
2860 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2861 strerror(errno));
2862 TALLOC_FREE(ev);
2863 return false;
2865 TALLOC_FREE(req);
2868 if (torture_close_connection(cli)) {
2869 correct = False;
2872 printf("finished negprot nowait test\n");
2874 return correct;
2877 /* send smb negprot commands, not reading the response */
2878 static bool run_bad_nbt_session(int dummy)
2880 static struct cli_state *cli;
2882 printf("starting bad nbt session test\n");
2884 if (!(cli = open_bad_nbt_connection())) {
2885 return False;
2888 cli_shutdown(cli);
2889 printf("finished bad nbt session test\n");
2890 return true;
2893 /* send random IPC commands */
2894 static bool run_randomipc(int dummy)
2896 char *rparam = NULL;
2897 char *rdata = NULL;
2898 unsigned int rdrcnt,rprcnt;
2899 char param[1024];
2900 int api, param_len, i;
2901 struct cli_state *cli;
2902 bool correct = True;
2903 int count = 50000;
2905 printf("starting random ipc test\n");
2907 if (!torture_open_connection(&cli, 0)) {
2908 return False;
2911 for (i=0;i<count;i++) {
2912 api = sys_random() % 500;
2913 param_len = (sys_random() % 64);
2915 rand_buf(param, param_len);
2917 SSVAL(param,0,api);
2919 cli_api(cli,
2920 param, param_len, 8,
2921 NULL, 0, BUFFER_SIZE,
2922 &rparam, &rprcnt,
2923 &rdata, &rdrcnt);
2924 if (i % 100 == 0) {
2925 printf("%d/%d\r", i,count);
2928 printf("%d/%d\n", i, count);
2930 if (!torture_close_connection(cli)) {
2931 correct = False;
2934 printf("finished random ipc test\n");
2936 return correct;
2941 static void browse_callback(const char *sname, uint32 stype,
2942 const char *comment, void *state)
2944 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2950 This test checks the browse list code
2953 static bool run_browsetest(int dummy)
2955 static struct cli_state *cli;
2956 bool correct = True;
2958 printf("starting browse test\n");
2960 if (!torture_open_connection(&cli, 0)) {
2961 return False;
2964 printf("domain list:\n");
2965 cli_NetServerEnum(cli, cli->server_domain,
2966 SV_TYPE_DOMAIN_ENUM,
2967 browse_callback, NULL);
2969 printf("machine list:\n");
2970 cli_NetServerEnum(cli, cli->server_domain,
2971 SV_TYPE_ALL,
2972 browse_callback, NULL);
2974 if (!torture_close_connection(cli)) {
2975 correct = False;
2978 printf("browse test finished\n");
2980 return correct;
2986 This checks how the getatr calls works
2988 static bool run_attrtest(int dummy)
2990 struct cli_state *cli;
2991 uint16_t fnum;
2992 time_t t, t2;
2993 const char *fname = "\\attrib123456789.tst";
2994 bool correct = True;
2996 printf("starting attrib test\n");
2998 if (!torture_open_connection(&cli, 0)) {
2999 return False;
3002 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3003 cli_open(cli, fname,
3004 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3005 cli_close(cli, fnum);
3006 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3007 printf("getatr failed (%s)\n", cli_errstr(cli));
3008 correct = False;
3011 if (abs(t - time(NULL)) > 60*60*24*10) {
3012 printf("ERROR: SMBgetatr bug. time is %s",
3013 ctime(&t));
3014 t = time(NULL);
3015 correct = True;
3018 t2 = t-60*60*24; /* 1 day ago */
3020 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
3021 printf("setatr failed (%s)\n", cli_errstr(cli));
3022 correct = True;
3025 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3026 printf("getatr failed (%s)\n", cli_errstr(cli));
3027 correct = True;
3030 if (t != t2) {
3031 printf("ERROR: getatr/setatr bug. times are\n%s",
3032 ctime(&t));
3033 printf("%s", ctime(&t2));
3034 correct = True;
3037 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3039 if (!torture_close_connection(cli)) {
3040 correct = False;
3043 printf("attrib test finished\n");
3045 return correct;
3050 This checks a couple of trans2 calls
3052 static bool run_trans2test(int dummy)
3054 struct cli_state *cli;
3055 uint16_t fnum;
3056 SMB_OFF_T size;
3057 time_t c_time, a_time, m_time;
3058 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3059 const char *fname = "\\trans2.tst";
3060 const char *dname = "\\trans2";
3061 const char *fname2 = "\\trans2\\trans2.tst";
3062 char pname[1024];
3063 bool correct = True;
3064 NTSTATUS status;
3065 uint32_t fs_attr;
3067 printf("starting trans2 test\n");
3069 if (!torture_open_connection(&cli, 0)) {
3070 return False;
3073 status = cli_get_fs_attr_info(cli, &fs_attr);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3076 nt_errstr(status));
3077 correct = false;
3080 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3081 cli_open(cli, fname,
3082 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3083 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3084 cli, fnum, NULL, &size, &c_time_ts,
3085 &a_time_ts, &w_time_ts,
3086 &m_time_ts, NULL))) {
3087 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3088 correct = False;
3091 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3092 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3093 correct = False;
3096 if (strcmp(pname, fname)) {
3097 printf("qfilename gave different name? [%s] [%s]\n",
3098 fname, pname);
3099 correct = False;
3102 cli_close(cli, fnum);
3104 sleep(2);
3106 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3107 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3108 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3109 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3110 return False;
3112 cli_close(cli, fnum);
3114 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3115 NULL);
3116 if (!NT_STATUS_IS_OK(status)) {
3117 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3118 correct = False;
3119 } else {
3120 if (c_time != m_time) {
3121 printf("create time=%s", ctime(&c_time));
3122 printf("modify time=%s", ctime(&m_time));
3123 printf("This system appears to have sticky create times\n");
3125 if (a_time % (60*60) == 0) {
3126 printf("access time=%s", ctime(&a_time));
3127 printf("This system appears to set a midnight access time\n");
3128 correct = False;
3131 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3132 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3133 correct = False;
3138 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3139 cli_open(cli, fname,
3140 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3141 cli_close(cli, fnum);
3142 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3143 &m_time_ts, &size, NULL, NULL);
3144 if (!NT_STATUS_IS_OK(status)) {
3145 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3146 correct = False;
3147 } else {
3148 if (w_time_ts.tv_sec < 60*60*24*2) {
3149 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3150 printf("This system appears to set a initial 0 write time\n");
3151 correct = False;
3155 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3158 /* check if the server updates the directory modification time
3159 when creating a new file */
3160 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3161 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3162 correct = False;
3164 sleep(3);
3165 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3166 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3167 if (!NT_STATUS_IS_OK(status)) {
3168 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3169 correct = False;
3172 cli_open(cli, fname2,
3173 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3174 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3175 cli_close(cli, fnum);
3176 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3177 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3180 correct = False;
3181 } else {
3182 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3183 == 0) {
3184 printf("This system does not update directory modification times\n");
3185 correct = False;
3188 cli_unlink(cli, fname2, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3189 cli_rmdir(cli, dname);
3191 if (!torture_close_connection(cli)) {
3192 correct = False;
3195 printf("trans2 test finished\n");
3197 return correct;
3201 This checks new W2K calls.
3204 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3206 uint8_t *buf = NULL;
3207 uint32 len;
3208 NTSTATUS status;
3210 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3211 pcli->max_xmit, &buf, &len);
3212 if (!NT_STATUS_IS_OK(status)) {
3213 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3214 nt_errstr(status));
3215 } else {
3216 printf("qfileinfo: level %d, len = %u\n", level, len);
3217 dump_data(0, (uint8 *)buf, len);
3218 printf("\n");
3220 TALLOC_FREE(buf);
3221 return status;
3224 static bool run_w2ktest(int dummy)
3226 struct cli_state *cli;
3227 uint16_t fnum;
3228 const char *fname = "\\w2ktest\\w2k.tst";
3229 int level;
3230 bool correct = True;
3232 printf("starting w2k test\n");
3234 if (!torture_open_connection(&cli, 0)) {
3235 return False;
3238 cli_open(cli, fname,
3239 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3241 for (level = 1004; level < 1040; level++) {
3242 new_trans(cli, fnum, level);
3245 cli_close(cli, fnum);
3247 if (!torture_close_connection(cli)) {
3248 correct = False;
3251 printf("w2k test finished\n");
3253 return correct;
3258 this is a harness for some oplock tests
3260 static bool run_oplock1(int dummy)
3262 struct cli_state *cli1;
3263 const char *fname = "\\lockt1.lck";
3264 uint16_t fnum1;
3265 bool correct = True;
3267 printf("starting oplock test 1\n");
3269 if (!torture_open_connection(&cli1, 0)) {
3270 return False;
3273 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3275 cli_sockopt(cli1, sockops);
3277 cli1->use_oplocks = True;
3279 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3280 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3281 return False;
3284 cli1->use_oplocks = False;
3286 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3287 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3289 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3290 printf("close2 failed (%s)\n", cli_errstr(cli1));
3291 return False;
3294 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3295 printf("unlink failed (%s)\n", cli_errstr(cli1));
3296 return False;
3299 if (!torture_close_connection(cli1)) {
3300 correct = False;
3303 printf("finished oplock test 1\n");
3305 return correct;
3308 static bool run_oplock2(int dummy)
3310 struct cli_state *cli1, *cli2;
3311 const char *fname = "\\lockt2.lck";
3312 uint16_t fnum1, fnum2;
3313 int saved_use_oplocks = use_oplocks;
3314 char buf[4];
3315 bool correct = True;
3316 volatile bool *shared_correct;
3318 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3319 *shared_correct = True;
3321 use_level_II_oplocks = True;
3322 use_oplocks = True;
3324 printf("starting oplock test 2\n");
3326 if (!torture_open_connection(&cli1, 0)) {
3327 use_level_II_oplocks = False;
3328 use_oplocks = saved_use_oplocks;
3329 return False;
3332 cli1->use_oplocks = True;
3333 cli1->use_level_II_oplocks = True;
3335 if (!torture_open_connection(&cli2, 1)) {
3336 use_level_II_oplocks = False;
3337 use_oplocks = saved_use_oplocks;
3338 return False;
3341 cli2->use_oplocks = True;
3342 cli2->use_level_II_oplocks = True;
3344 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3346 cli_sockopt(cli1, sockops);
3347 cli_sockopt(cli2, sockops);
3349 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3350 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3351 return False;
3354 /* Don't need the globals any more. */
3355 use_level_II_oplocks = False;
3356 use_oplocks = saved_use_oplocks;
3358 if (fork() == 0) {
3359 /* Child code */
3360 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3361 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3362 *shared_correct = False;
3363 exit(0);
3366 sleep(2);
3368 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3369 printf("close2 failed (%s)\n", cli_errstr(cli1));
3370 *shared_correct = False;
3373 exit(0);
3376 sleep(2);
3378 /* Ensure cli1 processes the break. Empty file should always return 0
3379 * bytes. */
3381 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3382 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3383 correct = False;
3386 /* Should now be at level II. */
3387 /* Test if sending a write locks causes a break to none. */
3389 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3390 printf("lock failed (%s)\n", cli_errstr(cli1));
3391 correct = False;
3394 cli_unlock(cli1, fnum1, 0, 4);
3396 sleep(2);
3398 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3399 printf("lock failed (%s)\n", cli_errstr(cli1));
3400 correct = False;
3403 cli_unlock(cli1, fnum1, 0, 4);
3405 sleep(2);
3407 cli_read(cli1, fnum1, buf, 0, 4);
3409 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3410 printf("close1 failed (%s)\n", cli_errstr(cli1));
3411 correct = False;
3414 sleep(4);
3416 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3417 printf("unlink failed (%s)\n", cli_errstr(cli1));
3418 correct = False;
3421 if (!torture_close_connection(cli1)) {
3422 correct = False;
3425 if (!*shared_correct) {
3426 correct = False;
3429 printf("finished oplock test 2\n");
3431 return correct;
3434 /* handler for oplock 3 tests */
3435 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3437 printf("got oplock break fnum=%d level=%d\n",
3438 fnum, level);
3439 return cli_oplock_ack(cli, fnum, level);
3442 static bool run_oplock3(int dummy)
3444 struct cli_state *cli;
3445 const char *fname = "\\oplockt3.dat";
3446 uint16_t fnum;
3447 char buf[4] = "abcd";
3448 bool correct = True;
3449 volatile bool *shared_correct;
3451 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3452 *shared_correct = True;
3454 printf("starting oplock test 3\n");
3456 if (fork() == 0) {
3457 /* Child code */
3458 use_oplocks = True;
3459 use_level_II_oplocks = True;
3460 if (!torture_open_connection(&cli, 0)) {
3461 *shared_correct = False;
3462 exit(0);
3464 sleep(2);
3465 /* try to trigger a oplock break in parent */
3466 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3467 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3468 exit(0);
3471 /* parent code */
3472 use_oplocks = True;
3473 use_level_II_oplocks = True;
3474 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3475 return False;
3477 cli_oplock_handler(cli, oplock3_handler);
3478 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3479 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3480 cli_close(cli, fnum);
3481 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3482 cli->timeout = 20000;
3483 cli_receive_smb(cli);
3484 printf("finished oplock test 3\n");
3486 return (correct && *shared_correct);
3488 /* What are we looking for here? What's sucess and what's FAILURE? */
3491 /* handler for oplock 4 tests */
3492 bool *oplock4_shared_correct;
3494 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3496 printf("got oplock break fnum=%d level=%d\n",
3497 fnum, level);
3498 *oplock4_shared_correct = true;
3499 cli_oplock_ack(cli, fnum, level);
3500 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3503 static bool run_oplock4(int dummy)
3505 struct cli_state *cli1, *cli2;
3506 const char *fname = "\\lockt4.lck";
3507 const char *fname_ln = "\\lockt4_ln.lck";
3508 uint16_t fnum1, fnum2;
3509 int saved_use_oplocks = use_oplocks;
3510 NTSTATUS status;
3511 bool correct = true;
3513 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3514 *oplock4_shared_correct = false;
3516 printf("starting oplock test 4\n");
3518 if (!torture_open_connection(&cli1, 0)) {
3519 use_level_II_oplocks = false;
3520 use_oplocks = saved_use_oplocks;
3521 return false;
3524 if (!torture_open_connection(&cli2, 1)) {
3525 use_level_II_oplocks = false;
3526 use_oplocks = saved_use_oplocks;
3527 return false;
3530 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3531 cli_unlink(cli1, fname_ln, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3533 cli_sockopt(cli1, sockops);
3534 cli_sockopt(cli2, sockops);
3536 /* Create the file. */
3537 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3538 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3539 return false;
3542 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3543 printf("close1 failed (%s)\n", cli_errstr(cli1));
3544 return false;
3547 /* Now create a hardlink. */
3548 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3549 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3550 return false;
3553 /* Prove that opening hardlinks cause deny modes to conflict. */
3554 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3555 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3556 return false;
3559 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3560 if (NT_STATUS_IS_OK(status)) {
3561 printf("open of %s succeeded - should fail with sharing violation.\n",
3562 fname_ln);
3563 return false;
3566 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3567 printf("open of %s should fail with sharing violation. Got %s\n",
3568 fname_ln, nt_errstr(status));
3569 return false;
3572 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3573 printf("close1 failed (%s)\n", cli_errstr(cli1));
3574 return false;
3577 cli1->use_oplocks = true;
3578 cli1->use_level_II_oplocks = true;
3580 cli2->use_oplocks = true;
3581 cli2->use_level_II_oplocks = true;
3583 cli_oplock_handler(cli1, oplock4_handler);
3584 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3585 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3586 return false;
3589 if (fork() == 0) {
3590 /* Child code */
3591 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3592 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3593 *oplock4_shared_correct = false;
3594 exit(0);
3597 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3598 printf("close2 failed (%s)\n", cli_errstr(cli1));
3599 *oplock4_shared_correct = false;
3602 exit(0);
3605 sleep(2);
3607 /* Process the oplock break. */
3608 cli_receive_smb(cli1);
3610 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3611 printf("close1 failed (%s)\n", cli_errstr(cli1));
3612 correct = false;
3615 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3616 printf("unlink failed (%s)\n", cli_errstr(cli1));
3617 correct = false;
3619 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3620 printf("unlink failed (%s)\n", cli_errstr(cli1));
3621 correct = false;
3624 if (!torture_close_connection(cli1)) {
3625 correct = false;
3628 if (!*oplock4_shared_correct) {
3629 correct = false;
3632 printf("finished oplock test 4\n");
3634 return correct;
3639 Test delete on close semantics.
3641 static bool run_deletetest(int dummy)
3643 struct cli_state *cli1 = NULL;
3644 struct cli_state *cli2 = NULL;
3645 const char *fname = "\\delete.file";
3646 uint16_t fnum1 = (uint16_t)-1;
3647 uint16_t fnum2 = (uint16_t)-1;
3648 bool correct = True;
3650 printf("starting delete test\n");
3652 if (!torture_open_connection(&cli1, 0)) {
3653 return False;
3656 cli_sockopt(cli1, sockops);
3658 /* Test 1 - this should delete the file on close. */
3660 cli_setatr(cli1, fname, 0, 0);
3661 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3663 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3664 0, FILE_OVERWRITE_IF,
3665 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3666 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3667 correct = False;
3668 goto fail;
3671 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3672 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3673 correct = False;
3674 goto fail;
3677 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3678 printf("[1] open of %s succeeded (should fail)\n", fname);
3679 correct = False;
3680 goto fail;
3683 printf("first delete on close test succeeded.\n");
3685 /* Test 2 - this should delete the file on close. */
3687 cli_setatr(cli1, fname, 0, 0);
3688 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3690 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3691 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3692 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3693 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3694 correct = False;
3695 goto fail;
3698 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3699 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3700 correct = False;
3701 goto fail;
3704 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3705 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3706 correct = False;
3707 goto fail;
3710 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3711 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3712 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3713 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3714 correct = False;
3715 goto fail;
3717 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3718 } else
3719 printf("second delete on close test succeeded.\n");
3721 /* Test 3 - ... */
3722 cli_setatr(cli1, fname, 0, 0);
3723 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3725 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3726 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3727 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3728 correct = False;
3729 goto fail;
3732 /* This should fail with a sharing violation - open for delete is only compatible
3733 with SHARE_DELETE. */
3735 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3736 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3737 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3738 correct = False;
3739 goto fail;
3742 /* This should succeed. */
3744 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3745 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3746 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3747 correct = False;
3748 goto fail;
3751 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3752 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3753 correct = False;
3754 goto fail;
3757 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3758 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3759 correct = False;
3760 goto fail;
3763 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3764 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3765 correct = False;
3766 goto fail;
3769 /* This should fail - file should no longer be there. */
3771 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3772 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3773 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3774 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3776 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3777 correct = False;
3778 goto fail;
3779 } else
3780 printf("third delete on close test succeeded.\n");
3782 /* Test 4 ... */
3783 cli_setatr(cli1, fname, 0, 0);
3784 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3786 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3787 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3788 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3789 correct = False;
3790 goto fail;
3793 /* This should succeed. */
3794 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3795 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3796 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3797 correct = False;
3798 goto fail;
3801 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3802 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3803 correct = False;
3804 goto fail;
3807 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3808 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3809 correct = False;
3810 goto fail;
3813 /* This should fail - no more opens once delete on close set. */
3814 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3815 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3816 FILE_OPEN, 0, 0, &fnum2))) {
3817 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3818 correct = False;
3819 goto fail;
3820 } else
3821 printf("fourth delete on close test succeeded.\n");
3823 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3824 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3825 correct = False;
3826 goto fail;
3829 /* Test 5 ... */
3830 cli_setatr(cli1, fname, 0, 0);
3831 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3833 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3834 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3835 correct = False;
3836 goto fail;
3839 /* This should fail - only allowed on NT opens with DELETE access. */
3841 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3842 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3843 correct = False;
3844 goto fail;
3847 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3848 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3849 correct = False;
3850 goto fail;
3853 printf("fifth delete on close test succeeded.\n");
3855 /* Test 6 ... */
3856 cli_setatr(cli1, fname, 0, 0);
3857 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3859 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3860 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3861 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3862 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3863 correct = False;
3864 goto fail;
3867 /* This should fail - only allowed on NT opens with DELETE access. */
3869 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3870 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3871 correct = False;
3872 goto fail;
3875 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3876 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3877 correct = False;
3878 goto fail;
3881 printf("sixth delete on close test succeeded.\n");
3883 /* Test 7 ... */
3884 cli_setatr(cli1, fname, 0, 0);
3885 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3887 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3888 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3889 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3890 correct = False;
3891 goto fail;
3894 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3895 printf("[7] setting delete_on_close on file failed !\n");
3896 correct = False;
3897 goto fail;
3900 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3901 printf("[7] unsetting delete_on_close on file failed !\n");
3902 correct = False;
3903 goto fail;
3906 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3907 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3908 correct = False;
3909 goto fail;
3912 /* This next open should succeed - we reset the flag. */
3914 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3915 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3916 correct = False;
3917 goto fail;
3920 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3921 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3922 correct = False;
3923 goto fail;
3926 printf("seventh delete on close test succeeded.\n");
3928 /* Test 7 ... */
3929 cli_setatr(cli1, fname, 0, 0);
3930 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
3932 if (!torture_open_connection(&cli2, 1)) {
3933 printf("[8] failed to open second connection.\n");
3934 correct = False;
3935 goto fail;
3938 cli_sockopt(cli1, sockops);
3940 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3941 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3942 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3943 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3944 correct = False;
3945 goto fail;
3948 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3949 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3950 FILE_OPEN, 0, 0, &fnum2))) {
3951 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3952 correct = False;
3953 goto fail;
3956 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3957 printf("[8] setting delete_on_close on file failed !\n");
3958 correct = False;
3959 goto fail;
3962 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3963 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3964 correct = False;
3965 goto fail;
3968 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3969 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3970 correct = False;
3971 goto fail;
3974 /* This should fail.. */
3975 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3976 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3977 goto fail;
3978 correct = False;
3979 } else
3980 printf("eighth delete on close test succeeded.\n");
3982 /* This should fail - we need to set DELETE_ACCESS. */
3983 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3984 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3985 printf("[9] open of %s succeeded should have failed!\n", fname);
3986 correct = False;
3987 goto fail;
3990 printf("ninth delete on close test succeeded.\n");
3992 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3993 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3994 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3995 correct = False;
3996 goto fail;
3999 /* This should delete the file. */
4000 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4001 printf("[10] close failed (%s)\n", cli_errstr(cli1));
4002 correct = False;
4003 goto fail;
4006 /* This should fail.. */
4007 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4008 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4009 goto fail;
4010 correct = False;
4011 } else
4012 printf("tenth delete on close test succeeded.\n");
4014 cli_setatr(cli1, fname, 0, 0);
4015 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4017 /* What error do we get when attempting to open a read-only file with
4018 delete access ? */
4020 /* Create a readonly file. */
4021 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4022 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4023 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
4024 correct = False;
4025 goto fail;
4028 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4029 printf("[11] close failed (%s)\n", cli_errstr(cli1));
4030 correct = False;
4031 goto fail;
4034 /* Now try open for delete access. */
4035 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4036 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4037 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4038 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4039 cli_close(cli1, fnum1);
4040 goto fail;
4041 correct = False;
4042 } else {
4043 NTSTATUS nterr = cli_nt_error(cli1);
4044 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4045 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4046 goto fail;
4047 correct = False;
4048 } else {
4049 printf("eleventh delete on close test succeeded.\n");
4053 printf("finished delete test\n");
4055 fail:
4056 /* FIXME: This will crash if we aborted before cli2 got
4057 * intialized, because these functions don't handle
4058 * uninitialized connections. */
4060 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4061 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4062 cli_setatr(cli1, fname, 0, 0);
4063 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4065 if (cli1 && !torture_close_connection(cli1)) {
4066 correct = False;
4068 if (cli2 && !torture_close_connection(cli2)) {
4069 correct = False;
4071 return correct;
4074 static bool run_deletetest_ln(int dummy)
4076 struct cli_state *cli;
4077 const char *fname = "\\delete1";
4078 const char *fname_ln = "\\delete1_ln";
4079 uint16_t fnum;
4080 uint16_t fnum1;
4081 NTSTATUS status;
4082 bool correct = true;
4083 time_t t;
4085 printf("starting deletetest-ln\n");
4087 if (!torture_open_connection(&cli, 0)) {
4088 return false;
4091 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4092 cli_unlink(cli, fname_ln, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4094 cli_sockopt(cli, sockops);
4096 /* Create the file. */
4097 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4098 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4099 return false;
4102 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4103 printf("close1 failed (%s)\n", cli_errstr(cli));
4104 return false;
4107 /* Now create a hardlink. */
4108 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4109 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4110 return false;
4113 /* Open the original file. */
4114 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4115 FILE_ATTRIBUTE_NORMAL,
4116 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4117 FILE_OPEN_IF, 0, 0, &fnum);
4118 if (!NT_STATUS_IS_OK(status)) {
4119 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4120 return false;
4123 /* Unlink the hard link path. */
4124 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4125 FILE_ATTRIBUTE_NORMAL,
4126 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4127 FILE_OPEN_IF, 0, 0, &fnum1);
4128 if (!NT_STATUS_IS_OK(status)) {
4129 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4130 return false;
4132 status = cli_nt_delete_on_close(cli, fnum1, true);
4133 if (!NT_STATUS_IS_OK(status)) {
4134 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4135 __location__, fname_ln, nt_errstr(status));
4136 return false;
4139 status = cli_close(cli, fnum1);
4140 if (!NT_STATUS_IS_OK(status)) {
4141 printf("close %s failed (%s)\n",
4142 fname_ln, nt_errstr(status));
4143 return false;
4146 status = cli_close(cli, fnum);
4147 if (!NT_STATUS_IS_OK(status)) {
4148 printf("close %s failed (%s)\n",
4149 fname, nt_errstr(status));
4150 return false;
4153 /* Ensure the original file is still there. */
4154 status = cli_getatr(cli, fname, NULL, NULL, &t);
4155 if (!NT_STATUS_IS_OK(status)) {
4156 printf("%s getatr on file %s failed (%s)\n",
4157 __location__,
4158 fname,
4159 nt_errstr(status));
4160 correct = False;
4163 /* Ensure the link path is gone. */
4164 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4165 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4166 printf("%s, getatr for file %s returned wrong error code %s "
4167 "- should have been deleted\n",
4168 __location__,
4169 fname_ln, nt_errstr(status));
4170 correct = False;
4173 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4174 cli_unlink(cli, fname_ln, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4176 if (!torture_close_connection(cli)) {
4177 correct = false;
4180 printf("finished deletetest-ln\n");
4182 return correct;
4186 print out server properties
4188 static bool run_properties(int dummy)
4190 struct cli_state *cli;
4191 bool correct = True;
4193 printf("starting properties test\n");
4195 ZERO_STRUCT(cli);
4197 if (!torture_open_connection(&cli, 0)) {
4198 return False;
4201 cli_sockopt(cli, sockops);
4203 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4205 if (!torture_close_connection(cli)) {
4206 correct = False;
4209 return correct;
4214 /* FIRST_DESIRED_ACCESS 0xf019f */
4215 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4216 FILE_READ_EA| /* 0xf */ \
4217 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4218 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4219 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4220 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4221 /* SECOND_DESIRED_ACCESS 0xe0080 */
4222 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4223 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4224 WRITE_OWNER_ACCESS /* 0xe0000 */
4226 #if 0
4227 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4228 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4229 FILE_READ_DATA|\
4230 WRITE_OWNER_ACCESS /* */
4231 #endif
4234 Test ntcreate calls made by xcopy
4236 static bool run_xcopy(int dummy)
4238 static struct cli_state *cli1;
4239 const char *fname = "\\test.txt";
4240 bool correct = True;
4241 uint16_t fnum1, fnum2;
4243 printf("starting xcopy test\n");
4245 if (!torture_open_connection(&cli1, 0)) {
4246 return False;
4249 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4250 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4251 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4252 0x4044, 0, &fnum1))) {
4253 printf("First open failed - %s\n", cli_errstr(cli1));
4254 return False;
4257 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4258 SECOND_DESIRED_ACCESS, 0,
4259 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4260 0x200000, 0, &fnum2))) {
4261 printf("second open failed - %s\n", cli_errstr(cli1));
4262 return False;
4265 if (!torture_close_connection(cli1)) {
4266 correct = False;
4269 return correct;
4273 Test rename on files open with share delete and no share delete.
4275 static bool run_rename(int dummy)
4277 static struct cli_state *cli1;
4278 const char *fname = "\\test.txt";
4279 const char *fname1 = "\\test1.txt";
4280 bool correct = True;
4281 uint16_t fnum1;
4282 uint16_t attr;
4283 NTSTATUS status;
4285 printf("starting rename test\n");
4287 if (!torture_open_connection(&cli1, 0)) {
4288 return False;
4291 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4292 cli_unlink(cli1, fname1, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4293 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4294 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4295 printf("First open failed - %s\n", cli_errstr(cli1));
4296 return False;
4299 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4300 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4301 } else {
4302 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4303 correct = False;
4306 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4307 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4308 return False;
4311 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4312 cli_unlink(cli1, fname1, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4313 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4314 #if 0
4315 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4316 #else
4317 FILE_SHARE_DELETE|FILE_SHARE_READ,
4318 #endif
4319 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4320 if (!NT_STATUS_IS_OK(status)) {
4321 printf("Second open failed - %s\n", cli_errstr(cli1));
4322 return False;
4325 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4326 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4327 correct = False;
4328 } else {
4329 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4332 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4333 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4334 return False;
4337 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4338 cli_unlink(cli1, fname1, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4340 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4341 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4342 printf("Third open failed - %s\n", cli_errstr(cli1));
4343 return False;
4347 #if 0
4349 uint16_t fnum2;
4351 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4352 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4353 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4354 return False;
4356 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4357 printf("[8] setting delete_on_close on file failed !\n");
4358 return False;
4361 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4362 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4363 return False;
4366 #endif
4368 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4369 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4370 correct = False;
4371 } else {
4372 printf("Third rename succeeded (SHARE_NONE)\n");
4375 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4376 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4377 return False;
4380 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4381 cli_unlink(cli1, fname1, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4383 /*----*/
4385 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4386 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4387 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4388 return False;
4391 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4392 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4393 } else {
4394 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4395 correct = False;
4398 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4399 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4400 return False;
4403 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4404 cli_unlink(cli1, fname1, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4406 /*--*/
4408 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4409 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4410 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4411 return False;
4414 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4415 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4416 cli_errstr(cli1));
4417 correct = False;
4418 } else {
4419 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4423 * Now check if the first name still exists ...
4426 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4427 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4428 printf("Opening original file after rename of open file fails: %s\n",
4429 cli_errstr(cli1));
4431 else {
4432 printf("Opening original file after rename of open file works ...\n");
4433 (void)cli_close(cli1, fnum2);
4434 } */
4436 /*--*/
4437 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4438 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4439 return False;
4442 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4443 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4444 printf("getatr on file %s failed - %s ! \n",
4445 fname1,
4446 cli_errstr(cli1));
4447 correct = False;
4448 } else {
4449 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4450 printf("Renamed file %s has wrong attr 0x%x "
4451 "(should be 0x%x)\n",
4452 fname1,
4453 attr,
4454 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4455 correct = False;
4456 } else {
4457 printf("Renamed file %s has archive bit set\n", fname1);
4461 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4462 cli_unlink(cli1, fname1, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4464 if (!torture_close_connection(cli1)) {
4465 correct = False;
4468 return correct;
4471 static bool run_pipe_number(int dummy)
4473 struct cli_state *cli1;
4474 const char *pipe_name = "\\SPOOLSS";
4475 uint16_t fnum;
4476 int num_pipes = 0;
4478 printf("starting pipenumber test\n");
4479 if (!torture_open_connection(&cli1, 0)) {
4480 return False;
4483 cli_sockopt(cli1, sockops);
4484 while(1) {
4485 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4486 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4487 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4488 break;
4490 num_pipes++;
4491 printf("\r%6d", num_pipes);
4494 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4495 torture_close_connection(cli1);
4496 return True;
4500 Test open mode returns on read-only files.
4502 static bool run_opentest(int dummy)
4504 static struct cli_state *cli1;
4505 static struct cli_state *cli2;
4506 const char *fname = "\\readonly.file";
4507 uint16_t fnum1, fnum2;
4508 char buf[20];
4509 SMB_OFF_T fsize;
4510 bool correct = True;
4511 char *tmp_path;
4512 NTSTATUS status;
4514 printf("starting open test\n");
4516 if (!torture_open_connection(&cli1, 0)) {
4517 return False;
4520 cli_setatr(cli1, fname, 0, 0);
4521 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4523 cli_sockopt(cli1, sockops);
4525 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4526 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4527 return False;
4530 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4531 printf("close2 failed (%s)\n", cli_errstr(cli1));
4532 return False;
4535 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0))) {
4536 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4537 return False;
4540 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4541 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4542 return False;
4545 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4546 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4548 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4549 NT_STATUS_ACCESS_DENIED)) {
4550 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4553 printf("finished open test 1\n");
4555 cli_close(cli1, fnum1);
4557 /* Now try not readonly and ensure ERRbadshare is returned. */
4559 cli_setatr(cli1, fname, 0, 0);
4561 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4562 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4563 return False;
4566 /* This will fail - but the error should be ERRshare. */
4567 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4569 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4570 NT_STATUS_SHARING_VIOLATION)) {
4571 printf("correct error code ERRDOS/ERRbadshare returned\n");
4574 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4575 printf("close2 failed (%s)\n", cli_errstr(cli1));
4576 return False;
4579 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4581 printf("finished open test 2\n");
4583 /* Test truncate open disposition on file opened for read. */
4585 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4586 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4587 return False;
4590 /* write 20 bytes. */
4592 memset(buf, '\0', 20);
4594 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4595 if (!NT_STATUS_IS_OK(status)) {
4596 printf("write failed (%s)\n", nt_errstr(status));
4597 correct = False;
4600 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4601 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4602 return False;
4605 /* Ensure size == 20. */
4606 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4607 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4608 return False;
4611 if (fsize != 20) {
4612 printf("(3) file size != 20\n");
4613 return False;
4616 /* Now test if we can truncate a file opened for readonly. */
4618 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4619 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4620 return False;
4623 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4624 printf("close2 failed (%s)\n", cli_errstr(cli1));
4625 return False;
4628 /* Ensure size == 0. */
4629 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4630 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4631 return False;
4634 if (fsize != 0) {
4635 printf("(3) file size != 0\n");
4636 return False;
4638 printf("finished open test 3\n");
4640 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4642 printf("Do ctemp tests\n");
4643 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4644 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4645 return False;
4647 printf("ctemp gave path %s\n", tmp_path);
4648 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4649 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4651 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
4652 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4655 /* Test the non-io opens... */
4657 if (!torture_open_connection(&cli2, 1)) {
4658 return False;
4661 cli_setatr(cli2, fname, 0, 0);
4662 cli_unlink(cli2, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4664 cli_sockopt(cli2, sockops);
4666 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4668 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4669 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4670 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4671 return False;
4674 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4675 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4676 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4677 return False;
4680 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4681 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4682 return False;
4684 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4685 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4686 return False;
4689 printf("non-io open test #1 passed.\n");
4691 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4693 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4695 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4696 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4697 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4698 return False;
4701 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4702 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4703 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4704 return False;
4707 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4708 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4709 return False;
4711 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4712 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4713 return False;
4716 printf("non-io open test #2 passed.\n");
4718 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4720 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4722 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4723 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4724 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4725 return False;
4728 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4729 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4730 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4731 return False;
4734 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4735 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4736 return False;
4738 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4739 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4740 return False;
4743 printf("non-io open test #3 passed.\n");
4745 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4747 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4749 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4750 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4751 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4752 return False;
4755 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4756 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4757 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4758 return False;
4761 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4763 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4764 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4765 return False;
4768 printf("non-io open test #4 passed.\n");
4770 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4772 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4774 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4775 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4776 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4777 return False;
4780 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4781 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4782 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4783 return False;
4786 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4787 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4788 return False;
4791 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4792 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4793 return False;
4796 printf("non-io open test #5 passed.\n");
4798 printf("TEST #6 testing 1 non-io open, one io open\n");
4800 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4802 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4803 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4804 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4805 return False;
4808 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4809 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4810 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4811 return False;
4814 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4815 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4816 return False;
4819 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4820 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4821 return False;
4824 printf("non-io open test #6 passed.\n");
4826 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4828 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4830 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4831 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4832 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4833 return False;
4836 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4837 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4838 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4839 return False;
4842 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4844 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4845 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4846 return False;
4849 printf("non-io open test #7 passed.\n");
4851 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
4853 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4854 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4855 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4856 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4857 if (!NT_STATUS_IS_OK(status)) {
4858 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4859 correct = false;
4860 goto out;
4863 /* Write to ensure we have to update the file time. */
4864 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
4865 NULL);
4866 if (!NT_STATUS_IS_OK(status)) {
4867 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
4868 correct = false;
4869 goto out;
4872 status = cli_close(cli1, fnum1);
4873 if (!NT_STATUS_IS_OK(status)) {
4874 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4875 correct = false;
4878 out:
4880 if (!torture_close_connection(cli1)) {
4881 correct = False;
4883 if (!torture_close_connection(cli2)) {
4884 correct = False;
4887 return correct;
4890 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4892 uint16 major, minor;
4893 uint32 caplow, caphigh;
4894 NTSTATUS status;
4896 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4897 printf("Server doesn't support UNIX CIFS extensions.\n");
4898 return NT_STATUS_NOT_SUPPORTED;
4901 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4902 &caphigh);
4903 if (!NT_STATUS_IS_OK(status)) {
4904 printf("Server didn't return UNIX CIFS extensions: %s\n",
4905 nt_errstr(status));
4906 return status;
4909 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4910 caplow, caphigh);
4911 if (!NT_STATUS_IS_OK(status)) {
4912 printf("Server doesn't support setting UNIX CIFS extensions: "
4913 "%s.\n", nt_errstr(status));
4914 return status;
4917 return NT_STATUS_OK;
4921 Test POSIX open /mkdir calls.
4923 static bool run_simple_posix_open_test(int dummy)
4925 static struct cli_state *cli1;
4926 const char *fname = "posix:file";
4927 const char *hname = "posix:hlink";
4928 const char *sname = "posix:symlink";
4929 const char *dname = "posix:dir";
4930 char buf[10];
4931 char namebuf[11];
4932 uint16_t fnum1 = (uint16_t)-1;
4933 SMB_STRUCT_STAT sbuf;
4934 bool correct = false;
4935 NTSTATUS status;
4937 printf("Starting simple POSIX open test\n");
4939 if (!torture_open_connection(&cli1, 0)) {
4940 return false;
4943 cli_sockopt(cli1, sockops);
4945 status = torture_setup_unix_extensions(cli1);
4946 if (!NT_STATUS_IS_OK(status)) {
4947 return false;
4950 cli_setatr(cli1, fname, 0, 0);
4951 cli_posix_unlink(cli1, fname);
4952 cli_setatr(cli1, dname, 0, 0);
4953 cli_posix_rmdir(cli1, dname);
4954 cli_setatr(cli1, hname, 0, 0);
4955 cli_posix_unlink(cli1, hname);
4956 cli_setatr(cli1, sname, 0, 0);
4957 cli_posix_unlink(cli1, sname);
4959 /* Create a directory. */
4960 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4961 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4962 goto out;
4965 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4966 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4967 goto out;
4970 /* Test ftruncate - set file size. */
4971 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4972 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4973 goto out;
4976 /* Ensure st_size == 1000 */
4977 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4978 printf("stat failed (%s)\n", cli_errstr(cli1));
4979 goto out;
4982 if (sbuf.st_ex_size != 1000) {
4983 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4984 goto out;
4987 /* Test ftruncate - set file size back to zero. */
4988 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4989 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4990 goto out;
4993 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4994 printf("close failed (%s)\n", cli_errstr(cli1));
4995 goto out;
4998 /* Now open the file again for read only. */
4999 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5000 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
5001 goto out;
5004 /* Now unlink while open. */
5005 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5006 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5007 goto out;
5010 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5011 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5012 goto out;
5015 /* Ensure the file has gone. */
5016 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5017 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5018 goto out;
5021 /* What happens when we try and POSIX open a directory ? */
5022 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5023 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5024 goto out;
5025 } else {
5026 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5027 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5028 goto out;
5032 /* Create the file. */
5033 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5034 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5035 goto out;
5038 /* Write some data into it. */
5039 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
5040 NULL);
5041 if (!NT_STATUS_IS_OK(status)) {
5042 printf("cli_write failed: %s\n", nt_errstr(status));
5043 goto out;
5046 cli_close(cli1, fnum1);
5048 /* Now create a hardlink. */
5049 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5050 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5051 goto out;
5054 /* Now create a symlink. */
5055 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5056 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5057 goto out;
5060 /* Open the hardlink for read. */
5061 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5062 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5063 goto out;
5066 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5067 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5068 goto out;
5071 if (memcmp(buf, "TEST DATA\n", 10)) {
5072 printf("invalid data read from hardlink\n");
5073 goto out;
5076 /* Do a POSIX lock/unlock. */
5077 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5078 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5079 goto out;
5082 /* Punch a hole in the locked area. */
5083 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5084 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5085 goto out;
5088 cli_close(cli1, fnum1);
5090 /* Open the symlink for read - this should fail. A POSIX
5091 client should not be doing opens on a symlink. */
5092 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5093 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5094 goto out;
5095 } else {
5096 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5097 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5098 printf("POSIX open of %s should have failed "
5099 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5100 "failed with %s instead.\n",
5101 sname, cli_errstr(cli1));
5102 goto out;
5106 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5107 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5108 goto out;
5111 if (strcmp(namebuf, fname) != 0) {
5112 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5113 sname, fname, namebuf);
5114 goto out;
5117 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5118 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5119 goto out;
5122 printf("Simple POSIX open test passed\n");
5123 correct = true;
5125 out:
5127 if (fnum1 != (uint16_t)-1) {
5128 cli_close(cli1, fnum1);
5129 fnum1 = (uint16_t)-1;
5132 cli_setatr(cli1, sname, 0, 0);
5133 cli_posix_unlink(cli1, sname);
5134 cli_setatr(cli1, hname, 0, 0);
5135 cli_posix_unlink(cli1, hname);
5136 cli_setatr(cli1, fname, 0, 0);
5137 cli_posix_unlink(cli1, fname);
5138 cli_setatr(cli1, dname, 0, 0);
5139 cli_posix_rmdir(cli1, dname);
5141 if (!torture_close_connection(cli1)) {
5142 correct = false;
5145 return correct;
5149 static uint32 open_attrs_table[] = {
5150 FILE_ATTRIBUTE_NORMAL,
5151 FILE_ATTRIBUTE_ARCHIVE,
5152 FILE_ATTRIBUTE_READONLY,
5153 FILE_ATTRIBUTE_HIDDEN,
5154 FILE_ATTRIBUTE_SYSTEM,
5156 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5157 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5158 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5159 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5160 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5161 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5163 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5164 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5165 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5166 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5169 struct trunc_open_results {
5170 unsigned int num;
5171 uint32 init_attr;
5172 uint32 trunc_attr;
5173 uint32 result_attr;
5176 static struct trunc_open_results attr_results[] = {
5177 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5178 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5179 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5180 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5181 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5182 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5183 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5184 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5185 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5186 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5187 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5188 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5189 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5190 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5191 { 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 },
5192 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5193 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5194 { 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 },
5195 { 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 },
5196 { 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 },
5197 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5198 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5199 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5200 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5201 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5202 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5205 static bool run_openattrtest(int dummy)
5207 static struct cli_state *cli1;
5208 const char *fname = "\\openattr.file";
5209 uint16_t fnum1;
5210 bool correct = True;
5211 uint16 attr;
5212 unsigned int i, j, k, l;
5214 printf("starting open attr test\n");
5216 if (!torture_open_connection(&cli1, 0)) {
5217 return False;
5220 cli_sockopt(cli1, sockops);
5222 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5223 cli_setatr(cli1, fname, 0, 0);
5224 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
5225 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5226 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5227 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5228 return False;
5231 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5232 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5233 return False;
5236 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5237 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5238 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5239 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5240 if (attr_results[l].num == k) {
5241 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5242 k, open_attrs_table[i],
5243 open_attrs_table[j],
5244 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5245 correct = False;
5248 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5249 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5250 k, open_attrs_table[i], open_attrs_table[j],
5251 cli_errstr(cli1));
5252 correct = False;
5254 #if 0
5255 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5256 #endif
5257 k++;
5258 continue;
5261 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5262 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5263 return False;
5266 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5267 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5268 return False;
5271 #if 0
5272 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5273 k, open_attrs_table[i], open_attrs_table[j], attr );
5274 #endif
5276 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5277 if (attr_results[l].num == k) {
5278 if (attr != attr_results[l].result_attr ||
5279 open_attrs_table[i] != attr_results[l].init_attr ||
5280 open_attrs_table[j] != attr_results[l].trunc_attr) {
5281 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5282 open_attrs_table[i],
5283 open_attrs_table[j],
5284 (unsigned int)attr,
5285 attr_results[l].result_attr);
5286 correct = False;
5288 break;
5291 k++;
5295 cli_setatr(cli1, fname, 0, 0);
5296 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
5298 printf("open attr test %s.\n", correct ? "passed" : "failed");
5300 if (!torture_close_connection(cli1)) {
5301 correct = False;
5303 return correct;
5306 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5307 const char *name, void *state)
5309 int *matched = (int *)state;
5310 if (matched != NULL) {
5311 *matched += 1;
5313 return NT_STATUS_OK;
5317 test directory listing speed
5319 static bool run_dirtest(int dummy)
5321 int i;
5322 static struct cli_state *cli;
5323 uint16_t fnum;
5324 struct timeval core_start;
5325 bool correct = True;
5326 int matched;
5328 printf("starting directory test\n");
5330 if (!torture_open_connection(&cli, 0)) {
5331 return False;
5334 cli_sockopt(cli, sockops);
5336 srandom(0);
5337 for (i=0;i<torture_numops;i++) {
5338 fstring fname;
5339 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5340 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5341 fprintf(stderr,"Failed to open %s\n", fname);
5342 return False;
5344 cli_close(cli, fnum);
5347 core_start = timeval_current();
5349 matched = 0;
5350 cli_list(cli, "a*.*", 0, list_fn, &matched);
5351 printf("Matched %d\n", matched);
5353 matched = 0;
5354 cli_list(cli, "b*.*", 0, list_fn, &matched);
5355 printf("Matched %d\n", matched);
5357 matched = 0;
5358 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5359 printf("Matched %d\n", matched);
5361 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5363 srandom(0);
5364 for (i=0;i<torture_numops;i++) {
5365 fstring fname;
5366 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5367 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
5370 if (!torture_close_connection(cli)) {
5371 correct = False;
5374 printf("finished dirtest\n");
5376 return correct;
5379 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5380 void *state)
5382 struct cli_state *pcli = (struct cli_state *)state;
5383 fstring fname;
5384 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5386 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5387 return NT_STATUS_OK;
5389 if (finfo->mode & aDIR) {
5390 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5391 printf("del_fn: failed to rmdir %s\n,", fname );
5392 } else {
5393 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5394 printf("del_fn: failed to unlink %s\n,", fname );
5396 return NT_STATUS_OK;
5401 sees what IOCTLs are supported
5403 bool torture_ioctl_test(int dummy)
5405 static struct cli_state *cli;
5406 uint16_t device, function;
5407 uint16_t fnum;
5408 const char *fname = "\\ioctl.dat";
5409 DATA_BLOB blob;
5410 NTSTATUS status;
5412 if (!torture_open_connection(&cli, 0)) {
5413 return False;
5416 printf("starting ioctl test\n");
5418 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
5420 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5421 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5422 return False;
5425 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5426 printf("ioctl device info: %s\n", nt_errstr(status));
5428 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5429 printf("ioctl job info: %s\n", nt_errstr(status));
5431 for (device=0;device<0x100;device++) {
5432 printf("ioctl test with device = 0x%x\n", device);
5433 for (function=0;function<0x100;function++) {
5434 uint32 code = (device<<16) | function;
5436 status = cli_raw_ioctl(cli, fnum, code, &blob);
5438 if (NT_STATUS_IS_OK(status)) {
5439 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5440 (int)blob.length);
5441 data_blob_free(&blob);
5446 if (!torture_close_connection(cli)) {
5447 return False;
5450 return True;
5455 tries varients of chkpath
5457 bool torture_chkpath_test(int dummy)
5459 static struct cli_state *cli;
5460 uint16_t fnum;
5461 bool ret;
5463 if (!torture_open_connection(&cli, 0)) {
5464 return False;
5467 printf("starting chkpath test\n");
5469 /* cleanup from an old run */
5470 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5471 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
5472 cli_rmdir(cli, "\\chkpath.dir");
5474 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5475 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5476 return False;
5479 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5480 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5481 return False;
5484 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5485 printf("open1 failed (%s)\n", cli_errstr(cli));
5486 return False;
5488 cli_close(cli, fnum);
5490 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5491 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5492 ret = False;
5495 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5496 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5497 ret = False;
5500 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5501 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5502 NT_STATUS_NOT_A_DIRECTORY);
5503 } else {
5504 printf("* chkpath on a file should fail\n");
5505 ret = False;
5508 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5509 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5510 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5511 } else {
5512 printf("* chkpath on a non existant file should fail\n");
5513 ret = False;
5516 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5517 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5518 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5519 } else {
5520 printf("* chkpath on a non existent component should fail\n");
5521 ret = False;
5524 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5525 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
5526 cli_rmdir(cli, "\\chkpath.dir");
5528 if (!torture_close_connection(cli)) {
5529 return False;
5532 return ret;
5535 static bool run_eatest(int dummy)
5537 static struct cli_state *cli;
5538 const char *fname = "\\eatest.txt";
5539 bool correct = True;
5540 uint16_t fnum;
5541 int i;
5542 size_t num_eas;
5543 struct ea_struct *ea_list = NULL;
5544 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5545 NTSTATUS status;
5547 printf("starting eatest\n");
5549 if (!torture_open_connection(&cli, 0)) {
5550 talloc_destroy(mem_ctx);
5551 return False;
5554 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
5555 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5556 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5557 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5558 0x4044, 0, &fnum))) {
5559 printf("open failed - %s\n", cli_errstr(cli));
5560 talloc_destroy(mem_ctx);
5561 return False;
5564 for (i = 0; i < 10; i++) {
5565 fstring ea_name, ea_val;
5567 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5568 memset(ea_val, (char)i+1, i+1);
5569 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5570 if (!NT_STATUS_IS_OK(status)) {
5571 printf("ea_set of name %s failed - %s\n", ea_name,
5572 nt_errstr(status));
5573 talloc_destroy(mem_ctx);
5574 return False;
5578 cli_close(cli, fnum);
5579 for (i = 0; i < 10; i++) {
5580 fstring ea_name, ea_val;
5582 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5583 memset(ea_val, (char)i+1, i+1);
5584 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5585 if (!NT_STATUS_IS_OK(status)) {
5586 printf("ea_set of name %s failed - %s\n", ea_name,
5587 nt_errstr(status));
5588 talloc_destroy(mem_ctx);
5589 return False;
5593 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5594 if (!NT_STATUS_IS_OK(status)) {
5595 printf("ea_get list failed - %s\n", nt_errstr(status));
5596 correct = False;
5599 printf("num_eas = %d\n", (int)num_eas);
5601 if (num_eas != 20) {
5602 printf("Should be 20 EA's stored... failing.\n");
5603 correct = False;
5606 for (i = 0; i < num_eas; i++) {
5607 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5608 dump_data(0, ea_list[i].value.data,
5609 ea_list[i].value.length);
5612 /* Setting EA's to zero length deletes them. Test this */
5613 printf("Now deleting all EA's - case indepenent....\n");
5615 #if 1
5616 cli_set_ea_path(cli, fname, "", "", 0);
5617 #else
5618 for (i = 0; i < 20; i++) {
5619 fstring ea_name;
5620 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5621 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5622 if (!NT_STATUS_IS_OK(status)) {
5623 printf("ea_set of name %s failed - %s\n", ea_name,
5624 nt_errstr(status));
5625 talloc_destroy(mem_ctx);
5626 return False;
5629 #endif
5631 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5632 if (!NT_STATUS_IS_OK(status)) {
5633 printf("ea_get list failed - %s\n", nt_errstr(status));
5634 correct = False;
5637 printf("num_eas = %d\n", (int)num_eas);
5638 for (i = 0; i < num_eas; i++) {
5639 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5640 dump_data(0, ea_list[i].value.data,
5641 ea_list[i].value.length);
5644 if (num_eas != 0) {
5645 printf("deleting EA's failed.\n");
5646 correct = False;
5649 /* Try and delete a non existant EA. */
5650 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5651 if (!NT_STATUS_IS_OK(status)) {
5652 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5653 nt_errstr(status));
5654 correct = False;
5657 talloc_destroy(mem_ctx);
5658 if (!torture_close_connection(cli)) {
5659 correct = False;
5662 return correct;
5665 static bool run_dirtest1(int dummy)
5667 int i;
5668 static struct cli_state *cli;
5669 uint16_t fnum;
5670 int num_seen;
5671 bool correct = True;
5673 printf("starting directory test\n");
5675 if (!torture_open_connection(&cli, 0)) {
5676 return False;
5679 cli_sockopt(cli, sockops);
5681 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5682 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5683 cli_rmdir(cli, "\\LISTDIR");
5684 cli_mkdir(cli, "\\LISTDIR");
5686 /* Create 1000 files and 1000 directories. */
5687 for (i=0;i<1000;i++) {
5688 fstring fname;
5689 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5690 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5691 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5692 fprintf(stderr,"Failed to open %s\n", fname);
5693 return False;
5695 cli_close(cli, fnum);
5697 for (i=0;i<1000;i++) {
5698 fstring fname;
5699 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5700 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5701 fprintf(stderr,"Failed to open %s\n", fname);
5702 return False;
5706 /* Now ensure that doing an old list sees both files and directories. */
5707 num_seen = 0;
5708 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5709 printf("num_seen = %d\n", num_seen );
5710 /* We should see 100 files + 1000 directories + . and .. */
5711 if (num_seen != 2002)
5712 correct = False;
5714 /* Ensure if we have the "must have" bits we only see the
5715 * relevent entries.
5717 num_seen = 0;
5718 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5719 printf("num_seen = %d\n", num_seen );
5720 if (num_seen != 1002)
5721 correct = False;
5723 num_seen = 0;
5724 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5725 printf("num_seen = %d\n", num_seen );
5726 if (num_seen != 1000)
5727 correct = False;
5729 /* Delete everything. */
5730 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5731 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5732 cli_rmdir(cli, "\\LISTDIR");
5734 #if 0
5735 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5736 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5737 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5738 #endif
5740 if (!torture_close_connection(cli)) {
5741 correct = False;
5744 printf("finished dirtest1\n");
5746 return correct;
5749 static bool run_error_map_extract(int dummy) {
5751 static struct cli_state *c_dos;
5752 static struct cli_state *c_nt;
5753 NTSTATUS status;
5755 uint32 error;
5757 uint32 flgs2, errnum;
5758 uint8 errclass;
5760 NTSTATUS nt_status;
5762 fstring user;
5764 /* NT-Error connection */
5766 if (!(c_nt = open_nbt_connection())) {
5767 return False;
5770 c_nt->use_spnego = False;
5772 status = cli_negprot(c_nt);
5774 if (!NT_STATUS_IS_OK(status)) {
5775 printf("%s rejected the NT-error negprot (%s)\n", host,
5776 nt_errstr(status));
5777 cli_shutdown(c_nt);
5778 return False;
5781 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5782 workgroup))) {
5783 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5784 return False;
5787 /* DOS-Error connection */
5789 if (!(c_dos = open_nbt_connection())) {
5790 return False;
5793 c_dos->use_spnego = False;
5794 c_dos->force_dos_errors = True;
5796 status = cli_negprot(c_dos);
5797 if (!NT_STATUS_IS_OK(status)) {
5798 printf("%s rejected the DOS-error negprot (%s)\n", host,
5799 nt_errstr(status));
5800 cli_shutdown(c_dos);
5801 return False;
5804 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5805 workgroup))) {
5806 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5807 return False;
5810 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5811 fstr_sprintf(user, "%X", error);
5813 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5814 password, strlen(password),
5815 password, strlen(password),
5816 workgroup))) {
5817 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5820 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5822 /* Case #1: 32-bit NT errors */
5823 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5824 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5825 } else {
5826 printf("/** Dos error on NT connection! (%s) */\n",
5827 cli_errstr(c_nt));
5828 nt_status = NT_STATUS(0xc0000000);
5831 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5832 password, strlen(password),
5833 password, strlen(password),
5834 workgroup))) {
5835 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5837 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5839 /* Case #1: 32-bit NT errors */
5840 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5841 printf("/** NT error on DOS connection! (%s) */\n",
5842 cli_errstr(c_nt));
5843 errnum = errclass = 0;
5844 } else {
5845 cli_dos_error(c_dos, &errclass, &errnum);
5848 if (NT_STATUS_V(nt_status) != error) {
5849 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5850 get_nt_error_c_code(NT_STATUS(error)),
5851 get_nt_error_c_code(nt_status));
5854 printf("\t{%s,\t%s,\t%s},\n",
5855 smb_dos_err_class(errclass),
5856 smb_dos_err_name(errclass, errnum),
5857 get_nt_error_c_code(NT_STATUS(error)));
5859 return True;
5862 static bool run_sesssetup_bench(int dummy)
5864 static struct cli_state *c;
5865 const char *fname = "\\file.dat";
5866 uint16_t fnum;
5867 NTSTATUS status;
5868 int i;
5870 if (!torture_open_connection(&c, 0)) {
5871 return false;
5874 if (!NT_STATUS_IS_OK(cli_ntcreate(
5875 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5876 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5877 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5878 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5879 return false;
5882 for (i=0; i<torture_numops; i++) {
5883 status = cli_session_setup(
5884 c, username,
5885 password, strlen(password),
5886 password, strlen(password),
5887 workgroup);
5888 if (!NT_STATUS_IS_OK(status)) {
5889 d_printf("(%s) cli_session_setup failed: %s\n",
5890 __location__, nt_errstr(status));
5891 return false;
5894 d_printf("\r%d ", (int)c->vuid);
5896 status = cli_ulogoff(c);
5897 if (!NT_STATUS_IS_OK(status)) {
5898 d_printf("(%s) cli_ulogoff failed: %s\n",
5899 __location__, nt_errstr(status));
5900 return false;
5902 c->vuid = 0;
5905 return true;
5908 static bool subst_test(const char *str, const char *user, const char *domain,
5909 uid_t uid, gid_t gid, const char *expected)
5911 char *subst;
5912 bool result = true;
5914 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5916 if (strcmp(subst, expected) != 0) {
5917 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5918 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5919 expected);
5920 result = false;
5923 TALLOC_FREE(subst);
5924 return result;
5927 static void chain1_open_completion(struct tevent_req *req)
5929 uint16_t fnum;
5930 NTSTATUS status;
5931 status = cli_open_recv(req, &fnum);
5932 TALLOC_FREE(req);
5934 d_printf("cli_open_recv returned %s: %d\n",
5935 nt_errstr(status),
5936 NT_STATUS_IS_OK(status) ? fnum : -1);
5939 static void chain1_write_completion(struct tevent_req *req)
5941 size_t written;
5942 NTSTATUS status;
5943 status = cli_write_andx_recv(req, &written);
5944 TALLOC_FREE(req);
5946 d_printf("cli_write_andx_recv returned %s: %d\n",
5947 nt_errstr(status),
5948 NT_STATUS_IS_OK(status) ? (int)written : -1);
5951 static void chain1_close_completion(struct tevent_req *req)
5953 NTSTATUS status;
5954 bool *done = (bool *)tevent_req_callback_data_void(req);
5956 status = cli_close_recv(req);
5957 *done = true;
5959 TALLOC_FREE(req);
5961 d_printf("cli_close returned %s\n", nt_errstr(status));
5964 static bool run_chain1(int dummy)
5966 struct cli_state *cli1;
5967 struct event_context *evt = event_context_init(NULL);
5968 struct tevent_req *reqs[3], *smbreqs[3];
5969 bool done = false;
5970 const char *str = "foobar";
5971 NTSTATUS status;
5973 printf("starting chain1 test\n");
5974 if (!torture_open_connection(&cli1, 0)) {
5975 return False;
5978 cli_sockopt(cli1, sockops);
5980 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5981 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5982 if (reqs[0] == NULL) return false;
5983 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5986 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5987 (uint8_t *)str, 0, strlen(str)+1,
5988 smbreqs, 1, &smbreqs[1]);
5989 if (reqs[1] == NULL) return false;
5990 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5992 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5993 if (reqs[2] == NULL) return false;
5994 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5996 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5997 if (!NT_STATUS_IS_OK(status)) {
5998 return false;
6001 while (!done) {
6002 event_loop_once(evt);
6005 torture_close_connection(cli1);
6006 return True;
6009 static void chain2_sesssetup_completion(struct tevent_req *req)
6011 NTSTATUS status;
6012 status = cli_session_setup_guest_recv(req);
6013 d_printf("sesssetup returned %s\n", nt_errstr(status));
6016 static void chain2_tcon_completion(struct tevent_req *req)
6018 bool *done = (bool *)tevent_req_callback_data_void(req);
6019 NTSTATUS status;
6020 status = cli_tcon_andx_recv(req);
6021 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6022 *done = true;
6025 static bool run_chain2(int dummy)
6027 struct cli_state *cli1;
6028 struct event_context *evt = event_context_init(NULL);
6029 struct tevent_req *reqs[2], *smbreqs[2];
6030 bool done = false;
6031 NTSTATUS status;
6033 printf("starting chain2 test\n");
6034 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6035 port_to_use, Undefined, 0);
6036 if (!NT_STATUS_IS_OK(status)) {
6037 return False;
6040 cli_sockopt(cli1, sockops);
6042 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6043 &smbreqs[0]);
6044 if (reqs[0] == NULL) return false;
6045 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6047 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6048 "?????", NULL, 0, &smbreqs[1]);
6049 if (reqs[1] == NULL) return false;
6050 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6052 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6053 if (!NT_STATUS_IS_OK(status)) {
6054 return false;
6057 while (!done) {
6058 event_loop_once(evt);
6061 torture_close_connection(cli1);
6062 return True;
6066 struct torture_createdel_state {
6067 struct tevent_context *ev;
6068 struct cli_state *cli;
6071 static void torture_createdel_created(struct tevent_req *subreq);
6072 static void torture_createdel_closed(struct tevent_req *subreq);
6074 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6075 struct tevent_context *ev,
6076 struct cli_state *cli,
6077 const char *name)
6079 struct tevent_req *req, *subreq;
6080 struct torture_createdel_state *state;
6082 req = tevent_req_create(mem_ctx, &state,
6083 struct torture_createdel_state);
6084 if (req == NULL) {
6085 return NULL;
6087 state->ev = ev;
6088 state->cli = cli;
6090 subreq = cli_ntcreate_send(
6091 state, ev, cli, name, 0,
6092 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6093 FILE_ATTRIBUTE_NORMAL,
6094 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6095 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6097 if (tevent_req_nomem(subreq, req)) {
6098 return tevent_req_post(req, ev);
6100 tevent_req_set_callback(subreq, torture_createdel_created, req);
6101 return req;
6104 static void torture_createdel_created(struct tevent_req *subreq)
6106 struct tevent_req *req = tevent_req_callback_data(
6107 subreq, struct tevent_req);
6108 struct torture_createdel_state *state = tevent_req_data(
6109 req, struct torture_createdel_state);
6110 NTSTATUS status;
6111 uint16_t fnum;
6113 status = cli_ntcreate_recv(subreq, &fnum);
6114 TALLOC_FREE(subreq);
6115 if (!NT_STATUS_IS_OK(status)) {
6116 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6117 nt_errstr(status)));
6118 tevent_req_nterror(req, status);
6119 return;
6122 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6123 if (tevent_req_nomem(subreq, req)) {
6124 return;
6126 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6129 static void torture_createdel_closed(struct tevent_req *subreq)
6131 struct tevent_req *req = tevent_req_callback_data(
6132 subreq, struct tevent_req);
6133 NTSTATUS status;
6135 status = cli_close_recv(subreq);
6136 if (!NT_STATUS_IS_OK(status)) {
6137 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6138 tevent_req_nterror(req, status);
6139 return;
6141 tevent_req_done(req);
6144 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6146 return tevent_req_simple_recv_ntstatus(req);
6149 struct torture_createdels_state {
6150 struct tevent_context *ev;
6151 struct cli_state *cli;
6152 const char *base_name;
6153 int sent;
6154 int received;
6155 int num_files;
6156 struct tevent_req **reqs;
6159 static void torture_createdels_done(struct tevent_req *subreq);
6161 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6162 struct tevent_context *ev,
6163 struct cli_state *cli,
6164 const char *base_name,
6165 int num_parallel,
6166 int num_files)
6168 struct tevent_req *req;
6169 struct torture_createdels_state *state;
6170 int i;
6172 req = tevent_req_create(mem_ctx, &state,
6173 struct torture_createdels_state);
6174 if (req == NULL) {
6175 return NULL;
6177 state->ev = ev;
6178 state->cli = cli;
6179 state->base_name = talloc_strdup(state, base_name);
6180 if (tevent_req_nomem(state->base_name, req)) {
6181 return tevent_req_post(req, ev);
6183 state->num_files = MAX(num_parallel, num_files);
6184 state->sent = 0;
6185 state->received = 0;
6187 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6188 if (tevent_req_nomem(state->reqs, req)) {
6189 return tevent_req_post(req, ev);
6192 for (i=0; i<num_parallel; i++) {
6193 char *name;
6195 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6196 state->sent);
6197 if (tevent_req_nomem(name, req)) {
6198 return tevent_req_post(req, ev);
6200 state->reqs[i] = torture_createdel_send(
6201 state->reqs, state->ev, state->cli, name);
6202 if (tevent_req_nomem(state->reqs[i], req)) {
6203 return tevent_req_post(req, ev);
6205 name = talloc_move(state->reqs[i], &name);
6206 tevent_req_set_callback(state->reqs[i],
6207 torture_createdels_done, req);
6208 state->sent += 1;
6210 return req;
6213 static void torture_createdels_done(struct tevent_req *subreq)
6215 struct tevent_req *req = tevent_req_callback_data(
6216 subreq, struct tevent_req);
6217 struct torture_createdels_state *state = tevent_req_data(
6218 req, struct torture_createdels_state);
6219 size_t num_parallel = talloc_array_length(state->reqs);
6220 NTSTATUS status;
6221 char *name;
6222 int i;
6224 status = torture_createdel_recv(subreq);
6225 if (!NT_STATUS_IS_OK(status)){
6226 DEBUG(10, ("torture_createdel_recv returned %s\n",
6227 nt_errstr(status)));
6228 TALLOC_FREE(subreq);
6229 tevent_req_nterror(req, status);
6230 return;
6233 for (i=0; i<num_parallel; i++) {
6234 if (subreq == state->reqs[i]) {
6235 break;
6238 if (i == num_parallel) {
6239 DEBUG(10, ("received something we did not send\n"));
6240 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6241 return;
6243 TALLOC_FREE(state->reqs[i]);
6245 if (state->sent >= state->num_files) {
6246 tevent_req_done(req);
6247 return;
6250 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6251 state->sent);
6252 if (tevent_req_nomem(name, req)) {
6253 return;
6255 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6256 state->cli, name);
6257 if (tevent_req_nomem(state->reqs[i], req)) {
6258 return;
6260 name = talloc_move(state->reqs[i], &name);
6261 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6262 state->sent += 1;
6265 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6267 return tevent_req_simple_recv_ntstatus(req);
6270 struct swallow_notify_state {
6271 struct tevent_context *ev;
6272 struct cli_state *cli;
6273 uint16_t fnum;
6274 uint32_t completion_filter;
6275 bool recursive;
6276 bool (*fn)(uint32_t action, const char *name, void *priv);
6277 void *priv;
6280 static void swallow_notify_done(struct tevent_req *subreq);
6282 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6283 struct tevent_context *ev,
6284 struct cli_state *cli,
6285 uint16_t fnum,
6286 uint32_t completion_filter,
6287 bool recursive,
6288 bool (*fn)(uint32_t action,
6289 const char *name,
6290 void *priv),
6291 void *priv)
6293 struct tevent_req *req, *subreq;
6294 struct swallow_notify_state *state;
6296 req = tevent_req_create(mem_ctx, &state,
6297 struct swallow_notify_state);
6298 if (req == NULL) {
6299 return NULL;
6301 state->ev = ev;
6302 state->cli = cli;
6303 state->fnum = fnum;
6304 state->completion_filter = completion_filter;
6305 state->recursive = recursive;
6306 state->fn = fn;
6307 state->priv = priv;
6309 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6310 0xffff, state->completion_filter,
6311 state->recursive);
6312 if (tevent_req_nomem(subreq, req)) {
6313 return tevent_req_post(req, ev);
6315 tevent_req_set_callback(subreq, swallow_notify_done, req);
6316 return req;
6319 static void swallow_notify_done(struct tevent_req *subreq)
6321 struct tevent_req *req = tevent_req_callback_data(
6322 subreq, struct tevent_req);
6323 struct swallow_notify_state *state = tevent_req_data(
6324 req, struct swallow_notify_state);
6325 NTSTATUS status;
6326 uint32_t i, num_changes;
6327 struct notify_change *changes;
6329 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6330 TALLOC_FREE(subreq);
6331 if (!NT_STATUS_IS_OK(status)) {
6332 DEBUG(10, ("cli_notify_recv returned %s\n",
6333 nt_errstr(status)));
6334 tevent_req_nterror(req, status);
6335 return;
6338 for (i=0; i<num_changes; i++) {
6339 state->fn(changes[i].action, changes[i].name, state->priv);
6341 TALLOC_FREE(changes);
6343 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6344 0xffff, state->completion_filter,
6345 state->recursive);
6346 if (tevent_req_nomem(subreq, req)) {
6347 return;
6349 tevent_req_set_callback(subreq, swallow_notify_done, req);
6352 static bool print_notifies(uint32_t action, const char *name, void *priv)
6354 if (DEBUGLEVEL > 5) {
6355 d_printf("%d %s\n", (int)action, name);
6357 return true;
6360 static void notify_bench_done(struct tevent_req *req)
6362 int *num_finished = (int *)tevent_req_callback_data_void(req);
6363 *num_finished += 1;
6366 static bool run_notify_bench(int dummy)
6368 const char *dname = "\\notify-bench";
6369 struct tevent_context *ev;
6370 NTSTATUS status;
6371 uint16_t dnum;
6372 struct tevent_req *req1;
6373 struct tevent_req *req2 = NULL;
6374 int i, num_unc_names;
6375 int num_finished = 0;
6377 printf("starting notify-bench test\n");
6379 if (use_multishare_conn) {
6380 char **unc_list;
6381 unc_list = file_lines_load(multishare_conn_fname,
6382 &num_unc_names, 0, NULL);
6383 if (!unc_list || num_unc_names <= 0) {
6384 d_printf("Failed to load unc names list from '%s'\n",
6385 multishare_conn_fname);
6386 return false;
6388 TALLOC_FREE(unc_list);
6389 } else {
6390 num_unc_names = 1;
6393 ev = tevent_context_init(talloc_tos());
6394 if (ev == NULL) {
6395 d_printf("tevent_context_init failed\n");
6396 return false;
6399 for (i=0; i<num_unc_names; i++) {
6400 struct cli_state *cli;
6401 char *base_fname;
6403 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6404 dname, i);
6405 if (base_fname == NULL) {
6406 return false;
6409 if (!torture_open_connection(&cli, i)) {
6410 return false;
6413 status = cli_ntcreate(cli, dname, 0,
6414 MAXIMUM_ALLOWED_ACCESS,
6415 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6416 FILE_SHARE_DELETE,
6417 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6418 &dnum);
6420 if (!NT_STATUS_IS_OK(status)) {
6421 d_printf("Could not create %s: %s\n", dname,
6422 nt_errstr(status));
6423 return false;
6426 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6427 FILE_NOTIFY_CHANGE_FILE_NAME |
6428 FILE_NOTIFY_CHANGE_DIR_NAME |
6429 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6430 FILE_NOTIFY_CHANGE_LAST_WRITE,
6431 false, print_notifies, NULL);
6432 if (req1 == NULL) {
6433 d_printf("Could not create notify request\n");
6434 return false;
6437 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6438 base_fname, 10, torture_numops);
6439 if (req2 == NULL) {
6440 d_printf("Could not create createdels request\n");
6441 return false;
6443 TALLOC_FREE(base_fname);
6445 tevent_req_set_callback(req2, notify_bench_done,
6446 &num_finished);
6449 while (num_finished < num_unc_names) {
6450 int ret;
6451 ret = tevent_loop_once(ev);
6452 if (ret != 0) {
6453 d_printf("tevent_loop_once failed\n");
6454 return false;
6458 if (!tevent_req_poll(req2, ev)) {
6459 d_printf("tevent_req_poll failed\n");
6462 status = torture_createdels_recv(req2);
6463 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6465 return true;
6468 static bool run_mangle1(int dummy)
6470 struct cli_state *cli;
6471 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6472 uint16_t fnum;
6473 fstring alt_name;
6474 NTSTATUS status;
6475 time_t change_time, access_time, write_time;
6476 SMB_OFF_T size;
6477 uint16_t mode;
6479 printf("starting mangle1 test\n");
6480 if (!torture_open_connection(&cli, 0)) {
6481 return False;
6484 cli_sockopt(cli, sockops);
6486 if (!NT_STATUS_IS_OK(cli_ntcreate(
6487 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6488 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6489 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6490 return false;
6492 cli_close(cli, fnum);
6494 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6495 if (!NT_STATUS_IS_OK(status)) {
6496 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6497 nt_errstr(status));
6498 return false;
6500 d_printf("alt_name: %s\n", alt_name);
6502 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6503 d_printf("cli_open(%s) failed: %s\n", alt_name,
6504 cli_errstr(cli));
6505 return false;
6507 cli_close(cli, fnum);
6509 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6510 &write_time, &size, &mode);
6511 if (!NT_STATUS_IS_OK(status)) {
6512 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6513 nt_errstr(status));
6514 return false;
6517 return true;
6520 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6522 size_t *to_pull = (size_t *)priv;
6523 size_t thistime = *to_pull;
6525 thistime = MIN(thistime, n);
6526 if (thistime == 0) {
6527 return 0;
6530 memset(buf, 0, thistime);
6531 *to_pull -= thistime;
6532 return thistime;
6535 static bool run_windows_write(int dummy)
6537 struct cli_state *cli1;
6538 uint16_t fnum;
6539 int i;
6540 bool ret = false;
6541 const char *fname = "\\writetest.txt";
6542 struct timeval start_time;
6543 double seconds;
6544 double kbytes;
6546 printf("starting windows_write test\n");
6547 if (!torture_open_connection(&cli1, 0)) {
6548 return False;
6551 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6552 printf("open failed (%s)\n", cli_errstr(cli1));
6553 return False;
6556 cli_sockopt(cli1, sockops);
6558 start_time = timeval_current();
6560 for (i=0; i<torture_numops; i++) {
6561 uint8_t c = 0;
6562 off_t start = i * torture_blocksize;
6563 NTSTATUS status;
6564 size_t to_pull = torture_blocksize - 1;
6566 status = cli_writeall(cli1, fnum, 0, &c,
6567 start + torture_blocksize - 1, 1, NULL);
6568 if (!NT_STATUS_IS_OK(status)) {
6569 printf("cli_write failed: %s\n", nt_errstr(status));
6570 goto fail;
6573 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6574 null_source, &to_pull);
6575 if (!NT_STATUS_IS_OK(status)) {
6576 printf("cli_push returned: %s\n", nt_errstr(status));
6577 goto fail;
6581 seconds = timeval_elapsed(&start_time);
6582 kbytes = (double)torture_blocksize * torture_numops;
6583 kbytes /= 1024;
6585 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6586 (double)seconds, (int)(kbytes/seconds));
6588 ret = true;
6589 fail:
6590 cli_close(cli1, fnum);
6591 cli_unlink(cli1, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
6592 torture_close_connection(cli1);
6593 return ret;
6596 static bool run_cli_echo(int dummy)
6598 struct cli_state *cli;
6599 NTSTATUS status;
6601 printf("starting cli_echo test\n");
6602 if (!torture_open_connection(&cli, 0)) {
6603 return false;
6605 cli_sockopt(cli, sockops);
6607 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6609 d_printf("cli_echo returned %s\n", nt_errstr(status));
6611 torture_close_connection(cli);
6612 return NT_STATUS_IS_OK(status);
6615 static bool run_uid_regression_test(int dummy)
6617 static struct cli_state *cli;
6618 int16_t old_vuid;
6619 int16_t old_cnum;
6620 bool correct = True;
6621 NTSTATUS status;
6623 printf("starting uid regression test\n");
6625 if (!torture_open_connection(&cli, 0)) {
6626 return False;
6629 cli_sockopt(cli, sockops);
6631 /* Ok - now save then logoff our current user. */
6632 old_vuid = cli->vuid;
6634 status = cli_ulogoff(cli);
6635 if (!NT_STATUS_IS_OK(status)) {
6636 d_printf("(%s) cli_ulogoff failed: %s\n",
6637 __location__, nt_errstr(status));
6638 correct = false;
6639 goto out;
6642 cli->vuid = old_vuid;
6644 /* Try an operation. */
6645 status = cli_mkdir(cli, "\\uid_reg_test");
6646 if (NT_STATUS_IS_OK(status)) {
6647 d_printf("(%s) cli_mkdir succeeded\n",
6648 __location__);
6649 correct = false;
6650 goto out;
6651 } else {
6652 /* Should be bad uid. */
6653 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6654 NT_STATUS_USER_SESSION_DELETED)) {
6655 correct = false;
6656 goto out;
6660 old_cnum = cli->cnum;
6662 /* Now try a SMBtdis with the invald vuid set to zero. */
6663 cli->vuid = 0;
6665 /* This should succeed. */
6666 status = cli_tdis(cli);
6668 if (NT_STATUS_IS_OK(status)) {
6669 d_printf("First tdis with invalid vuid should succeed.\n");
6670 } else {
6671 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6672 correct = false;
6673 goto out;
6676 cli->vuid = old_vuid;
6677 cli->cnum = old_cnum;
6679 /* This should fail. */
6680 status = cli_tdis(cli);
6681 if (NT_STATUS_IS_OK(status)) {
6682 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6683 correct = false;
6684 goto out;
6685 } else {
6686 /* Should be bad tid. */
6687 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6688 NT_STATUS_NETWORK_NAME_DELETED)) {
6689 correct = false;
6690 goto out;
6694 cli_rmdir(cli, "\\uid_reg_test");
6696 out:
6698 cli_shutdown(cli);
6699 return correct;
6703 static const char *illegal_chars = "*\\/?<>|\":";
6704 static char force_shortname_chars[] = " +,.[];=\177";
6706 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6707 const char *mask, void *state)
6709 struct cli_state *pcli = (struct cli_state *)state;
6710 fstring fname;
6711 NTSTATUS status = NT_STATUS_OK;
6713 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6715 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6716 return NT_STATUS_OK;
6718 if (finfo->mode & aDIR) {
6719 status = cli_rmdir(pcli, fname);
6720 if (!NT_STATUS_IS_OK(status)) {
6721 printf("del_fn: failed to rmdir %s\n,", fname );
6723 } else {
6724 status = cli_unlink(pcli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
6725 if (!NT_STATUS_IS_OK(status)) {
6726 printf("del_fn: failed to unlink %s\n,", fname );
6729 return status;
6732 struct sn_state {
6733 int matched;
6734 int i;
6735 bool val;
6738 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6739 const char *name, void *state)
6741 struct sn_state *s = (struct sn_state *)state;
6742 int i = s->i;
6744 #if 0
6745 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6746 i, finfo->name, finfo->short_name);
6747 #endif
6749 if (strchr(force_shortname_chars, i)) {
6750 if (!finfo->short_name[0]) {
6751 /* Shortname not created when it should be. */
6752 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6753 __location__, finfo->name, i);
6754 s->val = true;
6756 } else if (finfo->short_name[0]){
6757 /* Shortname created when it should not be. */
6758 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6759 __location__, finfo->short_name, finfo->name);
6760 s->val = true;
6762 s->matched += 1;
6763 return NT_STATUS_OK;
6766 static bool run_shortname_test(int dummy)
6768 static struct cli_state *cli;
6769 bool correct = True;
6770 int i;
6771 struct sn_state s;
6772 char fname[20];
6774 printf("starting shortname test\n");
6776 if (!torture_open_connection(&cli, 0)) {
6777 return False;
6780 cli_sockopt(cli, sockops);
6782 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6783 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6784 cli_rmdir(cli, "\\shortname");
6786 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6787 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6788 __location__, cli_errstr(cli));
6789 correct = false;
6790 goto out;
6793 strlcpy(fname, "\\shortname\\", sizeof(fname));
6794 strlcat(fname, "test .txt", sizeof(fname));
6796 s.val = false;
6798 for (i = 32; i < 128; i++) {
6799 NTSTATUS status;
6800 uint16_t fnum = (uint16_t)-1;
6802 s.i = i;
6804 if (strchr(illegal_chars, i)) {
6805 continue;
6807 fname[15] = i;
6809 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6810 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6811 if (!NT_STATUS_IS_OK(status)) {
6812 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6813 __location__, fname, cli_errstr(cli));
6814 correct = false;
6815 goto out;
6817 cli_close(cli, fnum);
6819 s.matched = 0;
6820 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6821 &s);
6822 if (s.matched != 1) {
6823 d_printf("(%s) failed to list %s: %s\n",
6824 __location__, fname, cli_errstr(cli));
6825 correct = false;
6826 goto out;
6828 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
6829 d_printf("(%s) failed to delete %s: %s\n",
6830 __location__, fname, cli_errstr(cli));
6831 correct = false;
6832 goto out;
6835 if (s.val) {
6836 correct = false;
6837 goto out;
6841 out:
6843 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6844 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6845 cli_rmdir(cli, "\\shortname");
6846 torture_close_connection(cli);
6847 return correct;
6850 static void pagedsearch_cb(struct tevent_req *req)
6852 int rc;
6853 struct tldap_message *msg;
6854 char *dn;
6856 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6857 if (rc != TLDAP_SUCCESS) {
6858 d_printf("tldap_search_paged_recv failed: %s\n",
6859 tldap_err2string(rc));
6860 return;
6862 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6863 TALLOC_FREE(msg);
6864 return;
6866 if (!tldap_entry_dn(msg, &dn)) {
6867 d_printf("tldap_entry_dn failed\n");
6868 return;
6870 d_printf("%s\n", dn);
6871 TALLOC_FREE(msg);
6874 static bool run_tldap(int dummy)
6876 struct tldap_context *ld;
6877 int fd, rc;
6878 NTSTATUS status;
6879 struct sockaddr_storage addr;
6880 struct tevent_context *ev;
6881 struct tevent_req *req;
6882 char *basedn;
6883 const char *filter;
6885 if (!resolve_name(host, &addr, 0, false)) {
6886 d_printf("could not find host %s\n", host);
6887 return false;
6889 status = open_socket_out(&addr, 389, 9999, &fd);
6890 if (!NT_STATUS_IS_OK(status)) {
6891 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6892 return false;
6895 ld = tldap_context_create(talloc_tos(), fd);
6896 if (ld == NULL) {
6897 close(fd);
6898 d_printf("tldap_context_create failed\n");
6899 return false;
6902 rc = tldap_fetch_rootdse(ld);
6903 if (rc != TLDAP_SUCCESS) {
6904 d_printf("tldap_fetch_rootdse failed: %s\n",
6905 tldap_errstr(talloc_tos(), ld, rc));
6906 return false;
6909 basedn = tldap_talloc_single_attribute(
6910 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6911 if (basedn == NULL) {
6912 d_printf("no defaultNamingContext\n");
6913 return false;
6915 d_printf("defaultNamingContext: %s\n", basedn);
6917 ev = tevent_context_init(talloc_tos());
6918 if (ev == NULL) {
6919 d_printf("tevent_context_init failed\n");
6920 return false;
6923 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6924 TLDAP_SCOPE_SUB, "(objectclass=*)",
6925 NULL, 0, 0,
6926 NULL, 0, NULL, 0, 0, 0, 0, 5);
6927 if (req == NULL) {
6928 d_printf("tldap_search_paged_send failed\n");
6929 return false;
6931 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6933 tevent_req_poll(req, ev);
6935 TALLOC_FREE(req);
6937 /* test search filters against rootDSE */
6938 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6939 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6941 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6942 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6943 talloc_tos(), NULL, NULL);
6944 if (rc != TLDAP_SUCCESS) {
6945 d_printf("tldap_search with complex filter failed: %s\n",
6946 tldap_errstr(talloc_tos(), ld, rc));
6947 return false;
6950 TALLOC_FREE(ld);
6951 return true;
6954 /* Torture test to ensure no regression of :
6955 https://bugzilla.samba.org/show_bug.cgi?id=7084
6958 static bool run_dir_createtime(int dummy)
6960 struct cli_state *cli;
6961 const char *dname = "\\testdir";
6962 const char *fname = "\\testdir\\testfile";
6963 NTSTATUS status;
6964 struct timespec create_time;
6965 struct timespec create_time1;
6966 uint16_t fnum;
6967 bool ret = false;
6969 if (!torture_open_connection(&cli, 0)) {
6970 return false;
6973 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
6974 cli_rmdir(cli, dname);
6976 status = cli_mkdir(cli, dname);
6977 if (!NT_STATUS_IS_OK(status)) {
6978 printf("mkdir failed: %s\n", nt_errstr(status));
6979 goto out;
6982 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6983 NULL, NULL, NULL);
6984 if (!NT_STATUS_IS_OK(status)) {
6985 printf("cli_qpathinfo2 returned %s\n",
6986 nt_errstr(status));
6987 goto out;
6990 /* Sleep 3 seconds, then create a file. */
6991 sleep(3);
6993 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6994 DENY_NONE, &fnum);
6995 if (!NT_STATUS_IS_OK(status)) {
6996 printf("cli_open failed: %s\n", nt_errstr(status));
6997 goto out;
7000 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7001 NULL, NULL, NULL);
7002 if (!NT_STATUS_IS_OK(status)) {
7003 printf("cli_qpathinfo2 (2) returned %s\n",
7004 nt_errstr(status));
7005 goto out;
7008 if (timespec_compare(&create_time1, &create_time)) {
7009 printf("run_dir_createtime: create time was updated (error)\n");
7010 } else {
7011 printf("run_dir_createtime: create time was not updated (correct)\n");
7012 ret = true;
7015 out:
7017 cli_unlink(cli, fname, aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
7018 cli_rmdir(cli, dname);
7019 if (!torture_close_connection(cli)) {
7020 ret = false;
7022 return ret;
7026 static bool run_streamerror(int dummy)
7028 struct cli_state *cli;
7029 const char *dname = "\\testdir";
7030 const char *streamname =
7031 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7032 NTSTATUS status;
7033 time_t change_time, access_time, write_time;
7034 SMB_OFF_T size;
7035 uint16_t mode, fnum;
7036 bool ret = true;
7038 if (!torture_open_connection(&cli, 0)) {
7039 return false;
7042 cli_unlink(cli, "\\testdir\\*", aSYSTEM | FILE_ATTRIBUTE_HIDDEN);
7043 cli_rmdir(cli, dname);
7045 status = cli_mkdir(cli, dname);
7046 if (!NT_STATUS_IS_OK(status)) {
7047 printf("mkdir failed: %s\n", nt_errstr(status));
7048 return false;
7051 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7052 &size, &mode);
7053 status = cli_nt_error(cli);
7055 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7056 printf("pathinfo returned %s, expected "
7057 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7058 nt_errstr(status));
7059 ret = false;
7062 status = cli_ntcreate(cli, streamname, 0x16,
7063 FILE_READ_DATA|FILE_READ_EA|
7064 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7065 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7066 FILE_OPEN, 0, 0, &fnum);
7068 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7069 printf("ntcreate returned %s, expected "
7070 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7071 nt_errstr(status));
7072 ret = false;
7076 cli_rmdir(cli, dname);
7077 return ret;
7080 static bool run_local_substitute(int dummy)
7082 bool ok = true;
7084 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7085 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7086 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7087 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7088 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7089 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7090 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7091 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7093 /* Different captialization rules in sub_basic... */
7095 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7096 "blaDOM") == 0);
7098 return ok;
7101 static bool run_local_base64(int dummy)
7103 int i;
7104 bool ret = true;
7106 for (i=1; i<2000; i++) {
7107 DATA_BLOB blob1, blob2;
7108 char *b64;
7110 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7111 blob1.length = i;
7112 generate_random_buffer(blob1.data, blob1.length);
7114 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7115 if (b64 == NULL) {
7116 d_fprintf(stderr, "base64_encode_data_blob failed "
7117 "for %d bytes\n", i);
7118 ret = false;
7120 blob2 = base64_decode_data_blob(b64);
7121 TALLOC_FREE(b64);
7123 if (data_blob_cmp(&blob1, &blob2)) {
7124 d_fprintf(stderr, "data_blob_cmp failed for %d "
7125 "bytes\n", i);
7126 ret = false;
7128 TALLOC_FREE(blob1.data);
7129 data_blob_free(&blob2);
7131 return ret;
7134 static bool run_local_gencache(int dummy)
7136 char *val;
7137 time_t tm;
7138 DATA_BLOB blob;
7140 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7141 d_printf("%s: gencache_set() failed\n", __location__);
7142 return False;
7145 if (!gencache_get("foo", NULL, NULL)) {
7146 d_printf("%s: gencache_get() failed\n", __location__);
7147 return False;
7150 if (!gencache_get("foo", &val, &tm)) {
7151 d_printf("%s: gencache_get() failed\n", __location__);
7152 return False;
7155 if (strcmp(val, "bar") != 0) {
7156 d_printf("%s: gencache_get() returned %s, expected %s\n",
7157 __location__, val, "bar");
7158 SAFE_FREE(val);
7159 return False;
7162 SAFE_FREE(val);
7164 if (!gencache_del("foo")) {
7165 d_printf("%s: gencache_del() failed\n", __location__);
7166 return False;
7168 if (gencache_del("foo")) {
7169 d_printf("%s: second gencache_del() succeeded\n",
7170 __location__);
7171 return False;
7174 if (gencache_get("foo", &val, &tm)) {
7175 d_printf("%s: gencache_get() on deleted entry "
7176 "succeeded\n", __location__);
7177 return False;
7180 blob = data_blob_string_const_null("bar");
7181 tm = time(NULL) + 60;
7183 if (!gencache_set_data_blob("foo", &blob, tm)) {
7184 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7185 return False;
7188 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7189 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7190 return False;
7193 if (strcmp((const char *)blob.data, "bar") != 0) {
7194 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7195 __location__, (const char *)blob.data, "bar");
7196 data_blob_free(&blob);
7197 return False;
7200 data_blob_free(&blob);
7202 if (!gencache_del("foo")) {
7203 d_printf("%s: gencache_del() failed\n", __location__);
7204 return False;
7206 if (gencache_del("foo")) {
7207 d_printf("%s: second gencache_del() succeeded\n",
7208 __location__);
7209 return False;
7212 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7213 d_printf("%s: gencache_get_data_blob() on deleted entry "
7214 "succeeded\n", __location__);
7215 return False;
7218 return True;
7221 static bool rbt_testval(struct db_context *db, const char *key,
7222 const char *value)
7224 struct db_record *rec;
7225 TDB_DATA data = string_tdb_data(value);
7226 bool ret = false;
7227 NTSTATUS status;
7229 rec = db->fetch_locked(db, db, string_tdb_data(key));
7230 if (rec == NULL) {
7231 d_fprintf(stderr, "fetch_locked failed\n");
7232 goto done;
7234 status = rec->store(rec, data, 0);
7235 if (!NT_STATUS_IS_OK(status)) {
7236 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7237 goto done;
7239 TALLOC_FREE(rec);
7241 rec = db->fetch_locked(db, db, string_tdb_data(key));
7242 if (rec == NULL) {
7243 d_fprintf(stderr, "second fetch_locked failed\n");
7244 goto done;
7246 if ((rec->value.dsize != data.dsize)
7247 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7248 d_fprintf(stderr, "Got wrong data back\n");
7249 goto done;
7252 ret = true;
7253 done:
7254 TALLOC_FREE(rec);
7255 return ret;
7258 static bool run_local_rbtree(int dummy)
7260 struct db_context *db;
7261 bool ret = false;
7262 int i;
7264 db = db_open_rbt(NULL);
7266 if (db == NULL) {
7267 d_fprintf(stderr, "db_open_rbt failed\n");
7268 return false;
7271 for (i=0; i<1000; i++) {
7272 char *key, *value;
7274 if (asprintf(&key, "key%ld", random()) == -1) {
7275 goto done;
7277 if (asprintf(&value, "value%ld", random()) == -1) {
7278 SAFE_FREE(key);
7279 goto done;
7282 if (!rbt_testval(db, key, value)) {
7283 SAFE_FREE(key);
7284 SAFE_FREE(value);
7285 goto done;
7288 SAFE_FREE(value);
7289 if (asprintf(&value, "value%ld", random()) == -1) {
7290 SAFE_FREE(key);
7291 goto done;
7294 if (!rbt_testval(db, key, value)) {
7295 SAFE_FREE(key);
7296 SAFE_FREE(value);
7297 goto done;
7300 SAFE_FREE(key);
7301 SAFE_FREE(value);
7304 ret = true;
7306 done:
7307 TALLOC_FREE(db);
7308 return ret;
7311 struct talloc_dict_test {
7312 int content;
7315 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7317 int *count = (int *)priv;
7318 *count += 1;
7319 return 0;
7322 static bool run_local_talloc_dict(int dummy)
7324 struct talloc_dict *dict;
7325 struct talloc_dict_test *t;
7326 int key, count;
7328 dict = talloc_dict_init(talloc_tos());
7329 if (dict == NULL) {
7330 return false;
7333 t = talloc(talloc_tos(), struct talloc_dict_test);
7334 if (t == NULL) {
7335 return false;
7338 key = 1;
7339 t->content = 1;
7340 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7341 return false;
7344 count = 0;
7345 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7346 return false;
7349 if (count != 1) {
7350 return false;
7353 TALLOC_FREE(dict);
7355 return true;
7358 static bool run_local_string_to_sid(int dummy) {
7359 struct dom_sid sid;
7361 if (string_to_sid(&sid, "S--1-5-32-545")) {
7362 printf("allowing S--1-5-32-545\n");
7363 return false;
7365 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7366 printf("allowing S-1-5-32-+545\n");
7367 return false;
7369 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")) {
7370 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7371 return false;
7373 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7374 printf("allowing S-1-5-32-545-abc\n");
7375 return false;
7377 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7378 printf("could not parse S-1-5-32-545\n");
7379 return false;
7381 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7382 printf("mis-parsed S-1-5-32-545 as %s\n",
7383 sid_string_tos(&sid));
7384 return false;
7386 return true;
7389 static bool run_local_binary_to_sid(int dummy) {
7390 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7391 static const char good_binary_sid[] = {
7392 0x1, /* revision number */
7393 15, /* num auths */
7394 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7395 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7396 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7397 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7398 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7399 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7400 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7401 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7402 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7403 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7404 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7405 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7406 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7407 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7408 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7409 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7412 static const char long_binary_sid[] = {
7413 0x1, /* revision number */
7414 15, /* num auths */
7415 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7416 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7417 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7418 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7419 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7420 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7421 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7422 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7423 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7424 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7425 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7426 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7427 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7428 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7429 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7430 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7431 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7432 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7433 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7436 static const char long_binary_sid2[] = {
7437 0x1, /* revision number */
7438 32, /* num auths */
7439 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7440 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7441 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7442 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7443 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7444 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7445 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7446 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7447 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7448 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7449 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7450 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7451 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7452 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7453 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7454 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7455 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7456 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7457 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7458 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7459 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7460 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7461 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7462 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7463 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7464 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7465 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7466 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7467 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7468 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7469 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7470 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7471 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7474 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7475 return false;
7477 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7478 return false;
7480 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7481 return false;
7483 return true;
7486 /* Split a path name into filename and stream name components. Canonicalise
7487 * such that an implicit $DATA token is always explicit.
7489 * The "specification" of this function can be found in the
7490 * run_local_stream_name() function in torture.c, I've tried those
7491 * combinations against a W2k3 server.
7494 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7495 char **pbase, char **pstream)
7497 char *base = NULL;
7498 char *stream = NULL;
7499 char *sname; /* stream name */
7500 const char *stype; /* stream type */
7502 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7504 sname = strchr_m(fname, ':');
7506 if (lp_posix_pathnames() || (sname == NULL)) {
7507 if (pbase != NULL) {
7508 base = talloc_strdup(mem_ctx, fname);
7509 NT_STATUS_HAVE_NO_MEMORY(base);
7511 goto done;
7514 if (pbase != NULL) {
7515 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7516 NT_STATUS_HAVE_NO_MEMORY(base);
7519 sname += 1;
7521 stype = strchr_m(sname, ':');
7523 if (stype == NULL) {
7524 sname = talloc_strdup(mem_ctx, sname);
7525 stype = "$DATA";
7527 else {
7528 if (StrCaseCmp(stype, ":$DATA") != 0) {
7530 * If there is an explicit stream type, so far we only
7531 * allow $DATA. Is there anything else allowed? -- vl
7533 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7534 TALLOC_FREE(base);
7535 return NT_STATUS_OBJECT_NAME_INVALID;
7537 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7538 stype += 1;
7541 if (sname == NULL) {
7542 TALLOC_FREE(base);
7543 return NT_STATUS_NO_MEMORY;
7546 if (sname[0] == '\0') {
7548 * no stream name, so no stream
7550 goto done;
7553 if (pstream != NULL) {
7554 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7555 if (stream == NULL) {
7556 TALLOC_FREE(sname);
7557 TALLOC_FREE(base);
7558 return NT_STATUS_NO_MEMORY;
7561 * upper-case the type field
7563 strupper_m(strchr_m(stream, ':')+1);
7566 done:
7567 if (pbase != NULL) {
7568 *pbase = base;
7570 if (pstream != NULL) {
7571 *pstream = stream;
7573 return NT_STATUS_OK;
7576 static bool test_stream_name(const char *fname, const char *expected_base,
7577 const char *expected_stream,
7578 NTSTATUS expected_status)
7580 NTSTATUS status;
7581 char *base = NULL;
7582 char *stream = NULL;
7584 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7585 if (!NT_STATUS_EQUAL(status, expected_status)) {
7586 goto error;
7589 if (!NT_STATUS_IS_OK(status)) {
7590 return true;
7593 if (base == NULL) goto error;
7595 if (strcmp(expected_base, base) != 0) goto error;
7597 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7598 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7600 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7601 goto error;
7603 TALLOC_FREE(base);
7604 TALLOC_FREE(stream);
7605 return true;
7607 error:
7608 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7609 fname, expected_base ? expected_base : "<NULL>",
7610 expected_stream ? expected_stream : "<NULL>",
7611 nt_errstr(expected_status));
7612 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7613 base ? base : "<NULL>", stream ? stream : "<NULL>",
7614 nt_errstr(status));
7615 TALLOC_FREE(base);
7616 TALLOC_FREE(stream);
7617 return false;
7620 static bool run_local_stream_name(int dummy)
7622 bool ret = true;
7624 ret &= test_stream_name(
7625 "bla", "bla", NULL, NT_STATUS_OK);
7626 ret &= test_stream_name(
7627 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7628 ret &= test_stream_name(
7629 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7630 ret &= test_stream_name(
7631 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7632 ret &= test_stream_name(
7633 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7634 ret &= test_stream_name(
7635 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7636 ret &= test_stream_name(
7637 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7638 ret &= test_stream_name(
7639 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7641 return ret;
7644 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7646 if (a.length != b.length) {
7647 printf("a.length=%d != b.length=%d\n",
7648 (int)a.length, (int)b.length);
7649 return false;
7651 if (memcmp(a.data, b.data, a.length) != 0) {
7652 printf("a.data and b.data differ\n");
7653 return false;
7655 return true;
7658 static bool run_local_memcache(int dummy)
7660 struct memcache *cache;
7661 DATA_BLOB k1, k2;
7662 DATA_BLOB d1, d2, d3;
7663 DATA_BLOB v1, v2, v3;
7665 TALLOC_CTX *mem_ctx;
7666 char *str1, *str2;
7667 size_t size1, size2;
7668 bool ret = false;
7670 cache = memcache_init(NULL, 100);
7672 if (cache == NULL) {
7673 printf("memcache_init failed\n");
7674 return false;
7677 d1 = data_blob_const("d1", 2);
7678 d2 = data_blob_const("d2", 2);
7679 d3 = data_blob_const("d3", 2);
7681 k1 = data_blob_const("d1", 2);
7682 k2 = data_blob_const("d2", 2);
7684 memcache_add(cache, STAT_CACHE, k1, d1);
7685 memcache_add(cache, GETWD_CACHE, k2, d2);
7687 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7688 printf("could not find k1\n");
7689 return false;
7691 if (!data_blob_equal(d1, v1)) {
7692 return false;
7695 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7696 printf("could not find k2\n");
7697 return false;
7699 if (!data_blob_equal(d2, v2)) {
7700 return false;
7703 memcache_add(cache, STAT_CACHE, k1, d3);
7705 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7706 printf("could not find replaced k1\n");
7707 return false;
7709 if (!data_blob_equal(d3, v3)) {
7710 return false;
7713 memcache_add(cache, GETWD_CACHE, k1, d1);
7715 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7716 printf("Did find k2, should have been purged\n");
7717 return false;
7720 TALLOC_FREE(cache);
7722 cache = memcache_init(NULL, 0);
7724 mem_ctx = talloc_init("foo");
7726 str1 = talloc_strdup(mem_ctx, "string1");
7727 str2 = talloc_strdup(mem_ctx, "string2");
7729 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7730 data_blob_string_const("torture"), &str1);
7731 size1 = talloc_total_size(cache);
7733 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7734 data_blob_string_const("torture"), &str2);
7735 size2 = talloc_total_size(cache);
7737 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7739 if (size2 > size1) {
7740 printf("memcache leaks memory!\n");
7741 goto fail;
7744 ret = true;
7745 fail:
7746 TALLOC_FREE(cache);
7747 return ret;
7750 static void wbclient_done(struct tevent_req *req)
7752 wbcErr wbc_err;
7753 struct winbindd_response *wb_resp;
7754 int *i = (int *)tevent_req_callback_data_void(req);
7756 wbc_err = wb_trans_recv(req, req, &wb_resp);
7757 TALLOC_FREE(req);
7758 *i += 1;
7759 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7762 static bool run_local_wbclient(int dummy)
7764 struct event_context *ev;
7765 struct wb_context **wb_ctx;
7766 struct winbindd_request wb_req;
7767 bool result = false;
7768 int i, j;
7770 BlockSignals(True, SIGPIPE);
7772 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7773 if (ev == NULL) {
7774 goto fail;
7777 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7778 if (wb_ctx == NULL) {
7779 goto fail;
7782 ZERO_STRUCT(wb_req);
7783 wb_req.cmd = WINBINDD_PING;
7785 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7787 for (i=0; i<nprocs; i++) {
7788 wb_ctx[i] = wb_context_init(ev, NULL);
7789 if (wb_ctx[i] == NULL) {
7790 goto fail;
7792 for (j=0; j<torture_numops; j++) {
7793 struct tevent_req *req;
7794 req = wb_trans_send(ev, ev, wb_ctx[i],
7795 (j % 2) == 0, &wb_req);
7796 if (req == NULL) {
7797 goto fail;
7799 tevent_req_set_callback(req, wbclient_done, &i);
7803 i = 0;
7805 while (i < nprocs * torture_numops) {
7806 event_loop_once(ev);
7809 result = true;
7810 fail:
7811 TALLOC_FREE(ev);
7812 return result;
7815 static void getaddrinfo_finished(struct tevent_req *req)
7817 char *name = (char *)tevent_req_callback_data_void(req);
7818 struct addrinfo *ainfo;
7819 int res;
7821 res = getaddrinfo_recv(req, &ainfo);
7822 if (res != 0) {
7823 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7824 return;
7826 d_printf("gai(%s) succeeded\n", name);
7827 freeaddrinfo(ainfo);
7830 static bool run_getaddrinfo_send(int dummy)
7832 TALLOC_CTX *frame = talloc_stackframe();
7833 struct fncall_context *ctx;
7834 struct tevent_context *ev;
7835 bool result = false;
7836 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7837 "www.slashdot.org", "heise.de" };
7838 struct tevent_req *reqs[4];
7839 int i;
7841 ev = event_context_init(frame);
7842 if (ev == NULL) {
7843 goto fail;
7846 ctx = fncall_context_init(frame, 4);
7848 for (i=0; i<ARRAY_SIZE(names); i++) {
7849 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7850 NULL);
7851 if (reqs[i] == NULL) {
7852 goto fail;
7854 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7855 (void *)names[i]);
7858 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7859 tevent_loop_once(ev);
7862 result = true;
7863 fail:
7864 TALLOC_FREE(frame);
7865 return result;
7868 static bool dbtrans_inc(struct db_context *db)
7870 struct db_record *rec;
7871 uint32_t *val;
7872 bool ret = false;
7873 NTSTATUS status;
7875 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7876 if (rec == NULL) {
7877 printf(__location__ "fetch_lock failed\n");
7878 return false;
7881 if (rec->value.dsize != sizeof(uint32_t)) {
7882 printf(__location__ "value.dsize = %d\n",
7883 (int)rec->value.dsize);
7884 goto fail;
7887 val = (uint32_t *)rec->value.dptr;
7888 *val += 1;
7890 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7891 sizeof(uint32_t)),
7893 if (!NT_STATUS_IS_OK(status)) {
7894 printf(__location__ "store failed: %s\n",
7895 nt_errstr(status));
7896 goto fail;
7899 ret = true;
7900 fail:
7901 TALLOC_FREE(rec);
7902 return ret;
7905 static bool run_local_dbtrans(int dummy)
7907 struct db_context *db;
7908 struct db_record *rec;
7909 NTSTATUS status;
7910 uint32_t initial;
7911 int res;
7913 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7914 O_RDWR|O_CREAT, 0600);
7915 if (db == NULL) {
7916 printf("Could not open transtest.db\n");
7917 return false;
7920 res = db->transaction_start(db);
7921 if (res == -1) {
7922 printf(__location__ "transaction_start failed\n");
7923 return false;
7926 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7927 if (rec == NULL) {
7928 printf(__location__ "fetch_lock failed\n");
7929 return false;
7932 if (rec->value.dptr == NULL) {
7933 initial = 0;
7934 status = rec->store(
7935 rec, make_tdb_data((uint8_t *)&initial,
7936 sizeof(initial)),
7938 if (!NT_STATUS_IS_OK(status)) {
7939 printf(__location__ "store returned %s\n",
7940 nt_errstr(status));
7941 return false;
7945 TALLOC_FREE(rec);
7947 res = db->transaction_commit(db);
7948 if (res == -1) {
7949 printf(__location__ "transaction_commit failed\n");
7950 return false;
7953 while (true) {
7954 uint32_t val, val2;
7955 int i;
7957 res = db->transaction_start(db);
7958 if (res == -1) {
7959 printf(__location__ "transaction_start failed\n");
7960 break;
7963 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7964 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7965 break;
7968 for (i=0; i<10; i++) {
7969 if (!dbtrans_inc(db)) {
7970 return false;
7974 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7975 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7976 break;
7979 if (val2 != val + 10) {
7980 printf(__location__ "val=%d, val2=%d\n",
7981 (int)val, (int)val2);
7982 break;
7985 printf("val2=%d\r", val2);
7987 res = db->transaction_commit(db);
7988 if (res == -1) {
7989 printf(__location__ "transaction_commit failed\n");
7990 break;
7994 TALLOC_FREE(db);
7995 return true;
7999 * Just a dummy test to be run under a debugger. There's no real way
8000 * to inspect the tevent_select specific function from outside of
8001 * tevent_select.c.
8004 static bool run_local_tevent_select(int dummy)
8006 struct tevent_context *ev;
8007 struct tevent_fd *fd1, *fd2;
8008 bool result = false;
8010 ev = tevent_context_init_byname(NULL, "select");
8011 if (ev == NULL) {
8012 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8013 goto fail;
8016 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8017 if (fd1 == NULL) {
8018 d_fprintf(stderr, "tevent_add_fd failed\n");
8019 goto fail;
8021 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8022 if (fd2 == NULL) {
8023 d_fprintf(stderr, "tevent_add_fd failed\n");
8024 goto fail;
8026 TALLOC_FREE(fd2);
8028 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8029 if (fd2 == NULL) {
8030 d_fprintf(stderr, "tevent_add_fd failed\n");
8031 goto fail;
8034 result = true;
8035 fail:
8036 TALLOC_FREE(ev);
8037 return result;
8040 static double create_procs(bool (*fn)(int), bool *result)
8042 int i, status;
8043 volatile pid_t *child_status;
8044 volatile bool *child_status_out;
8045 int synccount;
8046 int tries = 8;
8047 struct timeval start;
8049 synccount = 0;
8051 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8052 if (!child_status) {
8053 printf("Failed to setup shared memory\n");
8054 return -1;
8057 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8058 if (!child_status_out) {
8059 printf("Failed to setup result status shared memory\n");
8060 return -1;
8063 for (i = 0; i < nprocs; i++) {
8064 child_status[i] = 0;
8065 child_status_out[i] = True;
8068 start = timeval_current();
8070 for (i=0;i<nprocs;i++) {
8071 procnum = i;
8072 if (fork() == 0) {
8073 pid_t mypid = getpid();
8074 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8076 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8078 while (1) {
8079 if (torture_open_connection(&current_cli, i)) break;
8080 if (tries-- == 0) {
8081 printf("pid %d failed to start\n", (int)getpid());
8082 _exit(1);
8084 smb_msleep(10);
8087 child_status[i] = getpid();
8089 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8091 child_status_out[i] = fn(i);
8092 _exit(0);
8096 do {
8097 synccount = 0;
8098 for (i=0;i<nprocs;i++) {
8099 if (child_status[i]) synccount++;
8101 if (synccount == nprocs) break;
8102 smb_msleep(10);
8103 } while (timeval_elapsed(&start) < 30);
8105 if (synccount != nprocs) {
8106 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8107 *result = False;
8108 return timeval_elapsed(&start);
8111 /* start the client load */
8112 start = timeval_current();
8114 for (i=0;i<nprocs;i++) {
8115 child_status[i] = 0;
8118 printf("%d clients started\n", nprocs);
8120 for (i=0;i<nprocs;i++) {
8121 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8124 printf("\n");
8126 for (i=0;i<nprocs;i++) {
8127 if (!child_status_out[i]) {
8128 *result = False;
8131 return timeval_elapsed(&start);
8134 #define FLAG_MULTIPROC 1
8136 static struct {
8137 const char *name;
8138 bool (*fn)(int);
8139 unsigned flags;
8140 } torture_ops[] = {
8141 {"FDPASS", run_fdpasstest, 0},
8142 {"LOCK1", run_locktest1, 0},
8143 {"LOCK2", run_locktest2, 0},
8144 {"LOCK3", run_locktest3, 0},
8145 {"LOCK4", run_locktest4, 0},
8146 {"LOCK5", run_locktest5, 0},
8147 {"LOCK6", run_locktest6, 0},
8148 {"LOCK7", run_locktest7, 0},
8149 {"LOCK8", run_locktest8, 0},
8150 {"LOCK9", run_locktest9, 0},
8151 {"UNLINK", run_unlinktest, 0},
8152 {"BROWSE", run_browsetest, 0},
8153 {"ATTR", run_attrtest, 0},
8154 {"TRANS2", run_trans2test, 0},
8155 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8156 {"TORTURE",run_torture, FLAG_MULTIPROC},
8157 {"RANDOMIPC", run_randomipc, 0},
8158 {"NEGNOWAIT", run_negprot_nowait, 0},
8159 {"NBENCH", run_nbench, 0},
8160 {"NBENCH2", run_nbench2, 0},
8161 {"OPLOCK1", run_oplock1, 0},
8162 {"OPLOCK2", run_oplock2, 0},
8163 {"OPLOCK3", run_oplock3, 0},
8164 {"OPLOCK4", run_oplock4, 0},
8165 {"DIR", run_dirtest, 0},
8166 {"DIR1", run_dirtest1, 0},
8167 {"DIR-CREATETIME", run_dir_createtime, 0},
8168 {"DENY1", torture_denytest1, 0},
8169 {"DENY2", torture_denytest2, 0},
8170 {"TCON", run_tcon_test, 0},
8171 {"TCONDEV", run_tcon_devtype_test, 0},
8172 {"RW1", run_readwritetest, 0},
8173 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8174 {"RW3", run_readwritelarge, 0},
8175 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8176 {"OPEN", run_opentest, 0},
8177 {"POSIX", run_simple_posix_open_test, 0},
8178 {"POSIX-APPEND", run_posix_append, 0},
8179 {"ASYNC-ECHO", run_async_echo, 0},
8180 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8181 { "SHORTNAME-TEST", run_shortname_test, 0},
8182 { "ADDRCHANGE", run_addrchange, 0},
8183 #if 1
8184 {"OPENATTR", run_openattrtest, 0},
8185 #endif
8186 {"XCOPY", run_xcopy, 0},
8187 {"RENAME", run_rename, 0},
8188 {"DELETE", run_deletetest, 0},
8189 {"DELETE-LN", run_deletetest_ln, 0},
8190 {"PROPERTIES", run_properties, 0},
8191 {"MANGLE", torture_mangle, 0},
8192 {"MANGLE1", run_mangle1, 0},
8193 {"W2K", run_w2ktest, 0},
8194 {"TRANS2SCAN", torture_trans2_scan, 0},
8195 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8196 {"UTABLE", torture_utable, 0},
8197 {"CASETABLE", torture_casetable, 0},
8198 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8199 {"PIPE_NUMBER", run_pipe_number, 0},
8200 {"TCON2", run_tcon2_test, 0},
8201 {"IOCTL", torture_ioctl_test, 0},
8202 {"CHKPATH", torture_chkpath_test, 0},
8203 {"FDSESS", run_fdsesstest, 0},
8204 { "EATEST", run_eatest, 0},
8205 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8206 { "CHAIN1", run_chain1, 0},
8207 { "CHAIN2", run_chain2, 0},
8208 { "WINDOWS-WRITE", run_windows_write, 0},
8209 { "CLI_ECHO", run_cli_echo, 0},
8210 { "GETADDRINFO", run_getaddrinfo_send, 0},
8211 { "TLDAP", run_tldap },
8212 { "STREAMERROR", run_streamerror },
8213 { "NOTIFY-BENCH", run_notify_bench },
8214 { "BAD-NBT-SESSION", run_bad_nbt_session },
8215 { "SMB-ANY-CONNECT", run_smb_any_connect },
8216 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8217 { "LOCAL-GENCACHE", run_local_gencache, 0},
8218 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8219 { "LOCAL-BASE64", run_local_base64, 0},
8220 { "LOCAL-RBTREE", run_local_rbtree, 0},
8221 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8222 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8223 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8224 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8225 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8226 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8227 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8228 {NULL, NULL, 0}};
8232 /****************************************************************************
8233 run a specified test or "ALL"
8234 ****************************************************************************/
8235 static bool run_test(const char *name)
8237 bool ret = True;
8238 bool result = True;
8239 bool found = False;
8240 int i;
8241 double t;
8242 if (strequal(name,"ALL")) {
8243 for (i=0;torture_ops[i].name;i++) {
8244 run_test(torture_ops[i].name);
8246 found = True;
8249 for (i=0;torture_ops[i].name;i++) {
8250 fstr_sprintf(randomfname, "\\XX%x",
8251 (unsigned)random());
8253 if (strequal(name, torture_ops[i].name)) {
8254 found = True;
8255 printf("Running %s\n", name);
8256 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8257 t = create_procs(torture_ops[i].fn, &result);
8258 if (!result) {
8259 ret = False;
8260 printf("TEST %s FAILED!\n", name);
8262 } else {
8263 struct timeval start;
8264 start = timeval_current();
8265 if (!torture_ops[i].fn(0)) {
8266 ret = False;
8267 printf("TEST %s FAILED!\n", name);
8269 t = timeval_elapsed(&start);
8271 printf("%s took %g secs\n\n", name, t);
8275 if (!found) {
8276 printf("Did not find a test named %s\n", name);
8277 ret = False;
8280 return ret;
8284 static void usage(void)
8286 int i;
8288 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8289 printf("Please use samba4 torture.\n\n");
8291 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8293 printf("\t-d debuglevel\n");
8294 printf("\t-U user%%pass\n");
8295 printf("\t-k use kerberos\n");
8296 printf("\t-N numprocs\n");
8297 printf("\t-n my_netbios_name\n");
8298 printf("\t-W workgroup\n");
8299 printf("\t-o num_operations\n");
8300 printf("\t-O socket_options\n");
8301 printf("\t-m maximum protocol\n");
8302 printf("\t-L use oplocks\n");
8303 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8304 printf("\t-A showall\n");
8305 printf("\t-p port\n");
8306 printf("\t-s seed\n");
8307 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8308 printf("\n\n");
8310 printf("tests are:");
8311 for (i=0;torture_ops[i].name;i++) {
8312 printf(" %s", torture_ops[i].name);
8314 printf("\n");
8316 printf("default test is ALL\n");
8318 exit(1);
8321 /****************************************************************************
8322 main program
8323 ****************************************************************************/
8324 int main(int argc,char *argv[])
8326 int opt, i;
8327 char *p;
8328 int gotuser = 0;
8329 int gotpass = 0;
8330 bool correct = True;
8331 TALLOC_CTX *frame = talloc_stackframe();
8332 int seed = time(NULL);
8334 #ifdef HAVE_SETBUFFER
8335 setbuffer(stdout, NULL, 0);
8336 #endif
8338 setup_logging("smbtorture", DEBUG_STDOUT);
8340 load_case_tables();
8342 if (is_default_dyn_CONFIGFILE()) {
8343 if(getenv("SMB_CONF_PATH")) {
8344 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8347 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8348 load_interfaces();
8350 if (argc < 2) {
8351 usage();
8354 for(p = argv[1]; *p; p++)
8355 if(*p == '\\')
8356 *p = '/';
8358 if (strncmp(argv[1], "//", 2)) {
8359 usage();
8362 fstrcpy(host, &argv[1][2]);
8363 p = strchr_m(&host[2],'/');
8364 if (!p) {
8365 usage();
8367 *p = 0;
8368 fstrcpy(share, p+1);
8370 fstrcpy(myname, get_myname(talloc_tos()));
8371 if (!*myname) {
8372 fprintf(stderr, "Failed to get my hostname.\n");
8373 return 1;
8376 if (*username == 0 && getenv("LOGNAME")) {
8377 fstrcpy(username,getenv("LOGNAME"));
8380 argc--;
8381 argv++;
8383 fstrcpy(workgroup, lp_workgroup());
8385 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8386 switch (opt) {
8387 case 'p':
8388 port_to_use = atoi(optarg);
8389 break;
8390 case 's':
8391 seed = atoi(optarg);
8392 break;
8393 case 'W':
8394 fstrcpy(workgroup,optarg);
8395 break;
8396 case 'm':
8397 max_protocol = interpret_protocol(optarg, max_protocol);
8398 break;
8399 case 'N':
8400 nprocs = atoi(optarg);
8401 break;
8402 case 'o':
8403 torture_numops = atoi(optarg);
8404 break;
8405 case 'd':
8406 lp_set_cmdline("log level", optarg);
8407 break;
8408 case 'O':
8409 sockops = optarg;
8410 break;
8411 case 'L':
8412 use_oplocks = True;
8413 break;
8414 case 'l':
8415 local_path = optarg;
8416 break;
8417 case 'A':
8418 torture_showall = True;
8419 break;
8420 case 'n':
8421 fstrcpy(myname, optarg);
8422 break;
8423 case 'c':
8424 client_txt = optarg;
8425 break;
8426 case 'e':
8427 do_encrypt = true;
8428 break;
8429 case 'k':
8430 #ifdef HAVE_KRB5
8431 use_kerberos = True;
8432 #else
8433 d_printf("No kerberos support compiled in\n");
8434 exit(1);
8435 #endif
8436 break;
8437 case 'U':
8438 gotuser = 1;
8439 fstrcpy(username,optarg);
8440 p = strchr_m(username,'%');
8441 if (p) {
8442 *p = 0;
8443 fstrcpy(password, p+1);
8444 gotpass = 1;
8446 break;
8447 case 'b':
8448 fstrcpy(multishare_conn_fname, optarg);
8449 use_multishare_conn = True;
8450 break;
8451 case 'B':
8452 torture_blocksize = atoi(optarg);
8453 break;
8454 default:
8455 printf("Unknown option %c (%d)\n", (char)opt, opt);
8456 usage();
8460 d_printf("using seed %d\n", seed);
8462 srandom(seed);
8464 if(use_kerberos && !gotuser) gotpass = True;
8466 while (!gotpass) {
8467 p = getpass("Password:");
8468 if (p) {
8469 fstrcpy(password, p);
8470 gotpass = 1;
8474 printf("host=%s share=%s user=%s myname=%s\n",
8475 host, share, username, myname);
8477 if (argc == optind) {
8478 correct = run_test("ALL");
8479 } else {
8480 for (i=optind;i<argc;i++) {
8481 if (!run_test(argv[i])) {
8482 correct = False;
8487 TALLOC_FREE(frame);
8489 if (correct) {
8490 return(0);
8491 } else {
8492 return(1);