2 Unix SMB/CIFS implementation.
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/>.
25 static fstring host, workgroup, share, password, username, myname;
26 static int max_protocol = PROTOCOL_NT1;
27 static const char *sockops="TCP_NODELAY";
29 static int port_to_use=0;
30 int torture_numops=100;
31 int torture_blocksize=1024*1024;
32 static int procnum; /* records process count number when forking */
33 static struct cli_state *current_cli;
34 static fstring randomfname;
35 static bool use_oplocks;
36 static bool use_level_II_oplocks;
37 static const char *client_txt = "client_oplocks.txt";
38 static bool use_kerberos;
39 static fstring multishare_conn_fname;
40 static bool use_multishare_conn = False;
41 static bool do_encrypt;
43 bool torture_showall = False;
45 static double create_procs(bool (*fn)(int), bool *result);
48 static struct timeval tp1,tp2;
51 void start_timer(void)
56 double end_timer(void)
59 return((tp2.tv_sec - tp1.tv_sec) +
60 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
64 /* return a pointer to a anonymous shared memory segment of size "size"
65 which will persist across fork() but will disappear when all processes
68 The memory is not zeroed
70 This function uses system5 shared memory. It takes advantage of a property
71 that the memory is not destroyed if it is attached when the id is removed
73 void *shm_setup(int size)
78 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
80 printf("can't get shared memory\n");
83 ret = (void *)shmat(shmid, 0, 0);
84 if (!ret || ret == (void *)-1) {
85 printf("can't attach to shared memory\n");
88 /* the following releases the ipc, but note that this process
89 and all its children will still have access to the memory, its
90 just that the shmid is no longer valid for other shm calls. This
91 means we don't leave behind lots of shm segments after we exit
93 See Stevens "advanced programming in unix env" for details
95 shmctl(shmid, IPC_RMID, 0);
100 /********************************************************************
101 Ensure a connection is encrypted.
102 ********************************************************************/
104 static bool force_cli_encryption(struct cli_state *c,
105 const char *sharename)
108 uint32 caplow, caphigh;
111 if (!SERVER_HAS_UNIX_CIFS(c)) {
112 d_printf("Encryption required and "
113 "server that doesn't support "
114 "UNIX extensions - failing connect\n");
118 if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
119 d_printf("Encryption required and "
120 "can't get UNIX CIFS extensions "
121 "version from server.\n");
125 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
126 d_printf("Encryption required and "
127 "share %s doesn't support "
128 "encryption.\n", sharename);
132 if (c->use_kerberos) {
133 status = cli_gss_smb_encryption_start(c);
135 status = cli_raw_ntlm_smb_encryption_start(c,
141 if (!NT_STATUS_IS_OK(status)) {
142 d_printf("Encryption required and "
143 "setup failed with error %s.\n",
152 static struct cli_state *open_nbt_connection(void)
154 struct nmb_name called, calling;
155 struct sockaddr_storage ss;
159 make_nmb_name(&calling, myname, 0x0);
160 make_nmb_name(&called , host, 0x20);
164 if (!(c = cli_initialise())) {
165 printf("Failed initialize cli_struct to connect with %s\n", host);
169 c->port = port_to_use;
171 status = cli_connect(c, host, &ss);
172 if (!NT_STATUS_IS_OK(status)) {
173 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
177 c->use_kerberos = use_kerberos;
179 c->timeout = 120000; /* set a really long timeout (2 minutes) */
180 if (use_oplocks) c->use_oplocks = True;
181 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
183 if (!cli_session_request(c, &calling, &called)) {
185 * Well, that failed, try *SMBSERVER ...
186 * However, we must reconnect as well ...
188 status = cli_connect(c, host, &ss);
189 if (!NT_STATUS_IS_OK(status)) {
190 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
194 make_nmb_name(&called, "*SMBSERVER", 0x20);
195 if (!cli_session_request(c, &calling, &called)) {
196 printf("%s rejected the session\n",host);
197 printf("We tried with a called name of %s & %s\n",
207 /* Insert a NULL at the first separator of the given path and return a pointer
208 * to the remainder of the string.
211 terminate_path_at_separator(char * path)
219 if ((p = strchr_m(path, '/'))) {
224 if ((p = strchr_m(path, '\\'))) {
234 parse a //server/share type UNC name
236 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
237 char **hostname, char **sharename)
241 *hostname = *sharename = NULL;
243 if (strncmp(unc_name, "\\\\", 2) &&
244 strncmp(unc_name, "//", 2)) {
248 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
249 p = terminate_path_at_separator(*hostname);
252 *sharename = talloc_strdup(mem_ctx, p);
253 terminate_path_at_separator(*sharename);
256 if (*hostname && *sharename) {
260 TALLOC_FREE(*hostname);
261 TALLOC_FREE(*sharename);
265 static bool torture_open_connection_share(struct cli_state **c,
266 const char *hostname,
267 const char *sharename)
274 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
276 status = cli_full_connection(c, myname,
277 hostname, NULL, port_to_use,
280 password, flags, Undefined, &retry);
281 if (!NT_STATUS_IS_OK(status)) {
282 printf("failed to open share connection: //%s/%s port:%d - %s\n",
283 hostname, sharename, port_to_use, nt_errstr(status));
287 if (use_oplocks) (*c)->use_oplocks = True;
288 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
289 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
292 return force_cli_encryption(*c,
298 bool torture_open_connection(struct cli_state **c, int conn_index)
300 char **unc_list = NULL;
301 int num_unc_names = 0;
304 if (use_multishare_conn==True) {
306 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
307 if (!unc_list || num_unc_names <= 0) {
308 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
312 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
314 printf("Failed to parse UNC name %s\n",
315 unc_list[conn_index % num_unc_names]);
316 TALLOC_FREE(unc_list);
320 result = torture_open_connection_share(c, h, s);
322 /* h, s were copied earlier */
323 TALLOC_FREE(unc_list);
327 return torture_open_connection_share(c, host, share);
330 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
332 uint16 old_vuid = cli->vuid;
333 fstring old_user_name;
334 size_t passlen = strlen(password);
337 fstrcpy(old_user_name, cli->user_name);
339 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
343 *new_vuid = cli->vuid;
344 cli->vuid = old_vuid;
345 fstrcpy(cli->user_name, old_user_name);
350 bool torture_close_connection(struct cli_state *c)
354 printf("tdis failed (%s)\n", cli_errstr(c));
364 /* check if the server produced the expected error code */
365 static bool check_error(int line, struct cli_state *c,
366 uint8 eclass, uint32 ecode, NTSTATUS nterr)
368 if (cli_is_dos_error(c)) {
372 /* Check DOS error */
374 cli_dos_error(c, &cclass, &num);
376 if (eclass != cclass || ecode != num) {
377 printf("unexpected error code class=%d code=%d\n",
378 (int)cclass, (int)num);
379 printf(" expected %d/%d %s (line=%d)\n",
380 (int)eclass, (int)ecode, nt_errstr(nterr), line);
389 status = cli_nt_error(c);
391 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
392 printf("unexpected error code %s\n", nt_errstr(status));
393 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
402 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
404 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
405 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
411 static bool rw_torture(struct cli_state *c)
413 const char *lockfname = "\\torture.lck";
417 pid_t pid2, pid = getpid();
422 memset(buf, '\0', sizeof(buf));
424 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
427 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
429 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
434 for (i=0;i<torture_numops;i++) {
435 unsigned n = (unsigned)sys_random()%10;
437 printf("%d\r", i); fflush(stdout);
439 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
441 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
445 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
447 printf("open failed (%s)\n", cli_errstr(c));
452 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
453 printf("write failed (%s)\n", cli_errstr(c));
458 if (cli_write(c, fnum, 0, (char *)buf,
459 sizeof(pid)+(j*sizeof(buf)),
460 sizeof(buf)) != sizeof(buf)) {
461 printf("write failed (%s)\n", cli_errstr(c));
468 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
469 printf("read failed (%s)\n", cli_errstr(c));
474 printf("data corruption!\n");
478 if (!cli_close(c, fnum)) {
479 printf("close failed (%s)\n", cli_errstr(c));
483 if (!cli_unlink(c, fname)) {
484 printf("unlink failed (%s)\n", cli_errstr(c));
488 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
489 printf("unlock failed (%s)\n", cli_errstr(c));
495 cli_unlink(c, lockfname);
502 static bool run_torture(int dummy)
504 struct cli_state *cli;
509 cli_sockopt(cli, sockops);
511 ret = rw_torture(cli);
513 if (!torture_close_connection(cli)) {
520 static bool rw_torture3(struct cli_state *c, char *lockfname)
527 unsigned countprev = 0;
532 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
534 SIVAL(buf, i, sys_random());
539 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
542 printf("first open read/write of %s failed (%s)\n",
543 lockfname, cli_errstr(c));
549 for (i = 0; i < 500 && fnum == -1; i++)
551 fnum = cli_open(c, lockfname, O_RDONLY,
556 printf("second open read-only of %s failed (%s)\n",
557 lockfname, cli_errstr(c));
563 for (count = 0; count < sizeof(buf); count += sent)
565 if (count >= countprev) {
566 printf("%d %8d\r", i, count);
569 countprev += (sizeof(buf) / 20);
574 sent = ((unsigned)sys_random()%(20))+ 1;
575 if (sent > sizeof(buf) - count)
577 sent = sizeof(buf) - count;
580 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
581 printf("write failed (%s)\n", cli_errstr(c));
587 sent = cli_read(c, fnum, buf_rd+count, count,
591 printf("read failed offset:%d size:%ld (%s)\n",
592 count, (unsigned long)sizeof(buf)-count,
599 if (memcmp(buf_rd+count, buf+count, sent) != 0)
601 printf("read/write compare failed\n");
602 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
611 if (!cli_close(c, fnum)) {
612 printf("close failed (%s)\n", cli_errstr(c));
619 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
621 const char *lockfname = "\\torture2.lck";
630 if (!cli_unlink(c1, lockfname)) {
631 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
634 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
637 printf("first open read/write of %s failed (%s)\n",
638 lockfname, cli_errstr(c1));
641 fnum2 = cli_open(c2, lockfname, O_RDONLY,
644 printf("second open read-only of %s failed (%s)\n",
645 lockfname, cli_errstr(c2));
646 cli_close(c1, fnum1);
650 for (i=0;i<torture_numops;i++)
652 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
654 printf("%d\r", i); fflush(stdout);
657 generate_random_buffer((unsigned char *)buf, buf_size);
659 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
660 printf("write failed (%s)\n", cli_errstr(c1));
665 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
666 printf("read failed (%s)\n", cli_errstr(c2));
667 printf("read %d, expected %ld\n", (int)bytes_read,
668 (unsigned long)buf_size);
673 if (memcmp(buf_rd, buf, buf_size) != 0)
675 printf("read/write compare failed\n");
681 if (!cli_close(c2, fnum2)) {
682 printf("close failed (%s)\n", cli_errstr(c2));
685 if (!cli_close(c1, fnum1)) {
686 printf("close failed (%s)\n", cli_errstr(c1));
690 if (!cli_unlink(c1, lockfname)) {
691 printf("unlink failed (%s)\n", cli_errstr(c1));
698 static bool run_readwritetest(int dummy)
700 static struct cli_state *cli1, *cli2;
701 bool test1, test2 = False;
703 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
706 cli_sockopt(cli1, sockops);
707 cli_sockopt(cli2, sockops);
709 printf("starting readwritetest\n");
711 test1 = rw_torture2(cli1, cli2);
712 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
715 test2 = rw_torture2(cli1, cli1);
716 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
719 if (!torture_close_connection(cli1)) {
723 if (!torture_close_connection(cli2)) {
727 return (test1 && test2);
730 static bool run_readwritemulti(int dummy)
732 struct cli_state *cli;
737 cli_sockopt(cli, sockops);
739 printf("run_readwritemulti: fname %s\n", randomfname);
740 test = rw_torture3(cli, randomfname);
742 if (!torture_close_connection(cli)) {
749 static bool run_readwritelarge(int dummy)
751 static struct cli_state *cli1;
753 const char *lockfname = "\\large.dat";
758 if (!torture_open_connection(&cli1, 0)) {
761 cli_sockopt(cli1, sockops);
762 memset(buf,'\0',sizeof(buf));
764 cli1->max_xmit = 128*1024;
766 printf("starting readwritelarge\n");
768 cli_unlink(cli1, lockfname);
770 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
772 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
776 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
778 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
779 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
783 if (fsize == sizeof(buf))
784 printf("readwritelarge test 1 succeeded (size = %lx)\n",
785 (unsigned long)fsize);
787 printf("readwritelarge test 1 failed (size = %lx)\n",
788 (unsigned long)fsize);
792 if (!cli_close(cli1, fnum1)) {
793 printf("close failed (%s)\n", cli_errstr(cli1));
797 if (!cli_unlink(cli1, lockfname)) {
798 printf("unlink failed (%s)\n", cli_errstr(cli1));
802 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
804 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
808 cli1->max_xmit = 4*1024;
810 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
812 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
813 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
817 if (fsize == sizeof(buf))
818 printf("readwritelarge test 2 succeeded (size = %lx)\n",
819 (unsigned long)fsize);
821 printf("readwritelarge test 2 failed (size = %lx)\n",
822 (unsigned long)fsize);
827 /* ToDo - set allocation. JRA */
828 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
829 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
832 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
833 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
837 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
840 if (!cli_close(cli1, fnum1)) {
841 printf("close failed (%s)\n", cli_errstr(cli1));
845 if (!torture_close_connection(cli1)) {
854 #define ival(s) strtol(s, NULL, 0)
856 /* run a test that simulates an approximate netbench client load */
857 static bool run_netbench(int client)
859 struct cli_state *cli;
864 const char *params[20];
871 cli_sockopt(cli, sockops);
875 slprintf(cname,sizeof(cname)-1, "client%d", client);
877 f = fopen(client_txt, "r");
884 while (fgets(line, sizeof(line)-1, f)) {
888 line[strlen(line)-1] = 0;
890 /* printf("[%d] %s\n", line_count, line); */
892 all_string_sub(line,"client1", cname, sizeof(line));
894 /* parse the command parameters */
895 params[0] = strtok_r(line, " ", &saveptr);
897 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
903 if (!strncmp(params[0],"SMB", 3)) {
904 printf("ERROR: You are using a dbench 1 load file\n");
908 if (!strcmp(params[0],"NTCreateX")) {
909 nb_createx(params[1], ival(params[2]), ival(params[3]),
911 } else if (!strcmp(params[0],"Close")) {
912 nb_close(ival(params[1]));
913 } else if (!strcmp(params[0],"Rename")) {
914 nb_rename(params[1], params[2]);
915 } else if (!strcmp(params[0],"Unlink")) {
916 nb_unlink(params[1]);
917 } else if (!strcmp(params[0],"Deltree")) {
918 nb_deltree(params[1]);
919 } else if (!strcmp(params[0],"Rmdir")) {
921 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
922 nb_qpathinfo(params[1]);
923 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
924 nb_qfileinfo(ival(params[1]));
925 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
926 nb_qfsinfo(ival(params[1]));
927 } else if (!strcmp(params[0],"FIND_FIRST")) {
928 nb_findfirst(params[1]);
929 } else if (!strcmp(params[0],"WriteX")) {
930 nb_writex(ival(params[1]),
931 ival(params[2]), ival(params[3]), ival(params[4]));
932 } else if (!strcmp(params[0],"ReadX")) {
933 nb_readx(ival(params[1]),
934 ival(params[2]), ival(params[3]), ival(params[4]));
935 } else if (!strcmp(params[0],"Flush")) {
936 nb_flush(ival(params[1]));
938 printf("Unknown operation %s\n", params[0]);
946 if (!torture_close_connection(cli)) {
954 /* run a test that simulates an approximate netbench client load */
955 static bool run_nbench(int dummy)
964 signal(SIGALRM, nb_alarm);
966 t = create_procs(run_netbench, &correct);
969 printf("\nThroughput %g MB/sec\n",
970 1.0e-6 * nbio_total() / t);
976 This test checks for two things:
978 1) correct support for retaining locks over a close (ie. the server
979 must not use posix semantics)
980 2) support for lock timeouts
982 static bool run_locktest1(int dummy)
984 struct cli_state *cli1, *cli2;
985 const char *fname = "\\lockt1.lck";
986 int fnum1, fnum2, fnum3;
988 unsigned lock_timeout;
990 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
993 cli_sockopt(cli1, sockops);
994 cli_sockopt(cli2, sockops);
996 printf("starting locktest1\n");
998 cli_unlink(cli1, fname);
1000 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1002 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1005 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1007 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1010 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1012 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1016 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1017 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1022 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1023 printf("lock2 succeeded! This is a locking bug\n");
1026 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1027 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1031 lock_timeout = (1 + (random() % 20));
1032 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1034 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1035 printf("lock3 succeeded! This is a locking bug\n");
1038 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1039 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1043 if (ABS(t2 - t1) < lock_timeout-1) {
1044 printf("error: This server appears not to support timed lock requests\n");
1047 printf("server slept for %u seconds for a %u second timeout\n",
1048 (unsigned int)(t2-t1), lock_timeout);
1050 if (!cli_close(cli1, fnum2)) {
1051 printf("close1 failed (%s)\n", cli_errstr(cli1));
1055 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1056 printf("lock4 succeeded! This is a locking bug\n");
1059 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1060 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1063 if (!cli_close(cli1, fnum1)) {
1064 printf("close2 failed (%s)\n", cli_errstr(cli1));
1068 if (!cli_close(cli2, fnum3)) {
1069 printf("close3 failed (%s)\n", cli_errstr(cli2));
1073 if (!cli_unlink(cli1, fname)) {
1074 printf("unlink failed (%s)\n", cli_errstr(cli1));
1079 if (!torture_close_connection(cli1)) {
1083 if (!torture_close_connection(cli2)) {
1087 printf("Passed locktest1\n");
1092 this checks to see if a secondary tconx can use open files from an
1095 static bool run_tcon_test(int dummy)
1097 static struct cli_state *cli;
1098 const char *fname = "\\tcontest.tmp";
1100 uint16 cnum1, cnum2, cnum3;
1101 uint16 vuid1, vuid2;
1105 memset(buf, '\0', sizeof(buf));
1107 if (!torture_open_connection(&cli, 0)) {
1110 cli_sockopt(cli, sockops);
1112 printf("starting tcontest\n");
1114 cli_unlink(cli, fname);
1116 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1118 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1125 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1126 printf("initial write failed (%s)", cli_errstr(cli));
1130 if (!cli_send_tconX(cli, share, "?????",
1131 password, strlen(password)+1)) {
1132 printf("%s refused 2nd tree connect (%s)\n", host,
1139 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1140 vuid2 = cli->vuid + 1;
1142 /* try a write with the wrong tid */
1145 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1146 printf("* server allows write with wrong TID\n");
1149 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1153 /* try a write with an invalid tid */
1156 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1157 printf("* server allows write with invalid TID\n");
1160 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1163 /* try a write with an invalid vuid */
1167 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1168 printf("* server allows write with invalid VUID\n");
1171 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1177 if (!cli_close(cli, fnum1)) {
1178 printf("close failed (%s)\n", cli_errstr(cli));
1184 if (!cli_tdis(cli)) {
1185 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1191 if (!torture_close_connection(cli)) {
1200 checks for old style tcon support
1202 static bool run_tcon2_test(int dummy)
1204 static struct cli_state *cli;
1205 uint16 cnum, max_xmit;
1209 if (!torture_open_connection(&cli, 0)) {
1212 cli_sockopt(cli, sockops);
1214 printf("starting tcon2 test\n");
1216 asprintf(&service, "\\\\%s\\%s", host, share);
1218 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1220 if (!NT_STATUS_IS_OK(status)) {
1221 printf("tcon2 failed : %s\n", cli_errstr(cli));
1223 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1224 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1227 if (!torture_close_connection(cli)) {
1231 printf("Passed tcon2 test\n");
1235 static bool tcon_devtest(struct cli_state *cli,
1236 const char *myshare, const char *devtype,
1237 const char *return_devtype,
1238 NTSTATUS expected_error)
1243 status = cli_send_tconX(cli, myshare, devtype,
1244 password, strlen(password)+1);
1246 if (NT_STATUS_IS_OK(expected_error)) {
1248 if (strcmp(cli->dev, return_devtype) == 0) {
1251 printf("tconX to share %s with type %s "
1252 "succeeded but returned the wrong "
1253 "device type (got [%s] but should have got [%s])\n",
1254 myshare, devtype, cli->dev, return_devtype);
1258 printf("tconX to share %s with type %s "
1259 "should have succeeded but failed\n",
1266 printf("tconx to share %s with type %s "
1267 "should have failed but succeeded\n",
1271 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1275 printf("Returned unexpected error\n");
1284 checks for correct tconX support
1286 static bool run_tcon_devtype_test(int dummy)
1288 static struct cli_state *cli1 = NULL;
1294 status = cli_full_connection(&cli1, myname,
1295 host, NULL, port_to_use,
1297 username, workgroup,
1298 password, flags, Undefined, &retry);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 printf("could not open connection\n");
1305 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1308 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1311 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1314 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1317 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1320 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1323 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1326 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1329 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1332 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1338 printf("Passed tcondevtest\n");
1345 This test checks that
1347 1) the server supports multiple locking contexts on the one SMB
1348 connection, distinguished by PID.
1350 2) the server correctly fails overlapping locks made by the same PID (this
1351 goes against POSIX behaviour, which is why it is tricky to implement)
1353 3) the server denies unlock requests by an incorrect client PID
1355 static bool run_locktest2(int dummy)
1357 static struct cli_state *cli;
1358 const char *fname = "\\lockt2.lck";
1359 int fnum1, fnum2, fnum3;
1360 bool correct = True;
1362 if (!torture_open_connection(&cli, 0)) {
1366 cli_sockopt(cli, sockops);
1368 printf("starting locktest2\n");
1370 cli_unlink(cli, fname);
1374 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1376 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1380 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1382 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1388 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1390 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1396 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1397 printf("lock1 failed (%s)\n", cli_errstr(cli));
1401 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1402 printf("WRITE lock1 succeeded! This is a locking bug\n");
1405 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1406 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1409 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1410 printf("WRITE lock2 succeeded! This is a locking bug\n");
1413 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1414 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1417 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1418 printf("READ lock2 succeeded! This is a locking bug\n");
1421 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1422 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1425 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1426 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1429 if (cli_unlock(cli, fnum1, 100, 4)) {
1430 printf("unlock at 100 succeeded! This is a locking bug\n");
1434 if (cli_unlock(cli, fnum1, 0, 4)) {
1435 printf("unlock1 succeeded! This is a locking bug\n");
1438 if (!check_error(__LINE__, cli,
1440 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1443 if (cli_unlock(cli, fnum1, 0, 8)) {
1444 printf("unlock2 succeeded! This is a locking bug\n");
1447 if (!check_error(__LINE__, cli,
1449 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1452 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1453 printf("lock3 succeeded! This is a locking bug\n");
1456 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1461 if (!cli_close(cli, fnum1)) {
1462 printf("close1 failed (%s)\n", cli_errstr(cli));
1466 if (!cli_close(cli, fnum2)) {
1467 printf("close2 failed (%s)\n", cli_errstr(cli));
1471 if (!cli_close(cli, fnum3)) {
1472 printf("close3 failed (%s)\n", cli_errstr(cli));
1476 if (!torture_close_connection(cli)) {
1480 printf("locktest2 finished\n");
1487 This test checks that
1489 1) the server supports the full offset range in lock requests
1491 static bool run_locktest3(int dummy)
1493 static struct cli_state *cli1, *cli2;
1494 const char *fname = "\\lockt3.lck";
1495 int fnum1, fnum2, i;
1497 bool correct = True;
1499 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1501 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1504 cli_sockopt(cli1, sockops);
1505 cli_sockopt(cli2, sockops);
1507 printf("starting locktest3\n");
1509 cli_unlink(cli1, fname);
1511 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1513 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1516 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1518 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1522 for (offset=i=0;i<torture_numops;i++) {
1524 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1525 printf("lock1 %d failed (%s)\n",
1531 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1532 printf("lock2 %d failed (%s)\n",
1539 for (offset=i=0;i<torture_numops;i++) {
1542 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1543 printf("error: lock1 %d succeeded!\n", i);
1547 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1548 printf("error: lock2 %d succeeded!\n", i);
1552 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1553 printf("error: lock3 %d succeeded!\n", i);
1557 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1558 printf("error: lock4 %d succeeded!\n", i);
1563 for (offset=i=0;i<torture_numops;i++) {
1566 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1567 printf("unlock1 %d failed (%s)\n",
1573 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1574 printf("unlock2 %d failed (%s)\n",
1581 if (!cli_close(cli1, fnum1)) {
1582 printf("close1 failed (%s)\n", cli_errstr(cli1));
1586 if (!cli_close(cli2, fnum2)) {
1587 printf("close2 failed (%s)\n", cli_errstr(cli2));
1591 if (!cli_unlink(cli1, fname)) {
1592 printf("unlink failed (%s)\n", cli_errstr(cli1));
1596 if (!torture_close_connection(cli1)) {
1600 if (!torture_close_connection(cli2)) {
1604 printf("finished locktest3\n");
1609 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1610 printf("** "); correct = False; \
1614 looks at overlapping locks
1616 static bool run_locktest4(int dummy)
1618 static struct cli_state *cli1, *cli2;
1619 const char *fname = "\\lockt4.lck";
1620 int fnum1, fnum2, f;
1623 bool correct = True;
1625 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1629 cli_sockopt(cli1, sockops);
1630 cli_sockopt(cli2, sockops);
1632 printf("starting locktest4\n");
1634 cli_unlink(cli1, fname);
1636 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1637 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1639 memset(buf, 0, sizeof(buf));
1641 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1642 printf("Failed to create file\n");
1647 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1648 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1649 EXPECTED(ret, False);
1650 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1652 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1653 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1654 EXPECTED(ret, True);
1655 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1657 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1658 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1659 EXPECTED(ret, False);
1660 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1662 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1663 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1664 EXPECTED(ret, True);
1665 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1667 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1668 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1669 EXPECTED(ret, False);
1670 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1672 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1673 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1674 EXPECTED(ret, True);
1675 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1677 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1678 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1679 EXPECTED(ret, True);
1680 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1682 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1683 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1684 EXPECTED(ret, False);
1685 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1687 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1688 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1689 EXPECTED(ret, False);
1690 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1692 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1693 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1694 EXPECTED(ret, True);
1695 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1697 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1698 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1699 EXPECTED(ret, False);
1700 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1702 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1703 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1704 cli_unlock(cli1, fnum1, 110, 6);
1705 EXPECTED(ret, False);
1706 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1709 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1710 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1711 EXPECTED(ret, False);
1712 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1714 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1715 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1716 EXPECTED(ret, False);
1717 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1720 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1721 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1722 cli_unlock(cli1, fnum1, 140, 4) &&
1723 cli_unlock(cli1, fnum1, 140, 4);
1724 EXPECTED(ret, True);
1725 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1728 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1729 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1730 cli_unlock(cli1, fnum1, 150, 4) &&
1731 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1732 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1733 cli_unlock(cli1, fnum1, 150, 4);
1734 EXPECTED(ret, True);
1735 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1737 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1738 cli_unlock(cli1, fnum1, 160, 4) &&
1739 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1740 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1741 EXPECTED(ret, True);
1742 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1744 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1745 cli_unlock(cli1, fnum1, 170, 4) &&
1746 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1747 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1748 EXPECTED(ret, True);
1749 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1751 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1752 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1753 cli_unlock(cli1, fnum1, 190, 4) &&
1754 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1755 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1756 EXPECTED(ret, True);
1757 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1759 cli_close(cli1, fnum1);
1760 cli_close(cli2, fnum2);
1761 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1762 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1763 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1764 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1765 cli_close(cli1, fnum1) &&
1766 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1767 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1769 cli_close(cli1, fnum1);
1770 EXPECTED(ret, True);
1771 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1774 cli_close(cli1, fnum1);
1775 cli_close(cli2, fnum2);
1776 cli_unlink(cli1, fname);
1777 torture_close_connection(cli1);
1778 torture_close_connection(cli2);
1780 printf("finished locktest4\n");
1785 looks at lock upgrade/downgrade.
1787 static bool run_locktest5(int dummy)
1789 static struct cli_state *cli1, *cli2;
1790 const char *fname = "\\lockt5.lck";
1791 int fnum1, fnum2, fnum3;
1794 bool correct = True;
1796 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1800 cli_sockopt(cli1, sockops);
1801 cli_sockopt(cli2, sockops);
1803 printf("starting locktest5\n");
1805 cli_unlink(cli1, fname);
1807 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1808 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1809 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1811 memset(buf, 0, sizeof(buf));
1813 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1814 printf("Failed to create file\n");
1819 /* Check for NT bug... */
1820 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1821 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1822 cli_close(cli1, fnum1);
1823 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1824 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1825 EXPECTED(ret, True);
1826 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1827 cli_close(cli1, fnum1);
1828 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1829 cli_unlock(cli1, fnum3, 0, 1);
1831 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1832 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1833 EXPECTED(ret, True);
1834 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1836 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1837 EXPECTED(ret, False);
1839 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1841 /* Unlock the process 2 lock. */
1842 cli_unlock(cli2, fnum2, 0, 4);
1844 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1845 EXPECTED(ret, False);
1847 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1849 /* Unlock the process 1 fnum3 lock. */
1850 cli_unlock(cli1, fnum3, 0, 4);
1852 /* Stack 2 more locks here. */
1853 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1854 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1856 EXPECTED(ret, True);
1857 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1859 /* Unlock the first process lock, then check this was the WRITE lock that was
1862 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1863 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1865 EXPECTED(ret, True);
1866 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1868 /* Unlock the process 2 lock. */
1869 cli_unlock(cli2, fnum2, 0, 4);
1871 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1873 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1874 cli_unlock(cli1, fnum1, 0, 4) &&
1875 cli_unlock(cli1, fnum1, 0, 4);
1877 EXPECTED(ret, True);
1878 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1880 /* Ensure the next unlock fails. */
1881 ret = cli_unlock(cli1, fnum1, 0, 4);
1882 EXPECTED(ret, False);
1883 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1885 /* Ensure connection 2 can get a write lock. */
1886 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1887 EXPECTED(ret, True);
1889 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1893 cli_close(cli1, fnum1);
1894 cli_close(cli2, fnum2);
1895 cli_unlink(cli1, fname);
1896 if (!torture_close_connection(cli1)) {
1899 if (!torture_close_connection(cli2)) {
1903 printf("finished locktest5\n");
1909 tries the unusual lockingX locktype bits
1911 static bool run_locktest6(int dummy)
1913 static struct cli_state *cli;
1914 const char *fname[1] = { "\\lock6.txt" };
1919 if (!torture_open_connection(&cli, 0)) {
1923 cli_sockopt(cli, sockops);
1925 printf("starting locktest6\n");
1928 printf("Testing %s\n", fname[i]);
1930 cli_unlink(cli, fname[i]);
1932 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1933 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1934 cli_close(cli, fnum);
1935 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1937 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1938 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1939 cli_close(cli, fnum);
1940 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1942 cli_unlink(cli, fname[i]);
1945 torture_close_connection(cli);
1947 printf("finished locktest6\n");
1951 static bool run_locktest7(int dummy)
1953 struct cli_state *cli1;
1954 const char *fname = "\\lockt7.lck";
1957 bool correct = False;
1959 if (!torture_open_connection(&cli1, 0)) {
1963 cli_sockopt(cli1, sockops);
1965 printf("starting locktest7\n");
1967 cli_unlink(cli1, fname);
1969 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1971 memset(buf, 0, sizeof(buf));
1973 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1974 printf("Failed to create file\n");
1978 cli_setpid(cli1, 1);
1980 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1981 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1984 printf("pid1 successfully locked range 130:4 for READ\n");
1987 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1988 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
1991 printf("pid1 successfully read the range 130:4\n");
1994 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
1995 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
1996 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
1997 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2001 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2005 cli_setpid(cli1, 2);
2007 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2008 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2010 printf("pid2 successfully read the range 130:4\n");
2013 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2014 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2015 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2016 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2020 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2024 cli_setpid(cli1, 1);
2025 cli_unlock(cli1, fnum1, 130, 4);
2027 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2028 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2031 printf("pid1 successfully locked range 130:4 for WRITE\n");
2034 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2035 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2038 printf("pid1 successfully read the range 130:4\n");
2041 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2042 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2045 printf("pid1 successfully wrote to the range 130:4\n");
2048 cli_setpid(cli1, 2);
2050 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2051 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2052 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2053 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2057 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2061 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2062 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2063 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2064 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2068 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2072 cli_unlock(cli1, fnum1, 130, 0);
2076 cli_close(cli1, fnum1);
2077 cli_unlink(cli1, fname);
2078 torture_close_connection(cli1);
2080 printf("finished locktest7\n");
2085 test whether fnums and tids open on one VC are available on another (a major
2088 static bool run_fdpasstest(int dummy)
2090 struct cli_state *cli1, *cli2;
2091 const char *fname = "\\fdpass.tst";
2095 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2098 cli_sockopt(cli1, sockops);
2099 cli_sockopt(cli2, sockops);
2101 printf("starting fdpasstest\n");
2103 cli_unlink(cli1, fname);
2105 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2107 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2111 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2112 printf("write failed (%s)\n", cli_errstr(cli1));
2116 cli2->vuid = cli1->vuid;
2117 cli2->cnum = cli1->cnum;
2118 cli2->pid = cli1->pid;
2120 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2121 printf("read succeeded! nasty security hole [%s]\n",
2126 cli_close(cli1, fnum1);
2127 cli_unlink(cli1, fname);
2129 torture_close_connection(cli1);
2130 torture_close_connection(cli2);
2132 printf("finished fdpasstest\n");
2136 static bool run_fdsesstest(int dummy)
2138 struct cli_state *cli;
2143 const char *fname = "\\fdsess.tst";
2144 const char *fname1 = "\\fdsess1.tst";
2150 if (!torture_open_connection(&cli, 0))
2152 cli_sockopt(cli, sockops);
2154 if (!torture_cli_session_setup2(cli, &new_vuid))
2157 saved_cnum = cli->cnum;
2158 if (!cli_send_tconX(cli, share, "?????", "", 1))
2160 new_cnum = cli->cnum;
2161 cli->cnum = saved_cnum;
2163 printf("starting fdsesstest\n");
2165 cli_unlink(cli, fname);
2166 cli_unlink(cli, fname1);
2168 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2170 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2174 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2175 printf("write failed (%s)\n", cli_errstr(cli));
2179 saved_vuid = cli->vuid;
2180 cli->vuid = new_vuid;
2182 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2183 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2187 /* Try to open a file with different vuid, samba cnum. */
2188 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2190 printf("create with different vuid, same cnum succeeded.\n");
2191 cli_close(cli, fnum2);
2192 cli_unlink(cli, fname1);
2194 printf("create with different vuid, same cnum failed.\n");
2195 printf("This will cause problems with service clients.\n");
2199 cli->vuid = saved_vuid;
2201 /* Try with same vuid, different cnum. */
2202 cli->cnum = new_cnum;
2204 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2205 printf("read succeeded with different cnum![%s]\n",
2210 cli->cnum = saved_cnum;
2211 cli_close(cli, fnum1);
2212 cli_unlink(cli, fname);
2214 torture_close_connection(cli);
2216 printf("finished fdsesstest\n");
2221 This test checks that
2223 1) the server does not allow an unlink on a file that is open
2225 static bool run_unlinktest(int dummy)
2227 struct cli_state *cli;
2228 const char *fname = "\\unlink.tst";
2230 bool correct = True;
2232 if (!torture_open_connection(&cli, 0)) {
2236 cli_sockopt(cli, sockops);
2238 printf("starting unlink test\n");
2240 cli_unlink(cli, fname);
2244 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2246 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2250 if (cli_unlink(cli, fname)) {
2251 printf("error: server allowed unlink on an open file\n");
2254 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2255 NT_STATUS_SHARING_VIOLATION);
2258 cli_close(cli, fnum);
2259 cli_unlink(cli, fname);
2261 if (!torture_close_connection(cli)) {
2265 printf("unlink test finished\n");
2272 test how many open files this server supports on the one socket
2274 static bool run_maxfidtest(int dummy)
2276 struct cli_state *cli;
2277 const char *ftemplate = "\\maxfid.%d.%d";
2279 int fnums[0x11000], i;
2281 bool correct = True;
2286 printf("failed to connect\n");
2290 cli_sockopt(cli, sockops);
2292 for (i=0; i<0x11000; i++) {
2293 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2294 if ((fnums[i] = cli_open(cli, fname,
2295 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2297 printf("open of %s failed (%s)\n",
2298 fname, cli_errstr(cli));
2299 printf("maximum fnum is %d\n", i);
2307 printf("cleaning up\n");
2309 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2310 cli_close(cli, fnums[i]);
2311 if (!cli_unlink(cli, fname)) {
2312 printf("unlink of %s failed (%s)\n",
2313 fname, cli_errstr(cli));
2320 printf("maxfid test finished\n");
2321 if (!torture_close_connection(cli)) {
2327 /* generate a random buffer */
2328 static void rand_buf(char *buf, int len)
2331 *buf = (char)sys_random();
2336 /* send smb negprot commands, not reading the response */
2337 static bool run_negprot_nowait(int dummy)
2340 static struct cli_state *cli;
2341 bool correct = True;
2343 printf("starting negprot nowait test\n");
2345 if (!(cli = open_nbt_connection())) {
2349 for (i=0;i<50000;i++) {
2350 cli_negprot_sendsync(cli);
2353 if (!torture_close_connection(cli)) {
2357 printf("finished negprot nowait test\n");
2363 /* send random IPC commands */
2364 static bool run_randomipc(int dummy)
2366 char *rparam = NULL;
2368 unsigned int rdrcnt,rprcnt;
2370 int api, param_len, i;
2371 struct cli_state *cli;
2372 bool correct = True;
2375 printf("starting random ipc test\n");
2377 if (!torture_open_connection(&cli, 0)) {
2381 for (i=0;i<count;i++) {
2382 api = sys_random() % 500;
2383 param_len = (sys_random() % 64);
2385 rand_buf(param, param_len);
2390 param, param_len, 8,
2391 NULL, 0, BUFFER_SIZE,
2395 printf("%d/%d\r", i,count);
2398 printf("%d/%d\n", i, count);
2400 if (!torture_close_connection(cli)) {
2404 printf("finished random ipc test\n");
2411 static void browse_callback(const char *sname, uint32 stype,
2412 const char *comment, void *state)
2414 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2420 This test checks the browse list code
2423 static bool run_browsetest(int dummy)
2425 static struct cli_state *cli;
2426 bool correct = True;
2428 printf("starting browse test\n");
2430 if (!torture_open_connection(&cli, 0)) {
2434 printf("domain list:\n");
2435 cli_NetServerEnum(cli, cli->server_domain,
2436 SV_TYPE_DOMAIN_ENUM,
2437 browse_callback, NULL);
2439 printf("machine list:\n");
2440 cli_NetServerEnum(cli, cli->server_domain,
2442 browse_callback, NULL);
2444 if (!torture_close_connection(cli)) {
2448 printf("browse test finished\n");
2456 This checks how the getatr calls works
2458 static bool run_attrtest(int dummy)
2460 struct cli_state *cli;
2463 const char *fname = "\\attrib123456789.tst";
2464 bool correct = True;
2466 printf("starting attrib test\n");
2468 if (!torture_open_connection(&cli, 0)) {
2472 cli_unlink(cli, fname);
2473 fnum = cli_open(cli, fname,
2474 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2475 cli_close(cli, fnum);
2476 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2477 printf("getatr failed (%s)\n", cli_errstr(cli));
2481 if (abs(t - time(NULL)) > 60*60*24*10) {
2482 printf("ERROR: SMBgetatr bug. time is %s",
2488 t2 = t-60*60*24; /* 1 day ago */
2490 if (!cli_setatr(cli, fname, 0, t2)) {
2491 printf("setatr failed (%s)\n", cli_errstr(cli));
2495 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2496 printf("getatr failed (%s)\n", cli_errstr(cli));
2501 printf("ERROR: getatr/setatr bug. times are\n%s",
2503 printf("%s", ctime(&t2));
2507 cli_unlink(cli, fname);
2509 if (!torture_close_connection(cli)) {
2513 printf("attrib test finished\n");
2520 This checks a couple of trans2 calls
2522 static bool run_trans2test(int dummy)
2524 struct cli_state *cli;
2527 time_t c_time, a_time, m_time;
2528 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2529 const char *fname = "\\trans2.tst";
2530 const char *dname = "\\trans2";
2531 const char *fname2 = "\\trans2\\trans2.tst";
2533 bool correct = True;
2535 printf("starting trans2 test\n");
2537 if (!torture_open_connection(&cli, 0)) {
2541 cli_unlink(cli, fname);
2542 fnum = cli_open(cli, fname,
2543 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2544 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2545 &m_time_ts, NULL)) {
2546 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2550 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2551 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2555 if (strcmp(pname, fname)) {
2556 printf("qfilename gave different name? [%s] [%s]\n",
2561 cli_close(cli, fnum);
2565 cli_unlink(cli, fname);
2566 fnum = cli_open(cli, fname,
2567 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2569 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2572 cli_close(cli, fnum);
2574 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2575 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2578 if (c_time != m_time) {
2579 printf("create time=%s", ctime(&c_time));
2580 printf("modify time=%s", ctime(&m_time));
2581 printf("This system appears to have sticky create times\n");
2583 if (a_time % (60*60) == 0) {
2584 printf("access time=%s", ctime(&a_time));
2585 printf("This system appears to set a midnight access time\n");
2589 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2590 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2596 cli_unlink(cli, fname);
2597 fnum = cli_open(cli, fname,
2598 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2599 cli_close(cli, fnum);
2600 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2601 &m_time_ts, &size, NULL, NULL)) {
2602 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2605 if (w_time_ts.tv_sec < 60*60*24*2) {
2606 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2607 printf("This system appears to set a initial 0 write time\n");
2612 cli_unlink(cli, fname);
2615 /* check if the server updates the directory modification time
2616 when creating a new file */
2617 if (!cli_mkdir(cli, dname)) {
2618 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2622 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2623 &m_time_ts, &size, NULL, NULL)) {
2624 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2628 fnum = cli_open(cli, fname2,
2629 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2630 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2631 cli_close(cli, fnum);
2632 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2633 &m_time2_ts, &size, NULL, NULL)) {
2634 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2637 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2639 printf("This system does not update directory modification times\n");
2643 cli_unlink(cli, fname2);
2644 cli_rmdir(cli, dname);
2646 if (!torture_close_connection(cli)) {
2650 printf("trans2 test finished\n");
2656 This checks new W2K calls.
2659 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2663 bool correct = True;
2665 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2666 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2669 printf("qfileinfo: level %d, len = %u\n", level, len);
2670 dump_data(0, (uint8 *)buf, len);
2677 static bool run_w2ktest(int dummy)
2679 struct cli_state *cli;
2681 const char *fname = "\\w2ktest\\w2k.tst";
2683 bool correct = True;
2685 printf("starting w2k test\n");
2687 if (!torture_open_connection(&cli, 0)) {
2691 fnum = cli_open(cli, fname,
2692 O_RDWR | O_CREAT , DENY_NONE);
2694 for (level = 1004; level < 1040; level++) {
2695 new_trans(cli, fnum, level);
2698 cli_close(cli, fnum);
2700 if (!torture_close_connection(cli)) {
2704 printf("w2k test finished\n");
2711 this is a harness for some oplock tests
2713 static bool run_oplock1(int dummy)
2715 struct cli_state *cli1;
2716 const char *fname = "\\lockt1.lck";
2718 bool correct = True;
2720 printf("starting oplock test 1\n");
2722 if (!torture_open_connection(&cli1, 0)) {
2726 cli_unlink(cli1, fname);
2728 cli_sockopt(cli1, sockops);
2730 cli1->use_oplocks = True;
2732 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2734 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2738 cli1->use_oplocks = False;
2740 cli_unlink(cli1, fname);
2741 cli_unlink(cli1, fname);
2743 if (!cli_close(cli1, fnum1)) {
2744 printf("close2 failed (%s)\n", cli_errstr(cli1));
2748 if (!cli_unlink(cli1, fname)) {
2749 printf("unlink failed (%s)\n", cli_errstr(cli1));
2753 if (!torture_close_connection(cli1)) {
2757 printf("finished oplock test 1\n");
2762 static bool run_oplock2(int dummy)
2764 struct cli_state *cli1, *cli2;
2765 const char *fname = "\\lockt2.lck";
2767 int saved_use_oplocks = use_oplocks;
2769 bool correct = True;
2770 volatile bool *shared_correct;
2772 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2773 *shared_correct = True;
2775 use_level_II_oplocks = True;
2778 printf("starting oplock test 2\n");
2780 if (!torture_open_connection(&cli1, 0)) {
2781 use_level_II_oplocks = False;
2782 use_oplocks = saved_use_oplocks;
2786 cli1->use_oplocks = True;
2787 cli1->use_level_II_oplocks = True;
2789 if (!torture_open_connection(&cli2, 1)) {
2790 use_level_II_oplocks = False;
2791 use_oplocks = saved_use_oplocks;
2795 cli2->use_oplocks = True;
2796 cli2->use_level_II_oplocks = True;
2798 cli_unlink(cli1, fname);
2800 cli_sockopt(cli1, sockops);
2801 cli_sockopt(cli2, sockops);
2803 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2805 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2809 /* Don't need the globals any more. */
2810 use_level_II_oplocks = False;
2811 use_oplocks = saved_use_oplocks;
2815 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2817 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2818 *shared_correct = False;
2824 if (!cli_close(cli2, fnum2)) {
2825 printf("close2 failed (%s)\n", cli_errstr(cli1));
2826 *shared_correct = False;
2834 /* Ensure cli1 processes the break. Empty file should always return 0
2837 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2838 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2842 /* Should now be at level II. */
2843 /* Test if sending a write locks causes a break to none. */
2845 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2846 printf("lock failed (%s)\n", cli_errstr(cli1));
2850 cli_unlock(cli1, fnum1, 0, 4);
2854 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2855 printf("lock failed (%s)\n", cli_errstr(cli1));
2859 cli_unlock(cli1, fnum1, 0, 4);
2863 cli_read(cli1, fnum1, buf, 0, 4);
2866 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2867 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2872 if (!cli_close(cli1, fnum1)) {
2873 printf("close1 failed (%s)\n", cli_errstr(cli1));
2879 if (!cli_unlink(cli1, fname)) {
2880 printf("unlink failed (%s)\n", cli_errstr(cli1));
2884 if (!torture_close_connection(cli1)) {
2888 if (!*shared_correct) {
2892 printf("finished oplock test 2\n");
2897 /* handler for oplock 3 tests */
2898 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2900 printf("got oplock break fnum=%d level=%d\n",
2902 return cli_oplock_ack(cli, fnum, level);
2905 static bool run_oplock3(int dummy)
2907 struct cli_state *cli;
2908 const char *fname = "\\oplockt3.dat";
2910 char buf[4] = "abcd";
2911 bool correct = True;
2912 volatile bool *shared_correct;
2914 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2915 *shared_correct = True;
2917 printf("starting oplock test 3\n");
2922 use_level_II_oplocks = True;
2923 if (!torture_open_connection(&cli, 0)) {
2924 *shared_correct = False;
2928 /* try to trigger a oplock break in parent */
2929 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2930 cli_write(cli, fnum, 0, buf, 0, 4);
2936 use_level_II_oplocks = True;
2937 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2940 cli_oplock_handler(cli, oplock3_handler);
2941 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2942 cli_write(cli, fnum, 0, buf, 0, 4);
2943 cli_close(cli, fnum);
2944 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2945 cli->timeout = 20000;
2946 cli_receive_smb(cli);
2947 printf("finished oplock test 3\n");
2949 return (correct && *shared_correct);
2951 /* What are we looking for here? What's sucess and what's FAILURE? */
2957 Test delete on close semantics.
2959 static bool run_deletetest(int dummy)
2961 struct cli_state *cli1 = NULL;
2962 struct cli_state *cli2 = NULL;
2963 const char *fname = "\\delete.file";
2966 bool correct = True;
2968 printf("starting delete test\n");
2970 if (!torture_open_connection(&cli1, 0)) {
2974 cli_sockopt(cli1, sockops);
2976 /* Test 1 - this should delete the file on close. */
2978 cli_setatr(cli1, fname, 0, 0);
2979 cli_unlink(cli1, fname);
2981 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2982 0, FILE_OVERWRITE_IF,
2983 FILE_DELETE_ON_CLOSE, 0);
2986 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
2993 uint32 *accinfo = NULL;
2995 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
2997 printf("access mode = 0x%lx\n", *accinfo);
3002 if (!cli_close(cli1, fnum1)) {
3003 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3008 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
3010 printf("[1] open of %s succeeded (should fail)\n", fname);
3015 printf("first delete on close test succeeded.\n");
3017 /* Test 2 - this should delete the file on close. */
3019 cli_setatr(cli1, fname, 0, 0);
3020 cli_unlink(cli1, fname);
3022 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
3023 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3024 FILE_OVERWRITE_IF, 0, 0);
3027 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3032 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3033 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3038 if (!cli_close(cli1, fnum1)) {
3039 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3044 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3046 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3047 if (!cli_close(cli1, fnum1)) {
3048 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3052 cli_unlink(cli1, fname);
3054 printf("second delete on close test succeeded.\n");
3057 cli_setatr(cli1, fname, 0, 0);
3058 cli_unlink(cli1, fname);
3060 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3061 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3064 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3069 /* This should fail with a sharing violation - open for delete is only compatible
3070 with SHARE_DELETE. */
3072 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3073 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3076 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3081 /* This should succeed. */
3083 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3084 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3087 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3092 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3093 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3098 if (!cli_close(cli1, fnum1)) {
3099 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3104 if (!cli_close(cli1, fnum2)) {
3105 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3110 /* This should fail - file should no longer be there. */
3112 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3114 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3115 if (!cli_close(cli1, fnum1)) {
3116 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3118 cli_unlink(cli1, fname);
3122 printf("third delete on close test succeeded.\n");
3125 cli_setatr(cli1, fname, 0, 0);
3126 cli_unlink(cli1, fname);
3128 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3129 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3132 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3137 /* This should succeed. */
3138 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3139 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3141 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3146 if (!cli_close(cli1, fnum2)) {
3147 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3152 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3153 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3158 /* This should fail - no more opens once delete on close set. */
3159 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3160 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3163 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3167 printf("fourth delete on close test succeeded.\n");
3169 if (!cli_close(cli1, fnum1)) {
3170 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3176 cli_setatr(cli1, fname, 0, 0);
3177 cli_unlink(cli1, fname);
3179 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3181 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3186 /* This should fail - only allowed on NT opens with DELETE access. */
3188 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3189 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3194 if (!cli_close(cli1, fnum1)) {
3195 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3200 printf("fifth delete on close test succeeded.\n");
3203 cli_setatr(cli1, fname, 0, 0);
3204 cli_unlink(cli1, fname);
3206 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3207 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3208 FILE_OVERWRITE_IF, 0, 0);
3211 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3216 /* This should fail - only allowed on NT opens with DELETE access. */
3218 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3219 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3224 if (!cli_close(cli1, fnum1)) {
3225 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3230 printf("sixth delete on close test succeeded.\n");
3233 cli_setatr(cli1, fname, 0, 0);
3234 cli_unlink(cli1, fname);
3236 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3237 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3240 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3245 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3246 printf("[7] setting delete_on_close on file failed !\n");
3251 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3252 printf("[7] unsetting delete_on_close on file failed !\n");
3257 if (!cli_close(cli1, fnum1)) {
3258 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3263 /* This next open should succeed - we reset the flag. */
3265 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3267 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3272 if (!cli_close(cli1, fnum1)) {
3273 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3278 printf("seventh delete on close test succeeded.\n");
3281 cli_setatr(cli1, fname, 0, 0);
3282 cli_unlink(cli1, fname);
3284 if (!torture_open_connection(&cli2, 1)) {
3285 printf("[8] failed to open second connection.\n");
3290 cli_sockopt(cli1, sockops);
3292 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3293 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3294 FILE_OVERWRITE_IF, 0, 0);
3297 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3302 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3303 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3307 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3312 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3313 printf("[8] setting delete_on_close on file failed !\n");
3318 if (!cli_close(cli1, fnum1)) {
3319 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3324 if (!cli_close(cli2, fnum2)) {
3325 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3330 /* This should fail.. */
3331 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3333 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3337 printf("eighth delete on close test succeeded.\n");
3339 /* This should fail - we need to set DELETE_ACCESS. */
3340 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3341 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3344 printf("[9] open of %s succeeded should have failed!\n", fname);
3349 printf("ninth delete on close test succeeded.\n");
3351 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3352 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3354 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3359 /* This should delete the file. */
3360 if (!cli_close(cli1, fnum1)) {
3361 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3366 /* This should fail.. */
3367 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3369 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3373 printf("tenth delete on close test succeeded.\n");
3375 cli_setatr(cli1, fname, 0, 0);
3376 cli_unlink(cli1, fname);
3378 /* What error do we get when attempting to open a read-only file with
3381 /* Create a readonly file. */
3382 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3383 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3385 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3390 if (!cli_close(cli1, fnum1)) {
3391 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3396 /* Now try open for delete access. */
3397 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3398 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3399 FILE_OVERWRITE_IF, 0, 0);
3402 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3403 cli_close(cli1, fnum1);
3407 NTSTATUS nterr = cli_nt_error(cli1);
3408 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3409 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3413 printf("eleventh delete on close test succeeded.\n");
3417 printf("finished delete test\n");
3420 /* FIXME: This will crash if we aborted before cli2 got
3421 * intialized, because these functions don't handle
3422 * uninitialized connections. */
3424 if (fnum1 != -1) cli_close(cli1, fnum1);
3425 if (fnum2 != -1) cli_close(cli1, fnum2);
3426 cli_setatr(cli1, fname, 0, 0);
3427 cli_unlink(cli1, fname);
3429 if (cli1 && !torture_close_connection(cli1)) {
3432 if (cli2 && !torture_close_connection(cli2)) {
3440 print out server properties
3442 static bool run_properties(int dummy)
3444 static struct cli_state *cli;
3445 bool correct = True;
3447 printf("starting properties test\n");
3451 if (!torture_open_connection(&cli, 0)) {
3455 cli_sockopt(cli, sockops);
3457 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3459 if (!torture_close_connection(cli)) {
3468 /* FIRST_DESIRED_ACCESS 0xf019f */
3469 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3470 FILE_READ_EA| /* 0xf */ \
3471 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3472 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3473 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3474 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3475 /* SECOND_DESIRED_ACCESS 0xe0080 */
3476 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3477 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3478 WRITE_OWNER_ACCESS /* 0xe0000 */
3481 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3482 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3484 WRITE_OWNER_ACCESS /* */
3488 Test ntcreate calls made by xcopy
3490 static bool run_xcopy(int dummy)
3492 static struct cli_state *cli1;
3493 const char *fname = "\\test.txt";
3494 bool correct = True;
3497 printf("starting xcopy test\n");
3499 if (!torture_open_connection(&cli1, 0)) {
3503 fnum1 = cli_nt_create_full(cli1, fname, 0,
3504 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3505 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3509 printf("First open failed - %s\n", cli_errstr(cli1));
3513 fnum2 = cli_nt_create_full(cli1, fname, 0,
3514 SECOND_DESIRED_ACCESS, 0,
3515 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3518 printf("second open failed - %s\n", cli_errstr(cli1));
3522 if (!torture_close_connection(cli1)) {
3530 Test rename on files open with share delete and no share delete.
3532 static bool run_rename(int dummy)
3534 static struct cli_state *cli1;
3535 const char *fname = "\\test.txt";
3536 const char *fname1 = "\\test1.txt";
3537 bool correct = True;
3540 printf("starting rename test\n");
3542 if (!torture_open_connection(&cli1, 0)) {
3546 cli_unlink(cli1, fname);
3547 cli_unlink(cli1, fname1);
3548 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3549 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3552 printf("First open failed - %s\n", cli_errstr(cli1));
3556 if (!cli_rename(cli1, fname, fname1)) {
3557 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3559 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3563 if (!cli_close(cli1, fnum1)) {
3564 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3568 cli_unlink(cli1, fname);
3569 cli_unlink(cli1, fname1);
3570 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3572 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3574 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3578 printf("Second open failed - %s\n", cli_errstr(cli1));
3582 if (!cli_rename(cli1, fname, fname1)) {
3583 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3586 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3589 if (!cli_close(cli1, fnum1)) {
3590 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3594 cli_unlink(cli1, fname);
3595 cli_unlink(cli1, fname1);
3597 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3598 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3601 printf("Third open failed - %s\n", cli_errstr(cli1));
3610 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3611 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3614 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3617 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3618 printf("[8] setting delete_on_close on file failed !\n");
3622 if (!cli_close(cli1, fnum2)) {
3623 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3629 if (!cli_rename(cli1, fname, fname1)) {
3630 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3633 printf("Third rename succeeded (SHARE_NONE)\n");
3636 if (!cli_close(cli1, fnum1)) {
3637 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3641 cli_unlink(cli1, fname);
3642 cli_unlink(cli1, fname1);
3646 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3647 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3650 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3654 if (!cli_rename(cli1, fname, fname1)) {
3655 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3657 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3661 if (!cli_close(cli1, fnum1)) {
3662 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3666 cli_unlink(cli1, fname);
3667 cli_unlink(cli1, fname1);
3671 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3672 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3675 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3679 if (!cli_rename(cli1, fname, fname1)) {
3680 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3684 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3688 * Now check if the first name still exists ...
3691 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3692 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3695 printf("Opening original file after rename of open file fails: %s\n",
3699 printf("Opening original file after rename of open file works ...\n");
3700 (void)cli_close(cli1, fnum2);
3706 if (!cli_close(cli1, fnum1)) {
3707 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3711 cli_unlink(cli1, fname);
3712 cli_unlink(cli1, fname1);
3714 if (!torture_close_connection(cli1)) {
3721 static bool run_pipe_number(int dummy)
3723 struct cli_state *cli1;
3724 const char *pipe_name = "\\SPOOLSS";
3728 printf("starting pipenumber test\n");
3729 if (!torture_open_connection(&cli1, 0)) {
3733 cli_sockopt(cli1, sockops);
3735 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3736 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3739 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3743 printf("\r%6d", num_pipes);
3746 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3747 torture_close_connection(cli1);
3752 Test open mode returns on read-only files.
3754 static bool run_opentest(int dummy)
3756 static struct cli_state *cli1;
3757 static struct cli_state *cli2;
3758 const char *fname = "\\readonly.file";
3762 bool correct = True;
3765 printf("starting open test\n");
3767 if (!torture_open_connection(&cli1, 0)) {
3771 cli_setatr(cli1, fname, 0, 0);
3772 cli_unlink(cli1, fname);
3774 cli_sockopt(cli1, sockops);
3776 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3778 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3782 if (!cli_close(cli1, fnum1)) {
3783 printf("close2 failed (%s)\n", cli_errstr(cli1));
3787 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3788 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3792 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3794 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3798 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3799 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3801 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3802 NT_STATUS_ACCESS_DENIED)) {
3803 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3806 printf("finished open test 1\n");
3808 cli_close(cli1, fnum1);
3810 /* Now try not readonly and ensure ERRbadshare is returned. */
3812 cli_setatr(cli1, fname, 0, 0);
3814 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3816 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3820 /* This will fail - but the error should be ERRshare. */
3821 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3823 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3824 NT_STATUS_SHARING_VIOLATION)) {
3825 printf("correct error code ERRDOS/ERRbadshare returned\n");
3828 if (!cli_close(cli1, fnum1)) {
3829 printf("close2 failed (%s)\n", cli_errstr(cli1));
3833 cli_unlink(cli1, fname);
3835 printf("finished open test 2\n");
3837 /* Test truncate open disposition on file opened for read. */
3839 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3841 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3845 /* write 20 bytes. */
3847 memset(buf, '\0', 20);
3849 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3850 printf("write failed (%s)\n", cli_errstr(cli1));
3854 if (!cli_close(cli1, fnum1)) {
3855 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3859 /* Ensure size == 20. */
3860 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3861 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3866 printf("(3) file size != 20\n");
3870 /* Now test if we can truncate a file opened for readonly. */
3872 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3874 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3878 if (!cli_close(cli1, fnum1)) {
3879 printf("close2 failed (%s)\n", cli_errstr(cli1));
3883 /* Ensure size == 0. */
3884 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3885 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3890 printf("(3) file size != 0\n");
3893 printf("finished open test 3\n");
3895 cli_unlink(cli1, fname);
3898 printf("testing ctemp\n");
3899 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3901 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3904 printf("ctemp gave path %s\n", tmp_path);
3905 if (!cli_close(cli1, fnum1)) {
3906 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3908 if (!cli_unlink(cli1, tmp_path)) {
3909 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3912 /* Test the non-io opens... */
3914 if (!torture_open_connection(&cli2, 1)) {
3918 cli_setatr(cli2, fname, 0, 0);
3919 cli_unlink(cli2, fname);
3921 cli_sockopt(cli2, sockops);
3923 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3925 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3926 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3929 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3933 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3934 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3937 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3941 if (!cli_close(cli1, fnum1)) {
3942 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3945 if (!cli_close(cli2, fnum2)) {
3946 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3950 printf("non-io open test #1 passed.\n");
3952 cli_unlink(cli1, fname);
3954 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3956 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3957 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3960 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3964 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3965 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3968 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3972 if (!cli_close(cli1, fnum1)) {
3973 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3976 if (!cli_close(cli2, fnum2)) {
3977 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3981 printf("non-io open test #2 passed.\n");
3983 cli_unlink(cli1, fname);
3985 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3987 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3988 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3991 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3995 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3996 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3999 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4003 if (!cli_close(cli1, fnum1)) {
4004 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4007 if (!cli_close(cli2, fnum2)) {
4008 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4012 printf("non-io open test #3 passed.\n");
4014 cli_unlink(cli1, fname);
4016 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4018 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4019 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4022 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4026 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4027 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4030 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4034 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4036 if (!cli_close(cli1, fnum1)) {
4037 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4041 printf("non-io open test #4 passed.\n");
4043 cli_unlink(cli1, fname);
4045 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4047 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4048 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4051 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4055 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4056 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4059 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4063 if (!cli_close(cli1, fnum1)) {
4064 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4068 if (!cli_close(cli2, fnum2)) {
4069 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4073 printf("non-io open test #5 passed.\n");
4075 printf("TEST #6 testing 1 non-io open, one io open\n");
4077 cli_unlink(cli1, fname);
4079 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4080 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4083 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4087 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4088 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4091 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4095 if (!cli_close(cli1, fnum1)) {
4096 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4100 if (!cli_close(cli2, fnum2)) {
4101 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4105 printf("non-io open test #6 passed.\n");
4107 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4109 cli_unlink(cli1, fname);
4111 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4112 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4115 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4119 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4120 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4123 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4127 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4129 if (!cli_close(cli1, fnum1)) {
4130 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4134 printf("non-io open test #7 passed.\n");
4136 cli_unlink(cli1, fname);
4138 if (!torture_close_connection(cli1)) {
4141 if (!torture_close_connection(cli2)) {
4148 static uint32 open_attrs_table[] = {
4149 FILE_ATTRIBUTE_NORMAL,
4150 FILE_ATTRIBUTE_ARCHIVE,
4151 FILE_ATTRIBUTE_READONLY,
4152 FILE_ATTRIBUTE_HIDDEN,
4153 FILE_ATTRIBUTE_SYSTEM,
4155 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4156 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4157 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4158 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4159 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4160 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4162 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4163 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4164 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4165 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4168 struct trunc_open_results {
4175 static struct trunc_open_results attr_results[] = {
4176 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4177 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4178 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4179 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4180 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4181 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4182 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4183 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4184 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4185 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4186 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4187 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4188 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4189 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4190 { 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 },
4191 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4192 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4193 { 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 },
4194 { 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 },
4195 { 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 },
4196 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4197 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4198 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4199 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4200 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4201 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4204 static bool run_openattrtest(int dummy)
4206 static struct cli_state *cli1;
4207 const char *fname = "\\openattr.file";
4209 bool correct = True;
4211 unsigned int i, j, k, l;
4213 printf("starting open attr test\n");
4215 if (!torture_open_connection(&cli1, 0)) {
4219 cli_sockopt(cli1, sockops);
4221 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4222 cli_setatr(cli1, fname, 0, 0);
4223 cli_unlink(cli1, fname);
4224 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4225 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4228 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4232 if (!cli_close(cli1, fnum1)) {
4233 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4237 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4238 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4239 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4242 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4243 if (attr_results[l].num == k) {
4244 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4245 k, open_attrs_table[i],
4246 open_attrs_table[j],
4247 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4251 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4252 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4253 k, open_attrs_table[i], open_attrs_table[j],
4258 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4264 if (!cli_close(cli1, fnum1)) {
4265 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4269 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4270 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4275 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4276 k, open_attrs_table[i], open_attrs_table[j], attr );
4279 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4280 if (attr_results[l].num == k) {
4281 if (attr != attr_results[l].result_attr ||
4282 open_attrs_table[i] != attr_results[l].init_attr ||
4283 open_attrs_table[j] != attr_results[l].trunc_attr) {
4284 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4285 open_attrs_table[i],
4286 open_attrs_table[j],
4288 attr_results[l].result_attr);
4298 cli_setatr(cli1, fname, 0, 0);
4299 cli_unlink(cli1, fname);
4301 printf("open attr test %s.\n", correct ? "passed" : "failed");
4303 if (!torture_close_connection(cli1)) {
4309 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4315 test directory listing speed
4317 static bool run_dirtest(int dummy)
4320 static struct cli_state *cli;
4323 bool correct = True;
4325 printf("starting directory test\n");
4327 if (!torture_open_connection(&cli, 0)) {
4331 cli_sockopt(cli, sockops);
4334 for (i=0;i<torture_numops;i++) {
4336 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4337 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4339 fprintf(stderr,"Failed to open %s\n", fname);
4342 cli_close(cli, fnum);
4347 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4348 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4349 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4351 printf("dirtest core %g seconds\n", end_timer() - t1);
4354 for (i=0;i<torture_numops;i++) {
4356 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4357 cli_unlink(cli, fname);
4360 if (!torture_close_connection(cli)) {
4364 printf("finished dirtest\n");
4369 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4371 struct cli_state *pcli = (struct cli_state *)state;
4373 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4375 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4378 if (finfo->mode & aDIR) {
4379 if (!cli_rmdir(pcli, fname))
4380 printf("del_fn: failed to rmdir %s\n,", fname );
4382 if (!cli_unlink(pcli, fname))
4383 printf("del_fn: failed to unlink %s\n,", fname );
4389 sees what IOCTLs are supported
4391 bool torture_ioctl_test(int dummy)
4393 static struct cli_state *cli;
4394 uint16 device, function;
4396 const char *fname = "\\ioctl.dat";
4400 if (!torture_open_connection(&cli, 0)) {
4404 printf("starting ioctl test\n");
4406 cli_unlink(cli, fname);
4408 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4410 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4414 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4415 printf("ioctl device info: %s\n", cli_errstr(cli));
4417 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4418 printf("ioctl job info: %s\n", cli_errstr(cli));
4420 for (device=0;device<0x100;device++) {
4421 printf("testing device=0x%x\n", device);
4422 for (function=0;function<0x100;function++) {
4423 uint32 code = (device<<16) | function;
4425 status = cli_raw_ioctl(cli, fnum, code, &blob);
4427 if (NT_STATUS_IS_OK(status)) {
4428 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4430 data_blob_free(&blob);
4435 if (!torture_close_connection(cli)) {
4444 tries varients of chkpath
4446 bool torture_chkpath_test(int dummy)
4448 static struct cli_state *cli;
4452 if (!torture_open_connection(&cli, 0)) {
4456 printf("starting chkpath test\n");
4458 /* cleanup from an old run */
4459 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4460 cli_unlink(cli, "\\chkpath.dir\\*");
4461 cli_rmdir(cli, "\\chkpath.dir");
4463 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4464 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4468 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4469 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4473 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4475 printf("open1 failed (%s)\n", cli_errstr(cli));
4478 cli_close(cli, fnum);
4480 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4481 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4485 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4486 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4490 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4491 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4492 NT_STATUS_NOT_A_DIRECTORY);
4494 printf("* chkpath on a file should fail\n");
4498 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4499 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4500 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4502 printf("* chkpath on a non existant file should fail\n");
4506 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4507 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4508 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4510 printf("* chkpath on a non existent component should fail\n");
4514 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4515 cli_unlink(cli, "\\chkpath.dir\\*");
4516 cli_rmdir(cli, "\\chkpath.dir");
4518 if (!torture_close_connection(cli)) {
4525 static bool run_eatest(int dummy)
4527 static struct cli_state *cli;
4528 const char *fname = "\\eatest.txt";
4529 bool correct = True;
4532 struct ea_struct *ea_list = NULL;
4533 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4535 printf("starting eatest\n");
4537 if (!torture_open_connection(&cli, 0)) {
4538 talloc_destroy(mem_ctx);
4542 cli_unlink(cli, fname);
4543 fnum = cli_nt_create_full(cli, fname, 0,
4544 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4545 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4549 printf("open failed - %s\n", cli_errstr(cli));
4550 talloc_destroy(mem_ctx);
4554 for (i = 0; i < 10; i++) {
4555 fstring ea_name, ea_val;
4557 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4558 memset(ea_val, (char)i+1, i+1);
4559 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4560 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4561 talloc_destroy(mem_ctx);
4566 cli_close(cli, fnum);
4567 for (i = 0; i < 10; i++) {
4568 fstring ea_name, ea_val;
4570 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4571 memset(ea_val, (char)i+1, i+1);
4572 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4573 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4574 talloc_destroy(mem_ctx);
4579 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4580 printf("ea_get list failed - %s\n", cli_errstr(cli));
4584 printf("num_eas = %d\n", (int)num_eas);
4586 if (num_eas != 20) {
4587 printf("Should be 20 EA's stored... failing.\n");
4591 for (i = 0; i < num_eas; i++) {
4592 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4593 dump_data(0, ea_list[i].value.data,
4594 ea_list[i].value.length);
4597 /* Setting EA's to zero length deletes them. Test this */
4598 printf("Now deleting all EA's - case indepenent....\n");
4601 cli_set_ea_path(cli, fname, "", "", 0);
4603 for (i = 0; i < 20; i++) {
4605 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4606 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4607 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4608 talloc_destroy(mem_ctx);
4614 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4615 printf("ea_get list failed - %s\n", cli_errstr(cli));
4619 printf("num_eas = %d\n", (int)num_eas);
4620 for (i = 0; i < num_eas; i++) {
4621 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4622 dump_data(0, ea_list[i].value.data,
4623 ea_list[i].value.length);
4627 printf("deleting EA's failed.\n");
4631 /* Try and delete a non existant EA. */
4632 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4633 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4637 talloc_destroy(mem_ctx);
4638 if (!torture_close_connection(cli)) {
4645 static bool run_dirtest1(int dummy)
4648 static struct cli_state *cli;
4650 bool correct = True;
4652 printf("starting directory test\n");
4654 if (!torture_open_connection(&cli, 0)) {
4658 cli_sockopt(cli, sockops);
4660 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4661 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4662 cli_rmdir(cli, "\\LISTDIR");
4663 cli_mkdir(cli, "\\LISTDIR");
4665 /* Create 1000 files and 1000 directories. */
4666 for (i=0;i<1000;i++) {
4668 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4669 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4670 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4672 fprintf(stderr,"Failed to open %s\n", fname);
4675 cli_close(cli, fnum);
4677 for (i=0;i<1000;i++) {
4679 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4680 if (!cli_mkdir(cli, fname)) {
4681 fprintf(stderr,"Failed to open %s\n", fname);
4686 /* Now ensure that doing an old list sees both files and directories. */
4687 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4688 printf("num_seen = %d\n", num_seen );
4689 /* We should see 100 files + 1000 directories + . and .. */
4690 if (num_seen != 2002)
4693 /* Ensure if we have the "must have" bits we only see the
4696 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4697 printf("num_seen = %d\n", num_seen );
4698 if (num_seen != 1002)
4701 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4702 printf("num_seen = %d\n", num_seen );
4703 if (num_seen != 1000)
4706 /* Delete everything. */
4707 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4708 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4709 cli_rmdir(cli, "\\LISTDIR");
4712 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4713 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4714 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4717 if (!torture_close_connection(cli)) {
4721 printf("finished dirtest1\n");
4726 static bool run_error_map_extract(int dummy) {
4728 static struct cli_state *c_dos;
4729 static struct cli_state *c_nt;
4734 uint32 flgs2, errnum;
4741 /* NT-Error connection */
4743 if (!(c_nt = open_nbt_connection())) {
4747 c_nt->use_spnego = False;
4749 status = cli_negprot(c_nt);
4751 if (!NT_STATUS_IS_OK(status)) {
4752 printf("%s rejected the NT-error negprot (%s)\n", host,
4758 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4760 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4764 /* DOS-Error connection */
4766 if (!(c_dos = open_nbt_connection())) {
4770 c_dos->use_spnego = False;
4771 c_dos->force_dos_errors = True;
4773 status = cli_negprot(c_dos);
4774 if (!NT_STATUS_IS_OK(status)) {
4775 printf("%s rejected the DOS-error negprot (%s)\n", host,
4777 cli_shutdown(c_dos);
4781 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4783 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4787 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4788 fstr_sprintf(user, "%X", error);
4790 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4791 password, strlen(password),
4792 password, strlen(password),
4794 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4797 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4799 /* Case #1: 32-bit NT errors */
4800 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4801 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4803 printf("/** Dos error on NT connection! (%s) */\n",
4805 nt_status = NT_STATUS(0xc0000000);
4808 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4809 password, strlen(password),
4810 password, strlen(password),
4812 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4814 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4816 /* Case #1: 32-bit NT errors */
4817 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4818 printf("/** NT error on DOS connection! (%s) */\n",
4820 errnum = errclass = 0;
4822 cli_dos_error(c_dos, &errclass, &errnum);
4825 if (NT_STATUS_V(nt_status) != error) {
4826 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4827 get_nt_error_c_code(NT_STATUS(error)),
4828 get_nt_error_c_code(nt_status));
4831 printf("\t{%s,\t%s,\t%s},\n",
4832 smb_dos_err_class(errclass),
4833 smb_dos_err_name(errclass, errnum),
4834 get_nt_error_c_code(NT_STATUS(error)));
4839 static bool run_sesssetup_bench(int dummy)
4841 static struct cli_state *c;
4842 const char *fname = "\\file.dat";
4847 if (!torture_open_connection(&c, 0)) {
4851 fnum = cli_nt_create_full(
4852 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4853 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4854 FILE_DELETE_ON_CLOSE, 0);
4856 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
4860 for (i=0; i<torture_numops; i++) {
4861 status = cli_session_setup(
4863 password, strlen(password),
4864 password, strlen(password),
4866 if (!NT_STATUS_IS_OK(status)) {
4867 d_printf("(%s) cli_session_setup failed: %s\n",
4868 __location__, nt_errstr(status));
4872 if (!cli_ulogoff(c)) {
4873 d_printf("(%s) cli_ulogoff failed: %s\n",
4874 __location__, cli_errstr(c));
4883 static bool subst_test(const char *str, const char *user, const char *domain,
4884 uid_t uid, gid_t gid, const char *expected)
4889 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
4891 if (strcmp(subst, expected) != 0) {
4892 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
4893 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
4902 static void chain1_open_completion(struct async_req *req)
4907 status = cli_open_recv(req, &fnum);
4910 d_printf("cli_open_recv returned %s: %d\n",
4912 NT_STATUS_IS_OK(status) ? fnum : -1);
4915 static void chain1_read_completion(struct async_req *req)
4921 status = cli_read_andx_recv(req, &received, &rcvbuf);
4922 if (!NT_STATUS_IS_OK(status)) {
4924 d_printf("cli_read_andx_recv returned %s\n",
4929 d_printf("got %d bytes: %.*s\n", (int)received, (int)received,
4934 static void chain1_write_completion(struct async_req *req)
4939 status = cli_write_andx_recv(req, &written);
4940 if (!NT_STATUS_IS_OK(status)) {
4942 d_printf("cli_write_andx_recv returned %s\n",
4947 d_printf("wrote %d bytes\n", (int)written);
4951 static void chain1_close_completion(struct async_req *req)
4955 status = cli_close_recv(req);
4956 *((bool *)(req->async.priv)) = true;
4960 d_printf("cli_close returned %s\n", nt_errstr(status));
4963 static bool run_chain1(int dummy)
4965 struct cli_state *cli1;
4966 struct event_context *evt = event_context_init(NULL);
4967 struct async_req *reqs[4];
4969 const char *text = "hallo";
4971 printf("starting chain1 test\n");
4972 if (!torture_open_connection(&cli1, 0)) {
4976 cli_sockopt(cli1, sockops);
4978 cli_chain_cork(cli1, evt, 0);
4979 reqs[0] = cli_open_send(talloc_tos(), evt, cli1, "\\test",
4981 reqs[0]->async.fn = chain1_open_completion;
4982 reqs[1] = cli_write_andx_send(talloc_tos(), evt, cli1, 0, 0,
4983 (uint8_t *)text, 0, strlen(text));
4984 reqs[1]->async.fn = chain1_write_completion;
4985 reqs[2] = cli_read_andx_send(talloc_tos(), evt, cli1, 0, 1, 10);
4986 reqs[2]->async.fn = chain1_read_completion;
4987 reqs[3] = cli_close_send(talloc_tos(), evt, cli1, 0);
4988 reqs[3]->async.fn = chain1_close_completion;
4989 reqs[3]->async.priv = (void *)&done;
4990 cli_chain_uncork(cli1);
4993 event_loop_once(evt);
4996 torture_close_connection(cli1);
5000 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5002 size_t *to_pull = (size_t *)priv;
5003 size_t thistime = *to_pull;
5005 thistime = MIN(thistime, n);
5006 if (thistime == 0) {
5010 memset(buf, 0, thistime);
5011 *to_pull -= thistime;
5015 static bool run_windows_write(int dummy)
5017 struct cli_state *cli1;
5021 const char *fname = "\\writetest.txt";
5025 printf("starting windows_write test\n");
5026 if (!torture_open_connection(&cli1, 0)) {
5030 fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5032 printf("open failed (%s)\n", cli_errstr(cli1));
5036 cli_sockopt(cli1, sockops);
5040 for (i=0; i<torture_numops; i++) {
5042 off_t start = i * torture_blocksize;
5044 size_t to_pull = torture_blocksize - 1;
5046 if (cli_write(cli1, fnum, 0, &c,
5047 start + torture_blocksize - 1, 1) != 1) {
5048 printf("cli_write failed: %s\n", cli_errstr(cli1));
5052 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5053 null_source, &to_pull);
5054 if (!NT_STATUS_IS_OK(status)) {
5055 printf("cli_push returned: %s\n", nt_errstr(status));
5060 seconds = end_timer();
5061 kbytes = (double)torture_blocksize * torture_numops;
5064 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5065 (double)seconds, (int)(kbytes/seconds));
5069 cli_close(cli1, fnum);
5070 cli_unlink(cli1, fname);
5071 torture_close_connection(cli1);
5075 static bool run_cli_echo(int dummy)
5077 struct cli_state *cli;
5078 struct event_context *ev = event_context_init(NULL);
5079 struct async_req *req;
5082 printf("starting chain1 test\n");
5083 if (!torture_open_connection(&cli, 0)) {
5086 cli_sockopt(cli, sockops);
5088 req = cli_echo_send(ev, ev, cli, 5, data_blob_const("hello", 5));
5090 d_printf("cli_echo_send failed\n");
5094 while (req->state < ASYNC_REQ_DONE) {
5095 event_loop_once(ev);
5098 status = cli_echo_recv(req);
5099 d_printf("cli_echo returned %s\n", nt_errstr(status));
5103 torture_close_connection(cli);
5104 return NT_STATUS_IS_OK(status);
5107 static bool run_local_substitute(int dummy)
5111 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5112 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5113 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5114 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5115 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5116 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5117 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5118 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5120 /* Different captialization rules in sub_basic... */
5122 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5128 static bool run_local_gencache(int dummy)
5134 if (!gencache_init()) {
5135 d_printf("%s: gencache_init() failed\n", __location__);
5139 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5140 d_printf("%s: gencache_set() failed\n", __location__);
5144 if (!gencache_get("foo", &val, &tm)) {
5145 d_printf("%s: gencache_get() failed\n", __location__);
5149 if (strcmp(val, "bar") != 0) {
5150 d_printf("%s: gencache_get() returned %s, expected %s\n",
5151 __location__, val, "bar");
5158 if (!gencache_del("foo")) {
5159 d_printf("%s: gencache_del() failed\n", __location__);
5162 if (gencache_del("foo")) {
5163 d_printf("%s: second gencache_del() succeeded\n",
5168 if (gencache_get("foo", &val, &tm)) {
5169 d_printf("%s: gencache_get() on deleted entry "
5170 "succeeded\n", __location__);
5174 blob = data_blob_string_const_null("bar");
5177 if (!gencache_set_data_blob("foo", &blob, tm)) {
5178 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5182 data_blob_free(&blob);
5184 if (!gencache_get_data_blob("foo", &blob, NULL)) {
5185 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5189 if (strcmp((const char *)blob.data, "bar") != 0) {
5190 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5191 __location__, (const char *)blob.data, "bar");
5192 data_blob_free(&blob);
5196 data_blob_free(&blob);
5198 if (!gencache_del("foo")) {
5199 d_printf("%s: gencache_del() failed\n", __location__);
5202 if (gencache_del("foo")) {
5203 d_printf("%s: second gencache_del() succeeded\n",
5208 if (gencache_get_data_blob("foo", &blob, NULL)) {
5209 d_printf("%s: gencache_get_data_blob() on deleted entry "
5210 "succeeded\n", __location__);
5214 if (!gencache_shutdown()) {
5215 d_printf("%s: gencache_shutdown() failed\n", __location__);
5219 if (gencache_shutdown()) {
5220 d_printf("%s: second gencache_shutdown() succeeded\n",
5228 static bool rbt_testval(struct db_context *db, const char *key,
5231 struct db_record *rec;
5232 TDB_DATA data = string_tdb_data(value);
5236 rec = db->fetch_locked(db, db, string_tdb_data(key));
5238 d_fprintf(stderr, "fetch_locked failed\n");
5241 status = rec->store(rec, data, 0);
5242 if (!NT_STATUS_IS_OK(status)) {
5243 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5248 rec = db->fetch_locked(db, db, string_tdb_data(key));
5250 d_fprintf(stderr, "second fetch_locked failed\n");
5253 if ((rec->value.dsize != data.dsize)
5254 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5255 d_fprintf(stderr, "Got wrong data back\n");
5265 static bool run_local_rbtree(int dummy)
5267 struct db_context *db;
5271 db = db_open_rbt(NULL);
5274 d_fprintf(stderr, "db_open_rbt failed\n");
5278 for (i=0; i<1000; i++) {
5281 asprintf(&key, "key%ld", random());
5282 asprintf(&value, "value%ld", random());
5284 if (!rbt_testval(db, key, value)) {
5291 asprintf(&value, "value%ld", random());
5293 if (!rbt_testval(db, key, value)) {
5310 static bool test_stream_name(const char *fname, const char *expected_base,
5311 const char *expected_stream,
5312 NTSTATUS expected_status)
5316 char *stream = NULL;
5318 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5319 if (!NT_STATUS_EQUAL(status, expected_status)) {
5323 if (!NT_STATUS_IS_OK(status)) {
5327 if (base == NULL) goto error;
5329 if (strcmp(expected_base, base) != 0) goto error;
5331 if ((expected_stream != NULL) && (stream == NULL)) goto error;
5332 if ((expected_stream == NULL) && (stream != NULL)) goto error;
5334 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5338 TALLOC_FREE(stream);
5342 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5343 fname, expected_base ? expected_base : "<NULL>",
5344 expected_stream ? expected_stream : "<NULL>",
5345 nt_errstr(expected_status));
5346 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5347 base ? base : "<NULL>", stream ? stream : "<NULL>",
5350 TALLOC_FREE(stream);
5354 static bool run_local_stream_name(int dummy)
5358 ret &= test_stream_name(
5359 "bla", "bla", NULL, NT_STATUS_OK);
5360 ret &= test_stream_name(
5361 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5362 ret &= test_stream_name(
5363 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5364 ret &= test_stream_name(
5365 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5366 ret &= test_stream_name(
5367 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5368 ret &= test_stream_name(
5369 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5370 ret &= test_stream_name(
5371 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5372 ret &= test_stream_name(
5373 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5378 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
5380 if (a.length != b.length) {
5381 printf("a.length=%d != b.length=%d\n",
5382 (int)a.length, (int)b.length);
5385 if (memcmp(a.data, b.data, a.length) != 0) {
5386 printf("a.data and b.data differ\n");
5392 static bool run_local_memcache(int dummy)
5394 struct memcache *cache;
5396 DATA_BLOB d1, d2, d3;
5397 DATA_BLOB v1, v2, v3;
5399 TALLOC_CTX *mem_ctx;
5401 size_t size1, size2;
5404 cache = memcache_init(NULL, 100);
5406 if (cache == NULL) {
5407 printf("memcache_init failed\n");
5411 d1 = data_blob_const("d1", 2);
5412 d2 = data_blob_const("d2", 2);
5413 d3 = data_blob_const("d3", 2);
5415 k1 = data_blob_const("d1", 2);
5416 k2 = data_blob_const("d2", 2);
5418 memcache_add(cache, STAT_CACHE, k1, d1);
5419 memcache_add(cache, GETWD_CACHE, k2, d2);
5421 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5422 printf("could not find k1\n");
5425 if (!data_blob_equal(d1, v1)) {
5429 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5430 printf("could not find k2\n");
5433 if (!data_blob_equal(d2, v2)) {
5437 memcache_add(cache, STAT_CACHE, k1, d3);
5439 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5440 printf("could not find replaced k1\n");
5443 if (!data_blob_equal(d3, v3)) {
5447 memcache_add(cache, GETWD_CACHE, k1, d1);
5449 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5450 printf("Did find k2, should have been purged\n");
5456 cache = memcache_init(NULL, 0);
5458 mem_ctx = talloc_init("foo");
5460 str1 = talloc_strdup(mem_ctx, "string1");
5461 str2 = talloc_strdup(mem_ctx, "string2");
5463 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5464 data_blob_string_const("torture"), &str1);
5465 size1 = talloc_total_size(cache);
5467 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5468 data_blob_string_const("torture"), &str2);
5469 size2 = talloc_total_size(cache);
5471 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5473 if (size2 > size1) {
5474 printf("memcache leaks memory!\n");
5484 static double create_procs(bool (*fn)(int), bool *result)
5487 volatile pid_t *child_status;
5488 volatile bool *child_status_out;
5494 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5495 if (!child_status) {
5496 printf("Failed to setup shared memory\n");
5500 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5501 if (!child_status_out) {
5502 printf("Failed to setup result status shared memory\n");
5506 for (i = 0; i < nprocs; i++) {
5507 child_status[i] = 0;
5508 child_status_out[i] = True;
5513 for (i=0;i<nprocs;i++) {
5516 pid_t mypid = getpid();
5517 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
5519 slprintf(myname,sizeof(myname),"CLIENT%d", i);
5522 if (torture_open_connection(¤t_cli, i)) break;
5524 printf("pid %d failed to start\n", (int)getpid());
5530 child_status[i] = getpid();
5532 while (child_status[i] && end_timer() < 5) smb_msleep(2);
5534 child_status_out[i] = fn(i);
5541 for (i=0;i<nprocs;i++) {
5542 if (child_status[i]) synccount++;
5544 if (synccount == nprocs) break;
5546 } while (end_timer() < 30);
5548 if (synccount != nprocs) {
5549 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
5554 /* start the client load */
5557 for (i=0;i<nprocs;i++) {
5558 child_status[i] = 0;
5561 printf("%d clients started\n", nprocs);
5563 for (i=0;i<nprocs;i++) {
5564 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
5569 for (i=0;i<nprocs;i++) {
5570 if (!child_status_out[i]) {
5577 #define FLAG_MULTIPROC 1
5584 {"FDPASS", run_fdpasstest, 0},
5585 {"LOCK1", run_locktest1, 0},
5586 {"LOCK2", run_locktest2, 0},
5587 {"LOCK3", run_locktest3, 0},
5588 {"LOCK4", run_locktest4, 0},
5589 {"LOCK5", run_locktest5, 0},
5590 {"LOCK6", run_locktest6, 0},
5591 {"LOCK7", run_locktest7, 0},
5592 {"UNLINK", run_unlinktest, 0},
5593 {"BROWSE", run_browsetest, 0},
5594 {"ATTR", run_attrtest, 0},
5595 {"TRANS2", run_trans2test, 0},
5596 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
5597 {"TORTURE",run_torture, FLAG_MULTIPROC},
5598 {"RANDOMIPC", run_randomipc, 0},
5599 {"NEGNOWAIT", run_negprot_nowait, 0},
5600 {"NBENCH", run_nbench, 0},
5601 {"OPLOCK1", run_oplock1, 0},
5602 {"OPLOCK2", run_oplock2, 0},
5603 {"OPLOCK3", run_oplock3, 0},
5604 {"DIR", run_dirtest, 0},
5605 {"DIR1", run_dirtest1, 0},
5606 {"DENY1", torture_denytest1, 0},
5607 {"DENY2", torture_denytest2, 0},
5608 {"TCON", run_tcon_test, 0},
5609 {"TCONDEV", run_tcon_devtype_test, 0},
5610 {"RW1", run_readwritetest, 0},
5611 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
5612 {"RW3", run_readwritelarge, 0},
5613 {"OPEN", run_opentest, 0},
5615 {"OPENATTR", run_openattrtest, 0},
5617 {"XCOPY", run_xcopy, 0},
5618 {"RENAME", run_rename, 0},
5619 {"DELETE", run_deletetest, 0},
5620 {"PROPERTIES", run_properties, 0},
5621 {"MANGLE", torture_mangle, 0},
5622 {"W2K", run_w2ktest, 0},
5623 {"TRANS2SCAN", torture_trans2_scan, 0},
5624 {"NTTRANSSCAN", torture_nttrans_scan, 0},
5625 {"UTABLE", torture_utable, 0},
5626 {"CASETABLE", torture_casetable, 0},
5627 {"ERRMAPEXTRACT", run_error_map_extract, 0},
5628 {"PIPE_NUMBER", run_pipe_number, 0},
5629 {"TCON2", run_tcon2_test, 0},
5630 {"IOCTL", torture_ioctl_test, 0},
5631 {"CHKPATH", torture_chkpath_test, 0},
5632 {"FDSESS", run_fdsesstest, 0},
5633 { "EATEST", run_eatest, 0},
5634 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
5635 { "CHAIN1", run_chain1, 0},
5636 { "WINDOWS-WRITE", run_windows_write, 0},
5637 { "CLI_ECHO", run_cli_echo, 0},
5638 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
5639 { "LOCAL-GENCACHE", run_local_gencache, 0},
5640 { "LOCAL-RBTREE", run_local_rbtree, 0},
5641 { "LOCAL-MEMCACHE", run_local_memcache, 0},
5642 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
5647 /****************************************************************************
5648 run a specified test or "ALL"
5649 ****************************************************************************/
5650 static bool run_test(const char *name)
5657 if (strequal(name,"ALL")) {
5658 for (i=0;torture_ops[i].name;i++) {
5659 run_test(torture_ops[i].name);
5664 for (i=0;torture_ops[i].name;i++) {
5665 fstr_sprintf(randomfname, "\\XX%x",
5666 (unsigned)random());
5668 if (strequal(name, torture_ops[i].name)) {
5670 printf("Running %s\n", name);
5671 if (torture_ops[i].flags & FLAG_MULTIPROC) {
5672 t = create_procs(torture_ops[i].fn, &result);
5675 printf("TEST %s FAILED!\n", name);
5680 if (!torture_ops[i].fn(0)) {
5682 printf("TEST %s FAILED!\n", name);
5686 printf("%s took %g secs\n\n", name, t);
5691 printf("Did not find a test named %s\n", name);
5699 static void usage(void)
5703 printf("WARNING samba4 test suite is much more complete nowadays.\n");
5704 printf("Please use samba4 torture.\n\n");
5706 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
5708 printf("\t-d debuglevel\n");
5709 printf("\t-U user%%pass\n");
5710 printf("\t-k use kerberos\n");
5711 printf("\t-N numprocs\n");
5712 printf("\t-n my_netbios_name\n");
5713 printf("\t-W workgroup\n");
5714 printf("\t-o num_operations\n");
5715 printf("\t-O socket_options\n");
5716 printf("\t-m maximum protocol\n");
5717 printf("\t-L use oplocks\n");
5718 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
5719 printf("\t-A showall\n");
5720 printf("\t-p port\n");
5721 printf("\t-s seed\n");
5722 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
5725 printf("tests are:");
5726 for (i=0;torture_ops[i].name;i++) {
5727 printf(" %s", torture_ops[i].name);
5731 printf("default test is ALL\n");
5736 /****************************************************************************
5738 ****************************************************************************/
5739 int main(int argc,char *argv[])
5745 bool correct = True;
5746 TALLOC_CTX *frame = talloc_stackframe();
5747 int seed = time(NULL);
5751 #ifdef HAVE_SETBUFFER
5752 setbuffer(stdout, NULL, 0);
5757 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
5764 for(p = argv[1]; *p; p++)
5768 if (strncmp(argv[1], "//", 2)) {
5772 fstrcpy(host, &argv[1][2]);
5773 p = strchr_m(&host[2],'/');
5778 fstrcpy(share, p+1);
5780 fstrcpy(myname, talloc_get_myname(talloc_tos()));
5782 fprintf(stderr, "Failed to get my hostname.\n");
5786 if (*username == 0 && getenv("LOGNAME")) {
5787 fstrcpy(username,getenv("LOGNAME"));
5793 fstrcpy(workgroup, lp_workgroup());
5795 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
5798 port_to_use = atoi(optarg);
5801 seed = atoi(optarg);
5804 fstrcpy(workgroup,optarg);
5807 max_protocol = interpret_protocol(optarg, max_protocol);
5810 nprocs = atoi(optarg);
5813 torture_numops = atoi(optarg);
5816 DEBUGLEVEL = atoi(optarg);
5825 torture_showall = True;
5828 fstrcpy(myname, optarg);
5831 client_txt = optarg;
5838 use_kerberos = True;
5840 d_printf("No kerberos support compiled in\n");
5846 fstrcpy(username,optarg);
5847 p = strchr_m(username,'%');
5850 fstrcpy(password, p+1);
5855 fstrcpy(multishare_conn_fname, optarg);
5856 use_multishare_conn = True;
5859 torture_blocksize = atoi(optarg);
5862 printf("Unknown option %c (%d)\n", (char)opt, opt);
5867 d_printf("using seed %d\n", seed);
5871 if(use_kerberos && !gotuser) gotpass = True;
5874 p = getpass("Password:");
5876 fstrcpy(password, p);
5881 printf("host=%s share=%s user=%s myname=%s\n",
5882 host, share, username, myname);
5884 if (argc == optind) {
5885 correct = run_test("ALL");
5887 for (i=optind;i<argc;i++) {
5888 if (!run_test(argv[i])) {