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/>.
21 #include "wbc_async.h"
22 #include "torture/proto.h"
27 static fstring host, workgroup, share, password, username, myname;
28 static int max_protocol = PROTOCOL_NT1;
29 static const char *sockops="TCP_NODELAY";
31 static int port_to_use=0;
32 int torture_numops=100;
33 int torture_blocksize=1024*1024;
34 static int procnum; /* records process count number when forking */
35 static struct cli_state *current_cli;
36 static fstring randomfname;
37 static bool use_oplocks;
38 static bool use_level_II_oplocks;
39 static const char *client_txt = "client_oplocks.txt";
40 static bool use_kerberos;
41 static fstring multishare_conn_fname;
42 static bool use_multishare_conn = False;
43 static bool do_encrypt;
45 bool torture_showall = False;
47 static double create_procs(bool (*fn)(int), bool *result);
50 static struct timeval tp1,tp2;
53 void start_timer(void)
58 double end_timer(void)
61 return((tp2.tv_sec - tp1.tv_sec) +
62 (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
66 /* return a pointer to a anonymous shared memory segment of size "size"
67 which will persist across fork() but will disappear when all processes
70 The memory is not zeroed
72 This function uses system5 shared memory. It takes advantage of a property
73 that the memory is not destroyed if it is attached when the id is removed
75 void *shm_setup(int size)
80 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
82 printf("can't get shared memory\n");
85 ret = (void *)shmat(shmid, 0, 0);
86 if (!ret || ret == (void *)-1) {
87 printf("can't attach to shared memory\n");
90 /* the following releases the ipc, but note that this process
91 and all its children will still have access to the memory, its
92 just that the shmid is no longer valid for other shm calls. This
93 means we don't leave behind lots of shm segments after we exit
95 See Stevens "advanced programming in unix env" for details
97 shmctl(shmid, IPC_RMID, 0);
102 /********************************************************************
103 Ensure a connection is encrypted.
104 ********************************************************************/
106 static bool force_cli_encryption(struct cli_state *c,
107 const char *sharename)
110 uint32 caplow, caphigh;
113 if (!SERVER_HAS_UNIX_CIFS(c)) {
114 d_printf("Encryption required and "
115 "server that doesn't support "
116 "UNIX extensions - failing connect\n");
120 if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
121 d_printf("Encryption required and "
122 "can't get UNIX CIFS extensions "
123 "version from server.\n");
127 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
128 d_printf("Encryption required and "
129 "share %s doesn't support "
130 "encryption.\n", sharename);
134 if (c->use_kerberos) {
135 status = cli_gss_smb_encryption_start(c);
137 status = cli_raw_ntlm_smb_encryption_start(c,
143 if (!NT_STATUS_IS_OK(status)) {
144 d_printf("Encryption required and "
145 "setup failed with error %s.\n",
154 static struct cli_state *open_nbt_connection(void)
156 struct nmb_name called, calling;
157 struct sockaddr_storage ss;
161 make_nmb_name(&calling, myname, 0x0);
162 make_nmb_name(&called , host, 0x20);
166 if (!(c = cli_initialise())) {
167 printf("Failed initialize cli_struct to connect with %s\n", host);
171 c->port = port_to_use;
173 status = cli_connect(c, host, &ss);
174 if (!NT_STATUS_IS_OK(status)) {
175 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
179 c->use_kerberos = use_kerberos;
181 c->timeout = 120000; /* set a really long timeout (2 minutes) */
182 if (use_oplocks) c->use_oplocks = True;
183 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
185 if (!cli_session_request(c, &calling, &called)) {
187 * Well, that failed, try *SMBSERVER ...
188 * However, we must reconnect as well ...
190 status = cli_connect(c, host, &ss);
191 if (!NT_STATUS_IS_OK(status)) {
192 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
196 make_nmb_name(&called, "*SMBSERVER", 0x20);
197 if (!cli_session_request(c, &calling, &called)) {
198 printf("%s rejected the session\n",host);
199 printf("We tried with a called name of %s & %s\n",
209 /* Insert a NULL at the first separator of the given path and return a pointer
210 * to the remainder of the string.
213 terminate_path_at_separator(char * path)
221 if ((p = strchr_m(path, '/'))) {
226 if ((p = strchr_m(path, '\\'))) {
236 parse a //server/share type UNC name
238 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
239 char **hostname, char **sharename)
243 *hostname = *sharename = NULL;
245 if (strncmp(unc_name, "\\\\", 2) &&
246 strncmp(unc_name, "//", 2)) {
250 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
251 p = terminate_path_at_separator(*hostname);
254 *sharename = talloc_strdup(mem_ctx, p);
255 terminate_path_at_separator(*sharename);
258 if (*hostname && *sharename) {
262 TALLOC_FREE(*hostname);
263 TALLOC_FREE(*sharename);
267 static bool torture_open_connection_share(struct cli_state **c,
268 const char *hostname,
269 const char *sharename)
276 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
278 status = cli_full_connection(c, myname,
279 hostname, NULL, port_to_use,
282 password, flags, Undefined, &retry);
283 if (!NT_STATUS_IS_OK(status)) {
284 printf("failed to open share connection: //%s/%s port:%d - %s\n",
285 hostname, sharename, port_to_use, nt_errstr(status));
289 if (use_oplocks) (*c)->use_oplocks = True;
290 if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
291 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
294 return force_cli_encryption(*c,
300 bool torture_open_connection(struct cli_state **c, int conn_index)
302 char **unc_list = NULL;
303 int num_unc_names = 0;
306 if (use_multishare_conn==True) {
308 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
309 if (!unc_list || num_unc_names <= 0) {
310 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
314 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
316 printf("Failed to parse UNC name %s\n",
317 unc_list[conn_index % num_unc_names]);
318 TALLOC_FREE(unc_list);
322 result = torture_open_connection_share(c, h, s);
324 /* h, s were copied earlier */
325 TALLOC_FREE(unc_list);
329 return torture_open_connection_share(c, host, share);
332 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
334 uint16 old_vuid = cli->vuid;
335 fstring old_user_name;
336 size_t passlen = strlen(password);
340 fstrcpy(old_user_name, cli->user_name);
342 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
346 *new_vuid = cli->vuid;
347 cli->vuid = old_vuid;
348 status = cli_set_username(cli, old_user_name);
349 if (!NT_STATUS_IS_OK(status)) {
356 bool torture_close_connection(struct cli_state *c)
360 printf("tdis failed (%s)\n", cli_errstr(c));
370 /* check if the server produced the expected error code */
371 static bool check_error(int line, struct cli_state *c,
372 uint8 eclass, uint32 ecode, NTSTATUS nterr)
374 if (cli_is_dos_error(c)) {
378 /* Check DOS error */
380 cli_dos_error(c, &cclass, &num);
382 if (eclass != cclass || ecode != num) {
383 printf("unexpected error code class=%d code=%d\n",
384 (int)cclass, (int)num);
385 printf(" expected %d/%d %s (line=%d)\n",
386 (int)eclass, (int)ecode, nt_errstr(nterr), line);
395 status = cli_nt_error(c);
397 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
398 printf("unexpected error code %s\n", nt_errstr(status));
399 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
408 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
410 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
411 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
417 static bool rw_torture(struct cli_state *c)
419 const char *lockfname = "\\torture.lck";
423 pid_t pid2, pid = getpid();
428 memset(buf, '\0', sizeof(buf));
430 fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
433 fnum2 = cli_open(c, lockfname, O_RDWR, DENY_NONE);
435 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
440 for (i=0;i<torture_numops;i++) {
441 unsigned n = (unsigned)sys_random()%10;
443 printf("%d\r", i); fflush(stdout);
445 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
447 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
451 fnum = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL);
453 printf("open failed (%s)\n", cli_errstr(c));
458 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
459 printf("write failed (%s)\n", cli_errstr(c));
464 if (cli_write(c, fnum, 0, (char *)buf,
465 sizeof(pid)+(j*sizeof(buf)),
466 sizeof(buf)) != sizeof(buf)) {
467 printf("write failed (%s)\n", cli_errstr(c));
474 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
475 printf("read failed (%s)\n", cli_errstr(c));
480 printf("data corruption!\n");
484 if (!cli_close(c, fnum)) {
485 printf("close failed (%s)\n", cli_errstr(c));
489 if (!cli_unlink(c, fname)) {
490 printf("unlink failed (%s)\n", cli_errstr(c));
494 if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int))) {
495 printf("unlock failed (%s)\n", cli_errstr(c));
501 cli_unlink(c, lockfname);
508 static bool run_torture(int dummy)
510 struct cli_state *cli;
515 cli_sockopt(cli, sockops);
517 ret = rw_torture(cli);
519 if (!torture_close_connection(cli)) {
526 static bool rw_torture3(struct cli_state *c, char *lockfname)
533 unsigned countprev = 0;
538 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
540 SIVAL(buf, i, sys_random());
545 fnum = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
548 printf("first open read/write of %s failed (%s)\n",
549 lockfname, cli_errstr(c));
555 for (i = 0; i < 500 && fnum == -1; i++)
557 fnum = cli_open(c, lockfname, O_RDONLY,
562 printf("second open read-only of %s failed (%s)\n",
563 lockfname, cli_errstr(c));
569 for (count = 0; count < sizeof(buf); count += sent)
571 if (count >= countprev) {
572 printf("%d %8d\r", i, count);
575 countprev += (sizeof(buf) / 20);
580 sent = ((unsigned)sys_random()%(20))+ 1;
581 if (sent > sizeof(buf) - count)
583 sent = sizeof(buf) - count;
586 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
587 printf("write failed (%s)\n", cli_errstr(c));
593 sent = cli_read(c, fnum, buf_rd+count, count,
597 printf("read failed offset:%d size:%ld (%s)\n",
598 count, (unsigned long)sizeof(buf)-count,
605 if (memcmp(buf_rd+count, buf+count, sent) != 0)
607 printf("read/write compare failed\n");
608 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
617 if (!cli_close(c, fnum)) {
618 printf("close failed (%s)\n", cli_errstr(c));
625 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
627 const char *lockfname = "\\torture2.lck";
636 if (!cli_unlink(c1, lockfname)) {
637 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
640 fnum1 = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
643 printf("first open read/write of %s failed (%s)\n",
644 lockfname, cli_errstr(c1));
647 fnum2 = cli_open(c2, lockfname, O_RDONLY,
650 printf("second open read-only of %s failed (%s)\n",
651 lockfname, cli_errstr(c2));
652 cli_close(c1, fnum1);
656 for (i=0;i<torture_numops;i++)
658 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
660 printf("%d\r", i); fflush(stdout);
663 generate_random_buffer((unsigned char *)buf, buf_size);
665 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
666 printf("write failed (%s)\n", cli_errstr(c1));
671 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
672 printf("read failed (%s)\n", cli_errstr(c2));
673 printf("read %d, expected %ld\n", (int)bytes_read,
674 (unsigned long)buf_size);
679 if (memcmp(buf_rd, buf, buf_size) != 0)
681 printf("read/write compare failed\n");
687 if (!cli_close(c2, fnum2)) {
688 printf("close failed (%s)\n", cli_errstr(c2));
691 if (!cli_close(c1, fnum1)) {
692 printf("close failed (%s)\n", cli_errstr(c1));
696 if (!cli_unlink(c1, lockfname)) {
697 printf("unlink failed (%s)\n", cli_errstr(c1));
704 static bool run_readwritetest(int dummy)
706 static struct cli_state *cli1, *cli2;
707 bool test1, test2 = False;
709 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
712 cli_sockopt(cli1, sockops);
713 cli_sockopt(cli2, sockops);
715 printf("starting readwritetest\n");
717 test1 = rw_torture2(cli1, cli2);
718 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
721 test2 = rw_torture2(cli1, cli1);
722 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
725 if (!torture_close_connection(cli1)) {
729 if (!torture_close_connection(cli2)) {
733 return (test1 && test2);
736 static bool run_readwritemulti(int dummy)
738 struct cli_state *cli;
743 cli_sockopt(cli, sockops);
745 printf("run_readwritemulti: fname %s\n", randomfname);
746 test = rw_torture3(cli, randomfname);
748 if (!torture_close_connection(cli)) {
755 static bool run_readwritelarge(int dummy)
757 static struct cli_state *cli1;
759 const char *lockfname = "\\large.dat";
764 if (!torture_open_connection(&cli1, 0)) {
767 cli_sockopt(cli1, sockops);
768 memset(buf,'\0',sizeof(buf));
770 cli1->max_xmit = 128*1024;
772 printf("starting readwritelarge\n");
774 cli_unlink(cli1, lockfname);
776 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
778 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
782 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
784 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
785 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
789 if (fsize == sizeof(buf))
790 printf("readwritelarge test 1 succeeded (size = %lx)\n",
791 (unsigned long)fsize);
793 printf("readwritelarge test 1 failed (size = %lx)\n",
794 (unsigned long)fsize);
798 if (!cli_close(cli1, fnum1)) {
799 printf("close failed (%s)\n", cli_errstr(cli1));
803 if (!cli_unlink(cli1, lockfname)) {
804 printf("unlink failed (%s)\n", cli_errstr(cli1));
808 fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
810 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
814 cli1->max_xmit = 4*1024;
816 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
818 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
819 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
823 if (fsize == sizeof(buf))
824 printf("readwritelarge test 2 succeeded (size = %lx)\n",
825 (unsigned long)fsize);
827 printf("readwritelarge test 2 failed (size = %lx)\n",
828 (unsigned long)fsize);
833 /* ToDo - set allocation. JRA */
834 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
835 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
838 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
839 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
843 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
846 if (!cli_close(cli1, fnum1)) {
847 printf("close failed (%s)\n", cli_errstr(cli1));
851 if (!torture_close_connection(cli1)) {
860 #define ival(s) strtol(s, NULL, 0)
862 /* run a test that simulates an approximate netbench client load */
863 static bool run_netbench(int client)
865 struct cli_state *cli;
870 const char *params[20];
877 cli_sockopt(cli, sockops);
881 slprintf(cname,sizeof(cname)-1, "client%d", client);
883 f = fopen(client_txt, "r");
890 while (fgets(line, sizeof(line)-1, f)) {
894 line[strlen(line)-1] = 0;
896 /* printf("[%d] %s\n", line_count, line); */
898 all_string_sub(line,"client1", cname, sizeof(line));
900 /* parse the command parameters */
901 params[0] = strtok_r(line, " ", &saveptr);
903 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
909 if (!strncmp(params[0],"SMB", 3)) {
910 printf("ERROR: You are using a dbench 1 load file\n");
914 if (!strcmp(params[0],"NTCreateX")) {
915 nb_createx(params[1], ival(params[2]), ival(params[3]),
917 } else if (!strcmp(params[0],"Close")) {
918 nb_close(ival(params[1]));
919 } else if (!strcmp(params[0],"Rename")) {
920 nb_rename(params[1], params[2]);
921 } else if (!strcmp(params[0],"Unlink")) {
922 nb_unlink(params[1]);
923 } else if (!strcmp(params[0],"Deltree")) {
924 nb_deltree(params[1]);
925 } else if (!strcmp(params[0],"Rmdir")) {
927 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
928 nb_qpathinfo(params[1]);
929 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
930 nb_qfileinfo(ival(params[1]));
931 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
932 nb_qfsinfo(ival(params[1]));
933 } else if (!strcmp(params[0],"FIND_FIRST")) {
934 nb_findfirst(params[1]);
935 } else if (!strcmp(params[0],"WriteX")) {
936 nb_writex(ival(params[1]),
937 ival(params[2]), ival(params[3]), ival(params[4]));
938 } else if (!strcmp(params[0],"ReadX")) {
939 nb_readx(ival(params[1]),
940 ival(params[2]), ival(params[3]), ival(params[4]));
941 } else if (!strcmp(params[0],"Flush")) {
942 nb_flush(ival(params[1]));
944 printf("Unknown operation %s\n", params[0]);
952 if (!torture_close_connection(cli)) {
960 /* run a test that simulates an approximate netbench client load */
961 static bool run_nbench(int dummy)
970 signal(SIGALRM, nb_alarm);
972 t = create_procs(run_netbench, &correct);
975 printf("\nThroughput %g MB/sec\n",
976 1.0e-6 * nbio_total() / t);
982 This test checks for two things:
984 1) correct support for retaining locks over a close (ie. the server
985 must not use posix semantics)
986 2) support for lock timeouts
988 static bool run_locktest1(int dummy)
990 struct cli_state *cli1, *cli2;
991 const char *fname = "\\lockt1.lck";
992 int fnum1, fnum2, fnum3;
994 unsigned lock_timeout;
996 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
999 cli_sockopt(cli1, sockops);
1000 cli_sockopt(cli2, sockops);
1002 printf("starting locktest1\n");
1004 cli_unlink(cli1, fname);
1006 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1008 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1011 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1013 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1016 fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1018 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1022 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1023 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1028 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1029 printf("lock2 succeeded! This is a locking bug\n");
1032 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1033 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1037 lock_timeout = (1 + (random() % 20));
1038 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1040 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1041 printf("lock3 succeeded! This is a locking bug\n");
1044 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1045 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1049 if (ABS(t2 - t1) < lock_timeout-1) {
1050 printf("error: This server appears not to support timed lock requests\n");
1053 printf("server slept for %u seconds for a %u second timeout\n",
1054 (unsigned int)(t2-t1), lock_timeout);
1056 if (!cli_close(cli1, fnum2)) {
1057 printf("close1 failed (%s)\n", cli_errstr(cli1));
1061 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1062 printf("lock4 succeeded! This is a locking bug\n");
1065 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1066 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1069 if (!cli_close(cli1, fnum1)) {
1070 printf("close2 failed (%s)\n", cli_errstr(cli1));
1074 if (!cli_close(cli2, fnum3)) {
1075 printf("close3 failed (%s)\n", cli_errstr(cli2));
1079 if (!cli_unlink(cli1, fname)) {
1080 printf("unlink failed (%s)\n", cli_errstr(cli1));
1085 if (!torture_close_connection(cli1)) {
1089 if (!torture_close_connection(cli2)) {
1093 printf("Passed locktest1\n");
1098 this checks to see if a secondary tconx can use open files from an
1101 static bool run_tcon_test(int dummy)
1103 static struct cli_state *cli;
1104 const char *fname = "\\tcontest.tmp";
1106 uint16 cnum1, cnum2, cnum3;
1107 uint16 vuid1, vuid2;
1112 memset(buf, '\0', sizeof(buf));
1114 if (!torture_open_connection(&cli, 0)) {
1117 cli_sockopt(cli, sockops);
1119 printf("starting tcontest\n");
1121 cli_unlink(cli, fname);
1123 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1125 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1132 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1133 printf("initial write failed (%s)", cli_errstr(cli));
1137 status = cli_tcon_andx(cli, share, "?????",
1138 password, strlen(password)+1);
1139 if (!NT_STATUS_IS_OK(status)) {
1140 printf("%s refused 2nd tree connect (%s)\n", host,
1147 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1148 vuid2 = cli->vuid + 1;
1150 /* try a write with the wrong tid */
1153 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1154 printf("* server allows write with wrong TID\n");
1157 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1161 /* try a write with an invalid tid */
1164 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1165 printf("* server allows write with invalid TID\n");
1168 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1171 /* try a write with an invalid vuid */
1175 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1176 printf("* server allows write with invalid VUID\n");
1179 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1185 if (!cli_close(cli, fnum1)) {
1186 printf("close failed (%s)\n", cli_errstr(cli));
1192 if (!cli_tdis(cli)) {
1193 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1199 if (!torture_close_connection(cli)) {
1208 checks for old style tcon support
1210 static bool run_tcon2_test(int dummy)
1212 static struct cli_state *cli;
1213 uint16 cnum, max_xmit;
1217 if (!torture_open_connection(&cli, 0)) {
1220 cli_sockopt(cli, sockops);
1222 printf("starting tcon2 test\n");
1224 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1228 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 printf("tcon2 failed : %s\n", cli_errstr(cli));
1233 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1234 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1237 if (!torture_close_connection(cli)) {
1241 printf("Passed tcon2 test\n");
1245 static bool tcon_devtest(struct cli_state *cli,
1246 const char *myshare, const char *devtype,
1247 const char *return_devtype,
1248 NTSTATUS expected_error)
1253 status = cli_tcon_andx(cli, myshare, devtype,
1254 password, strlen(password)+1);
1256 if (NT_STATUS_IS_OK(expected_error)) {
1257 if (NT_STATUS_IS_OK(status)) {
1258 if (strcmp(cli->dev, return_devtype) == 0) {
1261 printf("tconX to share %s with type %s "
1262 "succeeded but returned the wrong "
1263 "device type (got [%s] but should have got [%s])\n",
1264 myshare, devtype, cli->dev, return_devtype);
1268 printf("tconX to share %s with type %s "
1269 "should have succeeded but failed\n",
1275 if (NT_STATUS_IS_OK(status)) {
1276 printf("tconx to share %s with type %s "
1277 "should have failed but succeeded\n",
1281 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1285 printf("Returned unexpected error\n");
1294 checks for correct tconX support
1296 static bool run_tcon_devtype_test(int dummy)
1298 static struct cli_state *cli1 = NULL;
1304 status = cli_full_connection(&cli1, myname,
1305 host, NULL, port_to_use,
1307 username, workgroup,
1308 password, flags, Undefined, &retry);
1310 if (!NT_STATUS_IS_OK(status)) {
1311 printf("could not open connection\n");
1315 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1318 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1321 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1324 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1327 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1330 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1333 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1336 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1339 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1342 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1348 printf("Passed tcondevtest\n");
1355 This test checks that
1357 1) the server supports multiple locking contexts on the one SMB
1358 connection, distinguished by PID.
1360 2) the server correctly fails overlapping locks made by the same PID (this
1361 goes against POSIX behaviour, which is why it is tricky to implement)
1363 3) the server denies unlock requests by an incorrect client PID
1365 static bool run_locktest2(int dummy)
1367 static struct cli_state *cli;
1368 const char *fname = "\\lockt2.lck";
1369 int fnum1, fnum2, fnum3;
1370 bool correct = True;
1372 if (!torture_open_connection(&cli, 0)) {
1376 cli_sockopt(cli, sockops);
1378 printf("starting locktest2\n");
1380 cli_unlink(cli, fname);
1384 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1386 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1390 fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1392 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1398 fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
1400 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1406 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1407 printf("lock1 failed (%s)\n", cli_errstr(cli));
1411 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1412 printf("WRITE lock1 succeeded! This is a locking bug\n");
1415 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1416 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1419 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1420 printf("WRITE lock2 succeeded! This is a locking bug\n");
1423 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1424 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1427 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1428 printf("READ lock2 succeeded! This is a locking bug\n");
1431 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1432 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1435 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1436 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1439 if (cli_unlock(cli, fnum1, 100, 4)) {
1440 printf("unlock at 100 succeeded! This is a locking bug\n");
1444 if (cli_unlock(cli, fnum1, 0, 4)) {
1445 printf("unlock1 succeeded! This is a locking bug\n");
1448 if (!check_error(__LINE__, cli,
1450 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1453 if (cli_unlock(cli, fnum1, 0, 8)) {
1454 printf("unlock2 succeeded! This is a locking bug\n");
1457 if (!check_error(__LINE__, cli,
1459 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1462 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1463 printf("lock3 succeeded! This is a locking bug\n");
1466 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1471 if (!cli_close(cli, fnum1)) {
1472 printf("close1 failed (%s)\n", cli_errstr(cli));
1476 if (!cli_close(cli, fnum2)) {
1477 printf("close2 failed (%s)\n", cli_errstr(cli));
1481 if (!cli_close(cli, fnum3)) {
1482 printf("close3 failed (%s)\n", cli_errstr(cli));
1486 if (!torture_close_connection(cli)) {
1490 printf("locktest2 finished\n");
1497 This test checks that
1499 1) the server supports the full offset range in lock requests
1501 static bool run_locktest3(int dummy)
1503 static struct cli_state *cli1, *cli2;
1504 const char *fname = "\\lockt3.lck";
1505 int fnum1, fnum2, i;
1507 bool correct = True;
1509 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1511 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1514 cli_sockopt(cli1, sockops);
1515 cli_sockopt(cli2, sockops);
1517 printf("starting locktest3\n");
1519 cli_unlink(cli1, fname);
1521 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1523 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1526 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1528 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1532 for (offset=i=0;i<torture_numops;i++) {
1534 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1535 printf("lock1 %d failed (%s)\n",
1541 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1542 printf("lock2 %d failed (%s)\n",
1549 for (offset=i=0;i<torture_numops;i++) {
1552 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1553 printf("error: lock1 %d succeeded!\n", i);
1557 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1558 printf("error: lock2 %d succeeded!\n", i);
1562 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1563 printf("error: lock3 %d succeeded!\n", i);
1567 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1568 printf("error: lock4 %d succeeded!\n", i);
1573 for (offset=i=0;i<torture_numops;i++) {
1576 if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
1577 printf("unlock1 %d failed (%s)\n",
1583 if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
1584 printf("unlock2 %d failed (%s)\n",
1591 if (!cli_close(cli1, fnum1)) {
1592 printf("close1 failed (%s)\n", cli_errstr(cli1));
1596 if (!cli_close(cli2, fnum2)) {
1597 printf("close2 failed (%s)\n", cli_errstr(cli2));
1601 if (!cli_unlink(cli1, fname)) {
1602 printf("unlink failed (%s)\n", cli_errstr(cli1));
1606 if (!torture_close_connection(cli1)) {
1610 if (!torture_close_connection(cli2)) {
1614 printf("finished locktest3\n");
1619 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1620 printf("** "); correct = False; \
1624 looks at overlapping locks
1626 static bool run_locktest4(int dummy)
1628 static struct cli_state *cli1, *cli2;
1629 const char *fname = "\\lockt4.lck";
1630 int fnum1, fnum2, f;
1633 bool correct = True;
1635 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1639 cli_sockopt(cli1, sockops);
1640 cli_sockopt(cli2, sockops);
1642 printf("starting locktest4\n");
1644 cli_unlink(cli1, fname);
1646 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1647 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1649 memset(buf, 0, sizeof(buf));
1651 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1652 printf("Failed to create file\n");
1657 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1658 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1659 EXPECTED(ret, False);
1660 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1662 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1663 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1664 EXPECTED(ret, True);
1665 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1667 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1668 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1669 EXPECTED(ret, False);
1670 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1672 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1673 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1674 EXPECTED(ret, True);
1675 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1677 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1678 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1679 EXPECTED(ret, False);
1680 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1682 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1683 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1684 EXPECTED(ret, True);
1685 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1687 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1688 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1689 EXPECTED(ret, True);
1690 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1692 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1693 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1694 EXPECTED(ret, False);
1695 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1697 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1698 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1699 EXPECTED(ret, False);
1700 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1702 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1703 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1704 EXPECTED(ret, True);
1705 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1707 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1708 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1709 EXPECTED(ret, False);
1710 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1712 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1713 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1714 cli_unlock(cli1, fnum1, 110, 6);
1715 EXPECTED(ret, False);
1716 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1719 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1720 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1721 EXPECTED(ret, False);
1722 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1724 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1725 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1726 EXPECTED(ret, False);
1727 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1730 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1731 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1732 cli_unlock(cli1, fnum1, 140, 4) &&
1733 cli_unlock(cli1, fnum1, 140, 4);
1734 EXPECTED(ret, True);
1735 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1738 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1739 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1740 cli_unlock(cli1, fnum1, 150, 4) &&
1741 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1742 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1743 cli_unlock(cli1, fnum1, 150, 4);
1744 EXPECTED(ret, True);
1745 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1747 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1748 cli_unlock(cli1, fnum1, 160, 4) &&
1749 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1750 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1751 EXPECTED(ret, True);
1752 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1754 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1755 cli_unlock(cli1, fnum1, 170, 4) &&
1756 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1757 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1758 EXPECTED(ret, True);
1759 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1761 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1762 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1763 cli_unlock(cli1, fnum1, 190, 4) &&
1764 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1765 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1766 EXPECTED(ret, True);
1767 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1769 cli_close(cli1, fnum1);
1770 cli_close(cli2, fnum2);
1771 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1772 f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1773 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1774 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1775 cli_close(cli1, fnum1) &&
1776 ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
1777 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1779 cli_close(cli1, fnum1);
1780 EXPECTED(ret, True);
1781 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1784 cli_close(cli1, fnum1);
1785 cli_close(cli2, fnum2);
1786 cli_unlink(cli1, fname);
1787 torture_close_connection(cli1);
1788 torture_close_connection(cli2);
1790 printf("finished locktest4\n");
1795 looks at lock upgrade/downgrade.
1797 static bool run_locktest5(int dummy)
1799 static struct cli_state *cli1, *cli2;
1800 const char *fname = "\\lockt5.lck";
1801 int fnum1, fnum2, fnum3;
1804 bool correct = True;
1806 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1810 cli_sockopt(cli1, sockops);
1811 cli_sockopt(cli2, sockops);
1813 printf("starting locktest5\n");
1815 cli_unlink(cli1, fname);
1817 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1818 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
1819 fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1821 memset(buf, 0, sizeof(buf));
1823 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1824 printf("Failed to create file\n");
1829 /* Check for NT bug... */
1830 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1831 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1832 cli_close(cli1, fnum1);
1833 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1834 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1835 EXPECTED(ret, True);
1836 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1837 cli_close(cli1, fnum1);
1838 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
1839 cli_unlock(cli1, fnum3, 0, 1);
1841 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1842 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1843 EXPECTED(ret, True);
1844 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1846 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1847 EXPECTED(ret, False);
1849 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1851 /* Unlock the process 2 lock. */
1852 cli_unlock(cli2, fnum2, 0, 4);
1854 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1855 EXPECTED(ret, False);
1857 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1859 /* Unlock the process 1 fnum3 lock. */
1860 cli_unlock(cli1, fnum3, 0, 4);
1862 /* Stack 2 more locks here. */
1863 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1864 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1866 EXPECTED(ret, True);
1867 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1869 /* Unlock the first process lock, then check this was the WRITE lock that was
1872 ret = cli_unlock(cli1, fnum1, 0, 4) &&
1873 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1875 EXPECTED(ret, True);
1876 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1878 /* Unlock the process 2 lock. */
1879 cli_unlock(cli2, fnum2, 0, 4);
1881 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1883 ret = cli_unlock(cli1, fnum1, 1, 1) &&
1884 cli_unlock(cli1, fnum1, 0, 4) &&
1885 cli_unlock(cli1, fnum1, 0, 4);
1887 EXPECTED(ret, True);
1888 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1890 /* Ensure the next unlock fails. */
1891 ret = cli_unlock(cli1, fnum1, 0, 4);
1892 EXPECTED(ret, False);
1893 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1895 /* Ensure connection 2 can get a write lock. */
1896 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1897 EXPECTED(ret, True);
1899 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1903 cli_close(cli1, fnum1);
1904 cli_close(cli2, fnum2);
1905 cli_unlink(cli1, fname);
1906 if (!torture_close_connection(cli1)) {
1909 if (!torture_close_connection(cli2)) {
1913 printf("finished locktest5\n");
1919 tries the unusual lockingX locktype bits
1921 static bool run_locktest6(int dummy)
1923 static struct cli_state *cli;
1924 const char *fname[1] = { "\\lock6.txt" };
1929 if (!torture_open_connection(&cli, 0)) {
1933 cli_sockopt(cli, sockops);
1935 printf("starting locktest6\n");
1938 printf("Testing %s\n", fname[i]);
1940 cli_unlink(cli, fname[i]);
1942 fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1943 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1944 cli_close(cli, fnum);
1945 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1947 fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
1948 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1949 cli_close(cli, fnum);
1950 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1952 cli_unlink(cli, fname[i]);
1955 torture_close_connection(cli);
1957 printf("finished locktest6\n");
1961 static bool run_locktest7(int dummy)
1963 struct cli_state *cli1;
1964 const char *fname = "\\lockt7.lck";
1967 bool correct = False;
1969 if (!torture_open_connection(&cli1, 0)) {
1973 cli_sockopt(cli1, sockops);
1975 printf("starting locktest7\n");
1977 cli_unlink(cli1, fname);
1979 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
1981 memset(buf, 0, sizeof(buf));
1983 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1984 printf("Failed to create file\n");
1988 cli_setpid(cli1, 1);
1990 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1991 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1994 printf("pid1 successfully locked range 130:4 for READ\n");
1997 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1998 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2001 printf("pid1 successfully read the range 130:4\n");
2004 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2005 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2006 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2007 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2011 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2015 cli_setpid(cli1, 2);
2017 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2018 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2020 printf("pid2 successfully read the range 130:4\n");
2023 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2024 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2025 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2026 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2030 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2034 cli_setpid(cli1, 1);
2035 cli_unlock(cli1, fnum1, 130, 4);
2037 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2038 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2041 printf("pid1 successfully locked range 130:4 for WRITE\n");
2044 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2045 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2048 printf("pid1 successfully read the range 130:4\n");
2051 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2052 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2055 printf("pid1 successfully wrote to the range 130:4\n");
2058 cli_setpid(cli1, 2);
2060 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2061 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2062 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2063 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2067 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2071 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2072 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2073 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2074 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2078 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2082 cli_unlock(cli1, fnum1, 130, 0);
2086 cli_close(cli1, fnum1);
2087 cli_unlink(cli1, fname);
2088 torture_close_connection(cli1);
2090 printf("finished locktest7\n");
2095 test whether fnums and tids open on one VC are available on another (a major
2098 static bool run_fdpasstest(int dummy)
2100 struct cli_state *cli1, *cli2;
2101 const char *fname = "\\fdpass.tst";
2105 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2108 cli_sockopt(cli1, sockops);
2109 cli_sockopt(cli2, sockops);
2111 printf("starting fdpasstest\n");
2113 cli_unlink(cli1, fname);
2115 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2117 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2121 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2122 printf("write failed (%s)\n", cli_errstr(cli1));
2126 cli2->vuid = cli1->vuid;
2127 cli2->cnum = cli1->cnum;
2128 cli2->pid = cli1->pid;
2130 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2131 printf("read succeeded! nasty security hole [%s]\n",
2136 cli_close(cli1, fnum1);
2137 cli_unlink(cli1, fname);
2139 torture_close_connection(cli1);
2140 torture_close_connection(cli2);
2142 printf("finished fdpasstest\n");
2146 static bool run_fdsesstest(int dummy)
2148 struct cli_state *cli;
2153 const char *fname = "\\fdsess.tst";
2154 const char *fname1 = "\\fdsess1.tst";
2160 if (!torture_open_connection(&cli, 0))
2162 cli_sockopt(cli, sockops);
2164 if (!torture_cli_session_setup2(cli, &new_vuid))
2167 saved_cnum = cli->cnum;
2168 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2170 new_cnum = cli->cnum;
2171 cli->cnum = saved_cnum;
2173 printf("starting fdsesstest\n");
2175 cli_unlink(cli, fname);
2176 cli_unlink(cli, fname1);
2178 fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2180 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2184 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2185 printf("write failed (%s)\n", cli_errstr(cli));
2189 saved_vuid = cli->vuid;
2190 cli->vuid = new_vuid;
2192 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2193 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2197 /* Try to open a file with different vuid, samba cnum. */
2198 fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2200 printf("create with different vuid, same cnum succeeded.\n");
2201 cli_close(cli, fnum2);
2202 cli_unlink(cli, fname1);
2204 printf("create with different vuid, same cnum failed.\n");
2205 printf("This will cause problems with service clients.\n");
2209 cli->vuid = saved_vuid;
2211 /* Try with same vuid, different cnum. */
2212 cli->cnum = new_cnum;
2214 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2215 printf("read succeeded with different cnum![%s]\n",
2220 cli->cnum = saved_cnum;
2221 cli_close(cli, fnum1);
2222 cli_unlink(cli, fname);
2224 torture_close_connection(cli);
2226 printf("finished fdsesstest\n");
2231 This test checks that
2233 1) the server does not allow an unlink on a file that is open
2235 static bool run_unlinktest(int dummy)
2237 struct cli_state *cli;
2238 const char *fname = "\\unlink.tst";
2240 bool correct = True;
2242 if (!torture_open_connection(&cli, 0)) {
2246 cli_sockopt(cli, sockops);
2248 printf("starting unlink test\n");
2250 cli_unlink(cli, fname);
2254 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2256 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2260 if (cli_unlink(cli, fname)) {
2261 printf("error: server allowed unlink on an open file\n");
2264 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2265 NT_STATUS_SHARING_VIOLATION);
2268 cli_close(cli, fnum);
2269 cli_unlink(cli, fname);
2271 if (!torture_close_connection(cli)) {
2275 printf("unlink test finished\n");
2282 test how many open files this server supports on the one socket
2284 static bool run_maxfidtest(int dummy)
2286 struct cli_state *cli;
2287 const char *ftemplate = "\\maxfid.%d.%d";
2289 int fnums[0x11000], i;
2291 bool correct = True;
2296 printf("failed to connect\n");
2300 cli_sockopt(cli, sockops);
2302 for (i=0; i<0x11000; i++) {
2303 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2304 if ((fnums[i] = cli_open(cli, fname,
2305 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
2307 printf("open of %s failed (%s)\n",
2308 fname, cli_errstr(cli));
2309 printf("maximum fnum is %d\n", i);
2317 printf("cleaning up\n");
2319 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2320 cli_close(cli, fnums[i]);
2321 if (!cli_unlink(cli, fname)) {
2322 printf("unlink of %s failed (%s)\n",
2323 fname, cli_errstr(cli));
2330 printf("maxfid test finished\n");
2331 if (!torture_close_connection(cli)) {
2337 /* generate a random buffer */
2338 static void rand_buf(char *buf, int len)
2341 *buf = (char)sys_random();
2346 /* send smb negprot commands, not reading the response */
2347 static bool run_negprot_nowait(int dummy)
2350 static struct cli_state *cli;
2351 bool correct = True;
2353 printf("starting negprot nowait test\n");
2355 if (!(cli = open_nbt_connection())) {
2359 for (i=0;i<50000;i++) {
2360 cli_negprot_sendsync(cli);
2363 if (!torture_close_connection(cli)) {
2367 printf("finished negprot nowait test\n");
2373 /* send random IPC commands */
2374 static bool run_randomipc(int dummy)
2376 char *rparam = NULL;
2378 unsigned int rdrcnt,rprcnt;
2380 int api, param_len, i;
2381 struct cli_state *cli;
2382 bool correct = True;
2385 printf("starting random ipc test\n");
2387 if (!torture_open_connection(&cli, 0)) {
2391 for (i=0;i<count;i++) {
2392 api = sys_random() % 500;
2393 param_len = (sys_random() % 64);
2395 rand_buf(param, param_len);
2400 param, param_len, 8,
2401 NULL, 0, BUFFER_SIZE,
2405 printf("%d/%d\r", i,count);
2408 printf("%d/%d\n", i, count);
2410 if (!torture_close_connection(cli)) {
2414 printf("finished random ipc test\n");
2421 static void browse_callback(const char *sname, uint32 stype,
2422 const char *comment, void *state)
2424 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2430 This test checks the browse list code
2433 static bool run_browsetest(int dummy)
2435 static struct cli_state *cli;
2436 bool correct = True;
2438 printf("starting browse test\n");
2440 if (!torture_open_connection(&cli, 0)) {
2444 printf("domain list:\n");
2445 cli_NetServerEnum(cli, cli->server_domain,
2446 SV_TYPE_DOMAIN_ENUM,
2447 browse_callback, NULL);
2449 printf("machine list:\n");
2450 cli_NetServerEnum(cli, cli->server_domain,
2452 browse_callback, NULL);
2454 if (!torture_close_connection(cli)) {
2458 printf("browse test finished\n");
2466 This checks how the getatr calls works
2468 static bool run_attrtest(int dummy)
2470 struct cli_state *cli;
2473 const char *fname = "\\attrib123456789.tst";
2474 bool correct = True;
2476 printf("starting attrib test\n");
2478 if (!torture_open_connection(&cli, 0)) {
2482 cli_unlink(cli, fname);
2483 fnum = cli_open(cli, fname,
2484 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2485 cli_close(cli, fnum);
2486 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2487 printf("getatr failed (%s)\n", cli_errstr(cli));
2491 if (abs(t - time(NULL)) > 60*60*24*10) {
2492 printf("ERROR: SMBgetatr bug. time is %s",
2498 t2 = t-60*60*24; /* 1 day ago */
2500 if (!cli_setatr(cli, fname, 0, t2)) {
2501 printf("setatr failed (%s)\n", cli_errstr(cli));
2505 if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
2506 printf("getatr failed (%s)\n", cli_errstr(cli));
2511 printf("ERROR: getatr/setatr bug. times are\n%s",
2513 printf("%s", ctime(&t2));
2517 cli_unlink(cli, fname);
2519 if (!torture_close_connection(cli)) {
2523 printf("attrib test finished\n");
2530 This checks a couple of trans2 calls
2532 static bool run_trans2test(int dummy)
2534 struct cli_state *cli;
2537 time_t c_time, a_time, m_time;
2538 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2539 const char *fname = "\\trans2.tst";
2540 const char *dname = "\\trans2";
2541 const char *fname2 = "\\trans2\\trans2.tst";
2543 bool correct = True;
2545 printf("starting trans2 test\n");
2547 if (!torture_open_connection(&cli, 0)) {
2551 cli_unlink(cli, fname);
2552 fnum = cli_open(cli, fname,
2553 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2554 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2555 &m_time_ts, NULL)) {
2556 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2560 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2561 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2565 if (strcmp(pname, fname)) {
2566 printf("qfilename gave different name? [%s] [%s]\n",
2571 cli_close(cli, fnum);
2575 cli_unlink(cli, fname);
2576 fnum = cli_open(cli, fname,
2577 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2579 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2582 cli_close(cli, fnum);
2584 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2585 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2588 if (c_time != m_time) {
2589 printf("create time=%s", ctime(&c_time));
2590 printf("modify time=%s", ctime(&m_time));
2591 printf("This system appears to have sticky create times\n");
2593 if (a_time % (60*60) == 0) {
2594 printf("access time=%s", ctime(&a_time));
2595 printf("This system appears to set a midnight access time\n");
2599 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2600 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2606 cli_unlink(cli, fname);
2607 fnum = cli_open(cli, fname,
2608 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2609 cli_close(cli, fnum);
2610 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2611 &m_time_ts, &size, NULL, NULL)) {
2612 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2615 if (w_time_ts.tv_sec < 60*60*24*2) {
2616 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2617 printf("This system appears to set a initial 0 write time\n");
2622 cli_unlink(cli, fname);
2625 /* check if the server updates the directory modification time
2626 when creating a new file */
2627 if (!cli_mkdir(cli, dname)) {
2628 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2632 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2633 &m_time_ts, &size, NULL, NULL)) {
2634 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2638 fnum = cli_open(cli, fname2,
2639 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
2640 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2641 cli_close(cli, fnum);
2642 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2643 &m_time2_ts, &size, NULL, NULL)) {
2644 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2647 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2649 printf("This system does not update directory modification times\n");
2653 cli_unlink(cli, fname2);
2654 cli_rmdir(cli, dname);
2656 if (!torture_close_connection(cli)) {
2660 printf("trans2 test finished\n");
2666 This checks new W2K calls.
2669 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2673 bool correct = True;
2675 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2676 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2679 printf("qfileinfo: level %d, len = %u\n", level, len);
2680 dump_data(0, (uint8 *)buf, len);
2687 static bool run_w2ktest(int dummy)
2689 struct cli_state *cli;
2691 const char *fname = "\\w2ktest\\w2k.tst";
2693 bool correct = True;
2695 printf("starting w2k test\n");
2697 if (!torture_open_connection(&cli, 0)) {
2701 fnum = cli_open(cli, fname,
2702 O_RDWR | O_CREAT , DENY_NONE);
2704 for (level = 1004; level < 1040; level++) {
2705 new_trans(cli, fnum, level);
2708 cli_close(cli, fnum);
2710 if (!torture_close_connection(cli)) {
2714 printf("w2k test finished\n");
2721 this is a harness for some oplock tests
2723 static bool run_oplock1(int dummy)
2725 struct cli_state *cli1;
2726 const char *fname = "\\lockt1.lck";
2728 bool correct = True;
2730 printf("starting oplock test 1\n");
2732 if (!torture_open_connection(&cli1, 0)) {
2736 cli_unlink(cli1, fname);
2738 cli_sockopt(cli1, sockops);
2740 cli1->use_oplocks = True;
2742 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2744 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2748 cli1->use_oplocks = False;
2750 cli_unlink(cli1, fname);
2751 cli_unlink(cli1, fname);
2753 if (!cli_close(cli1, fnum1)) {
2754 printf("close2 failed (%s)\n", cli_errstr(cli1));
2758 if (!cli_unlink(cli1, fname)) {
2759 printf("unlink failed (%s)\n", cli_errstr(cli1));
2763 if (!torture_close_connection(cli1)) {
2767 printf("finished oplock test 1\n");
2772 static bool run_oplock2(int dummy)
2774 struct cli_state *cli1, *cli2;
2775 const char *fname = "\\lockt2.lck";
2777 int saved_use_oplocks = use_oplocks;
2779 bool correct = True;
2780 volatile bool *shared_correct;
2782 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2783 *shared_correct = True;
2785 use_level_II_oplocks = True;
2788 printf("starting oplock test 2\n");
2790 if (!torture_open_connection(&cli1, 0)) {
2791 use_level_II_oplocks = False;
2792 use_oplocks = saved_use_oplocks;
2796 cli1->use_oplocks = True;
2797 cli1->use_level_II_oplocks = True;
2799 if (!torture_open_connection(&cli2, 1)) {
2800 use_level_II_oplocks = False;
2801 use_oplocks = saved_use_oplocks;
2805 cli2->use_oplocks = True;
2806 cli2->use_level_II_oplocks = True;
2808 cli_unlink(cli1, fname);
2810 cli_sockopt(cli1, sockops);
2811 cli_sockopt(cli2, sockops);
2813 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
2815 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2819 /* Don't need the globals any more. */
2820 use_level_II_oplocks = False;
2821 use_oplocks = saved_use_oplocks;
2825 fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
2827 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
2828 *shared_correct = False;
2834 if (!cli_close(cli2, fnum2)) {
2835 printf("close2 failed (%s)\n", cli_errstr(cli1));
2836 *shared_correct = False;
2844 /* Ensure cli1 processes the break. Empty file should always return 0
2847 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
2848 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
2852 /* Should now be at level II. */
2853 /* Test if sending a write locks causes a break to none. */
2855 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
2856 printf("lock failed (%s)\n", cli_errstr(cli1));
2860 cli_unlock(cli1, fnum1, 0, 4);
2864 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
2865 printf("lock failed (%s)\n", cli_errstr(cli1));
2869 cli_unlock(cli1, fnum1, 0, 4);
2873 cli_read(cli1, fnum1, buf, 0, 4);
2876 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
2877 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
2882 if (!cli_close(cli1, fnum1)) {
2883 printf("close1 failed (%s)\n", cli_errstr(cli1));
2889 if (!cli_unlink(cli1, fname)) {
2890 printf("unlink failed (%s)\n", cli_errstr(cli1));
2894 if (!torture_close_connection(cli1)) {
2898 if (!*shared_correct) {
2902 printf("finished oplock test 2\n");
2907 /* handler for oplock 3 tests */
2908 static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
2910 printf("got oplock break fnum=%d level=%d\n",
2912 return cli_oplock_ack(cli, fnum, level);
2915 static bool run_oplock3(int dummy)
2917 struct cli_state *cli;
2918 const char *fname = "\\oplockt3.dat";
2920 char buf[4] = "abcd";
2921 bool correct = True;
2922 volatile bool *shared_correct;
2924 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
2925 *shared_correct = True;
2927 printf("starting oplock test 3\n");
2932 use_level_II_oplocks = True;
2933 if (!torture_open_connection(&cli, 0)) {
2934 *shared_correct = False;
2938 /* try to trigger a oplock break in parent */
2939 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2940 cli_write(cli, fnum, 0, buf, 0, 4);
2946 use_level_II_oplocks = True;
2947 if (!torture_open_connection(&cli, 1)) { /* other is forked */
2950 cli_oplock_handler(cli, oplock3_handler);
2951 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
2952 cli_write(cli, fnum, 0, buf, 0, 4);
2953 cli_close(cli, fnum);
2954 fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
2955 cli->timeout = 20000;
2956 cli_receive_smb(cli);
2957 printf("finished oplock test 3\n");
2959 return (correct && *shared_correct);
2961 /* What are we looking for here? What's sucess and what's FAILURE? */
2967 Test delete on close semantics.
2969 static bool run_deletetest(int dummy)
2971 struct cli_state *cli1 = NULL;
2972 struct cli_state *cli2 = NULL;
2973 const char *fname = "\\delete.file";
2976 bool correct = True;
2978 printf("starting delete test\n");
2980 if (!torture_open_connection(&cli1, 0)) {
2984 cli_sockopt(cli1, sockops);
2986 /* Test 1 - this should delete the file on close. */
2988 cli_setatr(cli1, fname, 0, 0);
2989 cli_unlink(cli1, fname);
2991 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
2992 0, FILE_OVERWRITE_IF,
2993 FILE_DELETE_ON_CLOSE, 0);
2996 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3003 uint32 *accinfo = NULL;
3005 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3007 printf("access mode = 0x%lx\n", *accinfo);
3012 if (!cli_close(cli1, fnum1)) {
3013 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3018 fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
3020 printf("[1] open of %s succeeded (should fail)\n", fname);
3025 printf("first delete on close test succeeded.\n");
3027 /* Test 2 - this should delete the file on close. */
3029 cli_setatr(cli1, fname, 0, 0);
3030 cli_unlink(cli1, fname);
3032 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
3033 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3034 FILE_OVERWRITE_IF, 0, 0);
3037 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3042 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3043 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3048 if (!cli_close(cli1, fnum1)) {
3049 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3054 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3056 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3057 if (!cli_close(cli1, fnum1)) {
3058 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3062 cli_unlink(cli1, fname);
3064 printf("second delete on close test succeeded.\n");
3067 cli_setatr(cli1, fname, 0, 0);
3068 cli_unlink(cli1, fname);
3070 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3071 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3074 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3079 /* This should fail with a sharing violation - open for delete is only compatible
3080 with SHARE_DELETE. */
3082 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3083 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
3086 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3091 /* This should succeed. */
3093 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3094 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3097 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3102 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3103 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3108 if (!cli_close(cli1, fnum1)) {
3109 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3114 if (!cli_close(cli1, fnum2)) {
3115 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3120 /* This should fail - file should no longer be there. */
3122 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3124 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3125 if (!cli_close(cli1, fnum1)) {
3126 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3128 cli_unlink(cli1, fname);
3132 printf("third delete on close test succeeded.\n");
3135 cli_setatr(cli1, fname, 0, 0);
3136 cli_unlink(cli1, fname);
3138 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3139 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3142 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3147 /* This should succeed. */
3148 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3149 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
3151 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3156 if (!cli_close(cli1, fnum2)) {
3157 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3162 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3163 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3168 /* This should fail - no more opens once delete on close set. */
3169 fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
3170 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3173 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3177 printf("fourth delete on close test succeeded.\n");
3179 if (!cli_close(cli1, fnum1)) {
3180 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3186 cli_setatr(cli1, fname, 0, 0);
3187 cli_unlink(cli1, fname);
3189 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
3191 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3196 /* This should fail - only allowed on NT opens with DELETE access. */
3198 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3199 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3204 if (!cli_close(cli1, fnum1)) {
3205 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3210 printf("fifth delete on close test succeeded.\n");
3213 cli_setatr(cli1, fname, 0, 0);
3214 cli_unlink(cli1, fname);
3216 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3217 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3218 FILE_OVERWRITE_IF, 0, 0);
3221 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3226 /* This should fail - only allowed on NT opens with DELETE access. */
3228 if (cli_nt_delete_on_close(cli1, fnum1, True)) {
3229 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3234 if (!cli_close(cli1, fnum1)) {
3235 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3240 printf("sixth delete on close test succeeded.\n");
3243 cli_setatr(cli1, fname, 0, 0);
3244 cli_unlink(cli1, fname);
3246 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3247 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
3250 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3255 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3256 printf("[7] setting delete_on_close on file failed !\n");
3261 if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
3262 printf("[7] unsetting delete_on_close on file failed !\n");
3267 if (!cli_close(cli1, fnum1)) {
3268 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3273 /* This next open should succeed - we reset the flag. */
3275 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3277 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3282 if (!cli_close(cli1, fnum1)) {
3283 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3288 printf("seventh delete on close test succeeded.\n");
3291 cli_setatr(cli1, fname, 0, 0);
3292 cli_unlink(cli1, fname);
3294 if (!torture_open_connection(&cli2, 1)) {
3295 printf("[8] failed to open second connection.\n");
3300 cli_sockopt(cli1, sockops);
3302 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3303 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3304 FILE_OVERWRITE_IF, 0, 0);
3307 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3312 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3313 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3317 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3322 if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
3323 printf("[8] setting delete_on_close on file failed !\n");
3328 if (!cli_close(cli1, fnum1)) {
3329 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3334 if (!cli_close(cli2, fnum2)) {
3335 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3340 /* This should fail.. */
3341 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3343 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3347 printf("eighth delete on close test succeeded.\n");
3349 /* This should fail - we need to set DELETE_ACCESS. */
3350 fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3351 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3354 printf("[9] open of %s succeeded should have failed!\n", fname);
3359 printf("ninth delete on close test succeeded.\n");
3361 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3362 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
3364 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3369 /* This should delete the file. */
3370 if (!cli_close(cli1, fnum1)) {
3371 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3376 /* This should fail.. */
3377 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
3379 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3383 printf("tenth delete on close test succeeded.\n");
3385 cli_setatr(cli1, fname, 0, 0);
3386 cli_unlink(cli1, fname);
3388 /* What error do we get when attempting to open a read-only file with
3391 /* Create a readonly file. */
3392 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3393 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3395 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3400 if (!cli_close(cli1, fnum1)) {
3401 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3406 /* Now try open for delete access. */
3407 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3408 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3409 FILE_OVERWRITE_IF, 0, 0);
3412 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3413 cli_close(cli1, fnum1);
3417 NTSTATUS nterr = cli_nt_error(cli1);
3418 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3419 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3423 printf("eleventh delete on close test succeeded.\n");
3427 printf("finished delete test\n");
3430 /* FIXME: This will crash if we aborted before cli2 got
3431 * intialized, because these functions don't handle
3432 * uninitialized connections. */
3434 if (fnum1 != -1) cli_close(cli1, fnum1);
3435 if (fnum2 != -1) cli_close(cli1, fnum2);
3436 cli_setatr(cli1, fname, 0, 0);
3437 cli_unlink(cli1, fname);
3439 if (cli1 && !torture_close_connection(cli1)) {
3442 if (cli2 && !torture_close_connection(cli2)) {
3450 print out server properties
3452 static bool run_properties(int dummy)
3454 static struct cli_state *cli;
3455 bool correct = True;
3457 printf("starting properties test\n");
3461 if (!torture_open_connection(&cli, 0)) {
3465 cli_sockopt(cli, sockops);
3467 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3469 if (!torture_close_connection(cli)) {
3478 /* FIRST_DESIRED_ACCESS 0xf019f */
3479 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3480 FILE_READ_EA| /* 0xf */ \
3481 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3482 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3483 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3484 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3485 /* SECOND_DESIRED_ACCESS 0xe0080 */
3486 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3487 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3488 WRITE_OWNER_ACCESS /* 0xe0000 */
3491 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3492 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3494 WRITE_OWNER_ACCESS /* */
3498 Test ntcreate calls made by xcopy
3500 static bool run_xcopy(int dummy)
3502 static struct cli_state *cli1;
3503 const char *fname = "\\test.txt";
3504 bool correct = True;
3507 printf("starting xcopy test\n");
3509 if (!torture_open_connection(&cli1, 0)) {
3513 fnum1 = cli_nt_create_full(cli1, fname, 0,
3514 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3515 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3519 printf("First open failed - %s\n", cli_errstr(cli1));
3523 fnum2 = cli_nt_create_full(cli1, fname, 0,
3524 SECOND_DESIRED_ACCESS, 0,
3525 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3528 printf("second open failed - %s\n", cli_errstr(cli1));
3532 if (!torture_close_connection(cli1)) {
3540 Test rename on files open with share delete and no share delete.
3542 static bool run_rename(int dummy)
3544 static struct cli_state *cli1;
3545 const char *fname = "\\test.txt";
3546 const char *fname1 = "\\test1.txt";
3547 bool correct = True;
3550 printf("starting rename test\n");
3552 if (!torture_open_connection(&cli1, 0)) {
3556 cli_unlink(cli1, fname);
3557 cli_unlink(cli1, fname1);
3558 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3559 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3562 printf("First open failed - %s\n", cli_errstr(cli1));
3566 if (!cli_rename(cli1, fname, fname1)) {
3567 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3569 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3573 if (!cli_close(cli1, fnum1)) {
3574 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3578 cli_unlink(cli1, fname);
3579 cli_unlink(cli1, fname1);
3580 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3582 FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3584 FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
3588 printf("Second open failed - %s\n", cli_errstr(cli1));
3592 if (!cli_rename(cli1, fname, fname1)) {
3593 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3596 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3599 if (!cli_close(cli1, fnum1)) {
3600 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3604 cli_unlink(cli1, fname);
3605 cli_unlink(cli1, fname1);
3607 fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3608 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3611 printf("Third open failed - %s\n", cli_errstr(cli1));
3620 fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3621 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3624 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3627 if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
3628 printf("[8] setting delete_on_close on file failed !\n");
3632 if (!cli_close(cli1, fnum2)) {
3633 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3639 if (!cli_rename(cli1, fname, fname1)) {
3640 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3643 printf("Third rename succeeded (SHARE_NONE)\n");
3646 if (!cli_close(cli1, fnum1)) {
3647 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3651 cli_unlink(cli1, fname);
3652 cli_unlink(cli1, fname1);
3656 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3657 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
3660 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3664 if (!cli_rename(cli1, fname, fname1)) {
3665 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3667 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3671 if (!cli_close(cli1, fnum1)) {
3672 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3676 cli_unlink(cli1, fname);
3677 cli_unlink(cli1, fname1);
3681 fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3682 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3685 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3689 if (!cli_rename(cli1, fname, fname1)) {
3690 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3694 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3698 * Now check if the first name still exists ...
3701 /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3702 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
3705 printf("Opening original file after rename of open file fails: %s\n",
3709 printf("Opening original file after rename of open file works ...\n");
3710 (void)cli_close(cli1, fnum2);
3716 if (!cli_close(cli1, fnum1)) {
3717 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3721 cli_unlink(cli1, fname);
3722 cli_unlink(cli1, fname1);
3724 if (!torture_close_connection(cli1)) {
3731 static bool run_pipe_number(int dummy)
3733 struct cli_state *cli1;
3734 const char *pipe_name = "\\SPOOLSS";
3738 printf("starting pipenumber test\n");
3739 if (!torture_open_connection(&cli1, 0)) {
3743 cli_sockopt(cli1, sockops);
3745 fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
3746 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
3749 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
3753 printf("\r%6d", num_pipes);
3756 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
3757 torture_close_connection(cli1);
3762 Test open mode returns on read-only files.
3764 static bool run_opentest(int dummy)
3766 static struct cli_state *cli1;
3767 static struct cli_state *cli2;
3768 const char *fname = "\\readonly.file";
3772 bool correct = True;
3775 printf("starting open test\n");
3777 if (!torture_open_connection(&cli1, 0)) {
3781 cli_setatr(cli1, fname, 0, 0);
3782 cli_unlink(cli1, fname);
3784 cli_sockopt(cli1, sockops);
3786 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3788 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3792 if (!cli_close(cli1, fnum1)) {
3793 printf("close2 failed (%s)\n", cli_errstr(cli1));
3797 if (!cli_setatr(cli1, fname, aRONLY, 0)) {
3798 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
3802 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3804 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3808 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
3809 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3811 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
3812 NT_STATUS_ACCESS_DENIED)) {
3813 printf("correct error code ERRDOS/ERRnoaccess returned\n");
3816 printf("finished open test 1\n");
3818 cli_close(cli1, fnum1);
3820 /* Now try not readonly and ensure ERRbadshare is returned. */
3822 cli_setatr(cli1, fname, 0, 0);
3824 fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
3826 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3830 /* This will fail - but the error should be ERRshare. */
3831 fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
3833 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
3834 NT_STATUS_SHARING_VIOLATION)) {
3835 printf("correct error code ERRDOS/ERRbadshare returned\n");
3838 if (!cli_close(cli1, fnum1)) {
3839 printf("close2 failed (%s)\n", cli_errstr(cli1));
3843 cli_unlink(cli1, fname);
3845 printf("finished open test 2\n");
3847 /* Test truncate open disposition on file opened for read. */
3849 fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
3851 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
3855 /* write 20 bytes. */
3857 memset(buf, '\0', 20);
3859 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
3860 printf("write failed (%s)\n", cli_errstr(cli1));
3864 if (!cli_close(cli1, fnum1)) {
3865 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
3869 /* Ensure size == 20. */
3870 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3871 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3876 printf("(3) file size != 20\n");
3880 /* Now test if we can truncate a file opened for readonly. */
3882 fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
3884 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
3888 if (!cli_close(cli1, fnum1)) {
3889 printf("close2 failed (%s)\n", cli_errstr(cli1));
3893 /* Ensure size == 0. */
3894 if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
3895 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
3900 printf("(3) file size != 0\n");
3903 printf("finished open test 3\n");
3905 cli_unlink(cli1, fname);
3908 printf("testing ctemp\n");
3909 fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
3911 printf("ctemp failed (%s)\n", cli_errstr(cli1));
3914 printf("ctemp gave path %s\n", tmp_path);
3915 if (!cli_close(cli1, fnum1)) {
3916 printf("close of temp failed (%s)\n", cli_errstr(cli1));
3918 if (!cli_unlink(cli1, tmp_path)) {
3919 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
3922 /* Test the non-io opens... */
3924 if (!torture_open_connection(&cli2, 1)) {
3928 cli_setatr(cli2, fname, 0, 0);
3929 cli_unlink(cli2, fname);
3931 cli_sockopt(cli2, sockops);
3933 printf("TEST #1 testing 2 non-io opens (no delete)\n");
3935 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3936 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3939 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3943 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3944 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3947 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3951 if (!cli_close(cli1, fnum1)) {
3952 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3955 if (!cli_close(cli2, fnum2)) {
3956 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3960 printf("non-io open test #1 passed.\n");
3962 cli_unlink(cli1, fname);
3964 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
3966 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3967 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
3970 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3974 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3975 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
3978 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3982 if (!cli_close(cli1, fnum1)) {
3983 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3986 if (!cli_close(cli2, fnum2)) {
3987 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3991 printf("non-io open test #2 passed.\n");
3993 cli_unlink(cli1, fname);
3995 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
3997 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
3998 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4001 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4005 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4006 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4009 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4013 if (!cli_close(cli1, fnum1)) {
4014 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4017 if (!cli_close(cli2, fnum2)) {
4018 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4022 printf("non-io open test #3 passed.\n");
4024 cli_unlink(cli1, fname);
4026 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4028 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4029 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4032 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4036 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4037 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
4040 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4044 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4046 if (!cli_close(cli1, fnum1)) {
4047 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4051 printf("non-io open test #4 passed.\n");
4053 cli_unlink(cli1, fname);
4055 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4057 fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4058 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
4061 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4065 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4066 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4069 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4073 if (!cli_close(cli1, fnum1)) {
4074 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4078 if (!cli_close(cli2, fnum2)) {
4079 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4083 printf("non-io open test #5 passed.\n");
4085 printf("TEST #6 testing 1 non-io open, one io open\n");
4087 cli_unlink(cli1, fname);
4089 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4090 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4093 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4097 fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4098 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
4101 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4105 if (!cli_close(cli1, fnum1)) {
4106 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4110 if (!cli_close(cli2, fnum2)) {
4111 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4115 printf("non-io open test #6 passed.\n");
4117 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4119 cli_unlink(cli1, fname);
4121 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4122 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4125 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4129 fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4130 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
4133 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4137 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4139 if (!cli_close(cli1, fnum1)) {
4140 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4144 printf("non-io open test #7 passed.\n");
4146 cli_unlink(cli1, fname);
4148 if (!torture_close_connection(cli1)) {
4151 if (!torture_close_connection(cli2)) {
4159 Test POSIX open /mkdir calls.
4161 static bool run_simple_posix_open_test(int dummy)
4163 static struct cli_state *cli1;
4164 const char *fname = "\\posix:file";
4165 const char *dname = "\\posix:dir";
4166 uint16 major, minor;
4167 uint32 caplow, caphigh;
4169 bool correct = false;
4171 printf("Starting simple POSIX open test\n");
4173 if (!torture_open_connection(&cli1, 0)) {
4177 cli_sockopt(cli1, sockops);
4179 if (!SERVER_HAS_UNIX_CIFS(cli1)) {
4180 printf("Server doesn't support UNIX CIFS extensions.\n");
4184 if (!cli_unix_extensions_version(cli1, &major,
4185 &minor, &caplow, &caphigh)) {
4186 printf("Server didn't return UNIX CIFS extensions.\n");
4190 if (!cli_set_unix_extensions_capabilities(cli1,
4191 major, minor, caplow, caphigh)) {
4192 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4196 cli_setatr(cli1, fname, 0, 0);
4197 cli_posix_unlink(cli1, fname);
4198 cli_setatr(cli1, dname, 0, 0);
4199 cli_posix_rmdir(cli1, dname);
4201 /* Create a directory. */
4202 if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
4203 printf("Server doesn't support setting UNIX CIFS extensions.\n");
4207 fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
4209 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4213 if (!cli_close(cli1, fnum1)) {
4214 printf("close failed (%s)\n", cli_errstr(cli1));
4218 /* Now open the file again for read only. */
4219 fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4221 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4225 /* Now unlink while open. */
4226 if (!cli_posix_unlink(cli1, fname)) {
4227 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4231 if (!cli_close(cli1, fnum1)) {
4232 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4236 /* Ensure the file has gone. */
4237 fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
4239 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4243 /* What happens when we try and POSIX open a directory ? */
4244 fnum1 = cli_posix_open(cli1, dname, O_RDONLY, 0);
4246 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4249 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4250 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4255 if (!cli_posix_rmdir(cli1, dname)) {
4256 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4260 printf("Simple POSIX open test passed\n");
4266 cli_close(cli1, fnum1);
4270 cli_setatr(cli1, fname, 0, 0);
4271 cli_posix_unlink(cli1, fname);
4272 cli_setatr(cli1, dname, 0, 0);
4273 cli_posix_rmdir(cli1, dname);
4275 if (!torture_close_connection(cli1)) {
4283 static uint32 open_attrs_table[] = {
4284 FILE_ATTRIBUTE_NORMAL,
4285 FILE_ATTRIBUTE_ARCHIVE,
4286 FILE_ATTRIBUTE_READONLY,
4287 FILE_ATTRIBUTE_HIDDEN,
4288 FILE_ATTRIBUTE_SYSTEM,
4290 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4291 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4292 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4293 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4294 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4295 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4297 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4298 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4299 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4300 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4303 struct trunc_open_results {
4310 static struct trunc_open_results attr_results[] = {
4311 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4312 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4313 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4314 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4315 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4316 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4317 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4318 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4319 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4320 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4321 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4322 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4323 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4324 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4325 { 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 },
4326 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4327 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4328 { 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 },
4329 { 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 },
4330 { 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 },
4331 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4332 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4333 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4334 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4335 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4336 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4339 static bool run_openattrtest(int dummy)
4341 static struct cli_state *cli1;
4342 const char *fname = "\\openattr.file";
4344 bool correct = True;
4346 unsigned int i, j, k, l;
4348 printf("starting open attr test\n");
4350 if (!torture_open_connection(&cli1, 0)) {
4354 cli_sockopt(cli1, sockops);
4356 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4357 cli_setatr(cli1, fname, 0, 0);
4358 cli_unlink(cli1, fname);
4359 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4360 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
4363 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4367 if (!cli_close(cli1, fnum1)) {
4368 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4372 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4373 fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4374 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
4377 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4378 if (attr_results[l].num == k) {
4379 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4380 k, open_attrs_table[i],
4381 open_attrs_table[j],
4382 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4386 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4387 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4388 k, open_attrs_table[i], open_attrs_table[j],
4393 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4399 if (!cli_close(cli1, fnum1)) {
4400 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4404 if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
4405 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4410 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4411 k, open_attrs_table[i], open_attrs_table[j], attr );
4414 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4415 if (attr_results[l].num == k) {
4416 if (attr != attr_results[l].result_attr ||
4417 open_attrs_table[i] != attr_results[l].init_attr ||
4418 open_attrs_table[j] != attr_results[l].trunc_attr) {
4419 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4420 open_attrs_table[i],
4421 open_attrs_table[j],
4423 attr_results[l].result_attr);
4433 cli_setatr(cli1, fname, 0, 0);
4434 cli_unlink(cli1, fname);
4436 printf("open attr test %s.\n", correct ? "passed" : "failed");
4438 if (!torture_close_connection(cli1)) {
4444 static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
4450 test directory listing speed
4452 static bool run_dirtest(int dummy)
4455 static struct cli_state *cli;
4458 bool correct = True;
4460 printf("starting directory test\n");
4462 if (!torture_open_connection(&cli, 0)) {
4466 cli_sockopt(cli, sockops);
4469 for (i=0;i<torture_numops;i++) {
4471 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4472 fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
4474 fprintf(stderr,"Failed to open %s\n", fname);
4477 cli_close(cli, fnum);
4482 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4483 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4484 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4486 printf("dirtest core %g seconds\n", end_timer() - t1);
4489 for (i=0;i<torture_numops;i++) {
4491 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4492 cli_unlink(cli, fname);
4495 if (!torture_close_connection(cli)) {
4499 printf("finished dirtest\n");
4504 static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
4506 struct cli_state *pcli = (struct cli_state *)state;
4508 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4510 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4513 if (finfo->mode & aDIR) {
4514 if (!cli_rmdir(pcli, fname))
4515 printf("del_fn: failed to rmdir %s\n,", fname );
4517 if (!cli_unlink(pcli, fname))
4518 printf("del_fn: failed to unlink %s\n,", fname );
4524 sees what IOCTLs are supported
4526 bool torture_ioctl_test(int dummy)
4528 static struct cli_state *cli;
4529 uint16 device, function;
4531 const char *fname = "\\ioctl.dat";
4535 if (!torture_open_connection(&cli, 0)) {
4539 printf("starting ioctl test\n");
4541 cli_unlink(cli, fname);
4543 fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4545 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4549 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4550 printf("ioctl device info: %s\n", cli_errstr(cli));
4552 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4553 printf("ioctl job info: %s\n", cli_errstr(cli));
4555 for (device=0;device<0x100;device++) {
4556 printf("testing device=0x%x\n", device);
4557 for (function=0;function<0x100;function++) {
4558 uint32 code = (device<<16) | function;
4560 status = cli_raw_ioctl(cli, fnum, code, &blob);
4562 if (NT_STATUS_IS_OK(status)) {
4563 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4565 data_blob_free(&blob);
4570 if (!torture_close_connection(cli)) {
4579 tries varients of chkpath
4581 bool torture_chkpath_test(int dummy)
4583 static struct cli_state *cli;
4587 if (!torture_open_connection(&cli, 0)) {
4591 printf("starting chkpath test\n");
4593 /* cleanup from an old run */
4594 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4595 cli_unlink(cli, "\\chkpath.dir\\*");
4596 cli_rmdir(cli, "\\chkpath.dir");
4598 if (!cli_mkdir(cli, "\\chkpath.dir")) {
4599 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4603 if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
4604 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4608 fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
4610 printf("open1 failed (%s)\n", cli_errstr(cli));
4613 cli_close(cli, fnum);
4615 if (!cli_chkpath(cli, "\\chkpath.dir")) {
4616 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4620 if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
4621 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4625 if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
4626 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4627 NT_STATUS_NOT_A_DIRECTORY);
4629 printf("* chkpath on a file should fail\n");
4633 if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
4634 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4635 NT_STATUS_OBJECT_NAME_NOT_FOUND);
4637 printf("* chkpath on a non existant file should fail\n");
4641 if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
4642 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4643 NT_STATUS_OBJECT_PATH_NOT_FOUND);
4645 printf("* chkpath on a non existent component should fail\n");
4649 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4650 cli_unlink(cli, "\\chkpath.dir\\*");
4651 cli_rmdir(cli, "\\chkpath.dir");
4653 if (!torture_close_connection(cli)) {
4660 static bool run_eatest(int dummy)
4662 static struct cli_state *cli;
4663 const char *fname = "\\eatest.txt";
4664 bool correct = True;
4667 struct ea_struct *ea_list = NULL;
4668 TALLOC_CTX *mem_ctx = talloc_init("eatest");
4670 printf("starting eatest\n");
4672 if (!torture_open_connection(&cli, 0)) {
4673 talloc_destroy(mem_ctx);
4677 cli_unlink(cli, fname);
4678 fnum = cli_nt_create_full(cli, fname, 0,
4679 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4680 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4684 printf("open failed - %s\n", cli_errstr(cli));
4685 talloc_destroy(mem_ctx);
4689 for (i = 0; i < 10; i++) {
4690 fstring ea_name, ea_val;
4692 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
4693 memset(ea_val, (char)i+1, i+1);
4694 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
4695 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4696 talloc_destroy(mem_ctx);
4701 cli_close(cli, fnum);
4702 for (i = 0; i < 10; i++) {
4703 fstring ea_name, ea_val;
4705 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
4706 memset(ea_val, (char)i+1, i+1);
4707 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
4708 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4709 talloc_destroy(mem_ctx);
4714 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4715 printf("ea_get list failed - %s\n", cli_errstr(cli));
4719 printf("num_eas = %d\n", (int)num_eas);
4721 if (num_eas != 20) {
4722 printf("Should be 20 EA's stored... failing.\n");
4726 for (i = 0; i < num_eas; i++) {
4727 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4728 dump_data(0, ea_list[i].value.data,
4729 ea_list[i].value.length);
4732 /* Setting EA's to zero length deletes them. Test this */
4733 printf("Now deleting all EA's - case indepenent....\n");
4736 cli_set_ea_path(cli, fname, "", "", 0);
4738 for (i = 0; i < 20; i++) {
4740 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
4741 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
4742 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
4743 talloc_destroy(mem_ctx);
4749 if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
4750 printf("ea_get list failed - %s\n", cli_errstr(cli));
4754 printf("num_eas = %d\n", (int)num_eas);
4755 for (i = 0; i < num_eas; i++) {
4756 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
4757 dump_data(0, ea_list[i].value.data,
4758 ea_list[i].value.length);
4762 printf("deleting EA's failed.\n");
4766 /* Try and delete a non existant EA. */
4767 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
4768 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
4772 talloc_destroy(mem_ctx);
4773 if (!torture_close_connection(cli)) {
4780 static bool run_dirtest1(int dummy)
4783 static struct cli_state *cli;
4785 bool correct = True;
4787 printf("starting directory test\n");
4789 if (!torture_open_connection(&cli, 0)) {
4793 cli_sockopt(cli, sockops);
4795 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4796 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4797 cli_rmdir(cli, "\\LISTDIR");
4798 cli_mkdir(cli, "\\LISTDIR");
4800 /* Create 1000 files and 1000 directories. */
4801 for (i=0;i<1000;i++) {
4803 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
4804 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4805 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
4807 fprintf(stderr,"Failed to open %s\n", fname);
4810 cli_close(cli, fnum);
4812 for (i=0;i<1000;i++) {
4814 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
4815 if (!cli_mkdir(cli, fname)) {
4816 fprintf(stderr,"Failed to open %s\n", fname);
4821 /* Now ensure that doing an old list sees both files and directories. */
4822 num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
4823 printf("num_seen = %d\n", num_seen );
4824 /* We should see 100 files + 1000 directories + . and .. */
4825 if (num_seen != 2002)
4828 /* Ensure if we have the "must have" bits we only see the
4831 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
4832 printf("num_seen = %d\n", num_seen );
4833 if (num_seen != 1002)
4836 num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
4837 printf("num_seen = %d\n", num_seen );
4838 if (num_seen != 1000)
4841 /* Delete everything. */
4842 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
4843 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
4844 cli_rmdir(cli, "\\LISTDIR");
4847 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
4848 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
4849 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
4852 if (!torture_close_connection(cli)) {
4856 printf("finished dirtest1\n");
4861 static bool run_error_map_extract(int dummy) {
4863 static struct cli_state *c_dos;
4864 static struct cli_state *c_nt;
4869 uint32 flgs2, errnum;
4876 /* NT-Error connection */
4878 if (!(c_nt = open_nbt_connection())) {
4882 c_nt->use_spnego = False;
4884 status = cli_negprot(c_nt);
4886 if (!NT_STATUS_IS_OK(status)) {
4887 printf("%s rejected the NT-error negprot (%s)\n", host,
4893 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
4895 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
4899 /* DOS-Error connection */
4901 if (!(c_dos = open_nbt_connection())) {
4905 c_dos->use_spnego = False;
4906 c_dos->force_dos_errors = True;
4908 status = cli_negprot(c_dos);
4909 if (!NT_STATUS_IS_OK(status)) {
4910 printf("%s rejected the DOS-error negprot (%s)\n", host,
4912 cli_shutdown(c_dos);
4916 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
4918 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
4922 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
4923 fstr_sprintf(user, "%X", error);
4925 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
4926 password, strlen(password),
4927 password, strlen(password),
4929 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4932 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
4934 /* Case #1: 32-bit NT errors */
4935 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4936 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
4938 printf("/** Dos error on NT connection! (%s) */\n",
4940 nt_status = NT_STATUS(0xc0000000);
4943 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
4944 password, strlen(password),
4945 password, strlen(password),
4947 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
4949 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
4951 /* Case #1: 32-bit NT errors */
4952 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
4953 printf("/** NT error on DOS connection! (%s) */\n",
4955 errnum = errclass = 0;
4957 cli_dos_error(c_dos, &errclass, &errnum);
4960 if (NT_STATUS_V(nt_status) != error) {
4961 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
4962 get_nt_error_c_code(NT_STATUS(error)),
4963 get_nt_error_c_code(nt_status));
4966 printf("\t{%s,\t%s,\t%s},\n",
4967 smb_dos_err_class(errclass),
4968 smb_dos_err_name(errclass, errnum),
4969 get_nt_error_c_code(NT_STATUS(error)));
4974 static bool run_sesssetup_bench(int dummy)
4976 static struct cli_state *c;
4977 const char *fname = "\\file.dat";
4982 if (!torture_open_connection(&c, 0)) {
4986 fnum = cli_nt_create_full(
4987 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
4988 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4989 FILE_DELETE_ON_CLOSE, 0);
4991 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
4995 for (i=0; i<torture_numops; i++) {
4996 status = cli_session_setup(
4998 password, strlen(password),
4999 password, strlen(password),
5001 if (!NT_STATUS_IS_OK(status)) {
5002 d_printf("(%s) cli_session_setup failed: %s\n",
5003 __location__, nt_errstr(status));
5007 d_printf("\r%d ", (int)c->vuid);
5009 if (!cli_ulogoff(c)) {
5010 d_printf("(%s) cli_ulogoff failed: %s\n",
5011 __location__, cli_errstr(c));
5020 static bool subst_test(const char *str, const char *user, const char *domain,
5021 uid_t uid, gid_t gid, const char *expected)
5026 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5028 if (strcmp(subst, expected) != 0) {
5029 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5030 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5039 static void chain1_open_completion(struct async_req *req)
5044 status = cli_open_recv(req, &fnum);
5047 d_printf("cli_open_recv returned %s: %d\n",
5049 NT_STATUS_IS_OK(status) ? fnum : -1);
5052 static void chain1_read_completion(struct async_req *req)
5058 status = cli_read_andx_recv(req, &received, &rcvbuf);
5059 if (!NT_STATUS_IS_OK(status)) {
5061 d_printf("cli_read_andx_recv returned %s\n",
5066 d_printf("got %d bytes: %.*s\n", (int)received, (int)received,
5071 static void chain1_write_completion(struct async_req *req)
5076 status = cli_write_andx_recv(req, &written);
5077 if (!NT_STATUS_IS_OK(status)) {
5079 d_printf("cli_write_andx_recv returned %s\n",
5084 d_printf("wrote %d bytes\n", (int)written);
5088 static void chain1_close_completion(struct async_req *req)
5092 status = cli_close_recv(req);
5093 *((bool *)(req->async.priv)) = true;
5097 d_printf("cli_close returned %s\n", nt_errstr(status));
5100 static bool run_chain1(int dummy)
5102 struct cli_state *cli1;
5103 struct event_context *evt = event_context_init(NULL);
5104 struct async_req *reqs[4];
5106 const char *text = "hallo";
5108 printf("starting chain1 test\n");
5109 if (!torture_open_connection(&cli1, 0)) {
5113 cli_sockopt(cli1, sockops);
5115 cli_chain_cork(cli1, evt, 0);
5116 reqs[0] = cli_open_send(talloc_tos(), evt, cli1, "\\test",
5118 reqs[0]->async.fn = chain1_open_completion;
5119 reqs[1] = cli_write_andx_send(talloc_tos(), evt, cli1, 0, 0,
5120 (uint8_t *)text, 0, strlen(text));
5121 reqs[1]->async.fn = chain1_write_completion;
5122 reqs[2] = cli_read_andx_send(talloc_tos(), evt, cli1, 0, 1, 10);
5123 reqs[2]->async.fn = chain1_read_completion;
5124 reqs[3] = cli_close_send(talloc_tos(), evt, cli1, 0);
5125 reqs[3]->async.fn = chain1_close_completion;
5126 reqs[3]->async.priv = (void *)&done;
5127 cli_chain_uncork(cli1);
5130 event_loop_once(evt);
5133 torture_close_connection(cli1);
5137 static size_t null_source(uint8_t *buf, size_t n, void *priv)
5139 size_t *to_pull = (size_t *)priv;
5140 size_t thistime = *to_pull;
5142 thistime = MIN(thistime, n);
5143 if (thistime == 0) {
5147 memset(buf, 0, thistime);
5148 *to_pull -= thistime;
5152 static bool run_windows_write(int dummy)
5154 struct cli_state *cli1;
5158 const char *fname = "\\writetest.txt";
5162 printf("starting windows_write test\n");
5163 if (!torture_open_connection(&cli1, 0)) {
5167 fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
5169 printf("open failed (%s)\n", cli_errstr(cli1));
5173 cli_sockopt(cli1, sockops);
5177 for (i=0; i<torture_numops; i++) {
5179 off_t start = i * torture_blocksize;
5181 size_t to_pull = torture_blocksize - 1;
5183 if (cli_write(cli1, fnum, 0, &c,
5184 start + torture_blocksize - 1, 1) != 1) {
5185 printf("cli_write failed: %s\n", cli_errstr(cli1));
5189 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
5190 null_source, &to_pull);
5191 if (!NT_STATUS_IS_OK(status)) {
5192 printf("cli_push returned: %s\n", nt_errstr(status));
5197 seconds = end_timer();
5198 kbytes = (double)torture_blocksize * torture_numops;
5201 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
5202 (double)seconds, (int)(kbytes/seconds));
5206 cli_close(cli1, fnum);
5207 cli_unlink(cli1, fname);
5208 torture_close_connection(cli1);
5212 static bool run_cli_echo(int dummy)
5214 struct cli_state *cli;
5215 struct event_context *ev = event_context_init(NULL);
5216 struct async_req *req;
5219 printf("starting cli_echo test\n");
5220 if (!torture_open_connection(&cli, 0)) {
5223 cli_sockopt(cli, sockops);
5225 req = cli_echo_send(ev, ev, cli, 5, data_blob_const("hello", 5));
5227 d_printf("cli_echo_send failed\n");
5231 while (req->state < ASYNC_REQ_DONE) {
5232 event_loop_once(ev);
5235 status = cli_echo_recv(req);
5236 d_printf("cli_echo returned %s\n", nt_errstr(status));
5240 torture_close_connection(cli);
5241 return NT_STATUS_IS_OK(status);
5244 static bool run_uid_regression_test(int dummy)
5246 static struct cli_state *cli;
5248 bool correct = True;
5250 printf("starting uid regression test\n");
5252 if (!torture_open_connection(&cli, 0)) {
5256 cli_sockopt(cli, sockops);
5258 /* Ok - now save then logoff our current user. */
5259 old_vuid = cli->vuid;
5261 if (!cli_ulogoff(cli)) {
5262 d_printf("(%s) cli_ulogoff failed: %s\n",
5263 __location__, cli_errstr(cli));
5268 cli->vuid = old_vuid;
5270 /* Try an operation. */
5271 if (!cli_mkdir(cli, "\\uid_reg_test")) {
5272 /* We expect bad uid. */
5273 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
5274 NT_STATUS_NO_SUCH_USER)) {
5280 cli_rmdir(cli, "\\uid_reg_test");
5284 torture_close_connection(cli);
5289 static const char *illegal_chars = "*\\/?<>|\":";
5290 static char force_shortname_chars[] = " +,.[];=\177";
5292 static void shortname_del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
5294 struct cli_state *pcli = (struct cli_state *)state;
5296 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
5298 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5301 if (finfo->mode & aDIR) {
5302 if (!cli_rmdir(pcli, fname))
5303 printf("del_fn: failed to rmdir %s\n,", fname );
5305 if (!cli_unlink(pcli, fname))
5306 printf("del_fn: failed to unlink %s\n,", fname );
5315 static void shortname_list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
5317 struct sn_state *s = (struct sn_state *)state;
5321 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
5322 i, finfo->name, finfo->short_name);
5325 if (strchr(force_shortname_chars, i)) {
5326 if (!finfo->short_name[0]) {
5327 /* Shortname not created when it should be. */
5328 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
5329 __location__, finfo->name, i);
5332 } else if (finfo->short_name[0]){
5333 /* Shortname created when it should not be. */
5334 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
5335 __location__, finfo->short_name, finfo->name);
5340 static bool run_shortname_test(int dummy)
5342 static struct cli_state *cli;
5343 bool correct = True;
5348 printf("starting shortname test\n");
5350 if (!torture_open_connection(&cli, 0)) {
5354 cli_sockopt(cli, sockops);
5356 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
5357 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
5358 cli_rmdir(cli, "\\shortname");
5360 if (!cli_mkdir(cli, "\\shortname")) {
5361 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
5362 __location__, cli_errstr(cli));
5367 strlcpy(fname, "\\shortname\\", sizeof(fname));
5368 strlcat(fname, "test .txt", sizeof(fname));
5372 for (i = 32; i < 128; i++) {
5377 if (strchr(illegal_chars, i)) {
5381 fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
5382 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
5384 d_printf("(%s) cli_nt_create of %s failed: %s\n",
5385 __location__, fname, cli_errstr(cli));
5389 cli_close(cli, fnum);
5390 if (cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn, &s) != 1) {
5391 d_printf("(%s) failed to list %s: %s\n",
5392 __location__, fname, cli_errstr(cli));
5396 if (!cli_unlink(cli, fname)) {
5397 d_printf("(%s) failed to delete %s: %s\n",
5398 __location__, fname, cli_errstr(cli));
5411 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
5412 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
5413 cli_rmdir(cli, "\\shortname");
5414 torture_close_connection(cli);
5418 static bool run_local_substitute(int dummy)
5422 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
5423 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
5424 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
5425 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
5426 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
5427 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
5428 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
5429 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
5431 /* Different captialization rules in sub_basic... */
5433 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
5439 static bool run_local_gencache(int dummy)
5445 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
5446 d_printf("%s: gencache_set() failed\n", __location__);
5450 if (!gencache_get("foo", &val, &tm)) {
5451 d_printf("%s: gencache_get() failed\n", __location__);
5455 if (strcmp(val, "bar") != 0) {
5456 d_printf("%s: gencache_get() returned %s, expected %s\n",
5457 __location__, val, "bar");
5464 if (!gencache_del("foo")) {
5465 d_printf("%s: gencache_del() failed\n", __location__);
5468 if (gencache_del("foo")) {
5469 d_printf("%s: second gencache_del() succeeded\n",
5474 if (gencache_get("foo", &val, &tm)) {
5475 d_printf("%s: gencache_get() on deleted entry "
5476 "succeeded\n", __location__);
5480 blob = data_blob_string_const_null("bar");
5483 if (!gencache_set_data_blob("foo", &blob, tm)) {
5484 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
5488 data_blob_free(&blob);
5490 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
5491 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
5495 if (strcmp((const char *)blob.data, "bar") != 0) {
5496 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
5497 __location__, (const char *)blob.data, "bar");
5498 data_blob_free(&blob);
5502 data_blob_free(&blob);
5504 if (!gencache_del("foo")) {
5505 d_printf("%s: gencache_del() failed\n", __location__);
5508 if (gencache_del("foo")) {
5509 d_printf("%s: second gencache_del() succeeded\n",
5514 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
5515 d_printf("%s: gencache_get_data_blob() on deleted entry "
5516 "succeeded\n", __location__);
5523 static bool rbt_testval(struct db_context *db, const char *key,
5526 struct db_record *rec;
5527 TDB_DATA data = string_tdb_data(value);
5531 rec = db->fetch_locked(db, db, string_tdb_data(key));
5533 d_fprintf(stderr, "fetch_locked failed\n");
5536 status = rec->store(rec, data, 0);
5537 if (!NT_STATUS_IS_OK(status)) {
5538 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
5543 rec = db->fetch_locked(db, db, string_tdb_data(key));
5545 d_fprintf(stderr, "second fetch_locked failed\n");
5548 if ((rec->value.dsize != data.dsize)
5549 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
5550 d_fprintf(stderr, "Got wrong data back\n");
5560 static bool run_local_rbtree(int dummy)
5562 struct db_context *db;
5566 db = db_open_rbt(NULL);
5569 d_fprintf(stderr, "db_open_rbt failed\n");
5573 for (i=0; i<1000; i++) {
5576 if (asprintf(&key, "key%ld", random()) == -1) {
5579 if (asprintf(&value, "value%ld", random()) == -1) {
5584 if (!rbt_testval(db, key, value)) {
5591 if (asprintf(&value, "value%ld", random()) == -1) {
5596 if (!rbt_testval(db, key, value)) {
5613 static bool test_stream_name(const char *fname, const char *expected_base,
5614 const char *expected_stream,
5615 NTSTATUS expected_status)
5619 char *stream = NULL;
5621 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
5622 if (!NT_STATUS_EQUAL(status, expected_status)) {
5626 if (!NT_STATUS_IS_OK(status)) {
5630 if (base == NULL) goto error;
5632 if (strcmp(expected_base, base) != 0) goto error;
5634 if ((expected_stream != NULL) && (stream == NULL)) goto error;
5635 if ((expected_stream == NULL) && (stream != NULL)) goto error;
5637 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
5641 TALLOC_FREE(stream);
5645 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
5646 fname, expected_base ? expected_base : "<NULL>",
5647 expected_stream ? expected_stream : "<NULL>",
5648 nt_errstr(expected_status));
5649 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
5650 base ? base : "<NULL>", stream ? stream : "<NULL>",
5653 TALLOC_FREE(stream);
5657 static bool run_local_stream_name(int dummy)
5661 ret &= test_stream_name(
5662 "bla", "bla", NULL, NT_STATUS_OK);
5663 ret &= test_stream_name(
5664 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
5665 ret &= test_stream_name(
5666 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5667 ret &= test_stream_name(
5668 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
5669 ret &= test_stream_name(
5670 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
5671 ret &= test_stream_name(
5672 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
5673 ret &= test_stream_name(
5674 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
5675 ret &= test_stream_name(
5676 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
5681 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
5683 if (a.length != b.length) {
5684 printf("a.length=%d != b.length=%d\n",
5685 (int)a.length, (int)b.length);
5688 if (memcmp(a.data, b.data, a.length) != 0) {
5689 printf("a.data and b.data differ\n");
5695 static bool run_local_memcache(int dummy)
5697 struct memcache *cache;
5699 DATA_BLOB d1, d2, d3;
5700 DATA_BLOB v1, v2, v3;
5702 TALLOC_CTX *mem_ctx;
5704 size_t size1, size2;
5707 cache = memcache_init(NULL, 100);
5709 if (cache == NULL) {
5710 printf("memcache_init failed\n");
5714 d1 = data_blob_const("d1", 2);
5715 d2 = data_blob_const("d2", 2);
5716 d3 = data_blob_const("d3", 2);
5718 k1 = data_blob_const("d1", 2);
5719 k2 = data_blob_const("d2", 2);
5721 memcache_add(cache, STAT_CACHE, k1, d1);
5722 memcache_add(cache, GETWD_CACHE, k2, d2);
5724 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
5725 printf("could not find k1\n");
5728 if (!data_blob_equal(d1, v1)) {
5732 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5733 printf("could not find k2\n");
5736 if (!data_blob_equal(d2, v2)) {
5740 memcache_add(cache, STAT_CACHE, k1, d3);
5742 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
5743 printf("could not find replaced k1\n");
5746 if (!data_blob_equal(d3, v3)) {
5750 memcache_add(cache, GETWD_CACHE, k1, d1);
5752 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
5753 printf("Did find k2, should have been purged\n");
5759 cache = memcache_init(NULL, 0);
5761 mem_ctx = talloc_init("foo");
5763 str1 = talloc_strdup(mem_ctx, "string1");
5764 str2 = talloc_strdup(mem_ctx, "string2");
5766 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5767 data_blob_string_const("torture"), &str1);
5768 size1 = talloc_total_size(cache);
5770 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
5771 data_blob_string_const("torture"), &str2);
5772 size2 = talloc_total_size(cache);
5774 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
5776 if (size2 > size1) {
5777 printf("memcache leaks memory!\n");
5787 static void wbclient_done(struct tevent_req *req)
5790 struct winbindd_response *wb_resp;
5791 int *i = (int *)tevent_req_callback_data_void(req);
5793 wbc_err = wb_trans_recv(req, req, &wb_resp);
5796 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
5799 static bool run_local_wbclient(int dummy)
5801 struct event_context *ev;
5802 struct wb_context **wb_ctx;
5803 struct winbindd_request wb_req;
5804 bool result = false;
5807 BlockSignals(True, SIGPIPE);
5809 ev = event_context_init(talloc_tos());
5814 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
5815 if (wb_ctx == NULL) {
5819 ZERO_STRUCT(wb_req);
5820 wb_req.cmd = WINBINDD_PING;
5822 for (i=0; i<torture_numops; i++) {
5823 wb_ctx[i] = wb_context_init(ev);
5824 if (wb_ctx[i] == NULL) {
5827 for (j=0; j<5; j++) {
5828 struct tevent_req *req;
5829 req = wb_trans_send(ev, ev, wb_ctx[i],
5830 (j % 2) == 0, &wb_req);
5834 tevent_req_set_callback(req, wbclient_done, &i);
5840 while (i < 5 * torture_numops) {
5841 event_loop_once(ev);
5850 static bool dbtrans_inc(struct db_context *db)
5852 struct db_record *rec;
5857 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
5859 printf(__location__ "fetch_lock failed\n");
5863 if (rec->value.dsize != sizeof(uint32_t)) {
5864 printf(__location__ "value.dsize = %d\n",
5865 (int)rec->value.dsize);
5869 val = (uint32_t *)rec->value.dptr;
5872 status = rec->store(rec, make_tdb_data((uint8_t *)val,
5875 if (!NT_STATUS_IS_OK(status)) {
5876 printf(__location__ "store failed: %s\n",
5887 static bool run_local_dbtrans(int dummy)
5889 struct db_context *db;
5890 struct db_record *rec;
5895 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
5896 O_RDWR|O_CREAT, 0600);
5898 printf("Could not open transtest.db\n");
5902 res = db->transaction_start(db);
5904 printf(__location__ "transaction_start failed\n");
5908 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
5910 printf(__location__ "fetch_lock failed\n");
5914 if (rec->value.dptr == NULL) {
5916 status = rec->store(
5917 rec, make_tdb_data((uint8_t *)&initial,
5920 if (!NT_STATUS_IS_OK(status)) {
5921 printf(__location__ "store returned %s\n",
5929 res = db->transaction_commit(db);
5931 printf(__location__ "transaction_commit failed\n");
5939 res = db->transaction_start(db);
5941 printf(__location__ "transaction_start failed\n");
5945 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
5946 printf(__location__ "dbwrap_fetch_uint32 failed\n");
5950 for (i=0; i<10; i++) {
5951 if (!dbtrans_inc(db)) {
5956 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
5957 printf(__location__ "dbwrap_fetch_uint32 failed\n");
5961 if (val2 != val + 10) {
5962 printf(__location__ "val=%d, val2=%d\n",
5963 (int)val, (int)val2);
5967 printf("val2=%d\r", val2);
5969 res = db->transaction_commit(db);
5971 printf(__location__ "transaction_commit failed\n");
5980 static double create_procs(bool (*fn)(int), bool *result)
5983 volatile pid_t *child_status;
5984 volatile bool *child_status_out;
5990 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
5991 if (!child_status) {
5992 printf("Failed to setup shared memory\n");
5996 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
5997 if (!child_status_out) {
5998 printf("Failed to setup result status shared memory\n");
6002 for (i = 0; i < nprocs; i++) {
6003 child_status[i] = 0;
6004 child_status_out[i] = True;
6009 for (i=0;i<nprocs;i++) {
6012 pid_t mypid = getpid();
6013 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
6015 slprintf(myname,sizeof(myname),"CLIENT%d", i);
6018 if (torture_open_connection(¤t_cli, i)) break;
6020 printf("pid %d failed to start\n", (int)getpid());
6026 child_status[i] = getpid();
6028 while (child_status[i] && end_timer() < 5) smb_msleep(2);
6030 child_status_out[i] = fn(i);
6037 for (i=0;i<nprocs;i++) {
6038 if (child_status[i]) synccount++;
6040 if (synccount == nprocs) break;
6042 } while (end_timer() < 30);
6044 if (synccount != nprocs) {
6045 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
6050 /* start the client load */
6053 for (i=0;i<nprocs;i++) {
6054 child_status[i] = 0;
6057 printf("%d clients started\n", nprocs);
6059 for (i=0;i<nprocs;i++) {
6060 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
6065 for (i=0;i<nprocs;i++) {
6066 if (!child_status_out[i]) {
6073 #define FLAG_MULTIPROC 1
6080 {"FDPASS", run_fdpasstest, 0},
6081 {"LOCK1", run_locktest1, 0},
6082 {"LOCK2", run_locktest2, 0},
6083 {"LOCK3", run_locktest3, 0},
6084 {"LOCK4", run_locktest4, 0},
6085 {"LOCK5", run_locktest5, 0},
6086 {"LOCK6", run_locktest6, 0},
6087 {"LOCK7", run_locktest7, 0},
6088 {"UNLINK", run_unlinktest, 0},
6089 {"BROWSE", run_browsetest, 0},
6090 {"ATTR", run_attrtest, 0},
6091 {"TRANS2", run_trans2test, 0},
6092 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
6093 {"TORTURE",run_torture, FLAG_MULTIPROC},
6094 {"RANDOMIPC", run_randomipc, 0},
6095 {"NEGNOWAIT", run_negprot_nowait, 0},
6096 {"NBENCH", run_nbench, 0},
6097 {"OPLOCK1", run_oplock1, 0},
6098 {"OPLOCK2", run_oplock2, 0},
6099 {"OPLOCK3", run_oplock3, 0},
6100 {"DIR", run_dirtest, 0},
6101 {"DIR1", run_dirtest1, 0},
6102 {"DENY1", torture_denytest1, 0},
6103 {"DENY2", torture_denytest2, 0},
6104 {"TCON", run_tcon_test, 0},
6105 {"TCONDEV", run_tcon_devtype_test, 0},
6106 {"RW1", run_readwritetest, 0},
6107 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
6108 {"RW3", run_readwritelarge, 0},
6109 {"OPEN", run_opentest, 0},
6110 {"POSIX", run_simple_posix_open_test, 0},
6111 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
6112 { "SHORTNAME-TEST", run_shortname_test, 0},
6113 { "ADDRCHANGE", run_addrchange, 0},
6115 {"OPENATTR", run_openattrtest, 0},
6117 {"XCOPY", run_xcopy, 0},
6118 {"RENAME", run_rename, 0},
6119 {"DELETE", run_deletetest, 0},
6120 {"PROPERTIES", run_properties, 0},
6121 {"MANGLE", torture_mangle, 0},
6122 {"W2K", run_w2ktest, 0},
6123 {"TRANS2SCAN", torture_trans2_scan, 0},
6124 {"NTTRANSSCAN", torture_nttrans_scan, 0},
6125 {"UTABLE", torture_utable, 0},
6126 {"CASETABLE", torture_casetable, 0},
6127 {"ERRMAPEXTRACT", run_error_map_extract, 0},
6128 {"PIPE_NUMBER", run_pipe_number, 0},
6129 {"TCON2", run_tcon2_test, 0},
6130 {"IOCTL", torture_ioctl_test, 0},
6131 {"CHKPATH", torture_chkpath_test, 0},
6132 {"FDSESS", run_fdsesstest, 0},
6133 { "EATEST", run_eatest, 0},
6134 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
6135 { "CHAIN1", run_chain1, 0},
6136 { "WINDOWS-WRITE", run_windows_write, 0},
6137 { "CLI_ECHO", run_cli_echo, 0},
6138 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
6139 { "LOCAL-GENCACHE", run_local_gencache, 0},
6140 { "LOCAL-RBTREE", run_local_rbtree, 0},
6141 { "LOCAL-MEMCACHE", run_local_memcache, 0},
6142 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
6143 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
6144 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
6149 /****************************************************************************
6150 run a specified test or "ALL"
6151 ****************************************************************************/
6152 static bool run_test(const char *name)
6159 if (strequal(name,"ALL")) {
6160 for (i=0;torture_ops[i].name;i++) {
6161 run_test(torture_ops[i].name);
6166 for (i=0;torture_ops[i].name;i++) {
6167 fstr_sprintf(randomfname, "\\XX%x",
6168 (unsigned)random());
6170 if (strequal(name, torture_ops[i].name)) {
6172 printf("Running %s\n", name);
6173 if (torture_ops[i].flags & FLAG_MULTIPROC) {
6174 t = create_procs(torture_ops[i].fn, &result);
6177 printf("TEST %s FAILED!\n", name);
6182 if (!torture_ops[i].fn(0)) {
6184 printf("TEST %s FAILED!\n", name);
6188 printf("%s took %g secs\n\n", name, t);
6193 printf("Did not find a test named %s\n", name);
6201 static void usage(void)
6205 printf("WARNING samba4 test suite is much more complete nowadays.\n");
6206 printf("Please use samba4 torture.\n\n");
6208 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
6210 printf("\t-d debuglevel\n");
6211 printf("\t-U user%%pass\n");
6212 printf("\t-k use kerberos\n");
6213 printf("\t-N numprocs\n");
6214 printf("\t-n my_netbios_name\n");
6215 printf("\t-W workgroup\n");
6216 printf("\t-o num_operations\n");
6217 printf("\t-O socket_options\n");
6218 printf("\t-m maximum protocol\n");
6219 printf("\t-L use oplocks\n");
6220 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
6221 printf("\t-A showall\n");
6222 printf("\t-p port\n");
6223 printf("\t-s seed\n");
6224 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
6227 printf("tests are:");
6228 for (i=0;torture_ops[i].name;i++) {
6229 printf(" %s", torture_ops[i].name);
6233 printf("default test is ALL\n");
6238 /****************************************************************************
6240 ****************************************************************************/
6241 int main(int argc,char *argv[])
6247 bool correct = True;
6248 TALLOC_CTX *frame = talloc_stackframe();
6249 int seed = time(NULL);
6253 #ifdef HAVE_SETBUFFER
6254 setbuffer(stdout, NULL, 0);
6259 setup_logging("smbtorture", true);
6261 if (is_default_dyn_CONFIGFILE()) {
6262 if(getenv("SMB_CONF_PATH")) {
6263 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
6266 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
6273 for(p = argv[1]; *p; p++)
6277 if (strncmp(argv[1], "//", 2)) {
6281 fstrcpy(host, &argv[1][2]);
6282 p = strchr_m(&host[2],'/');
6287 fstrcpy(share, p+1);
6289 fstrcpy(myname, get_myname(talloc_tos()));
6291 fprintf(stderr, "Failed to get my hostname.\n");
6295 if (*username == 0 && getenv("LOGNAME")) {
6296 fstrcpy(username,getenv("LOGNAME"));
6302 fstrcpy(workgroup, lp_workgroup());
6304 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
6307 port_to_use = atoi(optarg);
6310 seed = atoi(optarg);
6313 fstrcpy(workgroup,optarg);
6316 max_protocol = interpret_protocol(optarg, max_protocol);
6319 nprocs = atoi(optarg);
6322 torture_numops = atoi(optarg);
6325 DEBUGLEVEL = atoi(optarg);
6334 torture_showall = True;
6337 fstrcpy(myname, optarg);
6340 client_txt = optarg;
6347 use_kerberos = True;
6349 d_printf("No kerberos support compiled in\n");
6355 fstrcpy(username,optarg);
6356 p = strchr_m(username,'%');
6359 fstrcpy(password, p+1);
6364 fstrcpy(multishare_conn_fname, optarg);
6365 use_multishare_conn = True;
6368 torture_blocksize = atoi(optarg);
6371 printf("Unknown option %c (%d)\n", (char)opt, opt);
6376 d_printf("using seed %d\n", seed);
6380 if(use_kerberos && !gotuser) gotpass = True;
6383 p = getpass("Password:");
6385 fstrcpy(password, p);
6390 printf("host=%s share=%s user=%s myname=%s\n",
6391 host, share, username, myname);
6393 if (argc == optind) {
6394 correct = run_test("ALL");
6396 for (i=optind;i<argc;i++) {
6397 if (!run_test(argv[i])) {