libreplace: added likely()/unlikely() macros for gcc
[Samba/aatanasov.git] / source3 / torture / torture.c
blob98694ed3d00a43e78d6aa4329e4105f77041a1e2
1 /*
2 Unix SMB/CIFS implementation.
3 SMB torture tester
4 Copyright (C) Andrew Tridgell 1997-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "includes.h"
21 #include "nsswitch/libwbclient/wbc_async.h"
23 extern char *optarg;
24 extern int optind;
26 static fstring host, workgroup, share, password, username, myname;
27 static int max_protocol = PROTOCOL_NT1;
28 static const char *sockops="TCP_NODELAY";
29 static int nprocs=1;
30 static int port_to_use=0;
31 int torture_numops=100;
32 int torture_blocksize=1024*1024;
33 static int procnum; /* records process count number when forking */
34 static struct cli_state *current_cli;
35 static fstring randomfname;
36 static bool use_oplocks;
37 static bool use_level_II_oplocks;
38 static const char *client_txt = "client_oplocks.txt";
39 static bool use_kerberos;
40 static fstring multishare_conn_fname;
41 static bool use_multishare_conn = False;
42 static bool do_encrypt;
44 bool torture_showall = False;
46 static double create_procs(bool (*fn)(int), bool *result);
49 static struct timeval tp1,tp2;
52 void start_timer(void)
54 GetTimeOfDay(&tp1);
57 double end_timer(void)
59 GetTimeOfDay(&tp2);
60 return((tp2.tv_sec - tp1.tv_sec) +
61 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
65 /* return a pointer to a anonymous shared memory segment of size "size"
66 which will persist across fork() but will disappear when all processes
67 exit
69 The memory is not zeroed
71 This function uses system5 shared memory. It takes advantage of a property
72 that the memory is not destroyed if it is attached when the id is removed
74 void *shm_setup(int size)
76 int shmid;
77 void *ret;
79 #ifdef __QNXNTO__
80 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
81 if (shmid == -1) {
82 printf("can't get shared memory\n");
83 exit(1);
85 shm_unlink("private");
86 if (ftruncate(shmid, size) == -1) {
87 printf("can't set shared memory size\n");
88 exit(1);
90 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
91 if (ret == MAP_FAILED) {
92 printf("can't map shared memory\n");
93 exit(1);
95 #else
96 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
97 if (shmid == -1) {
98 printf("can't get shared memory\n");
99 exit(1);
101 ret = (void *)shmat(shmid, 0, 0);
102 if (!ret || ret == (void *)-1) {
103 printf("can't attach to shared memory\n");
104 return NULL;
106 /* the following releases the ipc, but note that this process
107 and all its children will still have access to the memory, its
108 just that the shmid is no longer valid for other shm calls. This
109 means we don't leave behind lots of shm segments after we exit
111 See Stevens "advanced programming in unix env" for details
113 shmctl(shmid, IPC_RMID, 0);
114 #endif
116 return ret;
119 /********************************************************************
120 Ensure a connection is encrypted.
121 ********************************************************************/
123 static bool force_cli_encryption(struct cli_state *c,
124 const char *sharename)
126 uint16 major, minor;
127 uint32 caplow, caphigh;
128 NTSTATUS status;
130 if (!SERVER_HAS_UNIX_CIFS(c)) {
131 d_printf("Encryption required and "
132 "server that doesn't support "
133 "UNIX extensions - failing connect\n");
134 return false;
137 if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
138 d_printf("Encryption required and "
139 "can't get UNIX CIFS extensions "
140 "version from server.\n");
141 return false;
144 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
145 d_printf("Encryption required and "
146 "share %s doesn't support "
147 "encryption.\n", sharename);
148 return false;
151 if (c->use_kerberos) {
152 status = cli_gss_smb_encryption_start(c);
153 } else {
154 status = cli_raw_ntlm_smb_encryption_start(c,
155 username,
156 password,
157 workgroup);
160 if (!NT_STATUS_IS_OK(status)) {
161 d_printf("Encryption required and "
162 "setup failed with error %s.\n",
163 nt_errstr(status));
164 return false;
167 return true;
171 static struct cli_state *open_nbt_connection(void)
173 struct nmb_name called, calling;
174 struct sockaddr_storage ss;
175 struct cli_state *c;
176 NTSTATUS status;
178 make_nmb_name(&calling, myname, 0x0);
179 make_nmb_name(&called , host, 0x20);
181 zero_sockaddr(&ss);
183 if (!(c = cli_initialise())) {
184 printf("Failed initialize cli_struct to connect with %s\n", host);
185 return NULL;
188 c->port = port_to_use;
190 status = cli_connect(c, host, &ss);
191 if (!NT_STATUS_IS_OK(status)) {
192 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
193 return NULL;
196 c->use_kerberos = use_kerberos;
198 c->timeout = 120000; /* set a really long timeout (2 minutes) */
199 if (use_oplocks) c->use_oplocks = True;
200 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
202 if (!cli_session_request(c, &calling, &called)) {
204 * Well, that failed, try *SMBSERVER ...
205 * However, we must reconnect as well ...
207 status = cli_connect(c, host, &ss);
208 if (!NT_STATUS_IS_OK(status)) {
209 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
210 return NULL;
213 make_nmb_name(&called, "*SMBSERVER", 0x20);
214 if (!cli_session_request(c, &calling, &called)) {
215 printf("%s rejected the session\n",host);
216 printf("We tried with a called name of %s & %s\n",
217 host, "*SMBSERVER");
218 cli_shutdown(c);
219 return NULL;
223 return c;
226 /* Insert a NULL at the first separator of the given path and return a pointer
227 * to the remainder of the string.
229 static char *
230 terminate_path_at_separator(char * path)
232 char * p;
234 if (!path) {
235 return NULL;
238 if ((p = strchr_m(path, '/'))) {
239 *p = '\0';
240 return p + 1;
243 if ((p = strchr_m(path, '\\'))) {
244 *p = '\0';
245 return p + 1;
248 /* No separator. */
249 return NULL;
253 parse a //server/share type UNC name
255 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
256 char **hostname, char **sharename)
258 char *p;
260 *hostname = *sharename = NULL;
262 if (strncmp(unc_name, "\\\\", 2) &&
263 strncmp(unc_name, "//", 2)) {
264 return False;
267 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
268 p = terminate_path_at_separator(*hostname);
270 if (p && *p) {
271 *sharename = talloc_strdup(mem_ctx, p);
272 terminate_path_at_separator(*sharename);
275 if (*hostname && *sharename) {
276 return True;
279 TALLOC_FREE(*hostname);
280 TALLOC_FREE(*sharename);
281 return False;
284 static bool torture_open_connection_share(struct cli_state **c,
285 const char *hostname,
286 const char *sharename)
288 bool retry;
289 int flags = 0;
290 NTSTATUS status;
292 if (use_kerberos)
293 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
294 if (use_oplocks)
295 flags |= CLI_FULL_CONNECTION_OPLOCKS;
296 if (use_level_II_oplocks)
297 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
299 status = cli_full_connection(c, myname,
300 hostname, NULL, port_to_use,
301 sharename, "?????",
302 username, workgroup,
303 password, flags, Undefined, &retry);
304 if (!NT_STATUS_IS_OK(status)) {
305 printf("failed to open share connection: //%s/%s port:%d - %s\n",
306 hostname, sharename, port_to_use, nt_errstr(status));
307 return False;
310 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
312 if (do_encrypt) {
313 return force_cli_encryption(*c,
314 sharename);
316 return True;
319 bool torture_open_connection(struct cli_state **c, int conn_index)
321 char **unc_list = NULL;
322 int num_unc_names = 0;
323 bool result;
325 if (use_multishare_conn==True) {
326 char *h, *s;
327 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
328 if (!unc_list || num_unc_names <= 0) {
329 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
330 exit(1);
333 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
334 NULL, &h, &s)) {
335 printf("Failed to parse UNC name %s\n",
336 unc_list[conn_index % num_unc_names]);
337 TALLOC_FREE(unc_list);
338 exit(1);
341 result = torture_open_connection_share(c, h, s);
343 /* h, s were copied earlier */
344 TALLOC_FREE(unc_list);
345 return result;
348 return torture_open_connection_share(c, host, share);
351 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
353 uint16 old_vuid = cli->vuid;
354 fstring old_user_name;
355 size_t passlen = strlen(password);
356 NTSTATUS status;
357 bool ret;
359 fstrcpy(old_user_name, cli->user_name);
360 cli->vuid = 0;
361 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
362 password, passlen,
363 password, passlen,
364 workgroup));
365 *new_vuid = cli->vuid;
366 cli->vuid = old_vuid;
367 status = cli_set_username(cli, old_user_name);
368 if (!NT_STATUS_IS_OK(status)) {
369 return false;
371 return ret;
375 bool torture_close_connection(struct cli_state *c)
377 bool ret = True;
378 if (!cli_tdis(c)) {
379 printf("tdis failed (%s)\n", cli_errstr(c));
380 ret = False;
383 cli_shutdown(c);
385 return ret;
389 /* check if the server produced the expected error code */
390 static bool check_error(int line, struct cli_state *c,
391 uint8 eclass, uint32 ecode, NTSTATUS nterr)
393 if (cli_is_dos_error(c)) {
394 uint8 cclass;
395 uint32 num;
397 /* Check DOS error */
399 cli_dos_error(c, &cclass, &num);
401 if (eclass != cclass || ecode != num) {
402 printf("unexpected error code class=%d code=%d\n",
403 (int)cclass, (int)num);
404 printf(" expected %d/%d %s (line=%d)\n",
405 (int)eclass, (int)ecode, nt_errstr(nterr), line);
406 return False;
409 } else {
410 NTSTATUS status;
412 /* Check NT error */
414 status = cli_nt_error(c);
416 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
417 printf("unexpected error code %s\n", nt_errstr(status));
418 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
419 return False;
423 return True;
427 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
429 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
430 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
432 return True;
436 static bool rw_torture(struct cli_state *c)
438 const char *lockfname = "\\torture.lck";
439 fstring fname;
440 uint16_t fnum;
441 uint16_t fnum2;
442 pid_t pid2, pid = getpid();
443 int i, j;
444 char buf[1024];
445 bool correct = True;
446 NTSTATUS status;
448 memset(buf, '\0', sizeof(buf));
450 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
451 DENY_NONE, &fnum2);
452 if (!NT_STATUS_IS_OK(status)) {
453 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
455 if (!NT_STATUS_IS_OK(status)) {
456 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
457 return False;
460 for (i=0;i<torture_numops;i++) {
461 unsigned n = (unsigned)sys_random()%10;
462 if (i % 10 == 0) {
463 printf("%d\r", i); fflush(stdout);
465 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
467 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
468 return False;
471 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
472 printf("open failed (%s)\n", cli_errstr(c));
473 correct = False;
474 break;
477 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
478 printf("write failed (%s)\n", cli_errstr(c));
479 correct = False;
482 for (j=0;j<50;j++) {
483 if (cli_write(c, fnum, 0, (char *)buf,
484 sizeof(pid)+(j*sizeof(buf)),
485 sizeof(buf)) != sizeof(buf)) {
486 printf("write failed (%s)\n", cli_errstr(c));
487 correct = False;
491 pid2 = 0;
493 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
494 printf("read failed (%s)\n", cli_errstr(c));
495 correct = False;
498 if (pid2 != pid) {
499 printf("data corruption!\n");
500 correct = False;
503 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
504 printf("close failed (%s)\n", cli_errstr(c));
505 correct = False;
508 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
509 printf("unlink failed (%s)\n", cli_errstr(c));
510 correct = False;
513 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
514 printf("unlock failed (%s)\n", cli_errstr(c));
515 correct = False;
519 cli_close(c, fnum2);
520 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
522 printf("%d\n", i);
524 return correct;
527 static bool run_torture(int dummy)
529 struct cli_state *cli;
530 bool ret;
532 cli = current_cli;
534 cli_sockopt(cli, sockops);
536 ret = rw_torture(cli);
538 if (!torture_close_connection(cli)) {
539 ret = False;
542 return ret;
545 static bool rw_torture3(struct cli_state *c, char *lockfname)
547 uint16_t fnum = (uint16_t)-1;
548 unsigned int i = 0;
549 char buf[131072];
550 char buf_rd[131072];
551 unsigned count;
552 unsigned countprev = 0;
553 ssize_t sent = 0;
554 bool correct = True;
555 NTSTATUS status;
557 srandom(1);
558 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
560 SIVAL(buf, i, sys_random());
563 if (procnum == 0)
565 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
566 DENY_NONE, &fnum))) {
567 printf("first open read/write of %s failed (%s)\n",
568 lockfname, cli_errstr(c));
569 return False;
572 else
574 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
576 status = cli_open(c, lockfname, O_RDONLY,
577 DENY_NONE, &fnum);
578 if (!NT_STATUS_IS_OK(status)) {
579 break;
581 smb_msleep(10);
583 if (!NT_STATUS_IS_OK(status)) {
584 printf("second open read-only of %s failed (%s)\n",
585 lockfname, cli_errstr(c));
586 return False;
590 i = 0;
591 for (count = 0; count < sizeof(buf); count += sent)
593 if (count >= countprev) {
594 printf("%d %8d\r", i, count);
595 fflush(stdout);
596 i++;
597 countprev += (sizeof(buf) / 20);
600 if (procnum == 0)
602 sent = ((unsigned)sys_random()%(20))+ 1;
603 if (sent > sizeof(buf) - count)
605 sent = sizeof(buf) - count;
608 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
609 printf("write failed (%s)\n", cli_errstr(c));
610 correct = False;
613 else
615 sent = cli_read(c, fnum, buf_rd+count, count,
616 sizeof(buf)-count);
617 if (sent < 0)
619 printf("read failed offset:%d size:%ld (%s)\n",
620 count, (unsigned long)sizeof(buf)-count,
621 cli_errstr(c));
622 correct = False;
623 sent = 0;
625 if (sent > 0)
627 if (memcmp(buf_rd+count, buf+count, sent) != 0)
629 printf("read/write compare failed\n");
630 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
631 correct = False;
632 break;
639 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
640 printf("close failed (%s)\n", cli_errstr(c));
641 correct = False;
644 return correct;
647 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
649 const char *lockfname = "\\torture2.lck";
650 uint16_t fnum1;
651 uint16_t fnum2;
652 int i;
653 char buf[131072];
654 char buf_rd[131072];
655 bool correct = True;
656 ssize_t bytes_read;
658 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
659 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
662 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
663 DENY_NONE, &fnum1))) {
664 printf("first open read/write of %s failed (%s)\n",
665 lockfname, cli_errstr(c1));
666 return False;
668 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
669 DENY_NONE, &fnum2))) {
670 printf("second open read-only of %s failed (%s)\n",
671 lockfname, cli_errstr(c2));
672 cli_close(c1, fnum1);
673 return False;
676 for (i=0;i<torture_numops;i++)
678 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
679 if (i % 10 == 0) {
680 printf("%d\r", i); fflush(stdout);
683 generate_random_buffer((unsigned char *)buf, buf_size);
685 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
686 printf("write failed (%s)\n", cli_errstr(c1));
687 correct = False;
688 break;
691 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
692 printf("read failed (%s)\n", cli_errstr(c2));
693 printf("read %d, expected %ld\n", (int)bytes_read,
694 (unsigned long)buf_size);
695 correct = False;
696 break;
699 if (memcmp(buf_rd, buf, buf_size) != 0)
701 printf("read/write compare failed\n");
702 correct = False;
703 break;
707 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
708 printf("close failed (%s)\n", cli_errstr(c2));
709 correct = False;
711 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
712 printf("close failed (%s)\n", cli_errstr(c1));
713 correct = False;
716 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
717 printf("unlink failed (%s)\n", cli_errstr(c1));
718 correct = False;
721 return correct;
724 static bool run_readwritetest(int dummy)
726 struct cli_state *cli1, *cli2;
727 bool test1, test2 = False;
729 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
730 return False;
732 cli_sockopt(cli1, sockops);
733 cli_sockopt(cli2, sockops);
735 printf("starting readwritetest\n");
737 test1 = rw_torture2(cli1, cli2);
738 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
740 if (test1) {
741 test2 = rw_torture2(cli1, cli1);
742 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
745 if (!torture_close_connection(cli1)) {
746 test1 = False;
749 if (!torture_close_connection(cli2)) {
750 test2 = False;
753 return (test1 && test2);
756 static bool run_readwritemulti(int dummy)
758 struct cli_state *cli;
759 bool test;
761 cli = current_cli;
763 cli_sockopt(cli, sockops);
765 printf("run_readwritemulti: fname %s\n", randomfname);
766 test = rw_torture3(cli, randomfname);
768 if (!torture_close_connection(cli)) {
769 test = False;
772 return test;
775 static bool run_readwritelarge(int dummy)
777 static struct cli_state *cli1;
778 uint16_t fnum1;
779 const char *lockfname = "\\large.dat";
780 SMB_OFF_T fsize;
781 char buf[126*1024];
782 bool correct = True;
784 if (!torture_open_connection(&cli1, 0)) {
785 return False;
787 cli_sockopt(cli1, sockops);
788 memset(buf,'\0',sizeof(buf));
790 cli1->max_xmit = 128*1024;
792 printf("starting readwritelarge\n");
794 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
796 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
797 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
798 return False;
801 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
803 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
804 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
805 correct = False;
808 if (fsize == sizeof(buf))
809 printf("readwritelarge test 1 succeeded (size = %lx)\n",
810 (unsigned long)fsize);
811 else {
812 printf("readwritelarge test 1 failed (size = %lx)\n",
813 (unsigned long)fsize);
814 correct = False;
817 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
818 printf("close failed (%s)\n", cli_errstr(cli1));
819 correct = False;
822 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
823 printf("unlink failed (%s)\n", cli_errstr(cli1));
824 correct = False;
827 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
828 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
829 return False;
832 cli1->max_xmit = 4*1024;
834 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
836 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
837 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
838 correct = False;
841 if (fsize == sizeof(buf))
842 printf("readwritelarge test 2 succeeded (size = %lx)\n",
843 (unsigned long)fsize);
844 else {
845 printf("readwritelarge test 2 failed (size = %lx)\n",
846 (unsigned long)fsize);
847 correct = False;
850 #if 0
851 /* ToDo - set allocation. JRA */
852 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
853 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
854 return False;
856 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
857 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
858 correct = False;
860 if (fsize != 0)
861 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
862 #endif
864 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
865 printf("close failed (%s)\n", cli_errstr(cli1));
866 correct = False;
869 if (!torture_close_connection(cli1)) {
870 correct = False;
872 return correct;
875 int line_count = 0;
876 int nbio_id;
878 #define ival(s) strtol(s, NULL, 0)
880 /* run a test that simulates an approximate netbench client load */
881 static bool run_netbench(int client)
883 struct cli_state *cli;
884 int i;
885 char line[1024];
886 char cname[20];
887 FILE *f;
888 const char *params[20];
889 bool correct = True;
891 cli = current_cli;
893 nbio_id = client;
895 cli_sockopt(cli, sockops);
897 nb_setup(cli);
899 slprintf(cname,sizeof(cname)-1, "client%d", client);
901 f = fopen(client_txt, "r");
903 if (!f) {
904 perror(client_txt);
905 return False;
908 while (fgets(line, sizeof(line)-1, f)) {
909 char *saveptr;
910 line_count++;
912 line[strlen(line)-1] = 0;
914 /* printf("[%d] %s\n", line_count, line); */
916 all_string_sub(line,"client1", cname, sizeof(line));
918 /* parse the command parameters */
919 params[0] = strtok_r(line, " ", &saveptr);
920 i = 0;
921 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
923 params[i] = "";
925 if (i < 2) continue;
927 if (!strncmp(params[0],"SMB", 3)) {
928 printf("ERROR: You are using a dbench 1 load file\n");
929 exit(1);
932 if (!strcmp(params[0],"NTCreateX")) {
933 nb_createx(params[1], ival(params[2]), ival(params[3]),
934 ival(params[4]));
935 } else if (!strcmp(params[0],"Close")) {
936 nb_close(ival(params[1]));
937 } else if (!strcmp(params[0],"Rename")) {
938 nb_rename(params[1], params[2]);
939 } else if (!strcmp(params[0],"Unlink")) {
940 nb_unlink(params[1]);
941 } else if (!strcmp(params[0],"Deltree")) {
942 nb_deltree(params[1]);
943 } else if (!strcmp(params[0],"Rmdir")) {
944 nb_rmdir(params[1]);
945 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
946 nb_qpathinfo(params[1]);
947 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
948 nb_qfileinfo(ival(params[1]));
949 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
950 nb_qfsinfo(ival(params[1]));
951 } else if (!strcmp(params[0],"FIND_FIRST")) {
952 nb_findfirst(params[1]);
953 } else if (!strcmp(params[0],"WriteX")) {
954 nb_writex(ival(params[1]),
955 ival(params[2]), ival(params[3]), ival(params[4]));
956 } else if (!strcmp(params[0],"ReadX")) {
957 nb_readx(ival(params[1]),
958 ival(params[2]), ival(params[3]), ival(params[4]));
959 } else if (!strcmp(params[0],"Flush")) {
960 nb_flush(ival(params[1]));
961 } else {
962 printf("Unknown operation %s\n", params[0]);
963 exit(1);
966 fclose(f);
968 nb_cleanup();
970 if (!torture_close_connection(cli)) {
971 correct = False;
974 return correct;
978 /* run a test that simulates an approximate netbench client load */
979 static bool run_nbench(int dummy)
981 double t;
982 bool correct = True;
984 nbio_shmem(nprocs);
986 nbio_id = -1;
988 signal(SIGALRM, nb_alarm);
989 alarm(1);
990 t = create_procs(run_netbench, &correct);
991 alarm(0);
993 printf("\nThroughput %g MB/sec\n",
994 1.0e-6 * nbio_total() / t);
995 return correct;
1000 This test checks for two things:
1002 1) correct support for retaining locks over a close (ie. the server
1003 must not use posix semantics)
1004 2) support for lock timeouts
1006 static bool run_locktest1(int dummy)
1008 struct cli_state *cli1, *cli2;
1009 const char *fname = "\\lockt1.lck";
1010 uint16_t fnum1, fnum2, fnum3;
1011 time_t t1, t2;
1012 unsigned lock_timeout;
1014 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1015 return False;
1017 cli_sockopt(cli1, sockops);
1018 cli_sockopt(cli2, sockops);
1020 printf("starting locktest1\n");
1022 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1024 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1025 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1026 return False;
1028 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1029 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1030 return False;
1032 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1033 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1034 return False;
1037 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1038 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1039 return False;
1043 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1044 printf("lock2 succeeded! This is a locking bug\n");
1045 return False;
1046 } else {
1047 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1048 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1052 lock_timeout = (1 + (random() % 20));
1053 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1054 t1 = time(NULL);
1055 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1056 printf("lock3 succeeded! This is a locking bug\n");
1057 return False;
1058 } else {
1059 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1060 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1062 t2 = time(NULL);
1064 if (ABS(t2 - t1) < lock_timeout-1) {
1065 printf("error: This server appears not to support timed lock requests\n");
1068 printf("server slept for %u seconds for a %u second timeout\n",
1069 (unsigned int)(t2-t1), lock_timeout);
1071 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1072 printf("close1 failed (%s)\n", cli_errstr(cli1));
1073 return False;
1076 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1077 printf("lock4 succeeded! This is a locking bug\n");
1078 return False;
1079 } else {
1080 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1081 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1084 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1085 printf("close2 failed (%s)\n", cli_errstr(cli1));
1086 return False;
1089 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1090 printf("close3 failed (%s)\n", cli_errstr(cli2));
1091 return False;
1094 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1095 printf("unlink failed (%s)\n", cli_errstr(cli1));
1096 return False;
1100 if (!torture_close_connection(cli1)) {
1101 return False;
1104 if (!torture_close_connection(cli2)) {
1105 return False;
1108 printf("Passed locktest1\n");
1109 return True;
1113 this checks to see if a secondary tconx can use open files from an
1114 earlier tconx
1116 static bool run_tcon_test(int dummy)
1118 static struct cli_state *cli;
1119 const char *fname = "\\tcontest.tmp";
1120 uint16 fnum1;
1121 uint16 cnum1, cnum2, cnum3;
1122 uint16 vuid1, vuid2;
1123 char buf[4];
1124 bool ret = True;
1125 NTSTATUS status;
1127 memset(buf, '\0', sizeof(buf));
1129 if (!torture_open_connection(&cli, 0)) {
1130 return False;
1132 cli_sockopt(cli, sockops);
1134 printf("starting tcontest\n");
1136 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1138 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1139 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1140 return False;
1143 cnum1 = cli->cnum;
1144 vuid1 = cli->vuid;
1146 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1147 printf("initial write failed (%s)", cli_errstr(cli));
1148 return False;
1151 status = cli_tcon_andx(cli, share, "?????",
1152 password, strlen(password)+1);
1153 if (!NT_STATUS_IS_OK(status)) {
1154 printf("%s refused 2nd tree connect (%s)\n", host,
1155 nt_errstr(status));
1156 cli_shutdown(cli);
1157 return False;
1160 cnum2 = cli->cnum;
1161 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1162 vuid2 = cli->vuid + 1;
1164 /* try a write with the wrong tid */
1165 cli->cnum = cnum2;
1167 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1168 printf("* server allows write with wrong TID\n");
1169 ret = False;
1170 } else {
1171 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1175 /* try a write with an invalid tid */
1176 cli->cnum = cnum3;
1178 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1179 printf("* server allows write with invalid TID\n");
1180 ret = False;
1181 } else {
1182 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1185 /* try a write with an invalid vuid */
1186 cli->vuid = vuid2;
1187 cli->cnum = cnum1;
1189 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1190 printf("* server allows write with invalid VUID\n");
1191 ret = False;
1192 } else {
1193 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1196 cli->cnum = cnum1;
1197 cli->vuid = vuid1;
1199 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1200 printf("close failed (%s)\n", cli_errstr(cli));
1201 return False;
1204 cli->cnum = cnum2;
1206 if (!cli_tdis(cli)) {
1207 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1208 return False;
1211 cli->cnum = cnum1;
1213 if (!torture_close_connection(cli)) {
1214 return False;
1217 return ret;
1222 checks for old style tcon support
1224 static bool run_tcon2_test(int dummy)
1226 static struct cli_state *cli;
1227 uint16 cnum, max_xmit;
1228 char *service;
1229 NTSTATUS status;
1231 if (!torture_open_connection(&cli, 0)) {
1232 return False;
1234 cli_sockopt(cli, sockops);
1236 printf("starting tcon2 test\n");
1238 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1239 return false;
1242 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 printf("tcon2 failed : %s\n", cli_errstr(cli));
1246 } else {
1247 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1248 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1251 if (!torture_close_connection(cli)) {
1252 return False;
1255 printf("Passed tcon2 test\n");
1256 return True;
1259 static bool tcon_devtest(struct cli_state *cli,
1260 const char *myshare, const char *devtype,
1261 const char *return_devtype,
1262 NTSTATUS expected_error)
1264 NTSTATUS status;
1265 bool ret;
1267 status = cli_tcon_andx(cli, myshare, devtype,
1268 password, strlen(password)+1);
1270 if (NT_STATUS_IS_OK(expected_error)) {
1271 if (NT_STATUS_IS_OK(status)) {
1272 if (strcmp(cli->dev, return_devtype) == 0) {
1273 ret = True;
1274 } else {
1275 printf("tconX to share %s with type %s "
1276 "succeeded but returned the wrong "
1277 "device type (got [%s] but should have got [%s])\n",
1278 myshare, devtype, cli->dev, return_devtype);
1279 ret = False;
1281 } else {
1282 printf("tconX to share %s with type %s "
1283 "should have succeeded but failed\n",
1284 myshare, devtype);
1285 ret = False;
1287 cli_tdis(cli);
1288 } else {
1289 if (NT_STATUS_IS_OK(status)) {
1290 printf("tconx to share %s with type %s "
1291 "should have failed but succeeded\n",
1292 myshare, devtype);
1293 ret = False;
1294 } else {
1295 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1296 expected_error)) {
1297 ret = True;
1298 } else {
1299 printf("Returned unexpected error\n");
1300 ret = False;
1304 return ret;
1308 checks for correct tconX support
1310 static bool run_tcon_devtype_test(int dummy)
1312 static struct cli_state *cli1 = NULL;
1313 bool retry;
1314 int flags = 0;
1315 NTSTATUS status;
1316 bool ret = True;
1318 status = cli_full_connection(&cli1, myname,
1319 host, NULL, port_to_use,
1320 NULL, NULL,
1321 username, workgroup,
1322 password, flags, Undefined, &retry);
1324 if (!NT_STATUS_IS_OK(status)) {
1325 printf("could not open connection\n");
1326 return False;
1329 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1330 ret = False;
1332 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1333 ret = False;
1335 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1336 ret = False;
1338 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1339 ret = False;
1341 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1342 ret = False;
1344 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1345 ret = False;
1347 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1348 ret = False;
1350 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1351 ret = False;
1353 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1354 ret = False;
1356 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1357 ret = False;
1359 cli_shutdown(cli1);
1361 if (ret)
1362 printf("Passed tcondevtest\n");
1364 return ret;
1369 This test checks that
1371 1) the server supports multiple locking contexts on the one SMB
1372 connection, distinguished by PID.
1374 2) the server correctly fails overlapping locks made by the same PID (this
1375 goes against POSIX behaviour, which is why it is tricky to implement)
1377 3) the server denies unlock requests by an incorrect client PID
1379 static bool run_locktest2(int dummy)
1381 static struct cli_state *cli;
1382 const char *fname = "\\lockt2.lck";
1383 uint16_t fnum1, fnum2, fnum3;
1384 bool correct = True;
1386 if (!torture_open_connection(&cli, 0)) {
1387 return False;
1390 cli_sockopt(cli, sockops);
1392 printf("starting locktest2\n");
1394 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1396 cli_setpid(cli, 1);
1398 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1399 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1400 return False;
1403 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1404 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1405 return False;
1408 cli_setpid(cli, 2);
1410 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1411 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1412 return False;
1415 cli_setpid(cli, 1);
1417 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1418 printf("lock1 failed (%s)\n", cli_errstr(cli));
1419 return False;
1422 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1423 printf("WRITE lock1 succeeded! This is a locking bug\n");
1424 correct = False;
1425 } else {
1426 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1427 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1430 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1431 printf("WRITE lock2 succeeded! This is a locking bug\n");
1432 correct = False;
1433 } else {
1434 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1435 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1438 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1439 printf("READ lock2 succeeded! This is a locking bug\n");
1440 correct = False;
1441 } else {
1442 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1443 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1446 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1447 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1449 cli_setpid(cli, 2);
1450 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1451 printf("unlock at 100 succeeded! This is a locking bug\n");
1452 correct = False;
1455 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1456 printf("unlock1 succeeded! This is a locking bug\n");
1457 correct = False;
1458 } else {
1459 if (!check_error(__LINE__, cli,
1460 ERRDOS, ERRlock,
1461 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1464 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1465 printf("unlock2 succeeded! This is a locking bug\n");
1466 correct = False;
1467 } else {
1468 if (!check_error(__LINE__, cli,
1469 ERRDOS, ERRlock,
1470 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1473 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1474 printf("lock3 succeeded! This is a locking bug\n");
1475 correct = False;
1476 } else {
1477 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1480 cli_setpid(cli, 1);
1482 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1483 printf("close1 failed (%s)\n", cli_errstr(cli));
1484 return False;
1487 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1488 printf("close2 failed (%s)\n", cli_errstr(cli));
1489 return False;
1492 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1493 printf("close3 failed (%s)\n", cli_errstr(cli));
1494 return False;
1497 if (!torture_close_connection(cli)) {
1498 correct = False;
1501 printf("locktest2 finished\n");
1503 return correct;
1508 This test checks that
1510 1) the server supports the full offset range in lock requests
1512 static bool run_locktest3(int dummy)
1514 static struct cli_state *cli1, *cli2;
1515 const char *fname = "\\lockt3.lck";
1516 uint16_t fnum1, fnum2;
1517 int i;
1518 uint32 offset;
1519 bool correct = True;
1521 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1523 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1524 return False;
1526 cli_sockopt(cli1, sockops);
1527 cli_sockopt(cli2, sockops);
1529 printf("starting locktest3\n");
1531 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1533 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1534 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1535 return False;
1537 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1538 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1539 return False;
1542 for (offset=i=0;i<torture_numops;i++) {
1543 NEXT_OFFSET;
1544 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1545 printf("lock1 %d failed (%s)\n",
1547 cli_errstr(cli1));
1548 return False;
1551 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1552 printf("lock2 %d failed (%s)\n",
1554 cli_errstr(cli1));
1555 return False;
1559 for (offset=i=0;i<torture_numops;i++) {
1560 NEXT_OFFSET;
1562 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1563 printf("error: lock1 %d succeeded!\n", i);
1564 return False;
1567 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1568 printf("error: lock2 %d succeeded!\n", i);
1569 return False;
1572 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1573 printf("error: lock3 %d succeeded!\n", i);
1574 return False;
1577 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1578 printf("error: lock4 %d succeeded!\n", i);
1579 return False;
1583 for (offset=i=0;i<torture_numops;i++) {
1584 NEXT_OFFSET;
1586 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1587 printf("unlock1 %d failed (%s)\n",
1589 cli_errstr(cli1));
1590 return False;
1593 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1594 printf("unlock2 %d failed (%s)\n",
1596 cli_errstr(cli1));
1597 return False;
1601 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1602 printf("close1 failed (%s)\n", cli_errstr(cli1));
1603 return False;
1606 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1607 printf("close2 failed (%s)\n", cli_errstr(cli2));
1608 return False;
1611 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1612 printf("unlink failed (%s)\n", cli_errstr(cli1));
1613 return False;
1616 if (!torture_close_connection(cli1)) {
1617 correct = False;
1620 if (!torture_close_connection(cli2)) {
1621 correct = False;
1624 printf("finished locktest3\n");
1626 return correct;
1629 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1630 printf("** "); correct = False; \
1634 looks at overlapping locks
1636 static bool run_locktest4(int dummy)
1638 static struct cli_state *cli1, *cli2;
1639 const char *fname = "\\lockt4.lck";
1640 uint16_t fnum1, fnum2, f;
1641 bool ret;
1642 char buf[1000];
1643 bool correct = True;
1645 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1646 return False;
1649 cli_sockopt(cli1, sockops);
1650 cli_sockopt(cli2, sockops);
1652 printf("starting locktest4\n");
1654 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1656 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1657 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1659 memset(buf, 0, sizeof(buf));
1661 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1662 printf("Failed to create file\n");
1663 correct = False;
1664 goto fail;
1667 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1668 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1669 EXPECTED(ret, False);
1670 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1672 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1673 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1674 EXPECTED(ret, True);
1675 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1677 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1678 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1679 EXPECTED(ret, False);
1680 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1682 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1683 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1684 EXPECTED(ret, True);
1685 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1687 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1688 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1689 EXPECTED(ret, False);
1690 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1692 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1693 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1694 EXPECTED(ret, True);
1695 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1697 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1698 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1699 EXPECTED(ret, True);
1700 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1702 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1703 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1704 EXPECTED(ret, False);
1705 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1707 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1708 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1709 EXPECTED(ret, False);
1710 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1712 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1713 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1714 EXPECTED(ret, True);
1715 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1717 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1718 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1719 EXPECTED(ret, False);
1720 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1722 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1723 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1724 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1725 EXPECTED(ret, False);
1726 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1729 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1730 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1731 EXPECTED(ret, False);
1732 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1734 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1735 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1736 EXPECTED(ret, False);
1737 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1740 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1741 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1742 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1743 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1744 EXPECTED(ret, True);
1745 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1748 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1749 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1750 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1751 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1752 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1753 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1754 EXPECTED(ret, True);
1755 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1757 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1758 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1759 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1760 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1761 EXPECTED(ret, True);
1762 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1764 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1765 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1766 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1767 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1768 EXPECTED(ret, True);
1769 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1771 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1772 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1773 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1774 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1775 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1776 EXPECTED(ret, True);
1777 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1779 cli_close(cli1, fnum1);
1780 cli_close(cli2, fnum2);
1781 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1782 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1783 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1784 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1785 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1786 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1787 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1788 cli_close(cli1, f);
1789 cli_close(cli1, fnum1);
1790 EXPECTED(ret, True);
1791 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1793 fail:
1794 cli_close(cli1, fnum1);
1795 cli_close(cli2, fnum2);
1796 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1797 torture_close_connection(cli1);
1798 torture_close_connection(cli2);
1800 printf("finished locktest4\n");
1801 return correct;
1805 looks at lock upgrade/downgrade.
1807 static bool run_locktest5(int dummy)
1809 static struct cli_state *cli1, *cli2;
1810 const char *fname = "\\lockt5.lck";
1811 uint16_t fnum1, fnum2, fnum3;
1812 bool ret;
1813 char buf[1000];
1814 bool correct = True;
1816 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1817 return False;
1820 cli_sockopt(cli1, sockops);
1821 cli_sockopt(cli2, sockops);
1823 printf("starting locktest5\n");
1825 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1827 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1828 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1829 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1831 memset(buf, 0, sizeof(buf));
1833 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1834 printf("Failed to create file\n");
1835 correct = False;
1836 goto fail;
1839 /* Check for NT bug... */
1840 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1841 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1842 cli_close(cli1, fnum1);
1843 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1844 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1845 EXPECTED(ret, True);
1846 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1847 cli_close(cli1, fnum1);
1848 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1849 cli_unlock(cli1, fnum3, 0, 1);
1851 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1852 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1853 EXPECTED(ret, True);
1854 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1856 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1857 EXPECTED(ret, False);
1859 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1861 /* Unlock the process 2 lock. */
1862 cli_unlock(cli2, fnum2, 0, 4);
1864 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1865 EXPECTED(ret, False);
1867 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1869 /* Unlock the process 1 fnum3 lock. */
1870 cli_unlock(cli1, fnum3, 0, 4);
1872 /* Stack 2 more locks here. */
1873 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1874 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1876 EXPECTED(ret, True);
1877 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1879 /* Unlock the first process lock, then check this was the WRITE lock that was
1880 removed. */
1882 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1883 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1885 EXPECTED(ret, True);
1886 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1888 /* Unlock the process 2 lock. */
1889 cli_unlock(cli2, fnum2, 0, 4);
1891 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1893 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1894 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1895 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1897 EXPECTED(ret, True);
1898 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1900 /* Ensure the next unlock fails. */
1901 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1902 EXPECTED(ret, False);
1903 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1905 /* Ensure connection 2 can get a write lock. */
1906 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1907 EXPECTED(ret, True);
1909 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1912 fail:
1913 cli_close(cli1, fnum1);
1914 cli_close(cli2, fnum2);
1915 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1916 if (!torture_close_connection(cli1)) {
1917 correct = False;
1919 if (!torture_close_connection(cli2)) {
1920 correct = False;
1923 printf("finished locktest5\n");
1925 return correct;
1929 tries the unusual lockingX locktype bits
1931 static bool run_locktest6(int dummy)
1933 static struct cli_state *cli;
1934 const char *fname[1] = { "\\lock6.txt" };
1935 int i;
1936 uint16_t fnum;
1937 NTSTATUS status;
1939 if (!torture_open_connection(&cli, 0)) {
1940 return False;
1943 cli_sockopt(cli, sockops);
1945 printf("starting locktest6\n");
1947 for (i=0;i<1;i++) {
1948 printf("Testing %s\n", fname[i]);
1950 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1952 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1953 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1954 cli_close(cli, fnum);
1955 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1957 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1958 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1959 cli_close(cli, fnum);
1960 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1962 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1965 torture_close_connection(cli);
1967 printf("finished locktest6\n");
1968 return True;
1971 static bool run_locktest7(int dummy)
1973 struct cli_state *cli1;
1974 const char *fname = "\\lockt7.lck";
1975 uint16_t fnum1;
1976 char buf[200];
1977 bool correct = False;
1979 if (!torture_open_connection(&cli1, 0)) {
1980 return False;
1983 cli_sockopt(cli1, sockops);
1985 printf("starting locktest7\n");
1987 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1989 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1991 memset(buf, 0, sizeof(buf));
1993 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1994 printf("Failed to create file\n");
1995 goto fail;
1998 cli_setpid(cli1, 1);
2000 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2001 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2002 goto fail;
2003 } else {
2004 printf("pid1 successfully locked range 130:4 for READ\n");
2007 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2008 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2009 goto fail;
2010 } else {
2011 printf("pid1 successfully read the range 130:4\n");
2014 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2015 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2016 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2017 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2018 goto fail;
2020 } else {
2021 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2022 goto fail;
2025 cli_setpid(cli1, 2);
2027 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2028 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2029 } else {
2030 printf("pid2 successfully read the range 130:4\n");
2033 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2034 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2035 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2036 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2037 goto fail;
2039 } else {
2040 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2041 goto fail;
2044 cli_setpid(cli1, 1);
2045 cli_unlock(cli1, fnum1, 130, 4);
2047 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2048 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2049 goto fail;
2050 } else {
2051 printf("pid1 successfully locked range 130:4 for WRITE\n");
2054 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2055 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2056 goto fail;
2057 } else {
2058 printf("pid1 successfully read the range 130:4\n");
2061 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2062 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2063 goto fail;
2064 } else {
2065 printf("pid1 successfully wrote to the range 130:4\n");
2068 cli_setpid(cli1, 2);
2070 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2071 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2072 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2073 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2074 goto fail;
2076 } else {
2077 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2078 goto fail;
2081 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2082 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2083 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2084 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2085 goto fail;
2087 } else {
2088 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2089 goto fail;
2092 cli_unlock(cli1, fnum1, 130, 0);
2093 correct = True;
2095 fail:
2096 cli_close(cli1, fnum1);
2097 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2098 torture_close_connection(cli1);
2100 printf("finished locktest7\n");
2101 return correct;
2105 * This demonstrates a problem with our use of GPFS share modes: A file
2106 * descriptor sitting in the pending close queue holding a GPFS share mode
2107 * blocks opening a file another time. Happens with Word 2007 temp files.
2108 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2109 * open is denied with NT_STATUS_SHARING_VIOLATION.
2112 static bool run_locktest8(int dummy)
2114 struct cli_state *cli1;
2115 const char *fname = "\\lockt8.lck";
2116 uint16_t fnum1, fnum2;
2117 char buf[200];
2118 bool correct = False;
2119 NTSTATUS status;
2121 if (!torture_open_connection(&cli1, 0)) {
2122 return False;
2125 cli_sockopt(cli1, sockops);
2127 printf("starting locktest8\n");
2129 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2131 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2132 &fnum1);
2133 if (!NT_STATUS_IS_OK(status)) {
2134 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2135 return false;
2138 memset(buf, 0, sizeof(buf));
2140 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2141 if (!NT_STATUS_IS_OK(status)) {
2142 d_fprintf(stderr, "cli_open second time returned %s\n",
2143 cli_errstr(cli1));
2144 goto fail;
2147 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2148 printf("Unable to apply read lock on range 1:1, error was "
2149 "%s\n", cli_errstr(cli1));
2150 goto fail;
2153 status = cli_close(cli1, fnum1);
2154 if (!NT_STATUS_IS_OK(status)) {
2155 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2156 goto fail;
2159 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2160 if (!NT_STATUS_IS_OK(status)) {
2161 d_fprintf(stderr, "cli_open third time returned %s\n",
2162 cli_errstr(cli1));
2163 goto fail;
2166 correct = true;
2168 fail:
2169 cli_close(cli1, fnum1);
2170 cli_close(cli1, fnum2);
2171 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2172 torture_close_connection(cli1);
2174 printf("finished locktest8\n");
2175 return correct;
2179 test whether fnums and tids open on one VC are available on another (a major
2180 security hole)
2182 static bool run_fdpasstest(int dummy)
2184 struct cli_state *cli1, *cli2;
2185 const char *fname = "\\fdpass.tst";
2186 uint16_t fnum1;
2187 char buf[1024];
2189 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2190 return False;
2192 cli_sockopt(cli1, sockops);
2193 cli_sockopt(cli2, sockops);
2195 printf("starting fdpasstest\n");
2197 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2199 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2200 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2201 return False;
2204 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2205 printf("write failed (%s)\n", cli_errstr(cli1));
2206 return False;
2209 cli2->vuid = cli1->vuid;
2210 cli2->cnum = cli1->cnum;
2211 cli2->pid = cli1->pid;
2213 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2214 printf("read succeeded! nasty security hole [%s]\n",
2215 buf);
2216 return False;
2219 cli_close(cli1, fnum1);
2220 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2222 torture_close_connection(cli1);
2223 torture_close_connection(cli2);
2225 printf("finished fdpasstest\n");
2226 return True;
2229 static bool run_fdsesstest(int dummy)
2231 struct cli_state *cli;
2232 uint16 new_vuid;
2233 uint16 saved_vuid;
2234 uint16 new_cnum;
2235 uint16 saved_cnum;
2236 const char *fname = "\\fdsess.tst";
2237 const char *fname1 = "\\fdsess1.tst";
2238 uint16_t fnum1;
2239 uint16_t fnum2;
2240 char buf[1024];
2241 bool ret = True;
2243 if (!torture_open_connection(&cli, 0))
2244 return False;
2245 cli_sockopt(cli, sockops);
2247 if (!torture_cli_session_setup2(cli, &new_vuid))
2248 return False;
2250 saved_cnum = cli->cnum;
2251 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2252 return False;
2253 new_cnum = cli->cnum;
2254 cli->cnum = saved_cnum;
2256 printf("starting fdsesstest\n");
2258 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2259 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2261 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2262 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2263 return False;
2266 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2267 printf("write failed (%s)\n", cli_errstr(cli));
2268 return False;
2271 saved_vuid = cli->vuid;
2272 cli->vuid = new_vuid;
2274 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2275 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2276 buf);
2277 ret = False;
2279 /* Try to open a file with different vuid, samba cnum. */
2280 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2281 printf("create with different vuid, same cnum succeeded.\n");
2282 cli_close(cli, fnum2);
2283 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2284 } else {
2285 printf("create with different vuid, same cnum failed.\n");
2286 printf("This will cause problems with service clients.\n");
2287 ret = False;
2290 cli->vuid = saved_vuid;
2292 /* Try with same vuid, different cnum. */
2293 cli->cnum = new_cnum;
2295 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2296 printf("read succeeded with different cnum![%s]\n",
2297 buf);
2298 ret = False;
2301 cli->cnum = saved_cnum;
2302 cli_close(cli, fnum1);
2303 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2305 torture_close_connection(cli);
2307 printf("finished fdsesstest\n");
2308 return ret;
2312 This test checks that
2314 1) the server does not allow an unlink on a file that is open
2316 static bool run_unlinktest(int dummy)
2318 struct cli_state *cli;
2319 const char *fname = "\\unlink.tst";
2320 uint16_t fnum;
2321 bool correct = True;
2323 if (!torture_open_connection(&cli, 0)) {
2324 return False;
2327 cli_sockopt(cli, sockops);
2329 printf("starting unlink test\n");
2331 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2333 cli_setpid(cli, 1);
2335 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2336 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2337 return False;
2340 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2341 printf("error: server allowed unlink on an open file\n");
2342 correct = False;
2343 } else {
2344 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2345 NT_STATUS_SHARING_VIOLATION);
2348 cli_close(cli, fnum);
2349 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2351 if (!torture_close_connection(cli)) {
2352 correct = False;
2355 printf("unlink test finished\n");
2357 return correct;
2362 test how many open files this server supports on the one socket
2364 static bool run_maxfidtest(int dummy)
2366 struct cli_state *cli;
2367 const char *ftemplate = "\\maxfid.%d.%d";
2368 fstring fname;
2369 uint16_t fnums[0x11000];
2370 int i;
2371 int retries=4;
2372 bool correct = True;
2374 cli = current_cli;
2376 if (retries <= 0) {
2377 printf("failed to connect\n");
2378 return False;
2381 cli_sockopt(cli, sockops);
2383 for (i=0; i<0x11000; i++) {
2384 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2385 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2386 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2387 printf("open of %s failed (%s)\n",
2388 fname, cli_errstr(cli));
2389 printf("maximum fnum is %d\n", i);
2390 break;
2392 printf("%6d\r", i);
2394 printf("%6d\n", i);
2395 i--;
2397 printf("cleaning up\n");
2398 for (;i>=0;i--) {
2399 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2400 cli_close(cli, fnums[i]);
2401 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2402 printf("unlink of %s failed (%s)\n",
2403 fname, cli_errstr(cli));
2404 correct = False;
2406 printf("%6d\r", i);
2408 printf("%6d\n", 0);
2410 printf("maxfid test finished\n");
2411 if (!torture_close_connection(cli)) {
2412 correct = False;
2414 return correct;
2417 /* generate a random buffer */
2418 static void rand_buf(char *buf, int len)
2420 while (len--) {
2421 *buf = (char)sys_random();
2422 buf++;
2426 /* send smb negprot commands, not reading the response */
2427 static bool run_negprot_nowait(int dummy)
2429 int i;
2430 static struct cli_state *cli;
2431 bool correct = True;
2433 printf("starting negprot nowait test\n");
2435 if (!(cli = open_nbt_connection())) {
2436 return False;
2439 for (i=0;i<50000;i++) {
2440 cli_negprot_sendsync(cli);
2443 if (!torture_close_connection(cli)) {
2444 correct = False;
2447 printf("finished negprot nowait test\n");
2449 return correct;
2453 /* send random IPC commands */
2454 static bool run_randomipc(int dummy)
2456 char *rparam = NULL;
2457 char *rdata = NULL;
2458 unsigned int rdrcnt,rprcnt;
2459 char param[1024];
2460 int api, param_len, i;
2461 struct cli_state *cli;
2462 bool correct = True;
2463 int count = 50000;
2465 printf("starting random ipc test\n");
2467 if (!torture_open_connection(&cli, 0)) {
2468 return False;
2471 for (i=0;i<count;i++) {
2472 api = sys_random() % 500;
2473 param_len = (sys_random() % 64);
2475 rand_buf(param, param_len);
2477 SSVAL(param,0,api);
2479 cli_api(cli,
2480 param, param_len, 8,
2481 NULL, 0, BUFFER_SIZE,
2482 &rparam, &rprcnt,
2483 &rdata, &rdrcnt);
2484 if (i % 100 == 0) {
2485 printf("%d/%d\r", i,count);
2488 printf("%d/%d\n", i, count);
2490 if (!torture_close_connection(cli)) {
2491 correct = False;
2494 printf("finished random ipc test\n");
2496 return correct;
2501 static void browse_callback(const char *sname, uint32 stype,
2502 const char *comment, void *state)
2504 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2510 This test checks the browse list code
2513 static bool run_browsetest(int dummy)
2515 static struct cli_state *cli;
2516 bool correct = True;
2518 printf("starting browse test\n");
2520 if (!torture_open_connection(&cli, 0)) {
2521 return False;
2524 printf("domain list:\n");
2525 cli_NetServerEnum(cli, cli->server_domain,
2526 SV_TYPE_DOMAIN_ENUM,
2527 browse_callback, NULL);
2529 printf("machine list:\n");
2530 cli_NetServerEnum(cli, cli->server_domain,
2531 SV_TYPE_ALL,
2532 browse_callback, NULL);
2534 if (!torture_close_connection(cli)) {
2535 correct = False;
2538 printf("browse test finished\n");
2540 return correct;
2546 This checks how the getatr calls works
2548 static bool run_attrtest(int dummy)
2550 struct cli_state *cli;
2551 uint16_t fnum;
2552 time_t t, t2;
2553 const char *fname = "\\attrib123456789.tst";
2554 bool correct = True;
2556 printf("starting attrib test\n");
2558 if (!torture_open_connection(&cli, 0)) {
2559 return False;
2562 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2563 cli_open(cli, fname,
2564 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2565 cli_close(cli, fnum);
2566 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2567 printf("getatr failed (%s)\n", cli_errstr(cli));
2568 correct = False;
2571 if (abs(t - time(NULL)) > 60*60*24*10) {
2572 printf("ERROR: SMBgetatr bug. time is %s",
2573 ctime(&t));
2574 t = time(NULL);
2575 correct = True;
2578 t2 = t-60*60*24; /* 1 day ago */
2580 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2581 printf("setatr failed (%s)\n", cli_errstr(cli));
2582 correct = True;
2585 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2586 printf("getatr failed (%s)\n", cli_errstr(cli));
2587 correct = True;
2590 if (t != t2) {
2591 printf("ERROR: getatr/setatr bug. times are\n%s",
2592 ctime(&t));
2593 printf("%s", ctime(&t2));
2594 correct = True;
2597 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2599 if (!torture_close_connection(cli)) {
2600 correct = False;
2603 printf("attrib test finished\n");
2605 return correct;
2610 This checks a couple of trans2 calls
2612 static bool run_trans2test(int dummy)
2614 struct cli_state *cli;
2615 uint16_t fnum;
2616 SMB_OFF_T size;
2617 time_t c_time, a_time, m_time;
2618 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2619 const char *fname = "\\trans2.tst";
2620 const char *dname = "\\trans2";
2621 const char *fname2 = "\\trans2\\trans2.tst";
2622 char pname[1024];
2623 bool correct = True;
2625 printf("starting trans2 test\n");
2627 if (!torture_open_connection(&cli, 0)) {
2628 return False;
2631 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2632 cli_open(cli, fname,
2633 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2634 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2635 &m_time_ts, NULL)) {
2636 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2637 correct = False;
2640 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2641 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2642 correct = False;
2645 if (strcmp(pname, fname)) {
2646 printf("qfilename gave different name? [%s] [%s]\n",
2647 fname, pname);
2648 correct = False;
2651 cli_close(cli, fnum);
2653 sleep(2);
2655 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2656 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2657 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2658 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2659 return False;
2661 cli_close(cli, fnum);
2663 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2664 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2665 correct = False;
2666 } else {
2667 if (c_time != m_time) {
2668 printf("create time=%s", ctime(&c_time));
2669 printf("modify time=%s", ctime(&m_time));
2670 printf("This system appears to have sticky create times\n");
2672 if (a_time % (60*60) == 0) {
2673 printf("access time=%s", ctime(&a_time));
2674 printf("This system appears to set a midnight access time\n");
2675 correct = False;
2678 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2679 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2680 correct = False;
2685 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2686 cli_open(cli, fname,
2687 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2688 cli_close(cli, fnum);
2689 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2690 &m_time_ts, &size, NULL, NULL)) {
2691 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2692 correct = False;
2693 } else {
2694 if (w_time_ts.tv_sec < 60*60*24*2) {
2695 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2696 printf("This system appears to set a initial 0 write time\n");
2697 correct = False;
2701 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2704 /* check if the server updates the directory modification time
2705 when creating a new file */
2706 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2707 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2708 correct = False;
2710 sleep(3);
2711 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2712 &m_time_ts, &size, NULL, NULL)) {
2713 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2714 correct = False;
2717 cli_open(cli, fname2,
2718 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2719 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2720 cli_close(cli, fnum);
2721 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2722 &m_time2_ts, &size, NULL, NULL)) {
2723 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2724 correct = False;
2725 } else {
2726 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2727 == 0) {
2728 printf("This system does not update directory modification times\n");
2729 correct = False;
2732 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2733 cli_rmdir(cli, dname);
2735 if (!torture_close_connection(cli)) {
2736 correct = False;
2739 printf("trans2 test finished\n");
2741 return correct;
2745 This checks new W2K calls.
2748 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2750 char *buf = NULL;
2751 uint32 len;
2752 bool correct = True;
2754 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2755 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2756 correct = False;
2757 } else {
2758 printf("qfileinfo: level %d, len = %u\n", level, len);
2759 dump_data(0, (uint8 *)buf, len);
2760 printf("\n");
2762 SAFE_FREE(buf);
2763 return correct;
2766 static bool run_w2ktest(int dummy)
2768 struct cli_state *cli;
2769 uint16_t fnum;
2770 const char *fname = "\\w2ktest\\w2k.tst";
2771 int level;
2772 bool correct = True;
2774 printf("starting w2k test\n");
2776 if (!torture_open_connection(&cli, 0)) {
2777 return False;
2780 cli_open(cli, fname,
2781 O_RDWR | O_CREAT , DENY_NONE, &fnum);
2783 for (level = 1004; level < 1040; level++) {
2784 new_trans(cli, fnum, level);
2787 cli_close(cli, fnum);
2789 if (!torture_close_connection(cli)) {
2790 correct = False;
2793 printf("w2k test finished\n");
2795 return correct;
2800 this is a harness for some oplock tests
2802 static bool run_oplock1(int dummy)
2804 struct cli_state *cli1;
2805 const char *fname = "\\lockt1.lck";
2806 uint16_t fnum1;
2807 bool correct = True;
2809 printf("starting oplock test 1\n");
2811 if (!torture_open_connection(&cli1, 0)) {
2812 return False;
2815 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2817 cli_sockopt(cli1, sockops);
2819 cli1->use_oplocks = True;
2821 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2822 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2823 return False;
2826 cli1->use_oplocks = False;
2828 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2829 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2831 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
2832 printf("close2 failed (%s)\n", cli_errstr(cli1));
2833 return False;
2836 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
2837 printf("unlink failed (%s)\n", cli_errstr(cli1));
2838 return False;
2841 if (!torture_close_connection(cli1)) {
2842 correct = False;
2845 printf("finished oplock test 1\n");
2847 return correct;
2850 static bool run_oplock2(int dummy)
2852 struct cli_state *cli1, *cli2;
2853 const char *fname = "\\lockt2.lck";
2854 uint16_t fnum1, fnum2;
2855 int saved_use_oplocks = use_oplocks;
2856 char buf[4];
2857 bool correct = True;
2858 volatile bool *shared_correct;
2860 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2861 *shared_correct = True;
2863 use_level_II_oplocks = True;
2864 use_oplocks = True;
2866 printf("starting oplock test 2\n");
2868 if (!torture_open_connection(&cli1, 0)) {
2869 use_level_II_oplocks = False;
2870 use_oplocks = saved_use_oplocks;
2871 return False;
2874 cli1->use_oplocks = True;
2875 cli1->use_level_II_oplocks = True;
2877 if (!torture_open_connection(&cli2, 1)) {
2878 use_level_II_oplocks = False;
2879 use_oplocks = saved_use_oplocks;
2880 return False;
2883 cli2->use_oplocks = True;
2884 cli2->use_level_II_oplocks = True;
2886 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2888 cli_sockopt(cli1, sockops);
2889 cli_sockopt(cli2, sockops);
2891 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2892 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2893 return False;
2896 /* Don't need the globals any more. */
2897 use_level_II_oplocks = False;
2898 use_oplocks = saved_use_oplocks;
2900 if (fork() == 0) {
2901 /* Child code */
2902 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
2903 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2904 *shared_correct = False;
2905 exit(0);
2908 sleep(2);
2910 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
2911 printf("close2 failed (%s)\n", cli_errstr(cli1));
2912 *shared_correct = False;
2915 exit(0);
2918 sleep(2);
2920 /* Ensure cli1 processes the break. Empty file should always return 0
2921 * bytes. */
2923 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2924 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2925 correct = False;
2928 /* Should now be at level II. */
2929 /* Test if sending a write locks causes a break to none. */
2931 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2932 printf("lock failed (%s)\n", cli_errstr(cli1));
2933 correct = False;
2936 cli_unlock(cli1, fnum1, 0, 4);
2938 sleep(2);
2940 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2941 printf("lock failed (%s)\n", cli_errstr(cli1));
2942 correct = False;
2945 cli_unlock(cli1, fnum1, 0, 4);
2947 sleep(2);
2949 cli_read(cli1, fnum1, buf, 0, 4);
2951 #if 0
2952 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2953 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2954 correct = False;
2956 #endif
2958 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
2959 printf("close1 failed (%s)\n", cli_errstr(cli1));
2960 correct = False;
2963 sleep(4);
2965 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
2966 printf("unlink failed (%s)\n", cli_errstr(cli1));
2967 correct = False;
2970 if (!torture_close_connection(cli1)) {
2971 correct = False;
2974 if (!*shared_correct) {
2975 correct = False;
2978 printf("finished oplock test 2\n");
2980 return correct;
2983 /* handler for oplock 3 tests */
2984 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
2986 printf("got oplock break fnum=%d level=%d\n",
2987 fnum, level);
2988 return cli_oplock_ack(cli, fnum, level);
2991 static bool run_oplock3(int dummy)
2993 struct cli_state *cli;
2994 const char *fname = "\\oplockt3.dat";
2995 uint16_t fnum;
2996 char buf[4] = "abcd";
2997 bool correct = True;
2998 volatile bool *shared_correct;
3000 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3001 *shared_correct = True;
3003 printf("starting oplock test 3\n");
3005 if (fork() == 0) {
3006 /* Child code */
3007 use_oplocks = True;
3008 use_level_II_oplocks = True;
3009 if (!torture_open_connection(&cli, 0)) {
3010 *shared_correct = False;
3011 exit(0);
3013 sleep(2);
3014 /* try to trigger a oplock break in parent */
3015 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3016 cli_write(cli, fnum, 0, buf, 0, 4);
3017 exit(0);
3020 /* parent code */
3021 use_oplocks = True;
3022 use_level_II_oplocks = True;
3023 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3024 return False;
3026 cli_oplock_handler(cli, oplock3_handler);
3027 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3028 cli_write(cli, fnum, 0, buf, 0, 4);
3029 cli_close(cli, fnum);
3030 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3031 cli->timeout = 20000;
3032 cli_receive_smb(cli);
3033 printf("finished oplock test 3\n");
3035 return (correct && *shared_correct);
3037 /* What are we looking for here? What's sucess and what's FAILURE? */
3043 Test delete on close semantics.
3045 static bool run_deletetest(int dummy)
3047 struct cli_state *cli1 = NULL;
3048 struct cli_state *cli2 = NULL;
3049 const char *fname = "\\delete.file";
3050 uint16_t fnum1 = (uint16_t)-1;
3051 uint16_t fnum2 = (uint16_t)-1;
3052 bool correct = True;
3054 printf("starting delete test\n");
3056 if (!torture_open_connection(&cli1, 0)) {
3057 return False;
3060 cli_sockopt(cli1, sockops);
3062 /* Test 1 - this should delete the file on close. */
3064 cli_setatr(cli1, fname, 0, 0);
3065 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3067 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3068 0, FILE_OVERWRITE_IF,
3069 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3070 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3071 correct = False;
3072 goto fail;
3075 #if 0 /* JRATEST */
3077 uint32 *accinfo = NULL;
3078 uint32 len;
3079 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3080 if (accinfo)
3081 printf("access mode = 0x%lx\n", *accinfo);
3082 SAFE_FREE(accinfo);
3084 #endif
3086 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3087 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3088 correct = False;
3089 goto fail;
3092 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3093 printf("[1] open of %s succeeded (should fail)\n", fname);
3094 correct = False;
3095 goto fail;
3098 printf("first delete on close test succeeded.\n");
3100 /* Test 2 - this should delete the file on close. */
3102 cli_setatr(cli1, fname, 0, 0);
3103 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3105 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3106 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3107 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3108 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3109 correct = False;
3110 goto fail;
3113 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3114 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3115 correct = False;
3116 goto fail;
3119 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3120 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3121 correct = False;
3122 goto fail;
3125 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3126 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3127 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3128 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3129 correct = False;
3130 goto fail;
3132 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3133 } else
3134 printf("second delete on close test succeeded.\n");
3136 /* Test 3 - ... */
3137 cli_setatr(cli1, fname, 0, 0);
3138 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3140 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3141 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3142 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3143 correct = False;
3144 goto fail;
3147 /* This should fail with a sharing violation - open for delete is only compatible
3148 with SHARE_DELETE. */
3150 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3151 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3152 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3153 correct = False;
3154 goto fail;
3157 /* This should succeed. */
3159 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3160 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3161 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3162 correct = False;
3163 goto fail;
3166 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3167 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3168 correct = False;
3169 goto fail;
3172 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3173 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3174 correct = False;
3175 goto fail;
3178 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3179 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3180 correct = False;
3181 goto fail;
3184 /* This should fail - file should no longer be there. */
3186 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3187 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3188 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3189 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3191 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3192 correct = False;
3193 goto fail;
3194 } else
3195 printf("third delete on close test succeeded.\n");
3197 /* Test 4 ... */
3198 cli_setatr(cli1, fname, 0, 0);
3199 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3201 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3202 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3203 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3204 correct = False;
3205 goto fail;
3208 /* This should succeed. */
3209 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3210 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3211 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3212 correct = False;
3213 goto fail;
3216 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3217 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3218 correct = False;
3219 goto fail;
3222 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3223 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3224 correct = False;
3225 goto fail;
3228 /* This should fail - no more opens once delete on close set. */
3229 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3230 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3231 FILE_OPEN, 0, 0, &fnum2))) {
3232 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3233 correct = False;
3234 goto fail;
3235 } else
3236 printf("fourth delete on close test succeeded.\n");
3238 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3239 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3240 correct = False;
3241 goto fail;
3244 /* Test 5 ... */
3245 cli_setatr(cli1, fname, 0, 0);
3246 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3248 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3249 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3250 correct = False;
3251 goto fail;
3254 /* This should fail - only allowed on NT opens with DELETE access. */
3256 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3257 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3258 correct = False;
3259 goto fail;
3262 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3263 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3264 correct = False;
3265 goto fail;
3268 printf("fifth delete on close test succeeded.\n");
3270 /* Test 6 ... */
3271 cli_setatr(cli1, fname, 0, 0);
3272 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3274 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3275 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3276 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3277 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3278 correct = False;
3279 goto fail;
3282 /* This should fail - only allowed on NT opens with DELETE access. */
3284 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3285 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3286 correct = False;
3287 goto fail;
3290 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3291 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3292 correct = False;
3293 goto fail;
3296 printf("sixth delete on close test succeeded.\n");
3298 /* Test 7 ... */
3299 cli_setatr(cli1, fname, 0, 0);
3300 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3302 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3303 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3304 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3305 correct = False;
3306 goto fail;
3309 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3310 printf("[7] setting delete_on_close on file failed !\n");
3311 correct = False;
3312 goto fail;
3315 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3316 printf("[7] unsetting delete_on_close on file failed !\n");
3317 correct = False;
3318 goto fail;
3321 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3322 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3323 correct = False;
3324 goto fail;
3327 /* This next open should succeed - we reset the flag. */
3329 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3330 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3331 correct = False;
3332 goto fail;
3335 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3336 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3337 correct = False;
3338 goto fail;
3341 printf("seventh delete on close test succeeded.\n");
3343 /* Test 7 ... */
3344 cli_setatr(cli1, fname, 0, 0);
3345 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3347 if (!torture_open_connection(&cli2, 1)) {
3348 printf("[8] failed to open second connection.\n");
3349 correct = False;
3350 goto fail;
3353 cli_sockopt(cli1, sockops);
3355 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3356 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3357 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3358 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3359 correct = False;
3360 goto fail;
3363 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3364 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3365 FILE_OPEN, 0, 0, &fnum2))) {
3366 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3367 correct = False;
3368 goto fail;
3371 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3372 printf("[8] setting delete_on_close on file failed !\n");
3373 correct = False;
3374 goto fail;
3377 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3378 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3379 correct = False;
3380 goto fail;
3383 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3384 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3385 correct = False;
3386 goto fail;
3389 /* This should fail.. */
3390 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3391 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3392 goto fail;
3393 correct = False;
3394 } else
3395 printf("eighth delete on close test succeeded.\n");
3397 /* This should fail - we need to set DELETE_ACCESS. */
3398 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3399 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3400 printf("[9] open of %s succeeded should have failed!\n", fname);
3401 correct = False;
3402 goto fail;
3405 printf("ninth delete on close test succeeded.\n");
3407 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3408 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3409 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3410 correct = False;
3411 goto fail;
3414 /* This should delete the file. */
3415 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3416 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3417 correct = False;
3418 goto fail;
3421 /* This should fail.. */
3422 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3423 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3424 goto fail;
3425 correct = False;
3426 } else
3427 printf("tenth delete on close test succeeded.\n");
3429 cli_setatr(cli1, fname, 0, 0);
3430 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3432 /* What error do we get when attempting to open a read-only file with
3433 delete access ? */
3435 /* Create a readonly file. */
3436 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3437 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3438 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3439 correct = False;
3440 goto fail;
3443 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3444 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3445 correct = False;
3446 goto fail;
3449 /* Now try open for delete access. */
3450 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3451 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3452 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3453 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3454 cli_close(cli1, fnum1);
3455 goto fail;
3456 correct = False;
3457 } else {
3458 NTSTATUS nterr = cli_nt_error(cli1);
3459 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3460 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3461 goto fail;
3462 correct = False;
3463 } else {
3464 printf("eleventh delete on close test succeeded.\n");
3468 printf("finished delete test\n");
3470 fail:
3471 /* FIXME: This will crash if we aborted before cli2 got
3472 * intialized, because these functions don't handle
3473 * uninitialized connections. */
3475 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3476 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3477 cli_setatr(cli1, fname, 0, 0);
3478 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3480 if (cli1 && !torture_close_connection(cli1)) {
3481 correct = False;
3483 if (cli2 && !torture_close_connection(cli2)) {
3484 correct = False;
3486 return correct;
3491 print out server properties
3493 static bool run_properties(int dummy)
3495 struct cli_state *cli;
3496 bool correct = True;
3498 printf("starting properties test\n");
3500 ZERO_STRUCT(cli);
3502 if (!torture_open_connection(&cli, 0)) {
3503 return False;
3506 cli_sockopt(cli, sockops);
3508 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3510 if (!torture_close_connection(cli)) {
3511 correct = False;
3514 return correct;
3519 /* FIRST_DESIRED_ACCESS 0xf019f */
3520 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3521 FILE_READ_EA| /* 0xf */ \
3522 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3523 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3524 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3525 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3526 /* SECOND_DESIRED_ACCESS 0xe0080 */
3527 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3528 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3529 WRITE_OWNER_ACCESS /* 0xe0000 */
3531 #if 0
3532 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3533 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3534 FILE_READ_DATA|\
3535 WRITE_OWNER_ACCESS /* */
3536 #endif
3539 Test ntcreate calls made by xcopy
3541 static bool run_xcopy(int dummy)
3543 static struct cli_state *cli1;
3544 const char *fname = "\\test.txt";
3545 bool correct = True;
3546 uint16_t fnum1, fnum2;
3548 printf("starting xcopy test\n");
3550 if (!torture_open_connection(&cli1, 0)) {
3551 return False;
3554 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3555 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3556 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3557 0x4044, 0, &fnum1))) {
3558 printf("First open failed - %s\n", cli_errstr(cli1));
3559 return False;
3562 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3563 SECOND_DESIRED_ACCESS, 0,
3564 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3565 0x200000, 0, &fnum2))) {
3566 printf("second open failed - %s\n", cli_errstr(cli1));
3567 return False;
3570 if (!torture_close_connection(cli1)) {
3571 correct = False;
3574 return correct;
3578 Test rename on files open with share delete and no share delete.
3580 static bool run_rename(int dummy)
3582 static struct cli_state *cli1;
3583 const char *fname = "\\test.txt";
3584 const char *fname1 = "\\test1.txt";
3585 bool correct = True;
3586 uint16_t fnum1;
3587 NTSTATUS status;
3589 printf("starting rename test\n");
3591 if (!torture_open_connection(&cli1, 0)) {
3592 return False;
3595 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3596 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3597 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3598 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3599 printf("First open failed - %s\n", cli_errstr(cli1));
3600 return False;
3603 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3604 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3605 } else {
3606 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3607 correct = False;
3610 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3611 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3612 return False;
3615 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3616 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3617 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3618 #if 0
3619 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3620 #else
3621 FILE_SHARE_DELETE|FILE_SHARE_READ,
3622 #endif
3623 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3624 if (!NT_STATUS_IS_OK(status)) {
3625 printf("Second open failed - %s\n", cli_errstr(cli1));
3626 return False;
3629 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3630 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3631 correct = False;
3632 } else {
3633 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3636 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3637 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3638 return False;
3641 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3642 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3644 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3645 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3646 printf("Third open failed - %s\n", cli_errstr(cli1));
3647 return False;
3651 #if 0
3653 uint16_t fnum2;
3655 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3656 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3657 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3658 return False;
3660 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3661 printf("[8] setting delete_on_close on file failed !\n");
3662 return False;
3665 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3666 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3667 return False;
3670 #endif
3672 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3673 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3674 correct = False;
3675 } else {
3676 printf("Third rename succeeded (SHARE_NONE)\n");
3679 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3680 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3681 return False;
3684 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3685 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3687 /*----*/
3689 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3690 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3691 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3692 return False;
3695 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3696 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3697 } else {
3698 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3699 correct = False;
3702 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3703 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3704 return False;
3707 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3708 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3710 /*--*/
3712 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3713 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3714 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3715 return False;
3718 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3719 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3720 cli_errstr(cli1));
3721 correct = False;
3722 } else {
3723 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3727 * Now check if the first name still exists ...
3730 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3731 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3732 printf("Opening original file after rename of open file fails: %s\n",
3733 cli_errstr(cli1));
3735 else {
3736 printf("Opening original file after rename of open file works ...\n");
3737 (void)cli_close(cli1, fnum2);
3738 } */
3740 /*--*/
3743 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3744 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3745 return False;
3748 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3749 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3751 if (!torture_close_connection(cli1)) {
3752 correct = False;
3755 return correct;
3758 static bool run_pipe_number(int dummy)
3760 struct cli_state *cli1;
3761 const char *pipe_name = "\\SPOOLSS";
3762 uint16_t fnum;
3763 int num_pipes = 0;
3765 printf("starting pipenumber test\n");
3766 if (!torture_open_connection(&cli1, 0)) {
3767 return False;
3770 cli_sockopt(cli1, sockops);
3771 while(1) {
3772 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3773 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
3774 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3775 break;
3777 num_pipes++;
3778 printf("\r%6d", num_pipes);
3781 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3782 torture_close_connection(cli1);
3783 return True;
3787 Test open mode returns on read-only files.
3789 static bool run_opentest(int dummy)
3791 static struct cli_state *cli1;
3792 static struct cli_state *cli2;
3793 const char *fname = "\\readonly.file";
3794 uint16_t fnum1, fnum2;
3795 char buf[20];
3796 SMB_OFF_T fsize;
3797 bool correct = True;
3798 char *tmp_path;
3800 printf("starting open test\n");
3802 if (!torture_open_connection(&cli1, 0)) {
3803 return False;
3806 cli_setatr(cli1, fname, 0, 0);
3807 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3809 cli_sockopt(cli1, sockops);
3811 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3812 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3813 return False;
3816 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3817 printf("close2 failed (%s)\n", cli_errstr(cli1));
3818 return False;
3821 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
3822 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3823 return False;
3826 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
3827 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3828 return False;
3831 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3832 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
3834 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3835 NT_STATUS_ACCESS_DENIED)) {
3836 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3839 printf("finished open test 1\n");
3841 cli_close(cli1, fnum1);
3843 /* Now try not readonly and ensure ERRbadshare is returned. */
3845 cli_setatr(cli1, fname, 0, 0);
3847 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
3848 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3849 return False;
3852 /* This will fail - but the error should be ERRshare. */
3853 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
3855 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3856 NT_STATUS_SHARING_VIOLATION)) {
3857 printf("correct error code ERRDOS/ERRbadshare returned\n");
3860 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3861 printf("close2 failed (%s)\n", cli_errstr(cli1));
3862 return False;
3865 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3867 printf("finished open test 2\n");
3869 /* Test truncate open disposition on file opened for read. */
3871 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3872 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3873 return False;
3876 /* write 20 bytes. */
3878 memset(buf, '\0', 20);
3880 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3881 printf("write failed (%s)\n", cli_errstr(cli1));
3882 correct = False;
3885 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3886 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3887 return False;
3890 /* Ensure size == 20. */
3891 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
3892 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3893 return False;
3896 if (fsize != 20) {
3897 printf("(3) file size != 20\n");
3898 return False;
3901 /* Now test if we can truncate a file opened for readonly. */
3903 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
3904 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3905 return False;
3908 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3909 printf("close2 failed (%s)\n", cli_errstr(cli1));
3910 return False;
3913 /* Ensure size == 0. */
3914 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
3915 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3916 return False;
3919 if (fsize != 0) {
3920 printf("(3) file size != 0\n");
3921 return False;
3923 printf("finished open test 3\n");
3925 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3928 printf("testing ctemp\n");
3929 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
3930 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3931 return False;
3933 printf("ctemp gave path %s\n", tmp_path);
3934 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3935 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3937 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
3938 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3941 /* Test the non-io opens... */
3943 if (!torture_open_connection(&cli2, 1)) {
3944 return False;
3947 cli_setatr(cli2, fname, 0, 0);
3948 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
3950 cli_sockopt(cli2, sockops);
3952 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3954 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3955 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3956 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3957 return False;
3960 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3961 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
3962 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3963 return False;
3966 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3967 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3968 return False;
3970 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3971 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3972 return False;
3975 printf("non-io open test #1 passed.\n");
3977 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3979 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3981 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3982 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3983 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3984 return False;
3987 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3988 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
3989 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3990 return False;
3993 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3994 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3995 return False;
3997 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3998 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3999 return False;
4002 printf("non-io open test #2 passed.\n");
4004 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4006 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4008 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4009 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4010 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4011 return False;
4014 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4015 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4016 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4017 return False;
4020 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4021 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4022 return False;
4024 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4025 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4026 return False;
4029 printf("non-io open test #3 passed.\n");
4031 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4033 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4035 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4036 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4037 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4038 return False;
4041 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4042 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4043 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4044 return False;
4047 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4049 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4050 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4051 return False;
4054 printf("non-io open test #4 passed.\n");
4056 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4058 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4060 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4061 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4062 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4063 return False;
4066 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4067 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4068 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4069 return False;
4072 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4073 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4074 return False;
4077 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4078 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4079 return False;
4082 printf("non-io open test #5 passed.\n");
4084 printf("TEST #6 testing 1 non-io open, one io open\n");
4086 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4088 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4089 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4090 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4091 return False;
4094 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4095 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4096 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4097 return False;
4100 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4101 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4102 return False;
4105 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4106 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4107 return False;
4110 printf("non-io open test #6 passed.\n");
4112 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4114 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4116 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4117 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4118 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4119 return False;
4122 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4123 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4124 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4125 return False;
4128 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4130 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4131 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4132 return False;
4135 printf("non-io open test #7 passed.\n");
4137 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4139 if (!torture_close_connection(cli1)) {
4140 correct = False;
4142 if (!torture_close_connection(cli2)) {
4143 correct = False;
4146 return correct;
4150 Test POSIX open /mkdir calls.
4152 static bool run_simple_posix_open_test(int dummy)
4154 static struct cli_state *cli1;
4155 const char *fname = "posix:file";
4156 const char *hname = "posix:hlink";
4157 const char *sname = "posix:symlink";
4158 const char *dname = "posix:dir";
4159 char buf[10];
4160 char namebuf[11];
4161 uint16 major, minor;
4162 uint32 caplow, caphigh;
4163 uint16_t fnum1 = (uint16_t)-1;
4164 SMB_STRUCT_STAT sbuf;
4165 bool correct = false;
4167 printf("Starting simple POSIX open test\n");
4169 if (!torture_open_connection(&cli1, 0)) {
4170 return false;
4173 cli_sockopt(cli1, sockops);
4175 if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4176 printf("Server doesn't support UNIX CIFS extensions.\n");
4177 return false;
4180 if (!cli_unix_extensions_version(cli1, &major,
4181 &minor, &caplow, &caphigh)) {
4182 printf("Server didn't return UNIX CIFS extensions.\n");
4183 return false;
4186 if (!cli_set_unix_extensions_capabilities(cli1,
4187 major, minor, caplow, caphigh)) {
4188 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4189 return false;
4192 cli_setatr(cli1, fname, 0, 0);
4193 cli_posix_unlink(cli1, fname);
4194 cli_setatr(cli1, dname, 0, 0);
4195 cli_posix_rmdir(cli1, dname);
4196 cli_setatr(cli1, hname, 0, 0);
4197 cli_posix_unlink(cli1, hname);
4198 cli_setatr(cli1, sname, 0, 0);
4199 cli_posix_unlink(cli1, sname);
4201 /* Create a directory. */
4202 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4203 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4204 goto out;
4207 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4208 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4209 goto out;
4212 /* Test ftruncate - set file size. */
4213 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4214 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4215 goto out;
4218 /* Ensure st_size == 1000 */
4219 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4220 printf("stat failed (%s)\n", cli_errstr(cli1));
4221 goto out;
4224 if (sbuf.st_ex_size != 1000) {
4225 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4226 goto out;
4229 /* Test ftruncate - set file size back to zero. */
4230 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4231 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4232 goto out;
4235 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4236 printf("close failed (%s)\n", cli_errstr(cli1));
4237 goto out;
4240 /* Now open the file again for read only. */
4241 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4242 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4243 goto out;
4246 /* Now unlink while open. */
4247 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4248 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4249 goto out;
4252 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4253 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4254 goto out;
4257 /* Ensure the file has gone. */
4258 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4259 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4260 goto out;
4263 /* What happens when we try and POSIX open a directory ? */
4264 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4265 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4266 goto out;
4267 } else {
4268 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4269 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4270 goto out;
4274 /* Create the file. */
4275 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4276 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4277 goto out;
4280 /* Write some data into it. */
4281 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4282 printf("cli_write failed: %s\n", cli_errstr(cli1));
4283 goto out;
4286 cli_close(cli1, fnum1);
4288 /* Now create a hardlink. */
4289 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4290 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4291 goto out;
4294 /* Now create a symlink. */
4295 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4296 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4297 goto out;
4300 /* Open the hardlink for read. */
4301 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4302 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4303 goto out;
4306 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4307 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4308 goto out;
4311 if (memcmp(buf, "TEST DATA\n", 10)) {
4312 printf("invalid data read from hardlink\n");
4313 goto out;
4316 /* Do a POSIX lock/unlock. */
4317 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4318 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4319 goto out;
4322 /* Punch a hole in the locked area. */
4323 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4324 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4325 goto out;
4328 cli_close(cli1, fnum1);
4330 /* Open the symlink for read - this should fail. A POSIX
4331 client should not be doing opens on a symlink. */
4332 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4333 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4334 goto out;
4335 } else {
4336 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4337 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4338 printf("POSIX open of %s should have failed "
4339 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4340 "failed with %s instead.\n",
4341 sname, cli_errstr(cli1));
4342 goto out;
4346 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4347 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4348 goto out;
4351 if (strcmp(namebuf, fname) != 0) {
4352 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4353 sname, fname, namebuf);
4354 goto out;
4357 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4358 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4359 goto out;
4362 printf("Simple POSIX open test passed\n");
4363 correct = true;
4365 out:
4367 if (fnum1 != (uint16_t)-1) {
4368 cli_close(cli1, fnum1);
4369 fnum1 = (uint16_t)-1;
4372 cli_setatr(cli1, sname, 0, 0);
4373 cli_posix_unlink(cli1, sname);
4374 cli_setatr(cli1, hname, 0, 0);
4375 cli_posix_unlink(cli1, hname);
4376 cli_setatr(cli1, fname, 0, 0);
4377 cli_posix_unlink(cli1, fname);
4378 cli_setatr(cli1, dname, 0, 0);
4379 cli_posix_rmdir(cli1, dname);
4381 if (!torture_close_connection(cli1)) {
4382 correct = false;
4385 return correct;
4389 static uint32 open_attrs_table[] = {
4390 FILE_ATTRIBUTE_NORMAL,
4391 FILE_ATTRIBUTE_ARCHIVE,
4392 FILE_ATTRIBUTE_READONLY,
4393 FILE_ATTRIBUTE_HIDDEN,
4394 FILE_ATTRIBUTE_SYSTEM,
4396 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4397 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4398 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4399 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4400 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4401 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4403 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4404 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4405 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4406 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4409 struct trunc_open_results {
4410 unsigned int num;
4411 uint32 init_attr;
4412 uint32 trunc_attr;
4413 uint32 result_attr;
4416 static struct trunc_open_results attr_results[] = {
4417 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4418 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4419 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4420 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4421 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4422 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4423 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4424 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4425 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4426 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4427 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4428 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4429 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4430 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4431 { 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 },
4432 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4433 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4434 { 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 },
4435 { 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 },
4436 { 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 },
4437 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4438 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4439 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4440 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4441 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4442 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4445 static bool run_openattrtest(int dummy)
4447 static struct cli_state *cli1;
4448 const char *fname = "\\openattr.file";
4449 uint16_t fnum1;
4450 bool correct = True;
4451 uint16 attr;
4452 unsigned int i, j, k, l;
4454 printf("starting open attr test\n");
4456 if (!torture_open_connection(&cli1, 0)) {
4457 return False;
4460 cli_sockopt(cli1, sockops);
4462 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4463 cli_setatr(cli1, fname, 0, 0);
4464 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4465 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4466 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4467 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4468 return False;
4471 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4472 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4473 return False;
4476 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4477 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4478 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4479 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4480 if (attr_results[l].num == k) {
4481 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4482 k, open_attrs_table[i],
4483 open_attrs_table[j],
4484 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4485 correct = False;
4488 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4489 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4490 k, open_attrs_table[i], open_attrs_table[j],
4491 cli_errstr(cli1));
4492 correct = False;
4494 #if 0
4495 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4496 #endif
4497 k++;
4498 continue;
4501 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4502 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4503 return False;
4506 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4507 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4508 return False;
4511 #if 0
4512 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4513 k, open_attrs_table[i], open_attrs_table[j], attr );
4514 #endif
4516 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4517 if (attr_results[l].num == k) {
4518 if (attr != attr_results[l].result_attr ||
4519 open_attrs_table[i] != attr_results[l].init_attr ||
4520 open_attrs_table[j] != attr_results[l].trunc_attr) {
4521 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4522 open_attrs_table[i],
4523 open_attrs_table[j],
4524 (unsigned int)attr,
4525 attr_results[l].result_attr);
4526 correct = False;
4528 break;
4531 k++;
4535 cli_setatr(cli1, fname, 0, 0);
4536 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4538 printf("open attr test %s.\n", correct ? "passed" : "failed");
4540 if (!torture_close_connection(cli1)) {
4541 correct = False;
4543 return correct;
4546 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4552 test directory listing speed
4554 static bool run_dirtest(int dummy)
4556 int i;
4557 static struct cli_state *cli;
4558 uint16_t fnum;
4559 double t1;
4560 bool correct = True;
4562 printf("starting directory test\n");
4564 if (!torture_open_connection(&cli, 0)) {
4565 return False;
4568 cli_sockopt(cli, sockops);
4570 srandom(0);
4571 for (i=0;i<torture_numops;i++) {
4572 fstring fname;
4573 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4574 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4575 fprintf(stderr,"Failed to open %s\n", fname);
4576 return False;
4578 cli_close(cli, fnum);
4581 t1 = end_timer();
4583 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4584 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4585 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4587 printf("dirtest core %g seconds\n", end_timer() - t1);
4589 srandom(0);
4590 for (i=0;i<torture_numops;i++) {
4591 fstring fname;
4592 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4593 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4596 if (!torture_close_connection(cli)) {
4597 correct = False;
4600 printf("finished dirtest\n");
4602 return correct;
4605 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4607 struct cli_state *pcli = (struct cli_state *)state;
4608 fstring fname;
4609 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4611 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4612 return;
4614 if (finfo->mode & aDIR) {
4615 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4616 printf("del_fn: failed to rmdir %s\n,", fname );
4617 } else {
4618 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4619 printf("del_fn: failed to unlink %s\n,", fname );
4625 sees what IOCTLs are supported
4627 bool torture_ioctl_test(int dummy)
4629 static struct cli_state *cli;
4630 uint16_t device, function;
4631 uint16_t fnum;
4632 const char *fname = "\\ioctl.dat";
4633 DATA_BLOB blob;
4634 NTSTATUS status;
4636 if (!torture_open_connection(&cli, 0)) {
4637 return False;
4640 printf("starting ioctl test\n");
4642 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4644 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4645 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4646 return False;
4649 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4650 printf("ioctl device info: %s\n", cli_errstr(cli));
4652 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4653 printf("ioctl job info: %s\n", cli_errstr(cli));
4655 for (device=0;device<0x100;device++) {
4656 printf("testing device=0x%x\n", device);
4657 for (function=0;function<0x100;function++) {
4658 uint32 code = (device<<16) | function;
4660 status = cli_raw_ioctl(cli, fnum, code, &blob);
4662 if (NT_STATUS_IS_OK(status)) {
4663 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4664 (int)blob.length);
4665 data_blob_free(&blob);
4670 if (!torture_close_connection(cli)) {
4671 return False;
4674 return True;
4679 tries varients of chkpath
4681 bool torture_chkpath_test(int dummy)
4683 static struct cli_state *cli;
4684 uint16_t fnum;
4685 bool ret;
4687 if (!torture_open_connection(&cli, 0)) {
4688 return False;
4691 printf("starting chkpath test\n");
4693 /* cleanup from an old run */
4694 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4695 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4696 cli_rmdir(cli, "\\chkpath.dir");
4698 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4699 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4700 return False;
4703 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4704 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4705 return False;
4708 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4709 printf("open1 failed (%s)\n", cli_errstr(cli));
4710 return False;
4712 cli_close(cli, fnum);
4714 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4715 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4716 ret = False;
4719 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4720 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4721 ret = False;
4724 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4725 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4726 NT_STATUS_NOT_A_DIRECTORY);
4727 } else {
4728 printf("* chkpath on a file should fail\n");
4729 ret = False;
4732 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4733 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4734 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4735 } else {
4736 printf("* chkpath on a non existant file should fail\n");
4737 ret = False;
4740 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
4741 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4742 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4743 } else {
4744 printf("* chkpath on a non existent component should fail\n");
4745 ret = False;
4748 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4749 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4750 cli_rmdir(cli, "\\chkpath.dir");
4752 if (!torture_close_connection(cli)) {
4753 return False;
4756 return ret;
4759 static bool run_eatest(int dummy)
4761 static struct cli_state *cli;
4762 const char *fname = "\\eatest.txt";
4763 bool correct = True;
4764 uint16_t fnum;
4765 int i;
4766 size_t num_eas;
4767 struct ea_struct *ea_list = NULL;
4768 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4770 printf("starting eatest\n");
4772 if (!torture_open_connection(&cli, 0)) {
4773 talloc_destroy(mem_ctx);
4774 return False;
4777 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4778 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
4779 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4780 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4781 0x4044, 0, &fnum))) {
4782 printf("open failed - %s\n", cli_errstr(cli));
4783 talloc_destroy(mem_ctx);
4784 return False;
4787 for (i = 0; i < 10; i++) {
4788 fstring ea_name, ea_val;
4790 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4791 memset(ea_val, (char)i+1, i+1);
4792 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4793 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4794 talloc_destroy(mem_ctx);
4795 return False;
4799 cli_close(cli, fnum);
4800 for (i = 0; i < 10; i++) {
4801 fstring ea_name, ea_val;
4803 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4804 memset(ea_val, (char)i+1, i+1);
4805 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4806 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4807 talloc_destroy(mem_ctx);
4808 return False;
4812 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4813 printf("ea_get list failed - %s\n", cli_errstr(cli));
4814 correct = False;
4817 printf("num_eas = %d\n", (int)num_eas);
4819 if (num_eas != 20) {
4820 printf("Should be 20 EA's stored... failing.\n");
4821 correct = False;
4824 for (i = 0; i < num_eas; i++) {
4825 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4826 dump_data(0, ea_list[i].value.data,
4827 ea_list[i].value.length);
4830 /* Setting EA's to zero length deletes them. Test this */
4831 printf("Now deleting all EA's - case indepenent....\n");
4833 #if 1
4834 cli_set_ea_path(cli, fname, "", "", 0);
4835 #else
4836 for (i = 0; i < 20; i++) {
4837 fstring ea_name;
4838 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4839 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4840 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4841 talloc_destroy(mem_ctx);
4842 return False;
4845 #endif
4847 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4848 printf("ea_get list failed - %s\n", cli_errstr(cli));
4849 correct = False;
4852 printf("num_eas = %d\n", (int)num_eas);
4853 for (i = 0; i < num_eas; i++) {
4854 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4855 dump_data(0, ea_list[i].value.data,
4856 ea_list[i].value.length);
4859 if (num_eas != 0) {
4860 printf("deleting EA's failed.\n");
4861 correct = False;
4864 /* Try and delete a non existant EA. */
4865 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4866 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4867 correct = False;
4870 talloc_destroy(mem_ctx);
4871 if (!torture_close_connection(cli)) {
4872 correct = False;
4875 return correct;
4878 static bool run_dirtest1(int dummy)
4880 int i;
4881 static struct cli_state *cli;
4882 uint16_t fnum;
4883 int num_seen;
4884 bool correct = True;
4886 printf("starting directory test\n");
4888 if (!torture_open_connection(&cli, 0)) {
4889 return False;
4892 cli_sockopt(cli, sockops);
4894 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4895 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4896 cli_rmdir(cli, "\\LISTDIR");
4897 cli_mkdir(cli, "\\LISTDIR");
4899 /* Create 1000 files and 1000 directories. */
4900 for (i=0;i<1000;i++) {
4901 fstring fname;
4902 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4903 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4904 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
4905 fprintf(stderr,"Failed to open %s\n", fname);
4906 return False;
4908 cli_close(cli, fnum);
4910 for (i=0;i<1000;i++) {
4911 fstring fname;
4912 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4913 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
4914 fprintf(stderr,"Failed to open %s\n", fname);
4915 return False;
4919 /* Now ensure that doing an old list sees both files and directories. */
4920 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4921 printf("num_seen = %d\n", num_seen );
4922 /* We should see 100 files + 1000 directories + . and .. */
4923 if (num_seen != 2002)
4924 correct = False;
4926 /* Ensure if we have the "must have" bits we only see the
4927 * relevent entries.
4929 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4930 printf("num_seen = %d\n", num_seen );
4931 if (num_seen != 1002)
4932 correct = False;
4934 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4935 printf("num_seen = %d\n", num_seen );
4936 if (num_seen != 1000)
4937 correct = False;
4939 /* Delete everything. */
4940 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4941 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4942 cli_rmdir(cli, "\\LISTDIR");
4944 #if 0
4945 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4946 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4947 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4948 #endif
4950 if (!torture_close_connection(cli)) {
4951 correct = False;
4954 printf("finished dirtest1\n");
4956 return correct;
4959 static bool run_error_map_extract(int dummy) {
4961 static struct cli_state *c_dos;
4962 static struct cli_state *c_nt;
4963 NTSTATUS status;
4965 uint32 error;
4967 uint32 flgs2, errnum;
4968 uint8 errclass;
4970 NTSTATUS nt_status;
4972 fstring user;
4974 /* NT-Error connection */
4976 if (!(c_nt = open_nbt_connection())) {
4977 return False;
4980 c_nt->use_spnego = False;
4982 status = cli_negprot(c_nt);
4984 if (!NT_STATUS_IS_OK(status)) {
4985 printf("%s rejected the NT-error negprot (%s)\n", host,
4986 nt_errstr(status));
4987 cli_shutdown(c_nt);
4988 return False;
4991 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4992 workgroup))) {
4993 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4994 return False;
4997 /* DOS-Error connection */
4999 if (!(c_dos = open_nbt_connection())) {
5000 return False;
5003 c_dos->use_spnego = False;
5004 c_dos->force_dos_errors = True;
5006 status = cli_negprot(c_dos);
5007 if (!NT_STATUS_IS_OK(status)) {
5008 printf("%s rejected the DOS-error negprot (%s)\n", host,
5009 nt_errstr(status));
5010 cli_shutdown(c_dos);
5011 return False;
5014 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5015 workgroup))) {
5016 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5017 return False;
5020 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5021 fstr_sprintf(user, "%X", error);
5023 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5024 password, strlen(password),
5025 password, strlen(password),
5026 workgroup))) {
5027 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5030 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5032 /* Case #1: 32-bit NT errors */
5033 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5034 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5035 } else {
5036 printf("/** Dos error on NT connection! (%s) */\n",
5037 cli_errstr(c_nt));
5038 nt_status = NT_STATUS(0xc0000000);
5041 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5042 password, strlen(password),
5043 password, strlen(password),
5044 workgroup))) {
5045 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5047 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5049 /* Case #1: 32-bit NT errors */
5050 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5051 printf("/** NT error on DOS connection! (%s) */\n",
5052 cli_errstr(c_nt));
5053 errnum = errclass = 0;
5054 } else {
5055 cli_dos_error(c_dos, &errclass, &errnum);
5058 if (NT_STATUS_V(nt_status) != error) {
5059 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5060 get_nt_error_c_code(NT_STATUS(error)),
5061 get_nt_error_c_code(nt_status));
5064 printf("\t{%s,\t%s,\t%s},\n",
5065 smb_dos_err_class(errclass),
5066 smb_dos_err_name(errclass, errnum),
5067 get_nt_error_c_code(NT_STATUS(error)));
5069 return True;
5072 static bool run_sesssetup_bench(int dummy)
5074 static struct cli_state *c;
5075 const char *fname = "\\file.dat";
5076 uint16_t fnum;
5077 NTSTATUS status;
5078 int i;
5080 if (!torture_open_connection(&c, 0)) {
5081 return false;
5084 if (!NT_STATUS_IS_OK(cli_ntcreate(
5085 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5086 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5087 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5088 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5089 return false;
5092 for (i=0; i<torture_numops; i++) {
5093 status = cli_session_setup(
5094 c, username,
5095 password, strlen(password),
5096 password, strlen(password),
5097 workgroup);
5098 if (!NT_STATUS_IS_OK(status)) {
5099 d_printf("(%s) cli_session_setup failed: %s\n",
5100 __location__, nt_errstr(status));
5101 return false;
5104 d_printf("\r%d ", (int)c->vuid);
5106 if (!cli_ulogoff(c)) {
5107 d_printf("(%s) cli_ulogoff failed: %s\n",
5108 __location__, cli_errstr(c));
5109 return false;
5111 c->vuid = 0;
5114 return true;
5117 static bool subst_test(const char *str, const char *user, const char *domain,
5118 uid_t uid, gid_t gid, const char *expected)
5120 char *subst;
5121 bool result = true;
5123 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5125 if (strcmp(subst, expected) != 0) {
5126 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5127 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5128 expected);
5129 result = false;
5132 TALLOC_FREE(subst);
5133 return result;
5136 static void chain1_open_completion(struct tevent_req *req)
5138 uint16_t fnum;
5139 NTSTATUS status;
5140 status = cli_open_recv(req, &fnum);
5141 TALLOC_FREE(req);
5143 d_printf("cli_open_recv returned %s: %d\n",
5144 nt_errstr(status),
5145 NT_STATUS_IS_OK(status) ? fnum : -1);
5148 static void chain1_write_completion(struct tevent_req *req)
5150 size_t written;
5151 NTSTATUS status;
5152 status = cli_write_andx_recv(req, &written);
5153 TALLOC_FREE(req);
5155 d_printf("cli_write_andx_recv returned %s: %d\n",
5156 nt_errstr(status),
5157 NT_STATUS_IS_OK(status) ? (int)written : -1);
5160 static void chain1_close_completion(struct tevent_req *req)
5162 NTSTATUS status;
5163 bool *done = (bool *)tevent_req_callback_data_void(req);
5165 status = cli_close_recv(req);
5166 *done = true;
5168 TALLOC_FREE(req);
5170 d_printf("cli_close returned %s\n", nt_errstr(status));
5173 static bool run_chain1(int dummy)
5175 struct cli_state *cli1;
5176 struct event_context *evt = event_context_init(NULL);
5177 struct tevent_req *reqs[3], *smbreqs[3];
5178 bool done = false;
5179 const char *str = "foobar";
5180 NTSTATUS status;
5182 printf("starting chain1 test\n");
5183 if (!torture_open_connection(&cli1, 0)) {
5184 return False;
5187 cli_sockopt(cli1, sockops);
5189 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5190 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5191 if (reqs[0] == NULL) return false;
5192 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5195 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5196 (uint8_t *)str, 0, strlen(str)+1,
5197 smbreqs, 1, &smbreqs[1]);
5198 if (reqs[1] == NULL) return false;
5199 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5201 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5202 if (reqs[2] == NULL) return false;
5203 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5205 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5206 if (!NT_STATUS_IS_OK(status)) {
5207 return false;
5210 while (!done) {
5211 event_loop_once(evt);
5214 torture_close_connection(cli1);
5215 return True;
5218 static void chain2_sesssetup_completion(struct tevent_req *req)
5220 NTSTATUS status;
5221 status = cli_session_setup_guest_recv(req);
5222 d_printf("sesssetup returned %s\n", nt_errstr(status));
5225 static void chain2_tcon_completion(struct tevent_req *req)
5227 bool *done = (bool *)tevent_req_callback_data_void(req);
5228 NTSTATUS status;
5229 status = cli_tcon_andx_recv(req);
5230 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5231 *done = true;
5234 static bool run_chain2(int dummy)
5236 struct cli_state *cli1;
5237 struct event_context *evt = event_context_init(NULL);
5238 struct tevent_req *reqs[2], *smbreqs[2];
5239 bool done = false;
5240 NTSTATUS status;
5242 printf("starting chain2 test\n");
5243 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5244 port_to_use, Undefined, 0, NULL);
5245 if (!NT_STATUS_IS_OK(status)) {
5246 return False;
5249 cli_sockopt(cli1, sockops);
5251 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5252 &smbreqs[0]);
5253 if (reqs[0] == NULL) return false;
5254 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5256 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5257 "?????", NULL, 0, &smbreqs[1]);
5258 if (reqs[1] == NULL) return false;
5259 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5261 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5262 if (!NT_STATUS_IS_OK(status)) {
5263 return false;
5266 while (!done) {
5267 event_loop_once(evt);
5270 torture_close_connection(cli1);
5271 return True;
5274 static bool run_mangle1(int dummy)
5276 struct cli_state *cli;
5277 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5278 uint16_t fnum;
5279 fstring alt_name;
5280 NTSTATUS status;
5281 time_t change_time, access_time, write_time;
5282 SMB_OFF_T size;
5283 uint16_t mode;
5285 printf("starting mangle1 test\n");
5286 if (!torture_open_connection(&cli, 0)) {
5287 return False;
5290 cli_sockopt(cli, sockops);
5292 if (!NT_STATUS_IS_OK(cli_ntcreate(
5293 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5294 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5295 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5296 return false;
5298 cli_close(cli, fnum);
5300 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5301 if (!NT_STATUS_IS_OK(status)) {
5302 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5303 nt_errstr(status));
5304 return false;
5306 d_printf("alt_name: %s\n", alt_name);
5308 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5309 d_printf("cli_open(%s) failed: %s\n", alt_name,
5310 cli_errstr(cli));
5311 return false;
5313 cli_close(cli, fnum);
5315 if (!cli_qpathinfo(cli, alt_name, &change_time, &access_time,
5316 &write_time, &size, &mode)) {
5317 d_printf("cli_qpathinfo(%s) failed: %s\n", alt_name,
5318 cli_errstr(cli));
5319 return false;
5322 return true;
5325 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5327 size_t *to_pull = (size_t *)priv;
5328 size_t thistime = *to_pull;
5330 thistime = MIN(thistime, n);
5331 if (thistime == 0) {
5332 return 0;
5335 memset(buf, 0, thistime);
5336 *to_pull -= thistime;
5337 return thistime;
5340 static bool run_windows_write(int dummy)
5342 struct cli_state *cli1;
5343 uint16_t fnum;
5344 int i;
5345 bool ret = false;
5346 const char *fname = "\\writetest.txt";
5347 double seconds;
5348 double kbytes;
5350 printf("starting windows_write test\n");
5351 if (!torture_open_connection(&cli1, 0)) {
5352 return False;
5355 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5356 printf("open failed (%s)\n", cli_errstr(cli1));
5357 return False;
5360 cli_sockopt(cli1, sockops);
5362 start_timer();
5364 for (i=0; i<torture_numops; i++) {
5365 char c = 0;
5366 off_t start = i * torture_blocksize;
5367 NTSTATUS status;
5368 size_t to_pull = torture_blocksize - 1;
5370 if (cli_write(cli1, fnum, 0, &c,
5371 start + torture_blocksize - 1, 1) != 1) {
5372 printf("cli_write failed: %s\n", cli_errstr(cli1));
5373 goto fail;
5376 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5377 null_source, &to_pull);
5378 if (!NT_STATUS_IS_OK(status)) {
5379 printf("cli_push returned: %s\n", nt_errstr(status));
5380 goto fail;
5384 seconds = end_timer();
5385 kbytes = (double)torture_blocksize * torture_numops;
5386 kbytes /= 1024;
5388 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5389 (double)seconds, (int)(kbytes/seconds));
5391 ret = true;
5392 fail:
5393 cli_close(cli1, fnum);
5394 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5395 torture_close_connection(cli1);
5396 return ret;
5399 static bool run_cli_echo(int dummy)
5401 struct cli_state *cli;
5402 NTSTATUS status;
5404 printf("starting cli_echo test\n");
5405 if (!torture_open_connection(&cli, 0)) {
5406 return false;
5408 cli_sockopt(cli, sockops);
5410 status = cli_echo(cli, 5, data_blob_const("hello", 5));
5412 d_printf("cli_echo returned %s\n", nt_errstr(status));
5414 torture_close_connection(cli);
5415 return NT_STATUS_IS_OK(status);
5418 static bool run_uid_regression_test(int dummy)
5420 static struct cli_state *cli;
5421 int16_t old_vuid;
5422 int16_t old_cnum;
5423 bool correct = True;
5425 printf("starting uid regression test\n");
5427 if (!torture_open_connection(&cli, 0)) {
5428 return False;
5431 cli_sockopt(cli, sockops);
5433 /* Ok - now save then logoff our current user. */
5434 old_vuid = cli->vuid;
5436 if (!cli_ulogoff(cli)) {
5437 d_printf("(%s) cli_ulogoff failed: %s\n",
5438 __location__, cli_errstr(cli));
5439 correct = false;
5440 goto out;
5443 cli->vuid = old_vuid;
5445 /* Try an operation. */
5446 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
5447 /* We expect bad uid. */
5448 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
5449 NT_STATUS_NO_SUCH_USER)) {
5450 return False;
5454 old_cnum = cli->cnum;
5456 /* Now try a SMBtdis with the invald vuid set to zero. */
5457 cli->vuid = 0;
5459 /* This should succeed. */
5460 if (cli_tdis(cli)) {
5461 printf("First tdis with invalid vuid should succeed.\n");
5462 } else {
5463 printf("First tdis failed (%s)\n", cli_errstr(cli));
5466 cli->vuid = old_vuid;
5467 cli->cnum = old_cnum;
5469 /* This should fail. */
5470 if (cli_tdis(cli)) {
5471 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
5472 } else {
5473 /* Should be bad tid. */
5474 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
5475 NT_STATUS_NETWORK_NAME_DELETED)) {
5476 return False;
5480 cli_rmdir(cli, "\\uid_reg_test");
5482 out:
5484 cli_shutdown(cli);
5485 return correct;
5489 static const char *illegal_chars = "*\\/?<>|\":";
5490 static char force_shortname_chars[] = " +,.[];=\177";
5492 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
5494 struct cli_state *pcli = (struct cli_state *)state;
5495 fstring fname;
5496 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
5498 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5499 return;
5501 if (finfo->mode & aDIR) {
5502 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5503 printf("del_fn: failed to rmdir %s\n,", fname );
5504 } else {
5505 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5506 printf("del_fn: failed to unlink %s\n,", fname );
5510 struct sn_state {
5511 int i;
5512 bool val;
5515 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
5517 struct sn_state *s = (struct sn_state *)state;
5518 int i = s->i;
5520 #if 0
5521 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
5522 i, finfo->name, finfo->short_name);
5523 #endif
5525 if (strchr(force_shortname_chars, i)) {
5526 if (!finfo->short_name[0]) {
5527 /* Shortname not created when it should be. */
5528 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
5529 __location__, finfo->name, i);
5530 s->val = true;
5532 } else if (finfo->short_name[0]){
5533 /* Shortname created when it should not be. */
5534 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
5535 __location__, finfo->short_name, finfo->name);
5536 s->val = true;
5540 static bool run_shortname_test(int dummy)
5542 static struct cli_state *cli;
5543 bool correct = True;
5544 int i;
5545 struct sn_state s;
5546 char fname[20];
5548 printf("starting shortname test\n");
5550 if (!torture_open_connection(&cli, 0)) {
5551 return False;
5554 cli_sockopt(cli, sockops);
5556 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
5557 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
5558 cli_rmdir(cli, "\\shortname");
5560 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
5561 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
5562 __location__, cli_errstr(cli));
5563 correct = false;
5564 goto out;
5567 strlcpy(fname, "\\shortname\\", sizeof(fname));
5568 strlcat(fname, "test .txt", sizeof(fname));
5570 s.val = false;
5572 for (i = 32; i < 128; i++) {
5573 NTSTATUS status;
5574 uint16_t fnum = (uint16_t)-1;
5576 s.i = i;
5578 if (strchr(illegal_chars, i)) {
5579 continue;
5581 fname[15] = i;
5583 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
5584 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
5585 if (!NT_STATUS_IS_OK(status)) {
5586 d_printf("(%s) cli_nt_create of %s failed: %s\n",
5587 __location__, fname, cli_errstr(cli));
5588 correct = false;
5589 goto out;
5591 cli_close(cli, fnum);
5592 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
5593 d_printf("(%s) failed to list %s: %s\n",
5594 __location__, fname, cli_errstr(cli));
5595 correct = false;
5596 goto out;
5598 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
5599 d_printf("(%s) failed to delete %s: %s\n",
5600 __location__, fname, cli_errstr(cli));
5601 correct = false;
5602 goto out;
5605 if (s.val) {
5606 correct = false;
5607 goto out;
5611 out:
5613 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
5614 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
5615 cli_rmdir(cli, "\\shortname");
5616 torture_close_connection(cli);
5617 return correct;
5620 static void pagedsearch_cb(struct tevent_req *req)
5622 int rc;
5623 struct tldap_message *msg;
5624 char *dn;
5626 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
5627 if (rc != TLDAP_SUCCESS) {
5628 d_printf("tldap_search_paged_recv failed: %s\n",
5629 tldap_err2string(rc));
5630 return;
5632 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
5633 TALLOC_FREE(msg);
5634 return;
5636 if (!tldap_entry_dn(msg, &dn)) {
5637 d_printf("tldap_entry_dn failed\n");
5638 return;
5640 d_printf("%s\n", dn);
5641 TALLOC_FREE(msg);
5644 static bool run_tldap(int dummy)
5646 struct tldap_context *ld;
5647 int fd, rc;
5648 NTSTATUS status;
5649 struct sockaddr_storage addr;
5650 struct tevent_context *ev;
5651 struct tevent_req *req;
5652 char *basedn;
5654 if (!resolve_name(host, &addr, 0, false)) {
5655 d_printf("could not find host %s\n", host);
5656 return false;
5658 status = open_socket_out(&addr, 389, 9999, &fd);
5659 if (!NT_STATUS_IS_OK(status)) {
5660 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
5661 return false;
5664 ld = tldap_context_create(talloc_tos(), fd);
5665 if (ld == NULL) {
5666 close(fd);
5667 d_printf("tldap_context_create failed\n");
5668 return false;
5671 rc = tldap_fetch_rootdse(ld);
5672 if (rc != TLDAP_SUCCESS) {
5673 d_printf("tldap_fetch_rootdse failed: %s\n",
5674 tldap_errstr(talloc_tos(), ld, rc));
5675 return false;
5678 basedn = tldap_talloc_single_attribute(
5679 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
5680 if (basedn == NULL) {
5681 d_printf("no defaultNamingContext\n");
5682 return false;
5684 d_printf("defaultNamingContext: %s\n", basedn);
5686 ev = tevent_context_init(talloc_tos());
5687 if (ev == NULL) {
5688 d_printf("tevent_context_init failed\n");
5689 return false;
5692 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
5693 TLDAP_SCOPE_SUB, "(objectclass=*)",
5694 NULL, 0, 0,
5695 NULL, 0, NULL, 0, 0, 0, 0, 5);
5696 if (req == NULL) {
5697 d_printf("tldap_search_paged_send failed\n");
5698 return false;
5700 tevent_req_set_callback(req, pagedsearch_cb, NULL);
5702 tevent_req_poll(req, ev);
5704 TALLOC_FREE(req);
5706 TALLOC_FREE(ld);
5707 return true;
5710 static bool run_streamerror(int dummy)
5712 struct cli_state *cli;
5713 const char *dname = "\\testdir";
5714 const char *streamname =
5715 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
5716 NTSTATUS status;
5717 time_t change_time, access_time, write_time;
5718 SMB_OFF_T size;
5719 uint16_t mode, fnum;
5720 bool ret = true;
5722 if (!torture_open_connection(&cli, 0)) {
5723 return false;
5726 cli_rmdir(cli, dname);
5728 status = cli_mkdir(cli, dname);
5729 if (!NT_STATUS_IS_OK(status)) {
5730 printf("mkdir failed: %s\n", nt_errstr(status));
5731 return false;
5734 cli_qpathinfo(cli, streamname, &change_time, &access_time, &write_time,
5735 &size, &mode);
5736 status = cli_nt_error(cli);
5738 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5739 printf("pathinfo returned %s, expected "
5740 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
5741 nt_errstr(status));
5742 ret = false;
5745 status = cli_ntcreate(cli, streamname, 0x16,
5746 FILE_READ_DATA|FILE_READ_EA|
5747 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
5748 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5749 FILE_OPEN, 0, 0, &fnum);
5751 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5752 printf("ntcreate returned %s, expected "
5753 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
5754 nt_errstr(status));
5755 ret = false;
5759 cli_rmdir(cli, dname);
5760 return ret;
5763 static bool run_local_substitute(int dummy)
5765 bool ok = true;
5767 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5768 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5769 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5770 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5771 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5772 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5773 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5774 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5776 /* Different captialization rules in sub_basic... */
5778 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5779 "blaDOM") == 0);
5781 return ok;
5784 static bool run_local_base64(int dummy)
5786 int i;
5787 bool ret = true;
5789 for (i=1; i<2000; i++) {
5790 DATA_BLOB blob1, blob2;
5791 char *b64;
5793 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
5794 blob1.length = i;
5795 generate_random_buffer(blob1.data, blob1.length);
5797 b64 = base64_encode_data_blob(talloc_tos(), blob1);
5798 if (b64 == NULL) {
5799 d_fprintf(stderr, "base64_encode_data_blob failed "
5800 "for %d bytes\n", i);
5801 ret = false;
5803 blob2 = base64_decode_data_blob(b64);
5804 TALLOC_FREE(b64);
5806 if (data_blob_cmp(&blob1, &blob2)) {
5807 d_fprintf(stderr, "data_blob_cmp failed for %d "
5808 "bytes\n", i);
5809 ret = false;
5811 TALLOC_FREE(blob1.data);
5812 data_blob_free(&blob2);
5814 return ret;
5817 static bool run_local_gencache(int dummy)
5819 char *val;
5820 time_t tm;
5821 DATA_BLOB blob;
5823 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5824 d_printf("%s: gencache_set() failed\n", __location__);
5825 return False;
5828 if (!gencache_get("foo", &val, &tm)) {
5829 d_printf("%s: gencache_get() failed\n", __location__);
5830 return False;
5833 if (strcmp(val, "bar") != 0) {
5834 d_printf("%s: gencache_get() returned %s, expected %s\n",
5835 __location__, val, "bar");
5836 SAFE_FREE(val);
5837 return False;
5840 SAFE_FREE(val);
5842 if (!gencache_del("foo")) {
5843 d_printf("%s: gencache_del() failed\n", __location__);
5844 return False;
5846 if (gencache_del("foo")) {
5847 d_printf("%s: second gencache_del() succeeded\n",
5848 __location__);
5849 return False;
5852 if (gencache_get("foo", &val, &tm)) {
5853 d_printf("%s: gencache_get() on deleted entry "
5854 "succeeded\n", __location__);
5855 return False;
5858 blob = data_blob_string_const_null("bar");
5859 tm = time(NULL) + 60;
5861 if (!gencache_set_data_blob("foo", &blob, tm)) {
5862 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5863 return False;
5866 if (!gencache_get_data_blob("foo", &blob, NULL)) {
5867 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5868 return False;
5871 if (strcmp((const char *)blob.data, "bar") != 0) {
5872 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5873 __location__, (const char *)blob.data, "bar");
5874 data_blob_free(&blob);
5875 return False;
5878 data_blob_free(&blob);
5880 if (!gencache_del("foo")) {
5881 d_printf("%s: gencache_del() failed\n", __location__);
5882 return False;
5884 if (gencache_del("foo")) {
5885 d_printf("%s: second gencache_del() succeeded\n",
5886 __location__);
5887 return False;
5890 if (gencache_get_data_blob("foo", &blob, NULL)) {
5891 d_printf("%s: gencache_get_data_blob() on deleted entry "
5892 "succeeded\n", __location__);
5893 return False;
5896 return True;
5899 static bool rbt_testval(struct db_context *db, const char *key,
5900 const char *value)
5902 struct db_record *rec;
5903 TDB_DATA data = string_tdb_data(value);
5904 bool ret = false;
5905 NTSTATUS status;
5907 rec = db->fetch_locked(db, db, string_tdb_data(key));
5908 if (rec == NULL) {
5909 d_fprintf(stderr, "fetch_locked failed\n");
5910 goto done;
5912 status = rec->store(rec, data, 0);
5913 if (!NT_STATUS_IS_OK(status)) {
5914 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5915 goto done;
5917 TALLOC_FREE(rec);
5919 rec = db->fetch_locked(db, db, string_tdb_data(key));
5920 if (rec == NULL) {
5921 d_fprintf(stderr, "second fetch_locked failed\n");
5922 goto done;
5924 if ((rec->value.dsize != data.dsize)
5925 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5926 d_fprintf(stderr, "Got wrong data back\n");
5927 goto done;
5930 ret = true;
5931 done:
5932 TALLOC_FREE(rec);
5933 return ret;
5936 static bool run_local_rbtree(int dummy)
5938 struct db_context *db;
5939 bool ret = false;
5940 int i;
5942 db = db_open_rbt(NULL);
5944 if (db == NULL) {
5945 d_fprintf(stderr, "db_open_rbt failed\n");
5946 return false;
5949 for (i=0; i<1000; i++) {
5950 char *key, *value;
5952 if (asprintf(&key, "key%ld", random()) == -1) {
5953 goto done;
5955 if (asprintf(&value, "value%ld", random()) == -1) {
5956 SAFE_FREE(key);
5957 goto done;
5960 if (!rbt_testval(db, key, value)) {
5961 SAFE_FREE(key);
5962 SAFE_FREE(value);
5963 goto done;
5966 SAFE_FREE(value);
5967 if (asprintf(&value, "value%ld", random()) == -1) {
5968 SAFE_FREE(key);
5969 goto done;
5972 if (!rbt_testval(db, key, value)) {
5973 SAFE_FREE(key);
5974 SAFE_FREE(value);
5975 goto done;
5978 SAFE_FREE(key);
5979 SAFE_FREE(value);
5982 ret = true;
5984 done:
5985 TALLOC_FREE(db);
5986 return ret;
5989 struct talloc_dict_test {
5990 int content;
5993 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
5995 int *count = (int *)priv;
5996 *count += 1;
5997 return 0;
6000 static bool run_local_talloc_dict(int dummy)
6002 struct talloc_dict *dict;
6003 struct talloc_dict_test *t;
6004 int key, count;
6006 dict = talloc_dict_init(talloc_tos());
6007 if (dict == NULL) {
6008 return false;
6011 t = talloc(talloc_tos(), struct talloc_dict_test);
6012 if (t == NULL) {
6013 return false;
6016 key = 1;
6017 t->content = 1;
6018 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6019 return false;
6022 count = 0;
6023 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6024 return false;
6027 if (count != 1) {
6028 return false;
6031 TALLOC_FREE(dict);
6033 return true;
6036 /* Split a path name into filename and stream name components. Canonicalise
6037 * such that an implicit $DATA token is always explicit.
6039 * The "specification" of this function can be found in the
6040 * run_local_stream_name() function in torture.c, I've tried those
6041 * combinations against a W2k3 server.
6044 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6045 char **pbase, char **pstream)
6047 char *base = NULL;
6048 char *stream = NULL;
6049 char *sname; /* stream name */
6050 const char *stype; /* stream type */
6052 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6054 sname = strchr_m(fname, ':');
6056 if (lp_posix_pathnames() || (sname == NULL)) {
6057 if (pbase != NULL) {
6058 base = talloc_strdup(mem_ctx, fname);
6059 NT_STATUS_HAVE_NO_MEMORY(base);
6061 goto done;
6064 if (pbase != NULL) {
6065 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6066 NT_STATUS_HAVE_NO_MEMORY(base);
6069 sname += 1;
6071 stype = strchr_m(sname, ':');
6073 if (stype == NULL) {
6074 sname = talloc_strdup(mem_ctx, sname);
6075 stype = "$DATA";
6077 else {
6078 if (StrCaseCmp(stype, ":$DATA") != 0) {
6080 * If there is an explicit stream type, so far we only
6081 * allow $DATA. Is there anything else allowed? -- vl
6083 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6084 TALLOC_FREE(base);
6085 return NT_STATUS_OBJECT_NAME_INVALID;
6087 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6088 stype += 1;
6091 if (sname == NULL) {
6092 TALLOC_FREE(base);
6093 return NT_STATUS_NO_MEMORY;
6096 if (sname[0] == '\0') {
6098 * no stream name, so no stream
6100 goto done;
6103 if (pstream != NULL) {
6104 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6105 if (stream == NULL) {
6106 TALLOC_FREE(sname);
6107 TALLOC_FREE(base);
6108 return NT_STATUS_NO_MEMORY;
6111 * upper-case the type field
6113 strupper_m(strchr_m(stream, ':')+1);
6116 done:
6117 if (pbase != NULL) {
6118 *pbase = base;
6120 if (pstream != NULL) {
6121 *pstream = stream;
6123 return NT_STATUS_OK;
6126 static bool test_stream_name(const char *fname, const char *expected_base,
6127 const char *expected_stream,
6128 NTSTATUS expected_status)
6130 NTSTATUS status;
6131 char *base = NULL;
6132 char *stream = NULL;
6134 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6135 if (!NT_STATUS_EQUAL(status, expected_status)) {
6136 goto error;
6139 if (!NT_STATUS_IS_OK(status)) {
6140 return true;
6143 if (base == NULL) goto error;
6145 if (strcmp(expected_base, base) != 0) goto error;
6147 if ((expected_stream != NULL) && (stream == NULL)) goto error;
6148 if ((expected_stream == NULL) && (stream != NULL)) goto error;
6150 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6151 goto error;
6153 TALLOC_FREE(base);
6154 TALLOC_FREE(stream);
6155 return true;
6157 error:
6158 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6159 fname, expected_base ? expected_base : "<NULL>",
6160 expected_stream ? expected_stream : "<NULL>",
6161 nt_errstr(expected_status));
6162 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6163 base ? base : "<NULL>", stream ? stream : "<NULL>",
6164 nt_errstr(status));
6165 TALLOC_FREE(base);
6166 TALLOC_FREE(stream);
6167 return false;
6170 static bool run_local_stream_name(int dummy)
6172 bool ret = true;
6174 ret &= test_stream_name(
6175 "bla", "bla", NULL, NT_STATUS_OK);
6176 ret &= test_stream_name(
6177 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6178 ret &= test_stream_name(
6179 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6180 ret &= test_stream_name(
6181 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6182 ret &= test_stream_name(
6183 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6184 ret &= test_stream_name(
6185 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6186 ret &= test_stream_name(
6187 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
6188 ret &= test_stream_name(
6189 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
6191 return ret;
6194 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
6196 if (a.length != b.length) {
6197 printf("a.length=%d != b.length=%d\n",
6198 (int)a.length, (int)b.length);
6199 return false;
6201 if (memcmp(a.data, b.data, a.length) != 0) {
6202 printf("a.data and b.data differ\n");
6203 return false;
6205 return true;
6208 static bool run_local_memcache(int dummy)
6210 struct memcache *cache;
6211 DATA_BLOB k1, k2;
6212 DATA_BLOB d1, d2, d3;
6213 DATA_BLOB v1, v2, v3;
6215 TALLOC_CTX *mem_ctx;
6216 char *str1, *str2;
6217 size_t size1, size2;
6218 bool ret = false;
6220 cache = memcache_init(NULL, 100);
6222 if (cache == NULL) {
6223 printf("memcache_init failed\n");
6224 return false;
6227 d1 = data_blob_const("d1", 2);
6228 d2 = data_blob_const("d2", 2);
6229 d3 = data_blob_const("d3", 2);
6231 k1 = data_blob_const("d1", 2);
6232 k2 = data_blob_const("d2", 2);
6234 memcache_add(cache, STAT_CACHE, k1, d1);
6235 memcache_add(cache, GETWD_CACHE, k2, d2);
6237 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
6238 printf("could not find k1\n");
6239 return false;
6241 if (!data_blob_equal(d1, v1)) {
6242 return false;
6245 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6246 printf("could not find k2\n");
6247 return false;
6249 if (!data_blob_equal(d2, v2)) {
6250 return false;
6253 memcache_add(cache, STAT_CACHE, k1, d3);
6255 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
6256 printf("could not find replaced k1\n");
6257 return false;
6259 if (!data_blob_equal(d3, v3)) {
6260 return false;
6263 memcache_add(cache, GETWD_CACHE, k1, d1);
6265 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
6266 printf("Did find k2, should have been purged\n");
6267 return false;
6270 TALLOC_FREE(cache);
6272 cache = memcache_init(NULL, 0);
6274 mem_ctx = talloc_init("foo");
6276 str1 = talloc_strdup(mem_ctx, "string1");
6277 str2 = talloc_strdup(mem_ctx, "string2");
6279 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6280 data_blob_string_const("torture"), &str1);
6281 size1 = talloc_total_size(cache);
6283 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
6284 data_blob_string_const("torture"), &str2);
6285 size2 = talloc_total_size(cache);
6287 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
6289 if (size2 > size1) {
6290 printf("memcache leaks memory!\n");
6291 goto fail;
6294 ret = true;
6295 fail:
6296 TALLOC_FREE(cache);
6297 return ret;
6300 static void wbclient_done(struct tevent_req *req)
6302 wbcErr wbc_err;
6303 struct winbindd_response *wb_resp;
6304 int *i = (int *)tevent_req_callback_data_void(req);
6306 wbc_err = wb_trans_recv(req, req, &wb_resp);
6307 TALLOC_FREE(req);
6308 *i += 1;
6309 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
6312 static bool run_local_wbclient(int dummy)
6314 struct event_context *ev;
6315 struct wb_context **wb_ctx;
6316 struct winbindd_request wb_req;
6317 bool result = false;
6318 int i, j;
6320 BlockSignals(True, SIGPIPE);
6322 ev = tevent_context_init_byname(talloc_tos(), "epoll");
6323 if (ev == NULL) {
6324 goto fail;
6327 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
6328 if (wb_ctx == NULL) {
6329 goto fail;
6332 ZERO_STRUCT(wb_req);
6333 wb_req.cmd = WINBINDD_PING;
6335 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
6337 for (i=0; i<nprocs; i++) {
6338 wb_ctx[i] = wb_context_init(ev, NULL);
6339 if (wb_ctx[i] == NULL) {
6340 goto fail;
6342 for (j=0; j<torture_numops; j++) {
6343 struct tevent_req *req;
6344 req = wb_trans_send(ev, ev, wb_ctx[i],
6345 (j % 2) == 0, &wb_req);
6346 if (req == NULL) {
6347 goto fail;
6349 tevent_req_set_callback(req, wbclient_done, &i);
6353 i = 0;
6355 while (i < nprocs * torture_numops) {
6356 event_loop_once(ev);
6359 result = true;
6360 fail:
6361 TALLOC_FREE(ev);
6362 return result;
6365 static void getaddrinfo_finished(struct tevent_req *req)
6367 char *name = (char *)tevent_req_callback_data_void(req);
6368 struct addrinfo *ainfo;
6369 int res;
6371 res = getaddrinfo_recv(req, &ainfo);
6372 if (res != 0) {
6373 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
6374 return;
6376 d_printf("gai(%s) succeeded\n", name);
6377 freeaddrinfo(ainfo);
6380 static bool run_getaddrinfo_send(int dummy)
6382 TALLOC_CTX *frame = talloc_stackframe();
6383 struct fncall_context *ctx;
6384 struct tevent_context *ev;
6385 bool result = false;
6386 const char *names[4] = { "www.samba.org", "notfound.samba.org",
6387 "www.slashdot.org", "heise.de" };
6388 struct tevent_req *reqs[4];
6389 int i;
6391 ev = event_context_init(frame);
6392 if (ev == NULL) {
6393 goto fail;
6396 ctx = fncall_context_init(frame, 4);
6398 for (i=0; i<ARRAY_SIZE(names); i++) {
6399 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
6400 NULL);
6401 if (reqs[i] == NULL) {
6402 goto fail;
6404 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
6405 (void *)names[i]);
6408 for (i=0; i<ARRAY_SIZE(reqs); i++) {
6409 tevent_loop_once(ev);
6412 result = true;
6413 fail:
6414 TALLOC_FREE(frame);
6415 return result;
6419 static double create_procs(bool (*fn)(int), bool *result)
6421 int i, status;
6422 volatile pid_t *child_status;
6423 volatile bool *child_status_out;
6424 int synccount;
6425 int tries = 8;
6427 synccount = 0;
6429 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
6430 if (!child_status) {
6431 printf("Failed to setup shared memory\n");
6432 return -1;
6435 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
6436 if (!child_status_out) {
6437 printf("Failed to setup result status shared memory\n");
6438 return -1;
6441 for (i = 0; i < nprocs; i++) {
6442 child_status[i] = 0;
6443 child_status_out[i] = True;
6446 start_timer();
6448 for (i=0;i<nprocs;i++) {
6449 procnum = i;
6450 if (fork() == 0) {
6451 pid_t mypid = getpid();
6452 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
6454 slprintf(myname,sizeof(myname),"CLIENT%d", i);
6456 while (1) {
6457 if (torture_open_connection(&current_cli, i)) break;
6458 if (tries-- == 0) {
6459 printf("pid %d failed to start\n", (int)getpid());
6460 _exit(1);
6462 smb_msleep(10);
6465 child_status[i] = getpid();
6467 while (child_status[i] && end_timer() < 5) smb_msleep(2);
6469 child_status_out[i] = fn(i);
6470 _exit(0);
6474 do {
6475 synccount = 0;
6476 for (i=0;i<nprocs;i++) {
6477 if (child_status[i]) synccount++;
6479 if (synccount == nprocs) break;
6480 smb_msleep(10);
6481 } while (end_timer() < 30);
6483 if (synccount != nprocs) {
6484 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
6485 *result = False;
6486 return end_timer();
6489 /* start the client load */
6490 start_timer();
6492 for (i=0;i<nprocs;i++) {
6493 child_status[i] = 0;
6496 printf("%d clients started\n", nprocs);
6498 for (i=0;i<nprocs;i++) {
6499 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
6502 printf("\n");
6504 for (i=0;i<nprocs;i++) {
6505 if (!child_status_out[i]) {
6506 *result = False;
6509 return end_timer();
6512 #define FLAG_MULTIPROC 1
6514 static struct {
6515 const char *name;
6516 bool (*fn)(int);
6517 unsigned flags;
6518 } torture_ops[] = {
6519 {"FDPASS", run_fdpasstest, 0},
6520 {"LOCK1", run_locktest1, 0},
6521 {"LOCK2", run_locktest2, 0},
6522 {"LOCK3", run_locktest3, 0},
6523 {"LOCK4", run_locktest4, 0},
6524 {"LOCK5", run_locktest5, 0},
6525 {"LOCK6", run_locktest6, 0},
6526 {"LOCK7", run_locktest7, 0},
6527 {"LOCK8", run_locktest8, 0},
6528 {"UNLINK", run_unlinktest, 0},
6529 {"BROWSE", run_browsetest, 0},
6530 {"ATTR", run_attrtest, 0},
6531 {"TRANS2", run_trans2test, 0},
6532 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
6533 {"TORTURE",run_torture, FLAG_MULTIPROC},
6534 {"RANDOMIPC", run_randomipc, 0},
6535 {"NEGNOWAIT", run_negprot_nowait, 0},
6536 {"NBENCH", run_nbench, 0},
6537 {"OPLOCK1", run_oplock1, 0},
6538 {"OPLOCK2", run_oplock2, 0},
6539 {"OPLOCK3", run_oplock3, 0},
6540 {"DIR", run_dirtest, 0},
6541 {"DIR1", run_dirtest1, 0},
6542 {"DENY1", torture_denytest1, 0},
6543 {"DENY2", torture_denytest2, 0},
6544 {"TCON", run_tcon_test, 0},
6545 {"TCONDEV", run_tcon_devtype_test, 0},
6546 {"RW1", run_readwritetest, 0},
6547 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
6548 {"RW3", run_readwritelarge, 0},
6549 {"OPEN", run_opentest, 0},
6550 {"POSIX", run_simple_posix_open_test, 0},
6551 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
6552 { "SHORTNAME-TEST", run_shortname_test, 0},
6553 #if 1
6554 {"OPENATTR", run_openattrtest, 0},
6555 #endif
6556 {"XCOPY", run_xcopy, 0},
6557 {"RENAME", run_rename, 0},
6558 {"DELETE", run_deletetest, 0},
6559 {"PROPERTIES", run_properties, 0},
6560 {"MANGLE", torture_mangle, 0},
6561 {"MANGLE1", run_mangle1, 0},
6562 {"W2K", run_w2ktest, 0},
6563 {"TRANS2SCAN", torture_trans2_scan, 0},
6564 {"NTTRANSSCAN", torture_nttrans_scan, 0},
6565 {"UTABLE", torture_utable, 0},
6566 {"CASETABLE", torture_casetable, 0},
6567 {"ERRMAPEXTRACT", run_error_map_extract, 0},
6568 {"PIPE_NUMBER", run_pipe_number, 0},
6569 {"TCON2", run_tcon2_test, 0},
6570 {"IOCTL", torture_ioctl_test, 0},
6571 {"CHKPATH", torture_chkpath_test, 0},
6572 {"FDSESS", run_fdsesstest, 0},
6573 { "EATEST", run_eatest, 0},
6574 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
6575 { "CHAIN1", run_chain1, 0},
6576 { "CHAIN2", run_chain2, 0},
6577 { "WINDOWS-WRITE", run_windows_write, 0},
6578 { "CLI_ECHO", run_cli_echo, 0},
6579 { "GETADDRINFO", run_getaddrinfo_send, 0},
6580 { "TLDAP", run_tldap },
6581 { "STREAMERROR", run_streamerror },
6582 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
6583 { "LOCAL-GENCACHE", run_local_gencache, 0},
6584 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
6585 { "LOCAL-BASE64", run_local_base64, 0},
6586 { "LOCAL-RBTREE", run_local_rbtree, 0},
6587 { "LOCAL-MEMCACHE", run_local_memcache, 0},
6588 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
6589 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
6590 {NULL, NULL, 0}};
6594 /****************************************************************************
6595 run a specified test or "ALL"
6596 ****************************************************************************/
6597 static bool run_test(const char *name)
6599 bool ret = True;
6600 bool result = True;
6601 bool found = False;
6602 int i;
6603 double t;
6604 if (strequal(name,"ALL")) {
6605 for (i=0;torture_ops[i].name;i++) {
6606 run_test(torture_ops[i].name);
6608 found = True;
6611 for (i=0;torture_ops[i].name;i++) {
6612 fstr_sprintf(randomfname, "\\XX%x",
6613 (unsigned)random());
6615 if (strequal(name, torture_ops[i].name)) {
6616 found = True;
6617 printf("Running %s\n", name);
6618 if (torture_ops[i].flags & FLAG_MULTIPROC) {
6619 t = create_procs(torture_ops[i].fn, &result);
6620 if (!result) {
6621 ret = False;
6622 printf("TEST %s FAILED!\n", name);
6624 } else {
6625 start_timer();
6626 if (!torture_ops[i].fn(0)) {
6627 ret = False;
6628 printf("TEST %s FAILED!\n", name);
6630 t = end_timer();
6632 printf("%s took %g secs\n\n", name, t);
6636 if (!found) {
6637 printf("Did not find a test named %s\n", name);
6638 ret = False;
6641 return ret;
6645 static void usage(void)
6647 int i;
6649 printf("WARNING samba4 test suite is much more complete nowadays.\n");
6650 printf("Please use samba4 torture.\n\n");
6652 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
6654 printf("\t-d debuglevel\n");
6655 printf("\t-U user%%pass\n");
6656 printf("\t-k use kerberos\n");
6657 printf("\t-N numprocs\n");
6658 printf("\t-n my_netbios_name\n");
6659 printf("\t-W workgroup\n");
6660 printf("\t-o num_operations\n");
6661 printf("\t-O socket_options\n");
6662 printf("\t-m maximum protocol\n");
6663 printf("\t-L use oplocks\n");
6664 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
6665 printf("\t-A showall\n");
6666 printf("\t-p port\n");
6667 printf("\t-s seed\n");
6668 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
6669 printf("\n\n");
6671 printf("tests are:");
6672 for (i=0;torture_ops[i].name;i++) {
6673 printf(" %s", torture_ops[i].name);
6675 printf("\n");
6677 printf("default test is ALL\n");
6679 exit(1);
6682 /****************************************************************************
6683 main program
6684 ****************************************************************************/
6685 int main(int argc,char *argv[])
6687 int opt, i;
6688 char *p;
6689 int gotuser = 0;
6690 int gotpass = 0;
6691 bool correct = True;
6692 TALLOC_CTX *frame = talloc_stackframe();
6693 int seed = time(NULL);
6695 dbf = x_stdout;
6697 #ifdef HAVE_SETBUFFER
6698 setbuffer(stdout, NULL, 0);
6699 #endif
6701 load_case_tables();
6703 if (is_default_dyn_CONFIGFILE()) {
6704 if(getenv("SMB_CONF_PATH")) {
6705 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
6708 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
6709 load_interfaces();
6711 if (argc < 2) {
6712 usage();
6715 for(p = argv[1]; *p; p++)
6716 if(*p == '\\')
6717 *p = '/';
6719 if (strncmp(argv[1], "//", 2)) {
6720 usage();
6723 fstrcpy(host, &argv[1][2]);
6724 p = strchr_m(&host[2],'/');
6725 if (!p) {
6726 usage();
6728 *p = 0;
6729 fstrcpy(share, p+1);
6731 fstrcpy(myname, get_myname(talloc_tos()));
6732 if (!*myname) {
6733 fprintf(stderr, "Failed to get my hostname.\n");
6734 return 1;
6737 if (*username == 0 && getenv("LOGNAME")) {
6738 fstrcpy(username,getenv("LOGNAME"));
6741 argc--;
6742 argv++;
6744 fstrcpy(workgroup, lp_workgroup());
6746 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
6747 switch (opt) {
6748 case 'p':
6749 port_to_use = atoi(optarg);
6750 break;
6751 case 's':
6752 seed = atoi(optarg);
6753 break;
6754 case 'W':
6755 fstrcpy(workgroup,optarg);
6756 break;
6757 case 'm':
6758 max_protocol = interpret_protocol(optarg, max_protocol);
6759 break;
6760 case 'N':
6761 nprocs = atoi(optarg);
6762 break;
6763 case 'o':
6764 torture_numops = atoi(optarg);
6765 break;
6766 case 'd':
6767 DEBUGLEVEL = atoi(optarg);
6768 break;
6769 case 'O':
6770 sockops = optarg;
6771 break;
6772 case 'L':
6773 use_oplocks = True;
6774 break;
6775 case 'A':
6776 torture_showall = True;
6777 break;
6778 case 'n':
6779 fstrcpy(myname, optarg);
6780 break;
6781 case 'c':
6782 client_txt = optarg;
6783 break;
6784 case 'e':
6785 do_encrypt = true;
6786 break;
6787 case 'k':
6788 #ifdef HAVE_KRB5
6789 use_kerberos = True;
6790 #else
6791 d_printf("No kerberos support compiled in\n");
6792 exit(1);
6793 #endif
6794 break;
6795 case 'U':
6796 gotuser = 1;
6797 fstrcpy(username,optarg);
6798 p = strchr_m(username,'%');
6799 if (p) {
6800 *p = 0;
6801 fstrcpy(password, p+1);
6802 gotpass = 1;
6804 break;
6805 case 'b':
6806 fstrcpy(multishare_conn_fname, optarg);
6807 use_multishare_conn = True;
6808 break;
6809 case 'B':
6810 torture_blocksize = atoi(optarg);
6811 break;
6812 default:
6813 printf("Unknown option %c (%d)\n", (char)opt, opt);
6814 usage();
6818 d_printf("using seed %d\n", seed);
6820 srandom(seed);
6822 if(use_kerberos && !gotuser) gotpass = True;
6824 while (!gotpass) {
6825 p = getpass("Password:");
6826 if (p) {
6827 fstrcpy(password, p);
6828 gotpass = 1;
6832 printf("host=%s share=%s user=%s myname=%s\n",
6833 host, share, username, myname);
6835 if (argc == optind) {
6836 correct = run_test("ALL");
6837 } else {
6838 for (i=optind;i<argc;i++) {
6839 if (!run_test(argv[i])) {
6840 correct = False;
6845 TALLOC_FREE(frame);
6847 if (correct) {
6848 return(0);
6849 } else {
6850 return(1);