2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
28 static fstring host, workgroup, share, password, username, myname;
29 static int max_protocol = PROTOCOL_NT1;
30 static const char *sockops="TCP_NODELAY";
32 static int port_to_use=0;
33 int torture_numops=100;
34 int torture_blocksize=1024*1024;
35 static int procnum; /* records process count number when forking */
36 static struct cli_state *current_cli;
37 static fstring randomfname;
38 static bool use_oplocks;
39 static bool use_level_II_oplocks;
40 static const char *client_txt = "client_oplocks.txt";
41 static bool use_kerberos;
42 static fstring multishare_conn_fname;
43 static bool use_multishare_conn = False;
44 static bool do_encrypt;
45 static const char *local_path = NULL;
47 bool torture_showall = False;
49 static double create_procs(bool (*fn)(int), bool *result);
52 /* return a pointer to a anonymous shared memory segment of size "size"
53 which will persist across fork() but will disappear when all processes
56 The memory is not zeroed
58 This function uses system5 shared memory. It takes advantage of a property
59 that the memory is not destroyed if it is attached when the id is removed
61 void *shm_setup(int size)
67 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
69 printf("can't get shared memory\n");
72 shm_unlink("private");
73 if (ftruncate(shmid, size) == -1) {
74 printf("can't set shared memory size\n");
77 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
78 if (ret == MAP_FAILED) {
79 printf("can't map shared memory\n");
83 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
85 printf("can't get shared memory\n");
88 ret = (void *)shmat(shmid, 0, 0);
89 if (!ret || ret == (void *)-1) {
90 printf("can't attach to shared memory\n");
93 /* the following releases the ipc, but note that this process
94 and all its children will still have access to the memory, its
95 just that the shmid is no longer valid for other shm calls. This
96 means we don't leave behind lots of shm segments after we exit
98 See Stevens "advanced programming in unix env" for details
100 shmctl(shmid, IPC_RMID, 0);
106 /********************************************************************
107 Ensure a connection is encrypted.
108 ********************************************************************/
110 static bool force_cli_encryption(struct cli_state *c,
111 const char *sharename)
114 uint32 caplow, caphigh;
117 if (!SERVER_HAS_UNIX_CIFS(c)) {
118 d_printf("Encryption required and "
119 "server that doesn't support "
120 "UNIX extensions - failing connect\n");
124 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
126 if (!NT_STATUS_IS_OK(status)) {
127 d_printf("Encryption required and "
128 "can't get UNIX CIFS extensions "
129 "version from server: %s\n", nt_errstr(status));
133 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
134 d_printf("Encryption required and "
135 "share %s doesn't support "
136 "encryption.\n", sharename);
140 if (c->use_kerberos) {
141 status = cli_gss_smb_encryption_start(c);
143 status = cli_raw_ntlm_smb_encryption_start(c,
149 if (!NT_STATUS_IS_OK(status)) {
150 d_printf("Encryption required and "
151 "setup failed with error %s.\n",
160 static struct cli_state *open_nbt_connection(void)
162 struct nmb_name called, calling;
163 struct sockaddr_storage ss;
167 make_nmb_name(&calling, myname, 0x0);
168 make_nmb_name(&called , host, 0x20);
172 if (!(c = cli_initialise())) {
173 printf("Failed initialize cli_struct to connect with %s\n", host);
177 c->port = port_to_use;
179 status = cli_connect(c, host, &ss);
180 if (!NT_STATUS_IS_OK(status)) {
181 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
185 c->use_kerberos = use_kerberos;
187 c->timeout = 120000; /* set a really long timeout (2 minutes) */
188 if (use_oplocks) c->use_oplocks = True;
189 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
191 if (!cli_session_request(c, &calling, &called)) {
193 * Well, that failed, try *SMBSERVER ...
194 * However, we must reconnect as well ...
196 status = cli_connect(c, host, &ss);
197 if (!NT_STATUS_IS_OK(status)) {
198 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
202 make_nmb_name(&called, "*SMBSERVER", 0x20);
203 if (!cli_session_request(c, &calling, &called)) {
204 printf("%s rejected the session\n",host);
205 printf("We tried with a called name of %s & %s\n",
215 /* Insert a NULL at the first separator of the given path and return a pointer
216 * to the remainder of the string.
219 terminate_path_at_separator(char * path)
227 if ((p = strchr_m(path, '/'))) {
232 if ((p = strchr_m(path, '\\'))) {
242 parse a //server/share type UNC name
244 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
245 char **hostname, char **sharename)
249 *hostname = *sharename = NULL;
251 if (strncmp(unc_name, "\\\\", 2) &&
252 strncmp(unc_name, "//", 2)) {
256 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
257 p = terminate_path_at_separator(*hostname);
260 *sharename = talloc_strdup(mem_ctx, p);
261 terminate_path_at_separator(*sharename);
264 if (*hostname && *sharename) {
268 TALLOC_FREE(*hostname);
269 TALLOC_FREE(*sharename);
273 static bool torture_open_connection_share(struct cli_state **c,
274 const char *hostname,
275 const char *sharename)
282 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
284 flags |= CLI_FULL_CONNECTION_OPLOCKS;
285 if (use_level_II_oplocks)
286 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
288 status = cli_full_connection(c, myname,
289 hostname, NULL, port_to_use,
292 password, flags, Undefined, &retry);
293 if (!NT_STATUS_IS_OK(status)) {
294 printf("failed to open share connection: //%s/%s port:%d - %s\n",
295 hostname, sharename, port_to_use, nt_errstr(status));
299 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
302 return force_cli_encryption(*c,
308 bool torture_open_connection(struct cli_state **c, int conn_index)
310 char **unc_list = NULL;
311 int num_unc_names = 0;
314 if (use_multishare_conn==True) {
316 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
317 if (!unc_list || num_unc_names <= 0) {
318 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
322 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
324 printf("Failed to parse UNC name %s\n",
325 unc_list[conn_index % num_unc_names]);
326 TALLOC_FREE(unc_list);
330 result = torture_open_connection_share(c, h, s);
332 /* h, s were copied earlier */
333 TALLOC_FREE(unc_list);
337 return torture_open_connection_share(c, host, share);
340 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
342 uint16 old_vuid = cli->vuid;
343 fstring old_user_name;
344 size_t passlen = strlen(password);
348 fstrcpy(old_user_name, cli->user_name);
350 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
354 *new_vuid = cli->vuid;
355 cli->vuid = old_vuid;
356 status = cli_set_username(cli, old_user_name);
357 if (!NT_STATUS_IS_OK(status)) {
364 bool torture_close_connection(struct cli_state *c)
368 printf("tdis failed (%s)\n", cli_errstr(c));
378 /* check if the server produced the expected error code */
379 static bool check_error(int line, struct cli_state *c,
380 uint8 eclass, uint32 ecode, NTSTATUS nterr)
382 if (cli_is_dos_error(c)) {
386 /* Check DOS error */
388 cli_dos_error(c, &cclass, &num);
390 if (eclass != cclass || ecode != num) {
391 printf("unexpected error code class=%d code=%d\n",
392 (int)cclass, (int)num);
393 printf(" expected %d/%d %s (line=%d)\n",
394 (int)eclass, (int)ecode, nt_errstr(nterr), line);
403 status = cli_nt_error(c);
405 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
406 printf("unexpected error code %s\n", nt_errstr(status));
407 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
416 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
418 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
419 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
425 static bool rw_torture(struct cli_state *c)
427 const char *lockfname = "\\torture.lck";
431 pid_t pid2, pid = getpid();
437 memset(buf, '\0', sizeof(buf));
439 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
441 if (!NT_STATUS_IS_OK(status)) {
442 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
444 if (!NT_STATUS_IS_OK(status)) {
445 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
449 for (i=0;i<torture_numops;i++) {
450 unsigned n = (unsigned)sys_random()%10;
452 printf("%d\r", i); fflush(stdout);
454 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
456 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
460 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
461 printf("open failed (%s)\n", cli_errstr(c));
466 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
467 printf("write failed (%s)\n", cli_errstr(c));
472 if (cli_write(c, fnum, 0, (char *)buf,
473 sizeof(pid)+(j*sizeof(buf)),
474 sizeof(buf)) != sizeof(buf)) {
475 printf("write failed (%s)\n", cli_errstr(c));
482 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
483 printf("read failed (%s)\n", cli_errstr(c));
488 printf("data corruption!\n");
492 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
493 printf("close failed (%s)\n", cli_errstr(c));
497 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
498 printf("unlink failed (%s)\n", cli_errstr(c));
502 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
503 printf("unlock failed (%s)\n", cli_errstr(c));
509 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
516 static bool run_torture(int dummy)
518 struct cli_state *cli;
523 cli_sockopt(cli, sockops);
525 ret = rw_torture(cli);
527 if (!torture_close_connection(cli)) {
534 static bool rw_torture3(struct cli_state *c, char *lockfname)
536 uint16_t fnum = (uint16_t)-1;
541 unsigned countprev = 0;
547 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
549 SIVAL(buf, i, sys_random());
554 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
555 DENY_NONE, &fnum))) {
556 printf("first open read/write of %s failed (%s)\n",
557 lockfname, cli_errstr(c));
563 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
565 status = cli_open(c, lockfname, O_RDONLY,
567 if (!NT_STATUS_IS_OK(status)) {
572 if (!NT_STATUS_IS_OK(status)) {
573 printf("second open read-only of %s failed (%s)\n",
574 lockfname, cli_errstr(c));
580 for (count = 0; count < sizeof(buf); count += sent)
582 if (count >= countprev) {
583 printf("%d %8d\r", i, count);
586 countprev += (sizeof(buf) / 20);
591 sent = ((unsigned)sys_random()%(20))+ 1;
592 if (sent > sizeof(buf) - count)
594 sent = sizeof(buf) - count;
597 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
598 printf("write failed (%s)\n", cli_errstr(c));
604 sent = cli_read(c, fnum, buf_rd+count, count,
608 printf("read failed offset:%d size:%ld (%s)\n",
609 count, (unsigned long)sizeof(buf)-count,
616 if (memcmp(buf_rd+count, buf+count, sent) != 0)
618 printf("read/write compare failed\n");
619 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
628 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
629 printf("close failed (%s)\n", cli_errstr(c));
636 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
638 const char *lockfname = "\\torture2.lck";
647 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
648 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
651 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
652 DENY_NONE, &fnum1))) {
653 printf("first open read/write of %s failed (%s)\n",
654 lockfname, cli_errstr(c1));
657 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
658 DENY_NONE, &fnum2))) {
659 printf("second open read-only of %s failed (%s)\n",
660 lockfname, cli_errstr(c2));
661 cli_close(c1, fnum1);
665 for (i=0;i<torture_numops;i++)
667 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
669 printf("%d\r", i); fflush(stdout);
672 generate_random_buffer((unsigned char *)buf, buf_size);
674 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
675 printf("write failed (%s)\n", cli_errstr(c1));
680 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
681 printf("read failed (%s)\n", cli_errstr(c2));
682 printf("read %d, expected %ld\n", (int)bytes_read,
683 (unsigned long)buf_size);
688 if (memcmp(buf_rd, buf, buf_size) != 0)
690 printf("read/write compare failed\n");
696 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
697 printf("close failed (%s)\n", cli_errstr(c2));
700 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
701 printf("close failed (%s)\n", cli_errstr(c1));
705 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
706 printf("unlink failed (%s)\n", cli_errstr(c1));
713 static bool run_readwritetest(int dummy)
715 struct cli_state *cli1, *cli2;
716 bool test1, test2 = False;
718 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
721 cli_sockopt(cli1, sockops);
722 cli_sockopt(cli2, sockops);
724 printf("starting readwritetest\n");
726 test1 = rw_torture2(cli1, cli2);
727 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
730 test2 = rw_torture2(cli1, cli1);
731 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
734 if (!torture_close_connection(cli1)) {
738 if (!torture_close_connection(cli2)) {
742 return (test1 && test2);
745 static bool run_readwritemulti(int dummy)
747 struct cli_state *cli;
752 cli_sockopt(cli, sockops);
754 printf("run_readwritemulti: fname %s\n", randomfname);
755 test = rw_torture3(cli, randomfname);
757 if (!torture_close_connection(cli)) {
764 static bool run_readwritelarge(int dummy)
766 static struct cli_state *cli1;
768 const char *lockfname = "\\large.dat";
773 if (!torture_open_connection(&cli1, 0)) {
776 cli_sockopt(cli1, sockops);
777 memset(buf,'\0',sizeof(buf));
779 cli1->max_xmit = 128*1024;
781 printf("starting readwritelarge\n");
783 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
785 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
786 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
790 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
792 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
793 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
797 if (fsize == sizeof(buf))
798 printf("readwritelarge test 1 succeeded (size = %lx)\n",
799 (unsigned long)fsize);
801 printf("readwritelarge test 1 failed (size = %lx)\n",
802 (unsigned long)fsize);
806 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
807 printf("close failed (%s)\n", cli_errstr(cli1));
811 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
812 printf("unlink failed (%s)\n", cli_errstr(cli1));
816 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
817 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
821 cli1->max_xmit = 4*1024;
823 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
825 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
826 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
830 if (fsize == sizeof(buf))
831 printf("readwritelarge test 2 succeeded (size = %lx)\n",
832 (unsigned long)fsize);
834 printf("readwritelarge test 2 failed (size = %lx)\n",
835 (unsigned long)fsize);
840 /* ToDo - set allocation. JRA */
841 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
842 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
845 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
846 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
850 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
853 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
854 printf("close failed (%s)\n", cli_errstr(cli1));
858 if (!torture_close_connection(cli1)) {
867 #define ival(s) strtol(s, NULL, 0)
869 /* run a test that simulates an approximate netbench client load */
870 static bool run_netbench(int client)
872 struct cli_state *cli;
877 const char *params[20];
884 cli_sockopt(cli, sockops);
888 slprintf(cname,sizeof(cname)-1, "client%d", client);
890 f = fopen(client_txt, "r");
897 while (fgets(line, sizeof(line)-1, f)) {
901 line[strlen(line)-1] = 0;
903 /* printf("[%d] %s\n", line_count, line); */
905 all_string_sub(line,"client1", cname, sizeof(line));
907 /* parse the command parameters */
908 params[0] = strtok_r(line, " ", &saveptr);
910 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
916 if (!strncmp(params[0],"SMB", 3)) {
917 printf("ERROR: You are using a dbench 1 load file\n");
921 if (!strcmp(params[0],"NTCreateX")) {
922 nb_createx(params[1], ival(params[2]), ival(params[3]),
924 } else if (!strcmp(params[0],"Close")) {
925 nb_close(ival(params[1]));
926 } else if (!strcmp(params[0],"Rename")) {
927 nb_rename(params[1], params[2]);
928 } else if (!strcmp(params[0],"Unlink")) {
929 nb_unlink(params[1]);
930 } else if (!strcmp(params[0],"Deltree")) {
931 nb_deltree(params[1]);
932 } else if (!strcmp(params[0],"Rmdir")) {
934 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
935 nb_qpathinfo(params[1]);
936 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
937 nb_qfileinfo(ival(params[1]));
938 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
939 nb_qfsinfo(ival(params[1]));
940 } else if (!strcmp(params[0],"FIND_FIRST")) {
941 nb_findfirst(params[1]);
942 } else if (!strcmp(params[0],"WriteX")) {
943 nb_writex(ival(params[1]),
944 ival(params[2]), ival(params[3]), ival(params[4]));
945 } else if (!strcmp(params[0],"ReadX")) {
946 nb_readx(ival(params[1]),
947 ival(params[2]), ival(params[3]), ival(params[4]));
948 } else if (!strcmp(params[0],"Flush")) {
949 nb_flush(ival(params[1]));
951 printf("Unknown operation %s\n", params[0]);
959 if (!torture_close_connection(cli)) {
967 /* run a test that simulates an approximate netbench client load */
968 static bool run_nbench(int dummy)
977 signal(SIGALRM, nb_alarm);
979 t = create_procs(run_netbench, &correct);
982 printf("\nThroughput %g MB/sec\n",
983 1.0e-6 * nbio_total() / t);
989 This test checks for two things:
991 1) correct support for retaining locks over a close (ie. the server
992 must not use posix semantics)
993 2) support for lock timeouts
995 static bool run_locktest1(int dummy)
997 struct cli_state *cli1, *cli2;
998 const char *fname = "\\lockt1.lck";
999 uint16_t fnum1, fnum2, fnum3;
1001 unsigned lock_timeout;
1003 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1006 cli_sockopt(cli1, sockops);
1007 cli_sockopt(cli2, sockops);
1009 printf("starting locktest1\n");
1011 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1013 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1014 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1017 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1018 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1021 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1022 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1026 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1027 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1032 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1033 printf("lock2 succeeded! This is a locking bug\n");
1036 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1037 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1041 lock_timeout = (1 + (random() % 20));
1042 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1044 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1045 printf("lock3 succeeded! This is a locking bug\n");
1048 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1049 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1053 if (ABS(t2 - t1) < lock_timeout-1) {
1054 printf("error: This server appears not to support timed lock requests\n");
1057 printf("server slept for %u seconds for a %u second timeout\n",
1058 (unsigned int)(t2-t1), lock_timeout);
1060 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1061 printf("close1 failed (%s)\n", cli_errstr(cli1));
1065 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1066 printf("lock4 succeeded! This is a locking bug\n");
1069 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1070 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1073 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1074 printf("close2 failed (%s)\n", cli_errstr(cli1));
1078 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1079 printf("close3 failed (%s)\n", cli_errstr(cli2));
1083 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1084 printf("unlink failed (%s)\n", cli_errstr(cli1));
1089 if (!torture_close_connection(cli1)) {
1093 if (!torture_close_connection(cli2)) {
1097 printf("Passed locktest1\n");
1102 this checks to see if a secondary tconx can use open files from an
1105 static bool run_tcon_test(int dummy)
1107 static struct cli_state *cli;
1108 const char *fname = "\\tcontest.tmp";
1110 uint16 cnum1, cnum2, cnum3;
1111 uint16 vuid1, vuid2;
1116 memset(buf, '\0', sizeof(buf));
1118 if (!torture_open_connection(&cli, 0)) {
1121 cli_sockopt(cli, sockops);
1123 printf("starting tcontest\n");
1125 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1127 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1128 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1135 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1136 printf("initial write failed (%s)", cli_errstr(cli));
1140 status = cli_tcon_andx(cli, share, "?????",
1141 password, strlen(password)+1);
1142 if (!NT_STATUS_IS_OK(status)) {
1143 printf("%s refused 2nd tree connect (%s)\n", host,
1150 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1151 vuid2 = cli->vuid + 1;
1153 /* try a write with the wrong tid */
1156 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1157 printf("* server allows write with wrong TID\n");
1160 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1164 /* try a write with an invalid tid */
1167 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1168 printf("* server allows write with invalid TID\n");
1171 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1174 /* try a write with an invalid vuid */
1178 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1179 printf("* server allows write with invalid VUID\n");
1182 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1188 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1189 printf("close failed (%s)\n", cli_errstr(cli));
1195 if (!cli_tdis(cli)) {
1196 printf("secondary tdis failed (%s)\n", cli_errstr(cli));
1202 if (!torture_close_connection(cli)) {
1211 checks for old style tcon support
1213 static bool run_tcon2_test(int dummy)
1215 static struct cli_state *cli;
1216 uint16 cnum, max_xmit;
1220 if (!torture_open_connection(&cli, 0)) {
1223 cli_sockopt(cli, sockops);
1225 printf("starting tcon2 test\n");
1227 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1231 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1233 if (!NT_STATUS_IS_OK(status)) {
1234 printf("tcon2 failed : %s\n", cli_errstr(cli));
1236 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1237 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1240 if (!torture_close_connection(cli)) {
1244 printf("Passed tcon2 test\n");
1248 static bool tcon_devtest(struct cli_state *cli,
1249 const char *myshare, const char *devtype,
1250 const char *return_devtype,
1251 NTSTATUS expected_error)
1256 status = cli_tcon_andx(cli, myshare, devtype,
1257 password, strlen(password)+1);
1259 if (NT_STATUS_IS_OK(expected_error)) {
1260 if (NT_STATUS_IS_OK(status)) {
1261 if (strcmp(cli->dev, return_devtype) == 0) {
1264 printf("tconX to share %s with type %s "
1265 "succeeded but returned the wrong "
1266 "device type (got [%s] but should have got [%s])\n",
1267 myshare, devtype, cli->dev, return_devtype);
1271 printf("tconX to share %s with type %s "
1272 "should have succeeded but failed\n",
1278 if (NT_STATUS_IS_OK(status)) {
1279 printf("tconx to share %s with type %s "
1280 "should have failed but succeeded\n",
1284 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1288 printf("Returned unexpected error\n");
1297 checks for correct tconX support
1299 static bool run_tcon_devtype_test(int dummy)
1301 static struct cli_state *cli1 = NULL;
1307 status = cli_full_connection(&cli1, myname,
1308 host, NULL, port_to_use,
1310 username, workgroup,
1311 password, flags, Undefined, &retry);
1313 if (!NT_STATUS_IS_OK(status)) {
1314 printf("could not open connection\n");
1318 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1321 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1324 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1327 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1330 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1333 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1336 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1339 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1342 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1345 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1351 printf("Passed tcondevtest\n");
1358 This test checks that
1360 1) the server supports multiple locking contexts on the one SMB
1361 connection, distinguished by PID.
1363 2) the server correctly fails overlapping locks made by the same PID (this
1364 goes against POSIX behaviour, which is why it is tricky to implement)
1366 3) the server denies unlock requests by an incorrect client PID
1368 static bool run_locktest2(int dummy)
1370 static struct cli_state *cli;
1371 const char *fname = "\\lockt2.lck";
1372 uint16_t fnum1, fnum2, fnum3;
1373 bool correct = True;
1375 if (!torture_open_connection(&cli, 0)) {
1379 cli_sockopt(cli, sockops);
1381 printf("starting locktest2\n");
1383 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1387 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1388 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1392 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1393 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1399 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
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 (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1440 printf("unlock at 100 succeeded! This is a locking bug\n");
1444 if (NT_STATUS_IS_OK(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 (NT_STATUS_IS_OK(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 (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1472 printf("close1 failed (%s)\n", cli_errstr(cli));
1476 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1477 printf("close2 failed (%s)\n", cli_errstr(cli));
1481 if (!NT_STATUS_IS_OK(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 uint16_t fnum1, fnum2;
1508 bool correct = True;
1510 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1512 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1515 cli_sockopt(cli1, sockops);
1516 cli_sockopt(cli2, sockops);
1518 printf("starting locktest3\n");
1520 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1522 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1523 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1526 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1527 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1531 for (offset=i=0;i<torture_numops;i++) {
1533 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1534 printf("lock1 %d failed (%s)\n",
1540 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1541 printf("lock2 %d failed (%s)\n",
1548 for (offset=i=0;i<torture_numops;i++) {
1551 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1552 printf("error: lock1 %d succeeded!\n", i);
1556 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1557 printf("error: lock2 %d succeeded!\n", i);
1561 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1562 printf("error: lock3 %d succeeded!\n", i);
1566 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1567 printf("error: lock4 %d succeeded!\n", i);
1572 for (offset=i=0;i<torture_numops;i++) {
1575 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1576 printf("unlock1 %d failed (%s)\n",
1582 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1583 printf("unlock2 %d failed (%s)\n",
1590 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1591 printf("close1 failed (%s)\n", cli_errstr(cli1));
1595 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1596 printf("close2 failed (%s)\n", cli_errstr(cli2));
1600 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1601 printf("unlink failed (%s)\n", cli_errstr(cli1));
1605 if (!torture_close_connection(cli1)) {
1609 if (!torture_close_connection(cli2)) {
1613 printf("finished locktest3\n");
1618 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1619 printf("** "); correct = False; \
1623 looks at overlapping locks
1625 static bool run_locktest4(int dummy)
1627 static struct cli_state *cli1, *cli2;
1628 const char *fname = "\\lockt4.lck";
1629 uint16_t fnum1, fnum2, f;
1632 bool correct = True;
1634 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1638 cli_sockopt(cli1, sockops);
1639 cli_sockopt(cli2, sockops);
1641 printf("starting locktest4\n");
1643 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1645 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1646 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1648 memset(buf, 0, sizeof(buf));
1650 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1651 printf("Failed to create file\n");
1656 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1657 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1658 EXPECTED(ret, False);
1659 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1661 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1662 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1663 EXPECTED(ret, True);
1664 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1666 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1667 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1668 EXPECTED(ret, False);
1669 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1671 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1672 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1673 EXPECTED(ret, True);
1674 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1676 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1677 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1678 EXPECTED(ret, False);
1679 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1681 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1682 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1683 EXPECTED(ret, True);
1684 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1686 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1687 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1688 EXPECTED(ret, True);
1689 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1691 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1692 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1693 EXPECTED(ret, False);
1694 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1696 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1697 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1698 EXPECTED(ret, False);
1699 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1701 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1702 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1703 EXPECTED(ret, True);
1704 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1706 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1707 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1708 EXPECTED(ret, False);
1709 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1711 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1712 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1713 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1714 EXPECTED(ret, False);
1715 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1718 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1719 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1720 EXPECTED(ret, False);
1721 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1723 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1724 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1725 EXPECTED(ret, False);
1726 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1729 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1730 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1731 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1732 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1733 EXPECTED(ret, True);
1734 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1737 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1738 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1739 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1740 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1741 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1742 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1743 EXPECTED(ret, True);
1744 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1746 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1747 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1748 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1749 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1750 EXPECTED(ret, True);
1751 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1753 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1754 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1755 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1756 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1757 EXPECTED(ret, True);
1758 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1760 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1761 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1762 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1763 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1764 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1765 EXPECTED(ret, True);
1766 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1768 cli_close(cli1, fnum1);
1769 cli_close(cli2, fnum2);
1770 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1771 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1772 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1773 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1774 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1775 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1776 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1778 cli_close(cli1, fnum1);
1779 EXPECTED(ret, True);
1780 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1783 cli_close(cli1, fnum1);
1784 cli_close(cli2, fnum2);
1785 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1786 torture_close_connection(cli1);
1787 torture_close_connection(cli2);
1789 printf("finished locktest4\n");
1794 looks at lock upgrade/downgrade.
1796 static bool run_locktest5(int dummy)
1798 static struct cli_state *cli1, *cli2;
1799 const char *fname = "\\lockt5.lck";
1800 uint16_t fnum1, fnum2, fnum3;
1803 bool correct = True;
1805 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1809 cli_sockopt(cli1, sockops);
1810 cli_sockopt(cli2, sockops);
1812 printf("starting locktest5\n");
1814 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1816 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1817 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1818 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1820 memset(buf, 0, sizeof(buf));
1822 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1823 printf("Failed to create file\n");
1828 /* Check for NT bug... */
1829 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1830 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1831 cli_close(cli1, fnum1);
1832 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1833 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1834 EXPECTED(ret, True);
1835 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1836 cli_close(cli1, fnum1);
1837 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1838 cli_unlock(cli1, fnum3, 0, 1);
1840 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1841 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1842 EXPECTED(ret, True);
1843 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1845 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1846 EXPECTED(ret, False);
1848 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1850 /* Unlock the process 2 lock. */
1851 cli_unlock(cli2, fnum2, 0, 4);
1853 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1854 EXPECTED(ret, False);
1856 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1858 /* Unlock the process 1 fnum3 lock. */
1859 cli_unlock(cli1, fnum3, 0, 4);
1861 /* Stack 2 more locks here. */
1862 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1863 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1865 EXPECTED(ret, True);
1866 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1868 /* Unlock the first process lock, then check this was the WRITE lock that was
1871 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1872 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1874 EXPECTED(ret, True);
1875 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1877 /* Unlock the process 2 lock. */
1878 cli_unlock(cli2, fnum2, 0, 4);
1880 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1882 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1883 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1884 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1886 EXPECTED(ret, True);
1887 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1889 /* Ensure the next unlock fails. */
1890 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1891 EXPECTED(ret, False);
1892 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1894 /* Ensure connection 2 can get a write lock. */
1895 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1896 EXPECTED(ret, True);
1898 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1902 cli_close(cli1, fnum1);
1903 cli_close(cli2, fnum2);
1904 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1905 if (!torture_close_connection(cli1)) {
1908 if (!torture_close_connection(cli2)) {
1912 printf("finished locktest5\n");
1918 tries the unusual lockingX locktype bits
1920 static bool run_locktest6(int dummy)
1922 static struct cli_state *cli;
1923 const char *fname[1] = { "\\lock6.txt" };
1928 if (!torture_open_connection(&cli, 0)) {
1932 cli_sockopt(cli, sockops);
1934 printf("starting locktest6\n");
1937 printf("Testing %s\n", fname[i]);
1939 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1941 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1942 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1943 cli_close(cli, fnum);
1944 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1946 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1947 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1948 cli_close(cli, fnum);
1949 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1951 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1954 torture_close_connection(cli);
1956 printf("finished locktest6\n");
1960 static bool run_locktest7(int dummy)
1962 struct cli_state *cli1;
1963 const char *fname = "\\lockt7.lck";
1966 bool correct = False;
1968 if (!torture_open_connection(&cli1, 0)) {
1972 cli_sockopt(cli1, sockops);
1974 printf("starting locktest7\n");
1976 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1978 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1980 memset(buf, 0, sizeof(buf));
1982 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1983 printf("Failed to create file\n");
1987 cli_setpid(cli1, 1);
1989 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1990 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
1993 printf("pid1 successfully locked range 130:4 for READ\n");
1996 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
1997 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2000 printf("pid1 successfully read the range 130:4\n");
2003 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2004 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2005 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2006 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2010 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2014 cli_setpid(cli1, 2);
2016 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2017 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2019 printf("pid2 successfully read the range 130:4\n");
2022 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2023 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2024 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2025 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2029 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2033 cli_setpid(cli1, 1);
2034 cli_unlock(cli1, fnum1, 130, 4);
2036 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2037 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2040 printf("pid1 successfully locked range 130:4 for WRITE\n");
2043 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2044 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2047 printf("pid1 successfully read the range 130:4\n");
2050 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2051 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2054 printf("pid1 successfully wrote to the range 130:4\n");
2057 cli_setpid(cli1, 2);
2059 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2060 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2061 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2062 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2066 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2070 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2071 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2072 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2073 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2077 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2081 cli_unlock(cli1, fnum1, 130, 0);
2085 cli_close(cli1, fnum1);
2086 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2087 torture_close_connection(cli1);
2089 printf("finished locktest7\n");
2094 * This demonstrates a problem with our use of GPFS share modes: A file
2095 * descriptor sitting in the pending close queue holding a GPFS share mode
2096 * blocks opening a file another time. Happens with Word 2007 temp files.
2097 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2098 * open is denied with NT_STATUS_SHARING_VIOLATION.
2101 static bool run_locktest8(int dummy)
2103 struct cli_state *cli1;
2104 const char *fname = "\\lockt8.lck";
2105 uint16_t fnum1, fnum2;
2107 bool correct = False;
2110 if (!torture_open_connection(&cli1, 0)) {
2114 cli_sockopt(cli1, sockops);
2116 printf("starting locktest8\n");
2118 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2120 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2122 if (!NT_STATUS_IS_OK(status)) {
2123 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2127 memset(buf, 0, sizeof(buf));
2129 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2130 if (!NT_STATUS_IS_OK(status)) {
2131 d_fprintf(stderr, "cli_open second time returned %s\n",
2136 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2137 printf("Unable to apply read lock on range 1:1, error was "
2138 "%s\n", cli_errstr(cli1));
2142 status = cli_close(cli1, fnum1);
2143 if (!NT_STATUS_IS_OK(status)) {
2144 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2148 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2149 if (!NT_STATUS_IS_OK(status)) {
2150 d_fprintf(stderr, "cli_open third time returned %s\n",
2158 cli_close(cli1, fnum1);
2159 cli_close(cli1, fnum2);
2160 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2161 torture_close_connection(cli1);
2163 printf("finished locktest8\n");
2168 * This test is designed to be run in conjunction with
2169 * external NFS or POSIX locks taken in the filesystem.
2170 * It checks that the smbd server will block until the
2171 * lock is released and then acquire it. JRA.
2174 static bool got_alarm;
2175 static int alarm_fd;
2177 static void alarm_handler(int dummy)
2182 static void alarm_handler_parent(int dummy)
2187 static void do_local_lock(int read_fd, int write_fd)
2192 const char *local_pathname = NULL;
2195 local_pathname = talloc_asprintf(talloc_tos(),
2196 "%s/lockt9.lck", local_path);
2197 if (!local_pathname) {
2198 printf("child: alloc fail\n");
2202 unlink(local_pathname);
2203 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2205 printf("child: open of %s failed %s.\n",
2206 local_pathname, strerror(errno));
2210 /* Now take a fcntl lock. */
2211 lock.l_type = F_WRLCK;
2212 lock.l_whence = SEEK_SET;
2215 lock.l_pid = getpid();
2217 ret = fcntl(fd,F_SETLK,&lock);
2219 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2220 local_pathname, strerror(errno));
2223 printf("child: got lock 0:4 on file %s.\n",
2228 CatchSignal(SIGALRM, alarm_handler);
2230 /* Signal the parent. */
2231 if (write(write_fd, &c, 1) != 1) {
2232 printf("child: start signal fail %s.\n",
2239 /* Wait for the parent to be ready. */
2240 if (read(read_fd, &c, 1) != 1) {
2241 printf("child: reply signal fail %s.\n",
2249 printf("child: released lock 0:4 on file %s.\n",
2255 static bool run_locktest9(int dummy)
2257 struct cli_state *cli1;
2258 const char *fname = "\\lockt9.lck";
2260 bool correct = False;
2261 int pipe_in[2], pipe_out[2];
2265 struct timeval start;
2269 printf("starting locktest9\n");
2271 if (local_path == NULL) {
2272 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2276 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2281 if (child_pid == -1) {
2285 if (child_pid == 0) {
2287 do_local_lock(pipe_out[0], pipe_in[1]);
2297 ret = read(pipe_in[0], &c, 1);
2299 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2304 if (!torture_open_connection(&cli1, 0)) {
2308 cli_sockopt(cli1, sockops);
2310 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2312 if (!NT_STATUS_IS_OK(status)) {
2313 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2317 /* Ensure the child has the lock. */
2318 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2319 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2322 d_printf("Child has the lock.\n");
2325 /* Tell the child to wait 5 seconds then exit. */
2326 ret = write(pipe_out[1], &c, 1);
2328 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2333 /* Wait 20 seconds for the lock. */
2334 alarm_fd = cli1->fd;
2335 CatchSignal(SIGALRM, alarm_handler_parent);
2338 start = timeval_current();
2340 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2341 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2342 "%s\n", cli_errstr(cli1));
2347 seconds = timeval_elapsed(&start);
2349 printf("Parent got the lock after %.2f seconds.\n",
2352 status = cli_close(cli1, fnum);
2353 if (!NT_STATUS_IS_OK(status)) {
2354 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2361 cli_close(cli1, fnum);
2362 torture_close_connection(cli1);
2366 printf("finished locktest9\n");
2371 test whether fnums and tids open on one VC are available on another (a major
2374 static bool run_fdpasstest(int dummy)
2376 struct cli_state *cli1, *cli2;
2377 const char *fname = "\\fdpass.tst";
2381 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2384 cli_sockopt(cli1, sockops);
2385 cli_sockopt(cli2, sockops);
2387 printf("starting fdpasstest\n");
2389 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2391 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2392 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2396 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2397 printf("write failed (%s)\n", cli_errstr(cli1));
2401 cli2->vuid = cli1->vuid;
2402 cli2->cnum = cli1->cnum;
2403 cli2->pid = cli1->pid;
2405 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2406 printf("read succeeded! nasty security hole [%s]\n",
2411 cli_close(cli1, fnum1);
2412 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2414 torture_close_connection(cli1);
2415 torture_close_connection(cli2);
2417 printf("finished fdpasstest\n");
2421 static bool run_fdsesstest(int dummy)
2423 struct cli_state *cli;
2428 const char *fname = "\\fdsess.tst";
2429 const char *fname1 = "\\fdsess1.tst";
2435 if (!torture_open_connection(&cli, 0))
2437 cli_sockopt(cli, sockops);
2439 if (!torture_cli_session_setup2(cli, &new_vuid))
2442 saved_cnum = cli->cnum;
2443 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2445 new_cnum = cli->cnum;
2446 cli->cnum = saved_cnum;
2448 printf("starting fdsesstest\n");
2450 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2451 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2453 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2454 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2458 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2459 printf("write failed (%s)\n", cli_errstr(cli));
2463 saved_vuid = cli->vuid;
2464 cli->vuid = new_vuid;
2466 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2467 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2471 /* Try to open a file with different vuid, samba cnum. */
2472 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2473 printf("create with different vuid, same cnum succeeded.\n");
2474 cli_close(cli, fnum2);
2475 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2477 printf("create with different vuid, same cnum failed.\n");
2478 printf("This will cause problems with service clients.\n");
2482 cli->vuid = saved_vuid;
2484 /* Try with same vuid, different cnum. */
2485 cli->cnum = new_cnum;
2487 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2488 printf("read succeeded with different cnum![%s]\n",
2493 cli->cnum = saved_cnum;
2494 cli_close(cli, fnum1);
2495 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2497 torture_close_connection(cli);
2499 printf("finished fdsesstest\n");
2504 This test checks that
2506 1) the server does not allow an unlink on a file that is open
2508 static bool run_unlinktest(int dummy)
2510 struct cli_state *cli;
2511 const char *fname = "\\unlink.tst";
2513 bool correct = True;
2515 if (!torture_open_connection(&cli, 0)) {
2519 cli_sockopt(cli, sockops);
2521 printf("starting unlink test\n");
2523 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2527 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2528 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2532 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2533 printf("error: server allowed unlink on an open file\n");
2536 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2537 NT_STATUS_SHARING_VIOLATION);
2540 cli_close(cli, fnum);
2541 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2543 if (!torture_close_connection(cli)) {
2547 printf("unlink test finished\n");
2554 test how many open files this server supports on the one socket
2556 static bool run_maxfidtest(int dummy)
2558 struct cli_state *cli;
2559 const char *ftemplate = "\\maxfid.%d.%d";
2561 uint16_t fnums[0x11000];
2564 bool correct = True;
2569 printf("failed to connect\n");
2573 cli_sockopt(cli, sockops);
2575 for (i=0; i<0x11000; i++) {
2576 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2577 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2578 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2579 printf("open of %s failed (%s)\n",
2580 fname, cli_errstr(cli));
2581 printf("maximum fnum is %d\n", i);
2589 printf("cleaning up\n");
2591 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2592 cli_close(cli, fnums[i]);
2593 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2594 printf("unlink of %s failed (%s)\n",
2595 fname, cli_errstr(cli));
2602 printf("maxfid test finished\n");
2603 if (!torture_close_connection(cli)) {
2609 /* generate a random buffer */
2610 static void rand_buf(char *buf, int len)
2613 *buf = (char)sys_random();
2618 /* send smb negprot commands, not reading the response */
2619 static bool run_negprot_nowait(int dummy)
2622 static struct cli_state *cli;
2623 bool correct = True;
2625 printf("starting negprot nowait test\n");
2627 if (!(cli = open_nbt_connection())) {
2631 for (i=0;i<50000;i++) {
2632 cli_negprot_sendsync(cli);
2635 if (!torture_close_connection(cli)) {
2639 printf("finished negprot nowait test\n");
2645 /* send random IPC commands */
2646 static bool run_randomipc(int dummy)
2648 char *rparam = NULL;
2650 unsigned int rdrcnt,rprcnt;
2652 int api, param_len, i;
2653 struct cli_state *cli;
2654 bool correct = True;
2657 printf("starting random ipc test\n");
2659 if (!torture_open_connection(&cli, 0)) {
2663 for (i=0;i<count;i++) {
2664 api = sys_random() % 500;
2665 param_len = (sys_random() % 64);
2667 rand_buf(param, param_len);
2672 param, param_len, 8,
2673 NULL, 0, BUFFER_SIZE,
2677 printf("%d/%d\r", i,count);
2680 printf("%d/%d\n", i, count);
2682 if (!torture_close_connection(cli)) {
2686 printf("finished random ipc test\n");
2693 static void browse_callback(const char *sname, uint32 stype,
2694 const char *comment, void *state)
2696 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2702 This test checks the browse list code
2705 static bool run_browsetest(int dummy)
2707 static struct cli_state *cli;
2708 bool correct = True;
2710 printf("starting browse test\n");
2712 if (!torture_open_connection(&cli, 0)) {
2716 printf("domain list:\n");
2717 cli_NetServerEnum(cli, cli->server_domain,
2718 SV_TYPE_DOMAIN_ENUM,
2719 browse_callback, NULL);
2721 printf("machine list:\n");
2722 cli_NetServerEnum(cli, cli->server_domain,
2724 browse_callback, NULL);
2726 if (!torture_close_connection(cli)) {
2730 printf("browse test finished\n");
2738 This checks how the getatr calls works
2740 static bool run_attrtest(int dummy)
2742 struct cli_state *cli;
2745 const char *fname = "\\attrib123456789.tst";
2746 bool correct = True;
2748 printf("starting attrib test\n");
2750 if (!torture_open_connection(&cli, 0)) {
2754 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2755 cli_open(cli, fname,
2756 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2757 cli_close(cli, fnum);
2758 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2759 printf("getatr failed (%s)\n", cli_errstr(cli));
2763 if (abs(t - time(NULL)) > 60*60*24*10) {
2764 printf("ERROR: SMBgetatr bug. time is %s",
2770 t2 = t-60*60*24; /* 1 day ago */
2772 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2773 printf("setatr failed (%s)\n", cli_errstr(cli));
2777 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2778 printf("getatr failed (%s)\n", cli_errstr(cli));
2783 printf("ERROR: getatr/setatr bug. times are\n%s",
2785 printf("%s", ctime(&t2));
2789 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2791 if (!torture_close_connection(cli)) {
2795 printf("attrib test finished\n");
2802 This checks a couple of trans2 calls
2804 static bool run_trans2test(int dummy)
2806 struct cli_state *cli;
2809 time_t c_time, a_time, m_time;
2810 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2811 const char *fname = "\\trans2.tst";
2812 const char *dname = "\\trans2";
2813 const char *fname2 = "\\trans2\\trans2.tst";
2815 bool correct = True;
2819 printf("starting trans2 test\n");
2821 if (!torture_open_connection(&cli, 0)) {
2825 status = cli_get_fs_attr_info(cli, &fs_attr);
2826 if (!NT_STATUS_IS_OK(status)) {
2827 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2832 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2833 cli_open(cli, fname,
2834 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2835 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2836 &m_time_ts, NULL)) {
2837 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2841 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2842 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2846 if (strcmp(pname, fname)) {
2847 printf("qfilename gave different name? [%s] [%s]\n",
2852 cli_close(cli, fnum);
2856 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2857 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2858 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2859 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2862 cli_close(cli, fnum);
2864 if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
2865 printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
2868 if (c_time != m_time) {
2869 printf("create time=%s", ctime(&c_time));
2870 printf("modify time=%s", ctime(&m_time));
2871 printf("This system appears to have sticky create times\n");
2873 if (a_time % (60*60) == 0) {
2874 printf("access time=%s", ctime(&a_time));
2875 printf("This system appears to set a midnight access time\n");
2879 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2880 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2886 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2887 cli_open(cli, fname,
2888 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2889 cli_close(cli, fnum);
2890 if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2891 &m_time_ts, &size, NULL, NULL)) {
2892 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2895 if (w_time_ts.tv_sec < 60*60*24*2) {
2896 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2897 printf("This system appears to set a initial 0 write time\n");
2902 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2905 /* check if the server updates the directory modification time
2906 when creating a new file */
2907 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2908 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2912 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2913 &m_time_ts, &size, NULL, NULL)) {
2914 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2918 cli_open(cli, fname2,
2919 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2920 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2921 cli_close(cli, fnum);
2922 if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts,
2923 &m_time2_ts, &size, NULL, NULL)) {
2924 printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
2927 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2929 printf("This system does not update directory modification times\n");
2933 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2934 cli_rmdir(cli, dname);
2936 if (!torture_close_connection(cli)) {
2940 printf("trans2 test finished\n");
2946 This checks new W2K calls.
2949 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2953 bool correct = True;
2955 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2956 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2959 printf("qfileinfo: level %d, len = %u\n", level, len);
2960 dump_data(0, (uint8 *)buf, len);
2967 static bool run_w2ktest(int dummy)
2969 struct cli_state *cli;
2971 const char *fname = "\\w2ktest\\w2k.tst";
2973 bool correct = True;
2975 printf("starting w2k test\n");
2977 if (!torture_open_connection(&cli, 0)) {
2981 cli_open(cli, fname,
2982 O_RDWR | O_CREAT , DENY_NONE, &fnum);
2984 for (level = 1004; level < 1040; level++) {
2985 new_trans(cli, fnum, level);
2988 cli_close(cli, fnum);
2990 if (!torture_close_connection(cli)) {
2994 printf("w2k test finished\n");
3001 this is a harness for some oplock tests
3003 static bool run_oplock1(int dummy)
3005 struct cli_state *cli1;
3006 const char *fname = "\\lockt1.lck";
3008 bool correct = True;
3010 printf("starting oplock test 1\n");
3012 if (!torture_open_connection(&cli1, 0)) {
3016 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3018 cli_sockopt(cli1, sockops);
3020 cli1->use_oplocks = True;
3022 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3023 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3027 cli1->use_oplocks = False;
3029 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3030 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3032 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3033 printf("close2 failed (%s)\n", cli_errstr(cli1));
3037 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3038 printf("unlink failed (%s)\n", cli_errstr(cli1));
3042 if (!torture_close_connection(cli1)) {
3046 printf("finished oplock test 1\n");
3051 static bool run_oplock2(int dummy)
3053 struct cli_state *cli1, *cli2;
3054 const char *fname = "\\lockt2.lck";
3055 uint16_t fnum1, fnum2;
3056 int saved_use_oplocks = use_oplocks;
3058 bool correct = True;
3059 volatile bool *shared_correct;
3061 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3062 *shared_correct = True;
3064 use_level_II_oplocks = True;
3067 printf("starting oplock test 2\n");
3069 if (!torture_open_connection(&cli1, 0)) {
3070 use_level_II_oplocks = False;
3071 use_oplocks = saved_use_oplocks;
3075 cli1->use_oplocks = True;
3076 cli1->use_level_II_oplocks = True;
3078 if (!torture_open_connection(&cli2, 1)) {
3079 use_level_II_oplocks = False;
3080 use_oplocks = saved_use_oplocks;
3084 cli2->use_oplocks = True;
3085 cli2->use_level_II_oplocks = True;
3087 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3089 cli_sockopt(cli1, sockops);
3090 cli_sockopt(cli2, sockops);
3092 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3093 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3097 /* Don't need the globals any more. */
3098 use_level_II_oplocks = False;
3099 use_oplocks = saved_use_oplocks;
3103 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3104 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3105 *shared_correct = False;
3111 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3112 printf("close2 failed (%s)\n", cli_errstr(cli1));
3113 *shared_correct = False;
3121 /* Ensure cli1 processes the break. Empty file should always return 0
3124 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3125 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3129 /* Should now be at level II. */
3130 /* Test if sending a write locks causes a break to none. */
3132 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3133 printf("lock failed (%s)\n", cli_errstr(cli1));
3137 cli_unlock(cli1, fnum1, 0, 4);
3141 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3142 printf("lock failed (%s)\n", cli_errstr(cli1));
3146 cli_unlock(cli1, fnum1, 0, 4);
3150 cli_read(cli1, fnum1, buf, 0, 4);
3153 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3154 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3159 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3160 printf("close1 failed (%s)\n", cli_errstr(cli1));
3166 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3167 printf("unlink failed (%s)\n", cli_errstr(cli1));
3171 if (!torture_close_connection(cli1)) {
3175 if (!*shared_correct) {
3179 printf("finished oplock test 2\n");
3184 /* handler for oplock 3 tests */
3185 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3187 printf("got oplock break fnum=%d level=%d\n",
3189 return cli_oplock_ack(cli, fnum, level);
3192 static bool run_oplock3(int dummy)
3194 struct cli_state *cli;
3195 const char *fname = "\\oplockt3.dat";
3197 char buf[4] = "abcd";
3198 bool correct = True;
3199 volatile bool *shared_correct;
3201 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3202 *shared_correct = True;
3204 printf("starting oplock test 3\n");
3209 use_level_II_oplocks = True;
3210 if (!torture_open_connection(&cli, 0)) {
3211 *shared_correct = False;
3215 /* try to trigger a oplock break in parent */
3216 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3217 cli_write(cli, fnum, 0, buf, 0, 4);
3223 use_level_II_oplocks = True;
3224 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3227 cli_oplock_handler(cli, oplock3_handler);
3228 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3229 cli_write(cli, fnum, 0, buf, 0, 4);
3230 cli_close(cli, fnum);
3231 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3232 cli->timeout = 20000;
3233 cli_receive_smb(cli);
3234 printf("finished oplock test 3\n");
3236 return (correct && *shared_correct);
3238 /* What are we looking for here? What's sucess and what's FAILURE? */
3244 Test delete on close semantics.
3246 static bool run_deletetest(int dummy)
3248 struct cli_state *cli1 = NULL;
3249 struct cli_state *cli2 = NULL;
3250 const char *fname = "\\delete.file";
3251 uint16_t fnum1 = (uint16_t)-1;
3252 uint16_t fnum2 = (uint16_t)-1;
3253 bool correct = True;
3255 printf("starting delete test\n");
3257 if (!torture_open_connection(&cli1, 0)) {
3261 cli_sockopt(cli1, sockops);
3263 /* Test 1 - this should delete the file on close. */
3265 cli_setatr(cli1, fname, 0, 0);
3266 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3268 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3269 0, FILE_OVERWRITE_IF,
3270 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3271 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3278 uint32 *accinfo = NULL;
3280 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3282 printf("access mode = 0x%lx\n", *accinfo);
3287 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3288 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3293 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3294 printf("[1] open of %s succeeded (should fail)\n", fname);
3299 printf("first delete on close test succeeded.\n");
3301 /* Test 2 - this should delete the file on close. */
3303 cli_setatr(cli1, fname, 0, 0);
3304 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3306 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3307 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3308 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3309 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3314 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3315 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3320 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3321 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3326 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3327 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3328 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3329 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3333 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3335 printf("second delete on close test succeeded.\n");
3338 cli_setatr(cli1, fname, 0, 0);
3339 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3341 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3342 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {