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"
24 #include "libcli/security/dom_sid.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
29 #include "nsswitch/winbind_client.h"
31 #include "talloc_dict.h"
32 #include "async_smb.h"
37 static fstring host, workgroup, share, password, username, myname;
38 static int max_protocol = PROTOCOL_NT1;
39 static const char *sockops="TCP_NODELAY";
41 static int port_to_use=0;
42 int torture_numops=100;
43 int torture_blocksize=1024*1024;
44 static int procnum; /* records process count number when forking */
45 static struct cli_state *current_cli;
46 static fstring randomfname;
47 static bool use_oplocks;
48 static bool use_level_II_oplocks;
49 static const char *client_txt = "client_oplocks.txt";
50 static bool use_kerberos;
51 static fstring multishare_conn_fname;
52 static bool use_multishare_conn = False;
53 static bool do_encrypt;
54 static const char *local_path = NULL;
56 bool torture_showall = False;
58 static double create_procs(bool (*fn)(int), bool *result);
61 /* return a pointer to a anonymous shared memory segment of size "size"
62 which will persist across fork() but will disappear when all processes
65 The memory is not zeroed
67 This function uses system5 shared memory. It takes advantage of a property
68 that the memory is not destroyed if it is attached when the id is removed
70 void *shm_setup(int size)
76 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
78 printf("can't get shared memory\n");
81 shm_unlink("private");
82 if (ftruncate(shmid, size) == -1) {
83 printf("can't set shared memory size\n");
86 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
87 if (ret == MAP_FAILED) {
88 printf("can't map shared memory\n");
92 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
94 printf("can't get shared memory\n");
97 ret = (void *)shmat(shmid, 0, 0);
98 if (!ret || ret == (void *)-1) {
99 printf("can't attach to shared memory\n");
102 /* the following releases the ipc, but note that this process
103 and all its children will still have access to the memory, its
104 just that the shmid is no longer valid for other shm calls. This
105 means we don't leave behind lots of shm segments after we exit
107 See Stevens "advanced programming in unix env" for details
109 shmctl(shmid, IPC_RMID, 0);
115 /********************************************************************
116 Ensure a connection is encrypted.
117 ********************************************************************/
119 static bool force_cli_encryption(struct cli_state *c,
120 const char *sharename)
123 uint32 caplow, caphigh;
126 if (!SERVER_HAS_UNIX_CIFS(c)) {
127 d_printf("Encryption required and "
128 "server that doesn't support "
129 "UNIX extensions - failing connect\n");
133 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
135 if (!NT_STATUS_IS_OK(status)) {
136 d_printf("Encryption required and "
137 "can't get UNIX CIFS extensions "
138 "version from server: %s\n", nt_errstr(status));
142 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
143 d_printf("Encryption required and "
144 "share %s doesn't support "
145 "encryption.\n", sharename);
149 if (c->use_kerberos) {
150 status = cli_gss_smb_encryption_start(c);
152 status = cli_raw_ntlm_smb_encryption_start(c,
158 if (!NT_STATUS_IS_OK(status)) {
159 d_printf("Encryption required and "
160 "setup failed with error %s.\n",
169 static struct cli_state *open_nbt_connection(void)
171 struct nmb_name called, calling;
172 struct sockaddr_storage ss;
176 make_nmb_name(&calling, myname, 0x0);
177 make_nmb_name(&called , host, 0x20);
181 if (!(c = cli_initialise())) {
182 printf("Failed initialize cli_struct to connect with %s\n", host);
186 c->port = port_to_use;
188 status = cli_connect(c, host, &ss);
189 if (!NT_STATUS_IS_OK(status)) {
190 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
194 c->use_kerberos = use_kerberos;
196 c->timeout = 120000; /* set a really long timeout (2 minutes) */
197 if (use_oplocks) c->use_oplocks = True;
198 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
200 if (!cli_session_request(c, &calling, &called)) {
202 * Well, that failed, try *SMBSERVER ...
203 * However, we must reconnect as well ...
205 status = cli_connect(c, host, &ss);
206 if (!NT_STATUS_IS_OK(status)) {
207 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
211 make_nmb_name(&called, "*SMBSERVER", 0x20);
212 if (!cli_session_request(c, &calling, &called)) {
213 printf("%s rejected the session\n",host);
214 printf("We tried with a called name of %s & %s\n",
224 /* Insert a NULL at the first separator of the given path and return a pointer
225 * to the remainder of the string.
228 terminate_path_at_separator(char * path)
236 if ((p = strchr_m(path, '/'))) {
241 if ((p = strchr_m(path, '\\'))) {
251 parse a //server/share type UNC name
253 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
254 char **hostname, char **sharename)
258 *hostname = *sharename = NULL;
260 if (strncmp(unc_name, "\\\\", 2) &&
261 strncmp(unc_name, "//", 2)) {
265 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
266 p = terminate_path_at_separator(*hostname);
269 *sharename = talloc_strdup(mem_ctx, p);
270 terminate_path_at_separator(*sharename);
273 if (*hostname && *sharename) {
277 TALLOC_FREE(*hostname);
278 TALLOC_FREE(*sharename);
282 static bool torture_open_connection_share(struct cli_state **c,
283 const char *hostname,
284 const char *sharename)
291 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
293 flags |= CLI_FULL_CONNECTION_OPLOCKS;
294 if (use_level_II_oplocks)
295 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
297 status = cli_full_connection(c, myname,
298 hostname, NULL, port_to_use,
301 password, flags, Undefined, &retry);
302 if (!NT_STATUS_IS_OK(status)) {
303 printf("failed to open share connection: //%s/%s port:%d - %s\n",
304 hostname, sharename, port_to_use, nt_errstr(status));
308 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
311 return force_cli_encryption(*c,
317 bool torture_open_connection(struct cli_state **c, int conn_index)
319 char **unc_list = NULL;
320 int num_unc_names = 0;
323 if (use_multishare_conn==True) {
325 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
326 if (!unc_list || num_unc_names <= 0) {
327 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
331 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
333 printf("Failed to parse UNC name %s\n",
334 unc_list[conn_index % num_unc_names]);
335 TALLOC_FREE(unc_list);
339 result = torture_open_connection_share(c, h, s);
341 /* h, s were copied earlier */
342 TALLOC_FREE(unc_list);
346 return torture_open_connection_share(c, host, share);
349 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
351 uint16 old_vuid = cli->vuid;
352 fstring old_user_name;
353 size_t passlen = strlen(password);
357 fstrcpy(old_user_name, cli->user_name);
359 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
363 *new_vuid = cli->vuid;
364 cli->vuid = old_vuid;
365 status = cli_set_username(cli, old_user_name);
366 if (!NT_STATUS_IS_OK(status)) {
373 bool torture_close_connection(struct cli_state *c)
378 status = cli_tdis(c);
379 if (!NT_STATUS_IS_OK(status)) {
380 printf("tdis failed (%s)\n", nt_errstr(status));
390 /* check if the server produced the expected error code */
391 static bool check_error(int line, struct cli_state *c,
392 uint8 eclass, uint32 ecode, NTSTATUS nterr)
394 if (cli_is_dos_error(c)) {
398 /* Check DOS error */
400 cli_dos_error(c, &cclass, &num);
402 if (eclass != cclass || ecode != num) {
403 printf("unexpected error code class=%d code=%d\n",
404 (int)cclass, (int)num);
405 printf(" expected %d/%d %s (line=%d)\n",
406 (int)eclass, (int)ecode, nt_errstr(nterr), line);
415 status = cli_nt_error(c);
417 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
418 printf("unexpected error code %s\n", nt_errstr(status));
419 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
428 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
430 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
431 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
437 static bool rw_torture(struct cli_state *c)
439 const char *lockfname = "\\torture.lck";
443 pid_t pid2, pid = getpid();
449 memset(buf, '\0', sizeof(buf));
451 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
453 if (!NT_STATUS_IS_OK(status)) {
454 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
456 if (!NT_STATUS_IS_OK(status)) {
457 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
461 for (i=0;i<torture_numops;i++) {
462 unsigned n = (unsigned)sys_random()%10;
464 printf("%d\r", i); fflush(stdout);
466 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
468 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
472 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
473 printf("open failed (%s)\n", cli_errstr(c));
478 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
479 printf("write failed (%s)\n", cli_errstr(c));
484 if (cli_write(c, fnum, 0, (char *)buf,
485 sizeof(pid)+(j*sizeof(buf)),
486 sizeof(buf)) != sizeof(buf)) {
487 printf("write failed (%s)\n", cli_errstr(c));
494 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
495 printf("read failed (%s)\n", cli_errstr(c));
500 printf("data corruption!\n");
504 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
505 printf("close failed (%s)\n", cli_errstr(c));
509 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
510 printf("unlink failed (%s)\n", cli_errstr(c));
514 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
515 printf("unlock failed (%s)\n", cli_errstr(c));
521 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
528 static bool run_torture(int dummy)
530 struct cli_state *cli;
535 cli_sockopt(cli, sockops);
537 ret = rw_torture(cli);
539 if (!torture_close_connection(cli)) {
546 static bool rw_torture3(struct cli_state *c, char *lockfname)
548 uint16_t fnum = (uint16_t)-1;
553 unsigned countprev = 0;
559 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
561 SIVAL(buf, i, sys_random());
566 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
567 DENY_NONE, &fnum))) {
568 printf("first open read/write of %s failed (%s)\n",
569 lockfname, cli_errstr(c));
575 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
577 status = cli_open(c, lockfname, O_RDONLY,
579 if (!NT_STATUS_IS_OK(status)) {
584 if (!NT_STATUS_IS_OK(status)) {
585 printf("second open read-only of %s failed (%s)\n",
586 lockfname, cli_errstr(c));
592 for (count = 0; count < sizeof(buf); count += sent)
594 if (count >= countprev) {
595 printf("%d %8d\r", i, count);
598 countprev += (sizeof(buf) / 20);
603 sent = ((unsigned)sys_random()%(20))+ 1;
604 if (sent > sizeof(buf) - count)
606 sent = sizeof(buf) - count;
609 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
610 printf("write failed (%s)\n", cli_errstr(c));
616 sent = cli_read(c, fnum, buf_rd+count, count,
620 printf("read failed offset:%d size:%ld (%s)\n",
621 count, (unsigned long)sizeof(buf)-count,
628 if (memcmp(buf_rd+count, buf+count, sent) != 0)
630 printf("read/write compare failed\n");
631 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
640 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
641 printf("close failed (%s)\n", cli_errstr(c));
648 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
650 const char *lockfname = "\\torture2.lck";
659 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
660 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
663 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
664 DENY_NONE, &fnum1))) {
665 printf("first open read/write of %s failed (%s)\n",
666 lockfname, cli_errstr(c1));
669 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
670 DENY_NONE, &fnum2))) {
671 printf("second open read-only of %s failed (%s)\n",
672 lockfname, cli_errstr(c2));
673 cli_close(c1, fnum1);
677 for (i=0;i<torture_numops;i++)
679 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
681 printf("%d\r", i); fflush(stdout);
684 generate_random_buffer((unsigned char *)buf, buf_size);
686 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
687 printf("write failed (%s)\n", cli_errstr(c1));
692 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
693 printf("read failed (%s)\n", cli_errstr(c2));
694 printf("read %d, expected %ld\n", (int)bytes_read,
695 (unsigned long)buf_size);
700 if (memcmp(buf_rd, buf, buf_size) != 0)
702 printf("read/write compare failed\n");
708 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
709 printf("close failed (%s)\n", cli_errstr(c2));
712 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
713 printf("close failed (%s)\n", cli_errstr(c1));
717 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
718 printf("unlink failed (%s)\n", cli_errstr(c1));
725 static bool run_readwritetest(int dummy)
727 struct cli_state *cli1, *cli2;
728 bool test1, test2 = False;
730 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
733 cli_sockopt(cli1, sockops);
734 cli_sockopt(cli2, sockops);
736 printf("starting readwritetest\n");
738 test1 = rw_torture2(cli1, cli2);
739 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
742 test2 = rw_torture2(cli1, cli1);
743 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
746 if (!torture_close_connection(cli1)) {
750 if (!torture_close_connection(cli2)) {
754 return (test1 && test2);
757 static bool run_readwritemulti(int dummy)
759 struct cli_state *cli;
764 cli_sockopt(cli, sockops);
766 printf("run_readwritemulti: fname %s\n", randomfname);
767 test = rw_torture3(cli, randomfname);
769 if (!torture_close_connection(cli)) {
776 static bool run_readwritelarge(int dummy)
778 static struct cli_state *cli1;
780 const char *lockfname = "\\large.dat";
785 if (!torture_open_connection(&cli1, 0)) {
788 cli_sockopt(cli1, sockops);
789 memset(buf,'\0',sizeof(buf));
791 cli1->max_xmit = 128*1024;
793 printf("starting readwritelarge\n");
795 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
797 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
798 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
802 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
804 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
805 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
809 if (fsize == sizeof(buf))
810 printf("readwritelarge test 1 succeeded (size = %lx)\n",
811 (unsigned long)fsize);
813 printf("readwritelarge test 1 failed (size = %lx)\n",
814 (unsigned long)fsize);
818 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
819 printf("close failed (%s)\n", cli_errstr(cli1));
823 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
824 printf("unlink failed (%s)\n", cli_errstr(cli1));
828 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
829 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
833 cli1->max_xmit = 4*1024;
835 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
837 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
838 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
842 if (fsize == sizeof(buf))
843 printf("readwritelarge test 2 succeeded (size = %lx)\n",
844 (unsigned long)fsize);
846 printf("readwritelarge test 2 failed (size = %lx)\n",
847 (unsigned long)fsize);
852 /* ToDo - set allocation. JRA */
853 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
854 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
857 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
858 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
862 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
865 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
866 printf("close failed (%s)\n", cli_errstr(cli1));
870 if (!torture_close_connection(cli1)) {
879 #define ival(s) strtol(s, NULL, 0)
881 /* run a test that simulates an approximate netbench client load */
882 static bool run_netbench(int client)
884 struct cli_state *cli;
889 const char *params[20];
896 cli_sockopt(cli, sockops);
900 slprintf(cname,sizeof(cname)-1, "client%d", client);
902 f = fopen(client_txt, "r");
909 while (fgets(line, sizeof(line)-1, f)) {
913 line[strlen(line)-1] = 0;
915 /* printf("[%d] %s\n", line_count, line); */
917 all_string_sub(line,"client1", cname, sizeof(line));
919 /* parse the command parameters */
920 params[0] = strtok_r(line, " ", &saveptr);
922 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
928 if (!strncmp(params[0],"SMB", 3)) {
929 printf("ERROR: You are using a dbench 1 load file\n");
933 if (!strcmp(params[0],"NTCreateX")) {
934 nb_createx(params[1], ival(params[2]), ival(params[3]),
936 } else if (!strcmp(params[0],"Close")) {
937 nb_close(ival(params[1]));
938 } else if (!strcmp(params[0],"Rename")) {
939 nb_rename(params[1], params[2]);
940 } else if (!strcmp(params[0],"Unlink")) {
941 nb_unlink(params[1]);
942 } else if (!strcmp(params[0],"Deltree")) {
943 nb_deltree(params[1]);
944 } else if (!strcmp(params[0],"Rmdir")) {
946 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
947 nb_qpathinfo(params[1]);
948 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
949 nb_qfileinfo(ival(params[1]));
950 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
951 nb_qfsinfo(ival(params[1]));
952 } else if (!strcmp(params[0],"FIND_FIRST")) {
953 nb_findfirst(params[1]);
954 } else if (!strcmp(params[0],"WriteX")) {
955 nb_writex(ival(params[1]),
956 ival(params[2]), ival(params[3]), ival(params[4]));
957 } else if (!strcmp(params[0],"ReadX")) {
958 nb_readx(ival(params[1]),
959 ival(params[2]), ival(params[3]), ival(params[4]));
960 } else if (!strcmp(params[0],"Flush")) {
961 nb_flush(ival(params[1]));
963 printf("Unknown operation %s\n", params[0]);
971 if (!torture_close_connection(cli)) {
979 /* run a test that simulates an approximate netbench client load */
980 static bool run_nbench(int dummy)
989 signal(SIGALRM, nb_alarm);
991 t = create_procs(run_netbench, &correct);
994 printf("\nThroughput %g MB/sec\n",
995 1.0e-6 * nbio_total() / t);
1001 This test checks for two things:
1003 1) correct support for retaining locks over a close (ie. the server
1004 must not use posix semantics)
1005 2) support for lock timeouts
1007 static bool run_locktest1(int dummy)
1009 struct cli_state *cli1, *cli2;
1010 const char *fname = "\\lockt1.lck";
1011 uint16_t fnum1, fnum2, fnum3;
1013 unsigned lock_timeout;
1015 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1018 cli_sockopt(cli1, sockops);
1019 cli_sockopt(cli2, sockops);
1021 printf("starting locktest1\n");
1023 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1025 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1026 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1029 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1030 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1033 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1034 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1038 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1039 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1044 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1045 printf("lock2 succeeded! This is a locking bug\n");
1048 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1049 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1053 lock_timeout = (1 + (random() % 20));
1054 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1056 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1057 printf("lock3 succeeded! This is a locking bug\n");
1060 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1061 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1065 if (ABS(t2 - t1) < lock_timeout-1) {
1066 printf("error: This server appears not to support timed lock requests\n");
1069 printf("server slept for %u seconds for a %u second timeout\n",
1070 (unsigned int)(t2-t1), lock_timeout);
1072 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1073 printf("close1 failed (%s)\n", cli_errstr(cli1));
1077 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1078 printf("lock4 succeeded! This is a locking bug\n");
1081 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1082 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1085 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1086 printf("close2 failed (%s)\n", cli_errstr(cli1));
1090 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1091 printf("close3 failed (%s)\n", cli_errstr(cli2));
1095 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1096 printf("unlink failed (%s)\n", cli_errstr(cli1));
1101 if (!torture_close_connection(cli1)) {
1105 if (!torture_close_connection(cli2)) {
1109 printf("Passed locktest1\n");
1114 this checks to see if a secondary tconx can use open files from an
1117 static bool run_tcon_test(int dummy)
1119 static struct cli_state *cli;
1120 const char *fname = "\\tcontest.tmp";
1122 uint16 cnum1, cnum2, cnum3;
1123 uint16 vuid1, vuid2;
1128 memset(buf, '\0', sizeof(buf));
1130 if (!torture_open_connection(&cli, 0)) {
1133 cli_sockopt(cli, sockops);
1135 printf("starting tcontest\n");
1137 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1139 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1140 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1147 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1148 printf("initial write failed (%s)", cli_errstr(cli));
1152 status = cli_tcon_andx(cli, share, "?????",
1153 password, strlen(password)+1);
1154 if (!NT_STATUS_IS_OK(status)) {
1155 printf("%s refused 2nd tree connect (%s)\n", host,
1162 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1163 vuid2 = cli->vuid + 1;
1165 /* try a write with the wrong tid */
1168 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1169 printf("* server allows write with wrong TID\n");
1172 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1176 /* try a write with an invalid tid */
1179 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1180 printf("* server allows write with invalid TID\n");
1183 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1186 /* try a write with an invalid vuid */
1190 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1191 printf("* server allows write with invalid VUID\n");
1194 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1200 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1201 printf("close failed (%s)\n", cli_errstr(cli));
1207 status = cli_tdis(cli);
1208 if (!NT_STATUS_IS_OK(status)) {
1209 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1215 if (!torture_close_connection(cli)) {
1224 checks for old style tcon support
1226 static bool run_tcon2_test(int dummy)
1228 static struct cli_state *cli;
1229 uint16 cnum, max_xmit;
1233 if (!torture_open_connection(&cli, 0)) {
1236 cli_sockopt(cli, sockops);
1238 printf("starting tcon2 test\n");
1240 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1244 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1246 if (!NT_STATUS_IS_OK(status)) {
1247 printf("tcon2 failed : %s\n", cli_errstr(cli));
1249 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1250 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1253 if (!torture_close_connection(cli)) {
1257 printf("Passed tcon2 test\n");
1261 static bool tcon_devtest(struct cli_state *cli,
1262 const char *myshare, const char *devtype,
1263 const char *return_devtype,
1264 NTSTATUS expected_error)
1269 status = cli_tcon_andx(cli, myshare, devtype,
1270 password, strlen(password)+1);
1272 if (NT_STATUS_IS_OK(expected_error)) {
1273 if (NT_STATUS_IS_OK(status)) {
1274 if (strcmp(cli->dev, return_devtype) == 0) {
1277 printf("tconX to share %s with type %s "
1278 "succeeded but returned the wrong "
1279 "device type (got [%s] but should have got [%s])\n",
1280 myshare, devtype, cli->dev, return_devtype);
1284 printf("tconX to share %s with type %s "
1285 "should have succeeded but failed\n",
1291 if (NT_STATUS_IS_OK(status)) {
1292 printf("tconx to share %s with type %s "
1293 "should have failed but succeeded\n",
1297 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1301 printf("Returned unexpected error\n");
1310 checks for correct tconX support
1312 static bool run_tcon_devtype_test(int dummy)
1314 static struct cli_state *cli1 = NULL;
1320 status = cli_full_connection(&cli1, myname,
1321 host, NULL, port_to_use,
1323 username, workgroup,
1324 password, flags, Undefined, &retry);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 printf("could not open connection\n");
1331 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1334 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1337 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1340 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1343 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1346 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1349 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1352 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1355 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1358 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1364 printf("Passed tcondevtest\n");
1371 This test checks that
1373 1) the server supports multiple locking contexts on the one SMB
1374 connection, distinguished by PID.
1376 2) the server correctly fails overlapping locks made by the same PID (this
1377 goes against POSIX behaviour, which is why it is tricky to implement)
1379 3) the server denies unlock requests by an incorrect client PID
1381 static bool run_locktest2(int dummy)
1383 static struct cli_state *cli;
1384 const char *fname = "\\lockt2.lck";
1385 uint16_t fnum1, fnum2, fnum3;
1386 bool correct = True;
1388 if (!torture_open_connection(&cli, 0)) {
1392 cli_sockopt(cli, sockops);
1394 printf("starting locktest2\n");
1396 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1400 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1401 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1405 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1406 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1412 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1413 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1419 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1420 printf("lock1 failed (%s)\n", cli_errstr(cli));
1424 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1425 printf("WRITE lock1 succeeded! This is a locking bug\n");
1428 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1429 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1432 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1433 printf("WRITE lock2 succeeded! This is a locking bug\n");
1436 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1437 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1440 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1441 printf("READ lock2 succeeded! This is a locking bug\n");
1444 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1445 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1448 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1449 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1452 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1453 printf("unlock at 100 succeeded! This is a locking bug\n");
1457 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1458 printf("unlock1 succeeded! This is a locking bug\n");
1461 if (!check_error(__LINE__, cli,
1463 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1466 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1467 printf("unlock2 succeeded! This is a locking bug\n");
1470 if (!check_error(__LINE__, cli,
1472 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1475 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1476 printf("lock3 succeeded! This is a locking bug\n");
1479 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1484 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1485 printf("close1 failed (%s)\n", cli_errstr(cli));
1489 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1490 printf("close2 failed (%s)\n", cli_errstr(cli));
1494 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1495 printf("close3 failed (%s)\n", cli_errstr(cli));
1499 if (!torture_close_connection(cli)) {
1503 printf("locktest2 finished\n");
1510 This test checks that
1512 1) the server supports the full offset range in lock requests
1514 static bool run_locktest3(int dummy)
1516 static struct cli_state *cli1, *cli2;
1517 const char *fname = "\\lockt3.lck";
1518 uint16_t fnum1, fnum2;
1521 bool correct = True;
1523 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1525 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1528 cli_sockopt(cli1, sockops);
1529 cli_sockopt(cli2, sockops);
1531 printf("starting locktest3\n");
1533 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1535 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1536 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1539 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1540 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1544 for (offset=i=0;i<torture_numops;i++) {
1546 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1547 printf("lock1 %d failed (%s)\n",
1553 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1554 printf("lock2 %d failed (%s)\n",
1561 for (offset=i=0;i<torture_numops;i++) {
1564 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1565 printf("error: lock1 %d succeeded!\n", i);
1569 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1570 printf("error: lock2 %d succeeded!\n", i);
1574 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1575 printf("error: lock3 %d succeeded!\n", i);
1579 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1580 printf("error: lock4 %d succeeded!\n", i);
1585 for (offset=i=0;i<torture_numops;i++) {
1588 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1589 printf("unlock1 %d failed (%s)\n",
1595 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1596 printf("unlock2 %d failed (%s)\n",
1603 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1604 printf("close1 failed (%s)\n", cli_errstr(cli1));
1608 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1609 printf("close2 failed (%s)\n", cli_errstr(cli2));
1613 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1614 printf("unlink failed (%s)\n", cli_errstr(cli1));
1618 if (!torture_close_connection(cli1)) {
1622 if (!torture_close_connection(cli2)) {
1626 printf("finished locktest3\n");
1631 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1632 printf("** "); correct = False; \
1636 looks at overlapping locks
1638 static bool run_locktest4(int dummy)
1640 static struct cli_state *cli1, *cli2;
1641 const char *fname = "\\lockt4.lck";
1642 uint16_t fnum1, fnum2, f;
1645 bool correct = True;
1647 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1651 cli_sockopt(cli1, sockops);
1652 cli_sockopt(cli2, sockops);
1654 printf("starting locktest4\n");
1656 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1658 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1659 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1661 memset(buf, 0, sizeof(buf));
1663 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1664 printf("Failed to create file\n");
1669 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1670 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1671 EXPECTED(ret, False);
1672 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1674 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1675 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1676 EXPECTED(ret, True);
1677 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1679 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1680 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1681 EXPECTED(ret, False);
1682 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1684 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1685 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1686 EXPECTED(ret, True);
1687 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1689 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1690 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1691 EXPECTED(ret, False);
1692 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1694 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1695 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1696 EXPECTED(ret, True);
1697 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1699 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1700 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1701 EXPECTED(ret, True);
1702 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1704 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1705 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1706 EXPECTED(ret, False);
1707 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1709 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1710 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1711 EXPECTED(ret, False);
1712 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1714 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1715 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1716 EXPECTED(ret, True);
1717 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1719 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1720 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1721 EXPECTED(ret, False);
1722 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1724 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1725 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1726 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1727 EXPECTED(ret, False);
1728 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1731 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1732 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1733 EXPECTED(ret, False);
1734 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1736 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1737 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1738 EXPECTED(ret, False);
1739 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1742 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1743 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1744 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1745 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1746 EXPECTED(ret, True);
1747 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1750 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1751 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1752 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1753 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1754 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1755 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1756 EXPECTED(ret, True);
1757 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1759 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1760 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1761 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1762 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1763 EXPECTED(ret, True);
1764 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1766 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1767 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1768 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1769 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1770 EXPECTED(ret, True);
1771 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1773 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1774 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1775 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1776 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1777 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1778 EXPECTED(ret, True);
1779 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1781 cli_close(cli1, fnum1);
1782 cli_close(cli2, fnum2);
1783 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1784 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1785 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1786 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1787 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1788 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1789 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1791 cli_close(cli1, fnum1);
1792 EXPECTED(ret, True);
1793 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1796 cli_close(cli1, fnum1);
1797 cli_close(cli2, fnum2);
1798 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1799 torture_close_connection(cli1);
1800 torture_close_connection(cli2);
1802 printf("finished locktest4\n");
1807 looks at lock upgrade/downgrade.
1809 static bool run_locktest5(int dummy)
1811 static struct cli_state *cli1, *cli2;
1812 const char *fname = "\\lockt5.lck";
1813 uint16_t fnum1, fnum2, fnum3;
1816 bool correct = True;
1818 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1822 cli_sockopt(cli1, sockops);
1823 cli_sockopt(cli2, sockops);
1825 printf("starting locktest5\n");
1827 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1829 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1830 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1831 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1833 memset(buf, 0, sizeof(buf));
1835 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1836 printf("Failed to create file\n");
1841 /* Check for NT bug... */
1842 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1843 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1844 cli_close(cli1, fnum1);
1845 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1846 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1847 EXPECTED(ret, True);
1848 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1849 cli_close(cli1, fnum1);
1850 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1851 cli_unlock(cli1, fnum3, 0, 1);
1853 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1854 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1855 EXPECTED(ret, True);
1856 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1858 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1859 EXPECTED(ret, False);
1861 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1863 /* Unlock the process 2 lock. */
1864 cli_unlock(cli2, fnum2, 0, 4);
1866 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1867 EXPECTED(ret, False);
1869 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1871 /* Unlock the process 1 fnum3 lock. */
1872 cli_unlock(cli1, fnum3, 0, 4);
1874 /* Stack 2 more locks here. */
1875 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1876 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1878 EXPECTED(ret, True);
1879 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1881 /* Unlock the first process lock, then check this was the WRITE lock that was
1884 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1885 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1887 EXPECTED(ret, True);
1888 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1890 /* Unlock the process 2 lock. */
1891 cli_unlock(cli2, fnum2, 0, 4);
1893 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1895 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1896 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1897 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1899 EXPECTED(ret, True);
1900 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1902 /* Ensure the next unlock fails. */
1903 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1904 EXPECTED(ret, False);
1905 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1907 /* Ensure connection 2 can get a write lock. */
1908 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1909 EXPECTED(ret, True);
1911 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1915 cli_close(cli1, fnum1);
1916 cli_close(cli2, fnum2);
1917 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1918 if (!torture_close_connection(cli1)) {
1921 if (!torture_close_connection(cli2)) {
1925 printf("finished locktest5\n");
1931 tries the unusual lockingX locktype bits
1933 static bool run_locktest6(int dummy)
1935 static struct cli_state *cli;
1936 const char *fname[1] = { "\\lock6.txt" };
1941 if (!torture_open_connection(&cli, 0)) {
1945 cli_sockopt(cli, sockops);
1947 printf("starting locktest6\n");
1950 printf("Testing %s\n", fname[i]);
1952 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1954 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1955 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1956 cli_close(cli, fnum);
1957 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1959 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1960 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1961 cli_close(cli, fnum);
1962 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1964 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1967 torture_close_connection(cli);
1969 printf("finished locktest6\n");
1973 static bool run_locktest7(int dummy)
1975 struct cli_state *cli1;
1976 const char *fname = "\\lockt7.lck";
1979 bool correct = False;
1981 if (!torture_open_connection(&cli1, 0)) {
1985 cli_sockopt(cli1, sockops);
1987 printf("starting locktest7\n");
1989 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1991 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1993 memset(buf, 0, sizeof(buf));
1995 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1996 printf("Failed to create file\n");
2000 cli_setpid(cli1, 1);
2002 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2003 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2006 printf("pid1 successfully locked range 130:4 for READ\n");
2009 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2010 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2013 printf("pid1 successfully read the range 130:4\n");
2016 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2017 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2018 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2019 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2023 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2027 cli_setpid(cli1, 2);
2029 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2030 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2032 printf("pid2 successfully read the range 130:4\n");
2035 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2036 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2037 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2038 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2042 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2046 cli_setpid(cli1, 1);
2047 cli_unlock(cli1, fnum1, 130, 4);
2049 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2050 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2053 printf("pid1 successfully locked range 130:4 for WRITE\n");
2056 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2057 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2060 printf("pid1 successfully read the range 130:4\n");
2063 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2064 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2067 printf("pid1 successfully wrote to the range 130:4\n");
2070 cli_setpid(cli1, 2);
2072 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2073 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2074 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2075 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2079 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2083 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2084 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2085 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2086 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2090 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2094 cli_unlock(cli1, fnum1, 130, 0);
2098 cli_close(cli1, fnum1);
2099 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2100 torture_close_connection(cli1);
2102 printf("finished locktest7\n");
2107 * This demonstrates a problem with our use of GPFS share modes: A file
2108 * descriptor sitting in the pending close queue holding a GPFS share mode
2109 * blocks opening a file another time. Happens with Word 2007 temp files.
2110 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2111 * open is denied with NT_STATUS_SHARING_VIOLATION.
2114 static bool run_locktest8(int dummy)
2116 struct cli_state *cli1;
2117 const char *fname = "\\lockt8.lck";
2118 uint16_t fnum1, fnum2;
2120 bool correct = False;
2123 if (!torture_open_connection(&cli1, 0)) {
2127 cli_sockopt(cli1, sockops);
2129 printf("starting locktest8\n");
2131 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2133 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2135 if (!NT_STATUS_IS_OK(status)) {
2136 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2140 memset(buf, 0, sizeof(buf));
2142 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2143 if (!NT_STATUS_IS_OK(status)) {
2144 d_fprintf(stderr, "cli_open second time returned %s\n",
2149 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2150 printf("Unable to apply read lock on range 1:1, error was "
2151 "%s\n", cli_errstr(cli1));
2155 status = cli_close(cli1, fnum1);
2156 if (!NT_STATUS_IS_OK(status)) {
2157 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2161 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2162 if (!NT_STATUS_IS_OK(status)) {
2163 d_fprintf(stderr, "cli_open third time returned %s\n",
2171 cli_close(cli1, fnum1);
2172 cli_close(cli1, fnum2);
2173 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2174 torture_close_connection(cli1);
2176 printf("finished locktest8\n");
2181 * This test is designed to be run in conjunction with
2182 * external NFS or POSIX locks taken in the filesystem.
2183 * It checks that the smbd server will block until the
2184 * lock is released and then acquire it. JRA.
2187 static bool got_alarm;
2188 static int alarm_fd;
2190 static void alarm_handler(int dummy)
2195 static void alarm_handler_parent(int dummy)
2200 static void do_local_lock(int read_fd, int write_fd)
2205 const char *local_pathname = NULL;
2208 local_pathname = talloc_asprintf(talloc_tos(),
2209 "%s/lockt9.lck", local_path);
2210 if (!local_pathname) {
2211 printf("child: alloc fail\n");
2215 unlink(local_pathname);
2216 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2218 printf("child: open of %s failed %s.\n",
2219 local_pathname, strerror(errno));
2223 /* Now take a fcntl lock. */
2224 lock.l_type = F_WRLCK;
2225 lock.l_whence = SEEK_SET;
2228 lock.l_pid = getpid();
2230 ret = fcntl(fd,F_SETLK,&lock);
2232 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2233 local_pathname, strerror(errno));
2236 printf("child: got lock 0:4 on file %s.\n",
2241 CatchSignal(SIGALRM, alarm_handler);
2243 /* Signal the parent. */
2244 if (write(write_fd, &c, 1) != 1) {
2245 printf("child: start signal fail %s.\n",
2252 /* Wait for the parent to be ready. */
2253 if (read(read_fd, &c, 1) != 1) {
2254 printf("child: reply signal fail %s.\n",
2262 printf("child: released lock 0:4 on file %s.\n",
2268 static bool run_locktest9(int dummy)
2270 struct cli_state *cli1;
2271 const char *fname = "\\lockt9.lck";
2273 bool correct = False;
2274 int pipe_in[2], pipe_out[2];
2278 struct timeval start;
2282 printf("starting locktest9\n");
2284 if (local_path == NULL) {
2285 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2289 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2294 if (child_pid == -1) {
2298 if (child_pid == 0) {
2300 do_local_lock(pipe_out[0], pipe_in[1]);
2310 ret = read(pipe_in[0], &c, 1);
2312 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2317 if (!torture_open_connection(&cli1, 0)) {
2321 cli_sockopt(cli1, sockops);
2323 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2325 if (!NT_STATUS_IS_OK(status)) {
2326 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2330 /* Ensure the child has the lock. */
2331 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2332 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2335 d_printf("Child has the lock.\n");
2338 /* Tell the child to wait 5 seconds then exit. */
2339 ret = write(pipe_out[1], &c, 1);
2341 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2346 /* Wait 20 seconds for the lock. */
2347 alarm_fd = cli1->fd;
2348 CatchSignal(SIGALRM, alarm_handler_parent);
2351 start = timeval_current();
2353 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2354 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2355 "%s\n", cli_errstr(cli1));
2360 seconds = timeval_elapsed(&start);
2362 printf("Parent got the lock after %.2f seconds.\n",
2365 status = cli_close(cli1, fnum);
2366 if (!NT_STATUS_IS_OK(status)) {
2367 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2374 cli_close(cli1, fnum);
2375 torture_close_connection(cli1);
2379 printf("finished locktest9\n");
2384 test whether fnums and tids open on one VC are available on another (a major
2387 static bool run_fdpasstest(int dummy)
2389 struct cli_state *cli1, *cli2;
2390 const char *fname = "\\fdpass.tst";
2394 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2397 cli_sockopt(cli1, sockops);
2398 cli_sockopt(cli2, sockops);
2400 printf("starting fdpasstest\n");
2402 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2404 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2405 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2409 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2410 printf("write failed (%s)\n", cli_errstr(cli1));
2414 cli2->vuid = cli1->vuid;
2415 cli2->cnum = cli1->cnum;
2416 cli2->pid = cli1->pid;
2418 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2419 printf("read succeeded! nasty security hole [%s]\n",
2424 cli_close(cli1, fnum1);
2425 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2427 torture_close_connection(cli1);
2428 torture_close_connection(cli2);
2430 printf("finished fdpasstest\n");
2434 static bool run_fdsesstest(int dummy)
2436 struct cli_state *cli;
2441 const char *fname = "\\fdsess.tst";
2442 const char *fname1 = "\\fdsess1.tst";
2448 if (!torture_open_connection(&cli, 0))
2450 cli_sockopt(cli, sockops);
2452 if (!torture_cli_session_setup2(cli, &new_vuid))
2455 saved_cnum = cli->cnum;
2456 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2458 new_cnum = cli->cnum;
2459 cli->cnum = saved_cnum;
2461 printf("starting fdsesstest\n");
2463 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2464 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2466 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2467 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2471 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2472 printf("write failed (%s)\n", cli_errstr(cli));
2476 saved_vuid = cli->vuid;
2477 cli->vuid = new_vuid;
2479 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2480 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2484 /* Try to open a file with different vuid, samba cnum. */
2485 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2486 printf("create with different vuid, same cnum succeeded.\n");
2487 cli_close(cli, fnum2);
2488 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2490 printf("create with different vuid, same cnum failed.\n");
2491 printf("This will cause problems with service clients.\n");
2495 cli->vuid = saved_vuid;
2497 /* Try with same vuid, different cnum. */
2498 cli->cnum = new_cnum;
2500 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2501 printf("read succeeded with different cnum![%s]\n",
2506 cli->cnum = saved_cnum;
2507 cli_close(cli, fnum1);
2508 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2510 torture_close_connection(cli);
2512 printf("finished fdsesstest\n");
2517 This test checks that
2519 1) the server does not allow an unlink on a file that is open
2521 static bool run_unlinktest(int dummy)
2523 struct cli_state *cli;
2524 const char *fname = "\\unlink.tst";
2526 bool correct = True;
2528 if (!torture_open_connection(&cli, 0)) {
2532 cli_sockopt(cli, sockops);
2534 printf("starting unlink test\n");
2536 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2540 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2541 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2545 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2546 printf("error: server allowed unlink on an open file\n");
2549 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2550 NT_STATUS_SHARING_VIOLATION);
2553 cli_close(cli, fnum);
2554 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2556 if (!torture_close_connection(cli)) {
2560 printf("unlink test finished\n");
2567 test how many open files this server supports on the one socket
2569 static bool run_maxfidtest(int dummy)
2571 struct cli_state *cli;
2572 const char *ftemplate = "\\maxfid.%d.%d";
2574 uint16_t fnums[0x11000];
2577 bool correct = True;
2582 printf("failed to connect\n");
2586 cli_sockopt(cli, sockops);
2588 for (i=0; i<0x11000; i++) {
2589 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2590 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2591 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2592 printf("open of %s failed (%s)\n",
2593 fname, cli_errstr(cli));
2594 printf("maximum fnum is %d\n", i);
2602 printf("cleaning up\n");
2604 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2605 cli_close(cli, fnums[i]);
2606 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2607 printf("unlink of %s failed (%s)\n",
2608 fname, cli_errstr(cli));
2615 printf("maxfid test finished\n");
2616 if (!torture_close_connection(cli)) {
2622 /* generate a random buffer */
2623 static void rand_buf(char *buf, int len)
2626 *buf = (char)sys_random();
2631 /* send smb negprot commands, not reading the response */
2632 static bool run_negprot_nowait(int dummy)
2635 static struct cli_state *cli;
2636 bool correct = True;
2638 printf("starting negprot nowait test\n");
2640 if (!(cli = open_nbt_connection())) {
2644 for (i=0;i<50000;i++) {
2645 cli_negprot_sendsync(cli);
2648 if (!torture_close_connection(cli)) {
2652 printf("finished negprot nowait test\n");
2658 /* send random IPC commands */
2659 static bool run_randomipc(int dummy)
2661 char *rparam = NULL;
2663 unsigned int rdrcnt,rprcnt;
2665 int api, param_len, i;
2666 struct cli_state *cli;
2667 bool correct = True;
2670 printf("starting random ipc test\n");
2672 if (!torture_open_connection(&cli, 0)) {
2676 for (i=0;i<count;i++) {
2677 api = sys_random() % 500;
2678 param_len = (sys_random() % 64);
2680 rand_buf(param, param_len);
2685 param, param_len, 8,
2686 NULL, 0, BUFFER_SIZE,
2690 printf("%d/%d\r", i,count);
2693 printf("%d/%d\n", i, count);
2695 if (!torture_close_connection(cli)) {
2699 printf("finished random ipc test\n");
2706 static void browse_callback(const char *sname, uint32 stype,
2707 const char *comment, void *state)
2709 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2715 This test checks the browse list code
2718 static bool run_browsetest(int dummy)
2720 static struct cli_state *cli;
2721 bool correct = True;
2723 printf("starting browse test\n");
2725 if (!torture_open_connection(&cli, 0)) {
2729 printf("domain list:\n");
2730 cli_NetServerEnum(cli, cli->server_domain,
2731 SV_TYPE_DOMAIN_ENUM,
2732 browse_callback, NULL);
2734 printf("machine list:\n");
2735 cli_NetServerEnum(cli, cli->server_domain,
2737 browse_callback, NULL);
2739 if (!torture_close_connection(cli)) {
2743 printf("browse test finished\n");
2751 This checks how the getatr calls works
2753 static bool run_attrtest(int dummy)
2755 struct cli_state *cli;
2758 const char *fname = "\\attrib123456789.tst";
2759 bool correct = True;
2761 printf("starting attrib test\n");
2763 if (!torture_open_connection(&cli, 0)) {
2767 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2768 cli_open(cli, fname,
2769 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2770 cli_close(cli, fnum);
2771 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2772 printf("getatr failed (%s)\n", cli_errstr(cli));
2776 if (abs(t - time(NULL)) > 60*60*24*10) {
2777 printf("ERROR: SMBgetatr bug. time is %s",
2783 t2 = t-60*60*24; /* 1 day ago */
2785 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2786 printf("setatr failed (%s)\n", cli_errstr(cli));
2790 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2791 printf("getatr failed (%s)\n", cli_errstr(cli));
2796 printf("ERROR: getatr/setatr bug. times are\n%s",
2798 printf("%s", ctime(&t2));
2802 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2804 if (!torture_close_connection(cli)) {
2808 printf("attrib test finished\n");
2815 This checks a couple of trans2 calls
2817 static bool run_trans2test(int dummy)
2819 struct cli_state *cli;
2822 time_t c_time, a_time, m_time;
2823 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2824 const char *fname = "\\trans2.tst";
2825 const char *dname = "\\trans2";
2826 const char *fname2 = "\\trans2\\trans2.tst";
2828 bool correct = True;
2832 printf("starting trans2 test\n");
2834 if (!torture_open_connection(&cli, 0)) {
2838 status = cli_get_fs_attr_info(cli, &fs_attr);
2839 if (!NT_STATUS_IS_OK(status)) {
2840 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2845 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2846 cli_open(cli, fname,
2847 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2848 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2849 &m_time_ts, NULL)) {
2850 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2854 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2855 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2859 if (strcmp(pname, fname)) {
2860 printf("qfilename gave different name? [%s] [%s]\n",
2865 cli_close(cli, fnum);
2869 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2870 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2871 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2872 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2875 cli_close(cli, fnum);
2877 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
2879 if (!NT_STATUS_IS_OK(status)) {
2880 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
2883 if (c_time != m_time) {
2884 printf("create time=%s", ctime(&c_time));
2885 printf("modify time=%s", ctime(&m_time));
2886 printf("This system appears to have sticky create times\n");
2888 if (a_time % (60*60) == 0) {
2889 printf("access time=%s", ctime(&a_time));
2890 printf("This system appears to set a midnight access time\n");
2894 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2895 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2901 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2902 cli_open(cli, fname,
2903 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2904 cli_close(cli, fnum);
2905 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2906 &m_time_ts, &size, NULL, NULL);
2907 if (!NT_STATUS_IS_OK(status)) {
2908 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2911 if (w_time_ts.tv_sec < 60*60*24*2) {
2912 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2913 printf("This system appears to set a initial 0 write time\n");
2918 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2921 /* check if the server updates the directory modification time
2922 when creating a new file */
2923 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2924 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2928 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2929 &w_time_ts, &m_time_ts, &size, NULL, NULL);
2930 if (!NT_STATUS_IS_OK(status)) {
2931 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2935 cli_open(cli, fname2,
2936 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2937 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2938 cli_close(cli, fnum);
2939 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2940 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
2941 if (!NT_STATUS_IS_OK(status)) {
2942 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2945 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2947 printf("This system does not update directory modification times\n");
2951 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2952 cli_rmdir(cli, dname);
2954 if (!torture_close_connection(cli)) {
2958 printf("trans2 test finished\n");
2964 This checks new W2K calls.
2967 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2971 bool correct = True;
2973 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2974 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2977 printf("qfileinfo: level %d, len = %u\n", level, len);
2978 dump_data(0, (uint8 *)buf, len);
2985 static bool run_w2ktest(int dummy)
2987 struct cli_state *cli;
2989 const char *fname = "\\w2ktest\\w2k.tst";
2991 bool correct = True;
2993 printf("starting w2k test\n");
2995 if (!torture_open_connection(&cli, 0)) {
2999 cli_open(cli, fname,
3000 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3002 for (level = 1004; level < 1040; level++) {
3003 new_trans(cli, fnum, level);
3006 cli_close(cli, fnum);
3008 if (!torture_close_connection(cli)) {
3012 printf("w2k test finished\n");
3019 this is a harness for some oplock tests
3021 static bool run_oplock1(int dummy)
3023 struct cli_state *cli1;
3024 const char *fname = "\\lockt1.lck";
3026 bool correct = True;
3028 printf("starting oplock test 1\n");
3030 if (!torture_open_connection(&cli1, 0)) {
3034 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3036 cli_sockopt(cli1, sockops);
3038 cli1->use_oplocks = True;
3040 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3041 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3045 cli1->use_oplocks = False;
3047 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3048 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3050 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3051 printf("close2 failed (%s)\n", cli_errstr(cli1));
3055 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3056 printf("unlink failed (%s)\n", cli_errstr(cli1));
3060 if (!torture_close_connection(cli1)) {
3064 printf("finished oplock test 1\n");
3069 static bool run_oplock2(int dummy)
3071 struct cli_state *cli1, *cli2;
3072 const char *fname = "\\lockt2.lck";
3073 uint16_t fnum1, fnum2;
3074 int saved_use_oplocks = use_oplocks;
3076 bool correct = True;
3077 volatile bool *shared_correct;
3079 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3080 *shared_correct = True;
3082 use_level_II_oplocks = True;
3085 printf("starting oplock test 2\n");
3087 if (!torture_open_connection(&cli1, 0)) {
3088 use_level_II_oplocks = False;
3089 use_oplocks = saved_use_oplocks;
3093 cli1->use_oplocks = True;
3094 cli1->use_level_II_oplocks = True;
3096 if (!torture_open_connection(&cli2, 1)) {
3097 use_level_II_oplocks = False;
3098 use_oplocks = saved_use_oplocks;
3102 cli2->use_oplocks = True;
3103 cli2->use_level_II_oplocks = True;
3105 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3107 cli_sockopt(cli1, sockops);
3108 cli_sockopt(cli2, sockops);
3110 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3111 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3115 /* Don't need the globals any more. */
3116 use_level_II_oplocks = False;
3117 use_oplocks = saved_use_oplocks;
3121 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3122 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3123 *shared_correct = False;
3129 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3130 printf("close2 failed (%s)\n", cli_errstr(cli1));
3131 *shared_correct = False;
3139 /* Ensure cli1 processes the break. Empty file should always return 0
3142 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3143 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3147 /* Should now be at level II. */
3148 /* Test if sending a write locks causes a break to none. */
3150 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3151 printf("lock failed (%s)\n", cli_errstr(cli1));
3155 cli_unlock(cli1, fnum1, 0, 4);
3159 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3160 printf("lock failed (%s)\n", cli_errstr(cli1));
3164 cli_unlock(cli1, fnum1, 0, 4);
3168 cli_read(cli1, fnum1, buf, 0, 4);
3171 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3172 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3177 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3178 printf("close1 failed (%s)\n", cli_errstr(cli1));
3184 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3185 printf("unlink failed (%s)\n", cli_errstr(cli1));
3189 if (!torture_close_connection(cli1)) {
3193 if (!*shared_correct) {
3197 printf("finished oplock test 2\n");
3202 /* handler for oplock 3 tests */
3203 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3205 printf("got oplock break fnum=%d level=%d\n",
3207 return cli_oplock_ack(cli, fnum, level);
3210 static bool run_oplock3(int dummy)
3212 struct cli_state *cli;
3213 const char *fname = "\\oplockt3.dat";
3215 char buf[4] = "abcd";
3216 bool correct = True;
3217 volatile bool *shared_correct;
3219 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3220 *shared_correct = True;
3222 printf("starting oplock test 3\n");
3227 use_level_II_oplocks = True;
3228 if (!torture_open_connection(&cli, 0)) {
3229 *shared_correct = False;
3233 /* try to trigger a oplock break in parent */
3234 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3235 cli_write(cli, fnum, 0, buf, 0, 4);
3241 use_level_II_oplocks = True;
3242 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3245 cli_oplock_handler(cli, oplock3_handler);
3246 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3247 cli_write(cli, fnum, 0, buf, 0, 4);
3248 cli_close(cli, fnum);
3249 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3250 cli->timeout = 20000;
3251 cli_receive_smb(cli);
3252 printf("finished oplock test 3\n");
3254 return (correct && *shared_correct);
3256 /* What are we looking for here? What's sucess and what's FAILURE? */
3262 Test delete on close semantics.
3264 static bool run_deletetest(int dummy)
3266 struct cli_state *cli1 = NULL;
3267 struct cli_state *cli2 = NULL;
3268 const char *fname = "\\delete.file";
3269 uint16_t fnum1 = (uint16_t)-1;
3270 uint16_t fnum2 = (uint16_t)-1;
3271 bool correct = True;
3273 printf("starting delete test\n");
3275 if (!torture_open_connection(&cli1, 0)) {
3279 cli_sockopt(cli1, sockops);
3281 /* Test 1 - this should delete the file on close. */
3283 cli_setatr(cli1, fname, 0, 0);
3284 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3286 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3287 0, FILE_OVERWRITE_IF,
3288 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3289 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3296 uint32 *accinfo = NULL;
3298 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3300 printf("access mode = 0x%lx\n", *accinfo);
3305 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3306 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3311 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3312 printf("[1] open of %s succeeded (should fail)\n", fname);
3317 printf("first delete on close test succeeded.\n");
3319 /* Test 2 - this should delete the file on close. */
3321 cli_setatr(cli1, fname, 0, 0);
3322 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3324 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3325 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3326 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3327 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3332 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3333 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3338 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3339 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3344 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3345 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3346 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3347 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3351 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3353 printf("second delete on close test succeeded.\n");
3356 cli_setatr(cli1, fname, 0, 0);
3357 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3359 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3360 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3361 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3366 /* This should fail with a sharing violation - open for delete is only compatible
3367 with SHARE_DELETE. */
3369 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3370 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3371 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3376 /* This should succeed. */
3378 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3379 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3380 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3385 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3386 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3391 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3392 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3397 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3398 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3403 /* This should fail - file should no longer be there. */
3405 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3406 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3407 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3408 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3410 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3414 printf("third delete on close test succeeded.\n");
3417 cli_setatr(cli1, fname, 0, 0);
3418 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3420 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3421 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3422 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3427 /* This should succeed. */
3428 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3429 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3430 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3435 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3436 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3441 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3442 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3447 /* This should fail - no more opens once delete on close set. */
3448 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3449 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3450 FILE_OPEN, 0, 0, &fnum2))) {
3451 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3455 printf("fourth delete on close test succeeded.\n");
3457 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3458 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3464 cli_setatr(cli1, fname, 0, 0);
3465 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3467 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3468 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3473 /* This should fail - only allowed on NT opens with DELETE access. */
3475 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3476 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3481 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3482 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3487 printf("fifth delete on close test succeeded.\n");
3490 cli_setatr(cli1, fname, 0, 0);
3491 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3493 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3494 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3495 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3496 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3501 /* This should fail - only allowed on NT opens with DELETE access. */
3503 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3504 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3509 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3510 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3515 printf("sixth delete on close test succeeded.\n");
3518 cli_setatr(cli1, fname, 0, 0);
3519 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3521 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3522 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3523 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3528 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3529 printf("[7] setting delete_on_close on file failed !\n");
3534 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3535 printf("[7] unsetting delete_on_close on file failed !\n");
3540 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3541 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3546 /* This next open should succeed - we reset the flag. */
3548 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3549 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3554 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3555 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3560 printf("seventh delete on close test succeeded.\n");
3563 cli_setatr(cli1, fname, 0, 0);
3564 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3566 if (!torture_open_connection(&cli2, 1)) {
3567 printf("[8] failed to open second connection.\n");
3572 cli_sockopt(cli1, sockops);
3574 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3575 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3576 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3577 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3582 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3583 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3584 FILE_OPEN, 0, 0, &fnum2))) {
3585 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3590 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3591 printf("[8] setting delete_on_close on file failed !\n");
3596 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3597 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3602 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3603 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3608 /* This should fail.. */
3609 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3610 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3614 printf("eighth delete on close test succeeded.\n");
3616 /* This should fail - we need to set DELETE_ACCESS. */
3617 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3618 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3619 printf("[9] open of %s succeeded should have failed!\n", fname);
3624 printf("ninth delete on close test succeeded.\n");
3626 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3627 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3628 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3633 /* This should delete the file. */
3634 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3635 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3640 /* This should fail.. */
3641 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3642 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3646 printf("tenth delete on close test succeeded.\n");
3648 cli_setatr(cli1, fname, 0, 0);
3649 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3651 /* What error do we get when attempting to open a read-only file with
3654 /* Create a readonly file. */
3655 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3656 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3657 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3662 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3663 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3668 /* Now try open for delete access. */
3669 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3670 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3671 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3672 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3673 cli_close(cli1, fnum1);
3677 NTSTATUS nterr = cli_nt_error(cli1);
3678 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3679 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3683 printf("eleventh delete on close test succeeded.\n");
3687 printf("finished delete test\n");
3690 /* FIXME: This will crash if we aborted before cli2 got
3691 * intialized, because these functions don't handle
3692 * uninitialized connections. */
3694 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3695 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3696 cli_setatr(cli1, fname, 0, 0);
3697 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3699 if (cli1 && !torture_close_connection(cli1)) {
3702 if (cli2 && !torture_close_connection(cli2)) {
3710 print out server properties
3712 static bool run_properties(int dummy)
3714 struct cli_state *cli;
3715 bool correct = True;
3717 printf("starting properties test\n");
3721 if (!torture_open_connection(&cli, 0)) {
3725 cli_sockopt(cli, sockops);
3727 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3729 if (!torture_close_connection(cli)) {
3738 /* FIRST_DESIRED_ACCESS 0xf019f */
3739 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3740 FILE_READ_EA| /* 0xf */ \
3741 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3742 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3743 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3744 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3745 /* SECOND_DESIRED_ACCESS 0xe0080 */
3746 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3747 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3748 WRITE_OWNER_ACCESS /* 0xe0000 */
3751 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3752 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3754 WRITE_OWNER_ACCESS /* */
3758 Test ntcreate calls made by xcopy
3760 static bool run_xcopy(int dummy)
3762 static struct cli_state *cli1;
3763 const char *fname = "\\test.txt";
3764 bool correct = True;
3765 uint16_t fnum1, fnum2;
3767 printf("starting xcopy test\n");
3769 if (!torture_open_connection(&cli1, 0)) {
3773 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3774 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3775 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3776 0x4044, 0, &fnum1))) {
3777 printf("First open failed - %s\n", cli_errstr(cli1));
3781 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3782 SECOND_DESIRED_ACCESS, 0,
3783 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3784 0x200000, 0, &fnum2))) {
3785 printf("second open failed - %s\n", cli_errstr(cli1));
3789 if (!torture_close_connection(cli1)) {
3797 Test rename on files open with share delete and no share delete.
3799 static bool run_rename(int dummy)
3801 static struct cli_state *cli1;
3802 const char *fname = "\\test.txt";
3803 const char *fname1 = "\\test1.txt";
3804 bool correct = True;
3809 printf("starting rename test\n");
3811 if (!torture_open_connection(&cli1, 0)) {
3815 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3816 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3817 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3818 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3819 printf("First open failed - %s\n", cli_errstr(cli1));
3823 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3824 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3826 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3830 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3831 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3835 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3836 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3837 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3839 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3841 FILE_SHARE_DELETE|FILE_SHARE_READ,
3843 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3844 if (!NT_STATUS_IS_OK(status)) {
3845 printf("Second open failed - %s\n", cli_errstr(cli1));
3849 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3850 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3853 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3856 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3857 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3861 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3862 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3864 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3865 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3866 printf("Third open failed - %s\n", cli_errstr(cli1));
3875 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3876 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3877 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3880 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3881 printf("[8] setting delete_on_close on file failed !\n");
3885 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3886 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3892 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3893 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3896 printf("Third rename succeeded (SHARE_NONE)\n");
3899 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3900 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3904 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3905 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3909 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3910 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3911 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3915 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3916 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3918 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3922 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3923 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3927 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3928 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3932 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3933 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3934 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3938 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3939 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3943 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3947 * Now check if the first name still exists ...
3950 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3951 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3952 printf("Opening original file after rename of open file fails: %s\n",
3956 printf("Opening original file after rename of open file works ...\n");
3957 (void)cli_close(cli1, fnum2);
3961 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3962 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3966 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
3967 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
3968 printf("getatr on file %s failed - %s ! \n",
3973 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
3974 printf("Renamed file %s has wrong attr 0x%x "
3975 "(should be 0x%x)\n",
3978 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
3981 printf("Renamed file %s has archive bit set\n", fname1);
3985 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3986 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3988 if (!torture_close_connection(cli1)) {
3995 static bool run_pipe_number(int dummy)
3997 struct cli_state *cli1;
3998 const char *pipe_name = "\\SPOOLSS";
4002 printf("starting pipenumber test\n");
4003 if (!torture_open_connection(&cli1, 0)) {
4007 cli_sockopt(cli1, sockops);
4009 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4010 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4011 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4015 printf("\r%6d", num_pipes);
4018 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4019 torture_close_connection(cli1);
4024 Test open mode returns on read-only files.
4026 static bool run_opentest(int dummy)
4028 static struct cli_state *cli1;
4029 static struct cli_state *cli2;
4030 const char *fname = "\\readonly.file";
4031 uint16_t fnum1, fnum2;
4034 bool correct = True;
4037 printf("starting open test\n");
4039 if (!torture_open_connection(&cli1, 0)) {
4043 cli_setatr(cli1, fname, 0, 0);
4044 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4046 cli_sockopt(cli1, sockops);
4048 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4049 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4053 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4054 printf("close2 failed (%s)\n", cli_errstr(cli1));
4058 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4059 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4063 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4064 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4068 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4069 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4071 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4072 NT_STATUS_ACCESS_DENIED)) {
4073 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4076 printf("finished open test 1\n");
4078 cli_close(cli1, fnum1);
4080 /* Now try not readonly and ensure ERRbadshare is returned. */
4082 cli_setatr(cli1, fname, 0, 0);
4084 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4085 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4089 /* This will fail - but the error should be ERRshare. */
4090 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4092 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4093 NT_STATUS_SHARING_VIOLATION)) {
4094 printf("correct error code ERRDOS/ERRbadshare returned\n");
4097 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4098 printf("close2 failed (%s)\n", cli_errstr(cli1));
4102 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4104 printf("finished open test 2\n");
4106 /* Test truncate open disposition on file opened for read. */
4108 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4109 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4113 /* write 20 bytes. */
4115 memset(buf, '\0', 20);
4117 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4118 printf("write failed (%s)\n", cli_errstr(cli1));
4122 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4123 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4127 /* Ensure size == 20. */
4128 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4129 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4134 printf("(3) file size != 20\n");
4138 /* Now test if we can truncate a file opened for readonly. */
4140 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4141 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4145 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4146 printf("close2 failed (%s)\n", cli_errstr(cli1));
4150 /* Ensure size == 0. */
4151 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4152 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4157 printf("(3) file size != 0\n");
4160 printf("finished open test 3\n");
4162 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4164 printf("Do ctemp tests\n");
4165 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4166 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4169 printf("ctemp gave path %s\n", tmp_path);
4170 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4171 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4173 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4174 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4177 /* Test the non-io opens... */
4179 if (!torture_open_connection(&cli2, 1)) {
4183 cli_setatr(cli2, fname, 0, 0);
4184 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4186 cli_sockopt(cli2, sockops);
4188 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4190 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4191 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4192 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4196 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4197 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4198 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4202 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4203 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4206 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4207 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4211 printf("non-io open test #1 passed.\n");
4213 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4215 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4217 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4218 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4219 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4223 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4224 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4225 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4229 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4230 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4233 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4234 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4238 printf("non-io open test #2 passed.\n");
4240 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4242 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4244 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4245 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4246 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4250 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4251 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4252 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4256 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4257 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4260 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4261 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4265 printf("non-io open test #3 passed.\n");
4267 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4269 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4271 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4272 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4273 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4277 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4278 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4279 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4283 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4285 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4286 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4290 printf("non-io open test #4 passed.\n");
4292 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4294 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4296 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4297 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4298 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4302 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4303 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4304 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4308 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4309 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4313 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4314 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4318 printf("non-io open test #5 passed.\n");
4320 printf("TEST #6 testing 1 non-io open, one io open\n");
4322 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4324 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4325 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4326 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4330 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4331 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4332 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4336 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4337 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4341 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4342 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4346 printf("non-io open test #6 passed.\n");
4348 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4350 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4352 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4353 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4354 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4358 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4359 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4360 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4364 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4366 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4367 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4371 printf("non-io open test #7 passed.\n");
4373 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4375 if (!torture_close_connection(cli1)) {
4378 if (!torture_close_connection(cli2)) {
4385 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4387 uint16 major, minor;
4388 uint32 caplow, caphigh;
4391 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4392 printf("Server doesn't support UNIX CIFS extensions.\n");
4393 return NT_STATUS_NOT_SUPPORTED;
4396 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4398 if (!NT_STATUS_IS_OK(status)) {
4399 printf("Server didn't return UNIX CIFS extensions: %s\n",
4404 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4406 if (!NT_STATUS_IS_OK(status)) {
4407 printf("Server doesn't support setting UNIX CIFS extensions: "
4408 "%s.\n", nt_errstr(status));
4412 return NT_STATUS_OK;
4416 Test POSIX open /mkdir calls.
4418 static bool run_simple_posix_open_test(int dummy)
4420 static struct cli_state *cli1;
4421 const char *fname = "posix:file";
4422 const char *hname = "posix:hlink";
4423 const char *sname = "posix:symlink";
4424 const char *dname = "posix:dir";
4427 uint16_t fnum1 = (uint16_t)-1;
4428 SMB_STRUCT_STAT sbuf;
4429 bool correct = false;
4432 printf("Starting simple POSIX open test\n");
4434 if (!torture_open_connection(&cli1, 0)) {
4438 cli_sockopt(cli1, sockops);
4440 status = torture_setup_unix_extensions(cli1);
4441 if (!NT_STATUS_IS_OK(status)) {
4445 cli_setatr(cli1, fname, 0, 0);
4446 cli_posix_unlink(cli1, fname);
4447 cli_setatr(cli1, dname, 0, 0);
4448 cli_posix_rmdir(cli1, dname);
4449 cli_setatr(cli1, hname, 0, 0);
4450 cli_posix_unlink(cli1, hname);
4451 cli_setatr(cli1, sname, 0, 0);
4452 cli_posix_unlink(cli1, sname);
4454 /* Create a directory. */
4455 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4456 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4460 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4461 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4465 /* Test ftruncate - set file size. */
4466 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4467 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4471 /* Ensure st_size == 1000 */
4472 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4473 printf("stat failed (%s)\n", cli_errstr(cli1));
4477 if (sbuf.st_ex_size != 1000) {
4478 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4482 /* Test ftruncate - set file size back to zero. */
4483 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4484 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4488 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4489 printf("close failed (%s)\n", cli_errstr(cli1));
4493 /* Now open the file again for read only. */
4494 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4495 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4499 /* Now unlink while open. */
4500 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4501 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4505 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4506 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4510 /* Ensure the file has gone. */
4511 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4512 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4516 /* What happens when we try and POSIX open a directory ? */
4517 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4518 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4521 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4522 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4527 /* Create the file. */
4528 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4529 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4533 /* Write some data into it. */
4534 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4535 printf("cli_write failed: %s\n", cli_errstr(cli1));
4539 cli_close(cli1, fnum1);
4541 /* Now create a hardlink. */
4542 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4543 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4547 /* Now create a symlink. */
4548 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4549 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4553 /* Open the hardlink for read. */
4554 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4555 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4559 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4560 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4564 if (memcmp(buf, "TEST DATA\n", 10)) {
4565 printf("invalid data read from hardlink\n");
4569 /* Do a POSIX lock/unlock. */
4570 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4571 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4575 /* Punch a hole in the locked area. */
4576 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4577 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4581 cli_close(cli1, fnum1);
4583 /* Open the symlink for read - this should fail. A POSIX
4584 client should not be doing opens on a symlink. */
4585 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4586 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4589 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4590 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4591 printf("POSIX open of %s should have failed "
4592 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4593 "failed with %s instead.\n",
4594 sname, cli_errstr(cli1));
4599 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4600 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4604 if (strcmp(namebuf, fname) != 0) {
4605 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4606 sname, fname, namebuf);
4610 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4611 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4615 printf("Simple POSIX open test passed\n");
4620 if (fnum1 != (uint16_t)-1) {
4621 cli_close(cli1, fnum1);
4622 fnum1 = (uint16_t)-1;
4625 cli_setatr(cli1, sname, 0, 0);
4626 cli_posix_unlink(cli1, sname);
4627 cli_setatr(cli1, hname, 0, 0);
4628 cli_posix_unlink(cli1, hname);
4629 cli_setatr(cli1, fname, 0, 0);
4630 cli_posix_unlink(cli1, fname);
4631 cli_setatr(cli1, dname, 0, 0);
4632 cli_posix_rmdir(cli1, dname);
4634 if (!torture_close_connection(cli1)) {
4642 static uint32 open_attrs_table[] = {
4643 FILE_ATTRIBUTE_NORMAL,
4644 FILE_ATTRIBUTE_ARCHIVE,
4645 FILE_ATTRIBUTE_READONLY,
4646 FILE_ATTRIBUTE_HIDDEN,
4647 FILE_ATTRIBUTE_SYSTEM,
4649 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4650 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4651 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4652 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4653 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4654 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4656 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4657 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4658 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4659 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4662 struct trunc_open_results {
4669 static struct trunc_open_results attr_results[] = {
4670 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4671 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4672 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4673 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4674 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4675 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4676 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4677 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4678 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4679 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4680 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4681 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4682 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4683 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4684 { 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 },
4685 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4686 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4687 { 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 },
4688 { 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 },
4689 { 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 },
4690 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4691 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4692 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4693 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4694 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4695 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4698 static bool run_openattrtest(int dummy)
4700 static struct cli_state *cli1;
4701 const char *fname = "\\openattr.file";
4703 bool correct = True;
4705 unsigned int i, j, k, l;
4707 printf("starting open attr test\n");
4709 if (!torture_open_connection(&cli1, 0)) {
4713 cli_sockopt(cli1, sockops);
4715 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4716 cli_setatr(cli1, fname, 0, 0);
4717 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4718 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4719 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4720 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4724 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4725 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4729 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4730 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4731 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4732 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4733 if (attr_results[l].num == k) {
4734 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4735 k, open_attrs_table[i],
4736 open_attrs_table[j],
4737 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4741 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4742 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4743 k, open_attrs_table[i], open_attrs_table[j],
4748 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4754 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4755 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4759 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4760 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4765 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4766 k, open_attrs_table[i], open_attrs_table[j], attr );
4769 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4770 if (attr_results[l].num == k) {
4771 if (attr != attr_results[l].result_attr ||
4772 open_attrs_table[i] != attr_results[l].init_attr ||
4773 open_attrs_table[j] != attr_results[l].trunc_attr) {
4774 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4775 open_attrs_table[i],
4776 open_attrs_table[j],
4778 attr_results[l].result_attr);
4788 cli_setatr(cli1, fname, 0, 0);
4789 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4791 printf("open attr test %s.\n", correct ? "passed" : "failed");
4793 if (!torture_close_connection(cli1)) {
4799 static void list_fn(const char *mnt, struct file_info *finfo,
4800 const char *name, void *state)
4802 int *matched = (int *)state;
4803 if (matched != NULL) {
4809 test directory listing speed
4811 static bool run_dirtest(int dummy)
4814 static struct cli_state *cli;
4816 struct timeval core_start;
4817 bool correct = True;
4820 printf("starting directory test\n");
4822 if (!torture_open_connection(&cli, 0)) {
4826 cli_sockopt(cli, sockops);
4829 for (i=0;i<torture_numops;i++) {
4831 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4832 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4833 fprintf(stderr,"Failed to open %s\n", fname);
4836 cli_close(cli, fnum);
4839 core_start = timeval_current();
4842 cli_list(cli, "a*.*", 0, list_fn, &matched);
4843 printf("Matched %d\n", matched);
4846 cli_list(cli, "b*.*", 0, list_fn, &matched);
4847 printf("Matched %d\n", matched);
4850 cli_list(cli, "xyzabc", 0, list_fn, &matched);
4851 printf("Matched %d\n", matched);
4853 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4856 for (i=0;i<torture_numops;i++) {
4858 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4859 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4862 if (!torture_close_connection(cli)) {
4866 printf("finished dirtest\n");
4871 static void del_fn(const char *mnt, struct file_info *finfo, const char *mask,
4874 struct cli_state *pcli = (struct cli_state *)state;
4876 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4878 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4881 if (finfo->mode & aDIR) {
4882 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4883 printf("del_fn: failed to rmdir %s\n,", fname );
4885 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4886 printf("del_fn: failed to unlink %s\n,", fname );
4892 sees what IOCTLs are supported
4894 bool torture_ioctl_test(int dummy)
4896 static struct cli_state *cli;
4897 uint16_t device, function;
4899 const char *fname = "\\ioctl.dat";
4903 if (!torture_open_connection(&cli, 0)) {
4907 printf("starting ioctl test\n");
4909 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4911 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4912 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4916 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4917 printf("ioctl device info: %s\n", nt_errstr(status));
4919 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4920 printf("ioctl job info: %s\n", nt_errstr(status));
4922 for (device=0;device<0x100;device++) {
4923 printf("ioctl test with device = 0x%x\n", device);
4924 for (function=0;function<0x100;function++) {
4925 uint32 code = (device<<16) | function;
4927 status = cli_raw_ioctl(cli, fnum, code, &blob);
4929 if (NT_STATUS_IS_OK(status)) {
4930 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4932 data_blob_free(&blob);
4937 if (!torture_close_connection(cli)) {
4946 tries varients of chkpath
4948 bool torture_chkpath_test(int dummy)
4950 static struct cli_state *cli;
4954 if (!torture_open_connection(&cli, 0)) {
4958 printf("starting chkpath test\n");
4960 /* cleanup from an old run */
4961 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4962 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4963 cli_rmdir(cli, "\\chkpath.dir");
4965 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4966 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4970 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4971 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4975 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4976 printf("open1 failed (%s)\n", cli_errstr(cli));
4979 cli_close(cli, fnum);
4981 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4982 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4986 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4987 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4991 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4992 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4993 NT_STATUS_NOT_A_DIRECTORY);
4995 printf("* chkpath on a file should fail\n");
4999 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5000 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5001 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5003 printf("* chkpath on a non existant file should fail\n");
5007 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5008 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5009 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5011 printf("* chkpath on a non existent component should fail\n");
5015 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5016 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5017 cli_rmdir(cli, "\\chkpath.dir");
5019 if (!torture_close_connection(cli)) {
5026 static bool run_eatest(int dummy)
5028 static struct cli_state *cli;
5029 const char *fname = "\\eatest.txt";
5030 bool correct = True;
5034 struct ea_struct *ea_list = NULL;
5035 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5038 printf("starting eatest\n");
5040 if (!torture_open_connection(&cli, 0)) {
5041 talloc_destroy(mem_ctx);
5045 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5046 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5047 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5048 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5049 0x4044, 0, &fnum))) {
5050 printf("open failed - %s\n", cli_errstr(cli));
5051 talloc_destroy(mem_ctx);
5055 for (i = 0; i < 10; i++) {
5056 fstring ea_name, ea_val;
5058 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5059 memset(ea_val, (char)i+1, i+1);
5060 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5061 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5062 talloc_destroy(mem_ctx);
5067 cli_close(cli, fnum);
5068 for (i = 0; i < 10; i++) {
5069 fstring ea_name, ea_val;
5071 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5072 memset(ea_val, (char)i+1, i+1);
5073 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5074 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5075 talloc_destroy(mem_ctx);
5080 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5081 if (!NT_STATUS_IS_OK(status)) {
5082 printf("ea_get list failed - %s\n", nt_errstr(status));
5086 printf("num_eas = %d\n", (int)num_eas);
5088 if (num_eas != 20) {
5089 printf("Should be 20 EA's stored... failing.\n");
5093 for (i = 0; i < num_eas; i++) {
5094 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5095 dump_data(0, ea_list[i].value.data,
5096 ea_list[i].value.length);
5099 /* Setting EA's to zero length deletes them. Test this */
5100 printf("Now deleting all EA's - case indepenent....\n");
5103 cli_set_ea_path(cli, fname, "", "", 0);
5105 for (i = 0; i < 20; i++) {
5107 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5108 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5109 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5110 talloc_destroy(mem_ctx);
5116 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5117 if (!NT_STATUS_IS_OK(status)) {
5118 printf("ea_get list failed - %s\n", nt_errstr(status));
5122 printf("num_eas = %d\n", (int)num_eas);
5123 for (i = 0; i < num_eas; i++) {
5124 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5125 dump_data(0, ea_list[i].value.data,
5126 ea_list[i].value.length);
5130 printf("deleting EA's failed.\n");
5134 /* Try and delete a non existant EA. */
5135 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5136 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5140 talloc_destroy(mem_ctx);
5141 if (!torture_close_connection(cli)) {
5148 static bool run_dirtest1(int dummy)
5151 static struct cli_state *cli;
5154 bool correct = True;
5156 printf("starting directory test\n");
5158 if (!torture_open_connection(&cli, 0)) {
5162 cli_sockopt(cli, sockops);
5164 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5165 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5166 cli_rmdir(cli, "\\LISTDIR");
5167 cli_mkdir(cli, "\\LISTDIR");
5169 /* Create 1000 files and 1000 directories. */
5170 for (i=0;i<1000;i++) {
5172 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5173 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5174 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5175 fprintf(stderr,"Failed to open %s\n", fname);
5178 cli_close(cli, fnum);
5180 for (i=0;i<1000;i++) {
5182 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5183 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5184 fprintf(stderr,"Failed to open %s\n", fname);
5189 /* Now ensure that doing an old list sees both files and directories. */
5191 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5192 printf("num_seen = %d\n", num_seen );
5193 /* We should see 100 files + 1000 directories + . and .. */
5194 if (num_seen != 2002)
5197 /* Ensure if we have the "must have" bits we only see the
5201 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5202 printf("num_seen = %d\n", num_seen );
5203 if (num_seen != 1002)
5207 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5208 printf("num_seen = %d\n", num_seen );
5209 if (num_seen != 1000)
5212 /* Delete everything. */
5213 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5214 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5215 cli_rmdir(cli, "\\LISTDIR");
5218 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5219 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5220 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5223 if (!torture_close_connection(cli)) {
5227 printf("finished dirtest1\n");
5232 static bool run_error_map_extract(int dummy) {
5234 static struct cli_state *c_dos;
5235 static struct cli_state *c_nt;
5240 uint32 flgs2, errnum;
5247 /* NT-Error connection */
5249 if (!(c_nt = open_nbt_connection())) {
5253 c_nt->use_spnego = False;
5255 status = cli_negprot(c_nt);
5257 if (!NT_STATUS_IS_OK(status)) {
5258 printf("%s rejected the NT-error negprot (%s)\n", host,
5264 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5266 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5270 /* DOS-Error connection */
5272 if (!(c_dos = open_nbt_connection())) {
5276 c_dos->use_spnego = False;
5277 c_dos->force_dos_errors = True;
5279 status = cli_negprot(c_dos);
5280 if (!NT_STATUS_IS_OK(status)) {
5281 printf("%s rejected the DOS-error negprot (%s)\n", host,
5283 cli_shutdown(c_dos);
5287 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5289 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5293 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5294 fstr_sprintf(user, "%X", error);
5296 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5297 password, strlen(password),
5298 password, strlen(password),
5300 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5303 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5305 /* Case #1: 32-bit NT errors */
5306 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5307 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5309 printf("/** Dos error on NT connection! (%s) */\n",
5311 nt_status = NT_STATUS(0xc0000000);
5314 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5315 password, strlen(password),
5316 password, strlen(password),
5318 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5320 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5322 /* Case #1: 32-bit NT errors */
5323 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5324 printf("/** NT error on DOS connection! (%s) */\n",
5326 errnum = errclass = 0;
5328 cli_dos_error(c_dos, &errclass, &errnum);
5331 if (NT_STATUS_V(nt_status) != error) {
5332 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5333 get_nt_error_c_code(NT_STATUS(error)),
5334 get_nt_error_c_code(nt_status));
5337 printf("\t{%s,\t%s,\t%s},\n",
5338 smb_dos_err_class(errclass),
5339 smb_dos_err_name(errclass, errnum),
5340 get_nt_error_c_code(NT_STATUS(error)));
5345 static bool run_sesssetup_bench(int dummy)
5347 static struct cli_state *c;
5348 const char *fname = "\\file.dat";
5353 if (!torture_open_connection(&c, 0)) {
5357 if (!NT_STATUS_IS_OK(cli_ntcreate(
5358 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5359 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5360 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5361 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5365 for (i=0; i<torture_numops; i++) {
5366 status = cli_session_setup(
5368 password, strlen(password),
5369 password, strlen(password),
5371 if (!NT_STATUS_IS_OK(status)) {
5372 d_printf("(%s) cli_session_setup failed: %s\n",
5373 __location__, nt_errstr(status));
5377 d_printf("\r%d ", (int)c->vuid);
5379 status = cli_ulogoff(c);
5380 if (!NT_STATUS_IS_OK(status)) {
5381 d_printf("(%s) cli_ulogoff failed: %s\n",
5382 __location__, nt_errstr(status));
5391 static bool subst_test(const char *str, const char *user, const char *domain,
5392 uid_t uid, gid_t gid, const char *expected)
5397 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5399 if (strcmp(subst, expected) != 0) {
5400 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5401 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5410 static void chain1_open_completion(struct tevent_req *req)
5414 status = cli_open_recv(req, &fnum);
5417 d_printf("cli_open_recv returned %s: %d\n",
5419 NT_STATUS_IS_OK(status) ? fnum : -1);
5422 static void chain1_write_completion(struct tevent_req *req)
5426 status = cli_write_andx_recv(req, &written);
5429 d_printf("cli_write_andx_recv returned %s: %d\n",
5431 NT_STATUS_IS_OK(status) ? (int)written : -1);
5434 static void chain1_close_completion(struct tevent_req *req)
5437 bool *done = (bool *)tevent_req_callback_data_void(req);
5439 status = cli_close_recv(req);
5444 d_printf("cli_close returned %s\n", nt_errstr(status));
5447 static bool run_chain1(int dummy)
5449 struct cli_state *cli1;
5450 struct event_context *evt = event_context_init(NULL);
5451 struct tevent_req *reqs[3], *smbreqs[3];
5453 const char *str = "foobar";
5456 printf("starting chain1 test\n");
5457 if (!torture_open_connection(&cli1, 0)) {
5461 cli_sockopt(cli1, sockops);
5463 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5464 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5465 if (reqs[0] == NULL) return false;
5466 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5469 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5470 (uint8_t *)str, 0, strlen(str)+1,
5471 smbreqs, 1, &smbreqs[1]);
5472 if (reqs[1] == NULL) return false;
5473 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5475 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5476 if (reqs[2] == NULL) return false;
5477 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5479 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5480 if (!NT_STATUS_IS_OK(status)) {
5485 event_loop_once(evt);
5488 torture_close_connection(cli1);
5492 static void chain2_sesssetup_completion(struct tevent_req *req)
5495 status = cli_session_setup_guest_recv(req);
5496 d_printf("sesssetup returned %s\n", nt_errstr(status));
5499 static void chain2_tcon_completion(struct tevent_req *req)
5501 bool *done = (bool *)tevent_req_callback_data_void(req);
5503 status = cli_tcon_andx_recv(req);
5504 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5508 static bool run_chain2(int dummy)
5510 struct cli_state *cli1;
5511 struct event_context *evt = event_context_init(NULL);
5512 struct tevent_req *reqs[2], *smbreqs[2];
5516 printf("starting chain2 test\n");
5517 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5518 port_to_use, Undefined, 0, NULL);
5519 if (!NT_STATUS_IS_OK(status)) {
5523 cli_sockopt(cli1, sockops);
5525 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5527 if (reqs[0] == NULL) return false;
5528 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5530 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5531 "?????", NULL, 0, &smbreqs[1]);
5532 if (reqs[1] == NULL) return false;
5533 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5535 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5536 if (!NT_STATUS_IS_OK(status)) {
5541 event_loop_once(evt);
5544 torture_close_connection(cli1);
5549 struct torture_createdel_state {
5550 struct tevent_context *ev;
5551 struct cli_state *cli;
5554 static void torture_createdel_created(struct tevent_req *subreq);
5555 static void torture_createdel_closed(struct tevent_req *subreq);
5557 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5558 struct tevent_context *ev,
5559 struct cli_state *cli,
5562 struct tevent_req *req, *subreq;
5563 struct torture_createdel_state *state;
5565 req = tevent_req_create(mem_ctx, &state,
5566 struct torture_createdel_state);
5573 subreq = cli_ntcreate_send(
5574 state, ev, cli, name, 0,
5575 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5576 FILE_ATTRIBUTE_NORMAL,
5577 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5578 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5580 if (tevent_req_nomem(subreq, req)) {
5581 return tevent_req_post(req, ev);
5583 tevent_req_set_callback(subreq, torture_createdel_created, req);
5587 static void torture_createdel_created(struct tevent_req *subreq)
5589 struct tevent_req *req = tevent_req_callback_data(
5590 subreq, struct tevent_req);
5591 struct torture_createdel_state *state = tevent_req_data(
5592 req, struct torture_createdel_state);
5596 status = cli_ntcreate_recv(subreq, &fnum);
5597 TALLOC_FREE(subreq);
5598 if (!NT_STATUS_IS_OK(status)) {
5599 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5600 nt_errstr(status)));
5601 tevent_req_nterror(req, status);
5605 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5606 if (tevent_req_nomem(subreq, req)) {
5609 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5612 static void torture_createdel_closed(struct tevent_req *subreq)
5614 struct tevent_req *req = tevent_req_callback_data(
5615 subreq, struct tevent_req);
5618 status = cli_close_recv(subreq);
5619 if (!NT_STATUS_IS_OK(status)) {
5620 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5621 tevent_req_nterror(req, status);
5624 tevent_req_done(req);
5627 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5629 return tevent_req_simple_recv_ntstatus(req);
5632 struct torture_createdels_state {
5633 struct tevent_context *ev;
5634 struct cli_state *cli;
5635 const char *base_name;
5639 struct tevent_req **reqs;
5642 static void torture_createdels_done(struct tevent_req *subreq);
5644 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5645 struct tevent_context *ev,
5646 struct cli_state *cli,
5647 const char *base_name,
5651 struct tevent_req *req;
5652 struct torture_createdels_state *state;
5655 req = tevent_req_create(mem_ctx, &state,
5656 struct torture_createdels_state);
5662 state->base_name = talloc_strdup(state, base_name);
5663 if (tevent_req_nomem(state->base_name, req)) {
5664 return tevent_req_post(req, ev);
5666 state->num_files = MAX(num_parallel, num_files);
5668 state->received = 0;
5670 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5671 if (tevent_req_nomem(state->reqs, req)) {
5672 return tevent_req_post(req, ev);
5675 for (i=0; i<num_parallel; i++) {
5678 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5680 if (tevent_req_nomem(name, req)) {
5681 return tevent_req_post(req, ev);
5683 state->reqs[i] = torture_createdel_send(
5684 state->reqs, state->ev, state->cli, name);
5685 if (tevent_req_nomem(state->reqs[i], req)) {
5686 return tevent_req_post(req, ev);
5688 name = talloc_move(state->reqs[i], &name);
5689 tevent_req_set_callback(state->reqs[i],
5690 torture_createdels_done, req);
5696 static void torture_createdels_done(struct tevent_req *subreq)
5698 struct tevent_req *req = tevent_req_callback_data(
5699 subreq, struct tevent_req);
5700 struct torture_createdels_state *state = tevent_req_data(
5701 req, struct torture_createdels_state);
5702 size_t num_parallel = talloc_array_length(state->reqs);
5707 status = torture_createdel_recv(subreq);
5708 if (!NT_STATUS_IS_OK(status)){
5709 DEBUG(10, ("torture_createdel_recv returned %s\n",
5710 nt_errstr(status)));
5711 TALLOC_FREE(subreq);
5712 tevent_req_nterror(req, status);
5716 for (i=0; i<num_parallel; i++) {
5717 if (subreq == state->reqs[i]) {
5721 if (i == num_parallel) {
5722 DEBUG(10, ("received something we did not send\n"));
5723 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5726 TALLOC_FREE(state->reqs[i]);
5728 if (state->sent >= state->num_files) {
5729 tevent_req_done(req);
5733 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5735 if (tevent_req_nomem(name, req)) {
5738 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5740 if (tevent_req_nomem(state->reqs[i], req)) {
5743 name = talloc_move(state->reqs[i], &name);
5744 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5748 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5750 return tevent_req_simple_recv_ntstatus(req);
5753 struct swallow_notify_state {
5754 struct tevent_context *ev;
5755 struct cli_state *cli;
5757 uint32_t completion_filter;
5759 bool (*fn)(uint32_t action, const char *name, void *priv);
5763 static void swallow_notify_done(struct tevent_req *subreq);
5765 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5766 struct tevent_context *ev,
5767 struct cli_state *cli,
5769 uint32_t completion_filter,
5771 bool (*fn)(uint32_t action,
5776 struct tevent_req *req, *subreq;
5777 struct swallow_notify_state *state;
5779 req = tevent_req_create(mem_ctx, &state,
5780 struct swallow_notify_state);
5787 state->completion_filter = completion_filter;
5788 state->recursive = recursive;
5792 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5793 0xffff, state->completion_filter,
5795 if (tevent_req_nomem(subreq, req)) {
5796 return tevent_req_post(req, ev);
5798 tevent_req_set_callback(subreq, swallow_notify_done, req);
5802 static void swallow_notify_done(struct tevent_req *subreq)
5804 struct tevent_req *req = tevent_req_callback_data(
5805 subreq, struct tevent_req);
5806 struct swallow_notify_state *state = tevent_req_data(
5807 req, struct swallow_notify_state);
5809 uint32_t i, num_changes;
5810 struct notify_change *changes;
5812 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5813 TALLOC_FREE(subreq);
5814 if (!NT_STATUS_IS_OK(status)) {
5815 DEBUG(10, ("cli_notify_recv returned %s\n",
5816 nt_errstr(status)));
5817 tevent_req_nterror(req, status);
5821 for (i=0; i<num_changes; i++) {
5822 state->fn(changes[i].action, changes[i].name, state->priv);
5824 TALLOC_FREE(changes);
5826 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5827 0xffff, state->completion_filter,
5829 if (tevent_req_nomem(subreq, req)) {
5832 tevent_req_set_callback(subreq, swallow_notify_done, req);
5835 static bool print_notifies(uint32_t action, const char *name, void *priv)
5837 if (DEBUGLEVEL > 5) {
5838 d_printf("%d %s\n", (int)action, name);
5843 static void notify_bench_done(struct tevent_req *req)
5845 int *num_finished = (int *)tevent_req_callback_data_void(req);
5849 static bool run_notify_bench(int dummy)
5851 const char *dname = "\\notify-bench";
5852 struct tevent_context *ev;
5855 struct tevent_req *req1;
5856 struct tevent_req *req2 = NULL;
5857 int i, num_unc_names;
5858 int num_finished = 0;
5860 printf("starting notify-bench test\n");
5862 if (use_multishare_conn) {
5864 unc_list = file_lines_load(multishare_conn_fname,
5865 &num_unc_names, 0, NULL);
5866 if (!unc_list || num_unc_names <= 0) {
5867 d_printf("Failed to load unc names list from '%s'\n",
5868 multishare_conn_fname);
5871 TALLOC_FREE(unc_list);
5876 ev = tevent_context_init(talloc_tos());
5878 d_printf("tevent_context_init failed\n");
5882 for (i=0; i<num_unc_names; i++) {
5883 struct cli_state *cli;
5886 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5888 if (base_fname == NULL) {
5892 if (!torture_open_connection(&cli, i)) {
5896 status = cli_ntcreate(cli, dname, 0,
5897 MAXIMUM_ALLOWED_ACCESS,
5898 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5900 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5903 if (!NT_STATUS_IS_OK(status)) {
5904 d_printf("Could not create %s: %s\n", dname,
5909 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5910 FILE_NOTIFY_CHANGE_FILE_NAME |
5911 FILE_NOTIFY_CHANGE_DIR_NAME |
5912 FILE_NOTIFY_CHANGE_ATTRIBUTES |
5913 FILE_NOTIFY_CHANGE_LAST_WRITE,
5914 false, print_notifies, NULL);
5916 d_printf("Could not create notify request\n");
5920 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5921 base_fname, 10, torture_numops);
5923 d_printf("Could not create createdels request\n");
5926 TALLOC_FREE(base_fname);
5928 tevent_req_set_callback(req2, notify_bench_done,
5932 while (num_finished < num_unc_names) {
5934 ret = tevent_loop_once(ev);
5936 d_printf("tevent_loop_once failed\n");
5941 if (!tevent_req_poll(req2, ev)) {
5942 d_printf("tevent_req_poll failed\n");
5945 status = torture_createdels_recv(req2);
5946 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5951 static bool run_mangle1(int dummy)
5953 struct cli_state *cli;
5954 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5958 time_t change_time, access_time, write_time;
5962 printf("starting mangle1 test\n");
5963 if (!torture_open_connection(&cli, 0)) {
5967 cli_sockopt(cli, sockops);
5969 if (!NT_STATUS_IS_OK(cli_ntcreate(
5970 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5971 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5972 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5975 cli_close(cli, fnum);
5977 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5978 if (!NT_STATUS_IS_OK(status)) {
5979 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5983 d_printf("alt_name: %s\n", alt_name);
5985 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5986 d_printf("cli_open(%s) failed: %s\n", alt_name,
5990 cli_close(cli, fnum);
5992 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
5993 &write_time, &size, &mode);
5994 if (!NT_STATUS_IS_OK(status)) {
5995 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6003 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6005 size_t *to_pull = (size_t *)priv;
6006 size_t thistime = *to_pull;
6008 thistime = MIN(thistime, n);
6009 if (thistime == 0) {
6013 memset(buf, 0, thistime);
6014 *to_pull -= thistime;
6018 static bool run_windows_write(int dummy)
6020 struct cli_state *cli1;
6024 const char *fname = "\\writetest.txt";
6025 struct timeval start_time;
6029 printf("starting windows_write test\n");
6030 if (!torture_open_connection(&cli1, 0)) {
6034 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6035 printf("open failed (%s)\n", cli_errstr(cli1));
6039 cli_sockopt(cli1, sockops);
6041 start_time = timeval_current();
6043 for (i=0; i<torture_numops; i++) {
6045 off_t start = i * torture_blocksize;
6047 size_t to_pull = torture_blocksize - 1;
6049 if (cli_write(cli1, fnum, 0, &c,
6050 start + torture_blocksize - 1, 1) != 1) {
6051 printf("cli_write failed: %s\n", cli_errstr(cli1));
6055 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6056 null_source, &to_pull);
6057 if (!NT_STATUS_IS_OK(status)) {
6058 printf("cli_push returned: %s\n", nt_errstr(status));
6063 seconds = timeval_elapsed(&start_time);
6064 kbytes = (double)torture_blocksize * torture_numops;
6067 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6068 (double)seconds, (int)(kbytes/seconds));
6072 cli_close(cli1, fnum);
6073 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6074 torture_close_connection(cli1);
6078 static bool run_cli_echo(int dummy)
6080 struct cli_state *cli;
6083 printf("starting cli_echo test\n");
6084 if (!torture_open_connection(&cli, 0)) {
6087 cli_sockopt(cli, sockops);
6089 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6091 d_printf("cli_echo returned %s\n", nt_errstr(status));
6093 torture_close_connection(cli);
6094 return NT_STATUS_IS_OK(status);
6097 static bool run_uid_regression_test(int dummy)
6099 static struct cli_state *cli;
6102 bool correct = True;
6105 printf("starting uid regression test\n");
6107 if (!torture_open_connection(&cli, 0)) {
6111 cli_sockopt(cli, sockops);
6113 /* Ok - now save then logoff our current user. */
6114 old_vuid = cli->vuid;
6116 status = cli_ulogoff(cli);
6117 if (!NT_STATUS_IS_OK(status)) {
6118 d_printf("(%s) cli_ulogoff failed: %s\n",
6119 __location__, nt_errstr(status));
6124 cli->vuid = old_vuid;
6126 /* Try an operation. */
6127 status = cli_mkdir(cli, "\\uid_reg_test");
6128 if (NT_STATUS_IS_OK(status)) {
6129 d_printf("(%s) cli_mkdir succeeded\n",
6134 /* Should be bad uid. */
6135 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6136 NT_STATUS_USER_SESSION_DELETED)) {
6142 old_cnum = cli->cnum;
6144 /* Now try a SMBtdis with the invald vuid set to zero. */
6147 /* This should succeed. */
6148 status = cli_tdis(cli);
6150 if (NT_STATUS_IS_OK(status)) {
6151 d_printf("First tdis with invalid vuid should succeed.\n");
6153 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6158 cli->vuid = old_vuid;
6159 cli->cnum = old_cnum;
6161 /* This should fail. */
6162 status = cli_tdis(cli);
6163 if (NT_STATUS_IS_OK(status)) {
6164 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6168 /* Should be bad tid. */
6169 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6170 NT_STATUS_NETWORK_NAME_DELETED)) {
6176 cli_rmdir(cli, "\\uid_reg_test");
6185 static const char *illegal_chars = "*\\/?<>|\":";
6186 static char force_shortname_chars[] = " +,.[];=\177";
6188 static void shortname_del_fn(const char *mnt, struct file_info *finfo,
6189 const char *mask, void *state)
6191 struct cli_state *pcli = (struct cli_state *)state;
6193 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6195 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6198 if (finfo->mode & aDIR) {
6199 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6200 printf("del_fn: failed to rmdir %s\n,", fname );
6202 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6203 printf("del_fn: failed to unlink %s\n,", fname );
6213 static void shortname_list_fn(const char *mnt, struct file_info *finfo,
6214 const char *name, void *state)
6216 struct sn_state *s = (struct sn_state *)state;
6220 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6221 i, finfo->name, finfo->short_name);
6224 if (strchr(force_shortname_chars, i)) {
6225 if (!finfo->short_name[0]) {
6226 /* Shortname not created when it should be. */
6227 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6228 __location__, finfo->name, i);
6231 } else if (finfo->short_name[0]){
6232 /* Shortname created when it should not be. */
6233 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6234 __location__, finfo->short_name, finfo->name);
6240 static bool run_shortname_test(int dummy)
6242 static struct cli_state *cli;
6243 bool correct = True;
6248 printf("starting shortname test\n");
6250 if (!torture_open_connection(&cli, 0)) {
6254 cli_sockopt(cli, sockops);
6256 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6257 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6258 cli_rmdir(cli, "\\shortname");
6260 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6261 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6262 __location__, cli_errstr(cli));
6267 strlcpy(fname, "\\shortname\\", sizeof(fname));
6268 strlcat(fname, "test .txt", sizeof(fname));
6272 for (i = 32; i < 128; i++) {
6274 uint16_t fnum = (uint16_t)-1;
6278 if (strchr(illegal_chars, i)) {
6283 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6284 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6285 if (!NT_STATUS_IS_OK(status)) {
6286 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6287 __location__, fname, cli_errstr(cli));
6291 cli_close(cli, fnum);
6294 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6296 if (s.matched != 1) {
6297 d_printf("(%s) failed to list %s: %s\n",
6298 __location__, fname, cli_errstr(cli));
6302 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6303 d_printf("(%s) failed to delete %s: %s\n",
6304 __location__, fname, cli_errstr(cli));
6317 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6318 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6319 cli_rmdir(cli, "\\shortname");
6320 torture_close_connection(cli);
6324 static void pagedsearch_cb(struct tevent_req *req)
6327 struct tldap_message *msg;
6330 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6331 if (rc != TLDAP_SUCCESS) {
6332 d_printf("tldap_search_paged_recv failed: %s\n",
6333 tldap_err2string(rc));
6336 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6340 if (!tldap_entry_dn(msg, &dn)) {
6341 d_printf("tldap_entry_dn failed\n");
6344 d_printf("%s\n", dn);
6348 static bool run_tldap(int dummy)
6350 struct tldap_context *ld;
6353 struct sockaddr_storage addr;
6354 struct tevent_context *ev;
6355 struct tevent_req *req;
6359 if (!resolve_name(host, &addr, 0, false)) {
6360 d_printf("could not find host %s\n", host);
6363 status = open_socket_out(&addr, 389, 9999, &fd);
6364 if (!NT_STATUS_IS_OK(status)) {
6365 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6369 ld = tldap_context_create(talloc_tos(), fd);
6372 d_printf("tldap_context_create failed\n");
6376 rc = tldap_fetch_rootdse(ld);
6377 if (rc != TLDAP_SUCCESS) {
6378 d_printf("tldap_fetch_rootdse failed: %s\n",
6379 tldap_errstr(talloc_tos(), ld, rc));
6383 basedn = tldap_talloc_single_attribute(
6384 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6385 if (basedn == NULL) {
6386 d_printf("no defaultNamingContext\n");
6389 d_printf("defaultNamingContext: %s\n", basedn);
6391 ev = tevent_context_init(talloc_tos());
6393 d_printf("tevent_context_init failed\n");
6397 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6398 TLDAP_SCOPE_SUB, "(objectclass=*)",
6400 NULL, 0, NULL, 0, 0, 0, 0, 5);
6402 d_printf("tldap_search_paged_send failed\n");
6405 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6407 tevent_req_poll(req, ev);
6411 /* test search filters against rootDSE */
6412 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6413 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6415 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6416 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6417 talloc_tos(), NULL, NULL);
6418 if (rc != TLDAP_SUCCESS) {
6419 d_printf("tldap_search with complex filter failed: %s\n",
6420 tldap_errstr(talloc_tos(), ld, rc));
6428 /* Torture test to ensure no regression of :
6429 https://bugzilla.samba.org/show_bug.cgi?id=7084
6432 static bool run_dir_createtime(int dummy)
6434 struct cli_state *cli;
6435 const char *dname = "\\testdir";
6436 const char *fname = "\\testdir\\testfile";
6438 struct timespec create_time;
6439 struct timespec create_time1;
6443 if (!torture_open_connection(&cli, 0)) {
6447 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6448 cli_rmdir(cli, dname);
6450 status = cli_mkdir(cli, dname);
6451 if (!NT_STATUS_IS_OK(status)) {
6452 printf("mkdir failed: %s\n", nt_errstr(status));
6456 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6458 if (!NT_STATUS_IS_OK(status)) {
6459 printf("cli_qpathinfo2 returned %s\n",
6464 /* Sleep 3 seconds, then create a file. */
6467 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6469 if (!NT_STATUS_IS_OK(status)) {
6470 printf("cli_open failed: %s\n", nt_errstr(status));
6474 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6476 if (!NT_STATUS_IS_OK(status)) {
6477 printf("cli_qpathinfo2 (2) returned %s\n",
6482 if (timespec_compare(&create_time1, &create_time)) {
6483 printf("run_dir_createtime: create time was updated (error)\n");
6485 printf("run_dir_createtime: create time was not updated (correct)\n");
6491 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6492 cli_rmdir(cli, dname);
6493 if (!torture_close_connection(cli)) {
6500 static bool run_streamerror(int dummy)
6502 struct cli_state *cli;
6503 const char *dname = "\\testdir";
6504 const char *streamname =
6505 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6507 time_t change_time, access_time, write_time;
6509 uint16_t mode, fnum;
6512 if (!torture_open_connection(&cli, 0)) {
6516 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6517 cli_rmdir(cli, dname);
6519 status = cli_mkdir(cli, dname);
6520 if (!NT_STATUS_IS_OK(status)) {
6521 printf("mkdir failed: %s\n", nt_errstr(status));
6525 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6527 status = cli_nt_error(cli);
6529 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6530 printf("pathinfo returned %s, expected "
6531 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6536 status = cli_ntcreate(cli, streamname, 0x16,
6537 FILE_READ_DATA|FILE_READ_EA|
6538 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6539 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6540 FILE_OPEN, 0, 0, &fnum);
6542 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6543 printf("ntcreate returned %s, expected "
6544 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6550 cli_rmdir(cli, dname);
6554 static bool run_local_substitute(int dummy)
6558 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6559 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6560 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6561 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6562 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6563 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6564 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6565 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6567 /* Different captialization rules in sub_basic... */
6569 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6575 static bool run_local_base64(int dummy)
6580 for (i=1; i<2000; i++) {
6581 DATA_BLOB blob1, blob2;
6584 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6586 generate_random_buffer(blob1.data, blob1.length);
6588 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6590 d_fprintf(stderr, "base64_encode_data_blob failed "
6591 "for %d bytes\n", i);
6594 blob2 = base64_decode_data_blob(b64);
6597 if (data_blob_cmp(&blob1, &blob2)) {
6598 d_fprintf(stderr, "data_blob_cmp failed for %d "
6602 TALLOC_FREE(blob1.data);
6603 data_blob_free(&blob2);
6608 static bool run_local_gencache(int dummy)
6614 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6615 d_printf("%s: gencache_set() failed\n", __location__);
6619 if (!gencache_get("foo", NULL, NULL)) {
6620 d_printf("%s: gencache_get() failed\n", __location__);
6624 if (!gencache_get("foo", &val, &tm)) {
6625 d_printf("%s: gencache_get() failed\n", __location__);
6629 if (strcmp(val, "bar") != 0) {
6630 d_printf("%s: gencache_get() returned %s, expected %s\n",
6631 __location__, val, "bar");
6638 if (!gencache_del("foo")) {
6639 d_printf("%s: gencache_del() failed\n", __location__);
6642 if (gencache_del("foo")) {
6643 d_printf("%s: second gencache_del() succeeded\n",
6648 if (gencache_get("foo", &val, &tm)) {
6649 d_printf("%s: gencache_get() on deleted entry "
6650 "succeeded\n", __location__);
6654 blob = data_blob_string_const_null("bar");
6655 tm = time(NULL) + 60;
6657 if (!gencache_set_data_blob("foo", &blob, tm)) {
6658 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6662 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6663 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6667 if (strcmp((const char *)blob.data, "bar") != 0) {
6668 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6669 __location__, (const char *)blob.data, "bar");
6670 data_blob_free(&blob);
6674 data_blob_free(&blob);
6676 if (!gencache_del("foo")) {
6677 d_printf("%s: gencache_del() failed\n", __location__);
6680 if (gencache_del("foo")) {
6681 d_printf("%s: second gencache_del() succeeded\n",
6686 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6687 d_printf("%s: gencache_get_data_blob() on deleted entry "
6688 "succeeded\n", __location__);
6695 static bool rbt_testval(struct db_context *db, const char *key,
6698 struct db_record *rec;
6699 TDB_DATA data = string_tdb_data(value);
6703 rec = db->fetch_locked(db, db, string_tdb_data(key));
6705 d_fprintf(stderr, "fetch_locked failed\n");
6708 status = rec->store(rec, data, 0);
6709 if (!NT_STATUS_IS_OK(status)) {
6710 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6715 rec = db->fetch_locked(db, db, string_tdb_data(key));
6717 d_fprintf(stderr, "second fetch_locked failed\n");
6720 if ((rec->value.dsize != data.dsize)
6721 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6722 d_fprintf(stderr, "Got wrong data back\n");
6732 static bool run_local_rbtree(int dummy)
6734 struct db_context *db;
6738 db = db_open_rbt(NULL);
6741 d_fprintf(stderr, "db_open_rbt failed\n");
6745 for (i=0; i<1000; i++) {
6748 if (asprintf(&key, "key%ld", random()) == -1) {
6751 if (asprintf(&value, "value%ld", random()) == -1) {
6756 if (!rbt_testval(db, key, value)) {
6763 if (asprintf(&value, "value%ld", random()) == -1) {
6768 if (!rbt_testval(db, key, value)) {
6785 struct talloc_dict_test {
6789 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6791 int *count = (int *)priv;
6796 static bool run_local_talloc_dict(int dummy)
6798 struct talloc_dict *dict;
6799 struct talloc_dict_test *t;
6802 dict = talloc_dict_init(talloc_tos());
6807 t = talloc(talloc_tos(), struct talloc_dict_test);
6814 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6819 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6832 static bool run_local_string_to_sid(int dummy) {
6835 if (string_to_sid(&sid, "S--1-5-32-545")) {
6836 printf("allowing S--1-5-32-545\n");
6839 if (string_to_sid(&sid, "S-1-5-32-+545")) {
6840 printf("allowing S-1-5-32-+545\n");
6843 if (string_to_sid(&sid, "S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
6844 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6847 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
6848 printf("allowing S-1-5-32-545-abc\n");
6851 if (!string_to_sid(&sid, "S-1-5-32-545")) {
6852 printf("could not parse S-1-5-32-545\n");
6855 if (!sid_equal(&sid, &global_sid_Builtin_Users)) {
6856 printf("mis-parsed S-1-5-32-545 as %s\n",
6857 sid_string_tos(&sid));
6863 static bool run_local_binary_to_sid(int dummy) {
6864 struct dom_sid *sid = talloc(NULL, struct dom_sid);
6865 static const char good_binary_sid[] = {
6866 0x1, /* revision number */
6868 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
6869 0x1, 0x1, 0x1, 0x1, /* auth[0] */
6870 0x1, 0x1, 0x1, 0x1, /* auth[1] */
6871 0x1, 0x1, 0x1, 0x1, /* auth[2] */
6872 0x1, 0x1, 0x1, 0x1, /* auth[3] */
6873 0x1, 0x1, 0x1, 0x1, /* auth[4] */
6874 0x1, 0x1, 0x1, 0x1, /* auth[5] */
6875 0x1, 0x1, 0x1, 0x1, /* auth[6] */
6876 0x1, 0x1, 0x1, 0x1, /* auth[7] */
6877 0x1, 0x1, 0x1, 0x1, /* auth[8] */
6878 0x1, 0x1, 0x1, 0x1, /* auth[9] */
6879 0x1, 0x1, 0x1, 0x1, /* auth[10] */
6880 0x1, 0x1, 0x1, 0x1, /* auth[11] */
6881 0x1, 0x1, 0x1, 0x1, /* auth[12] */
6882 0x1, 0x1, 0x1, 0x1, /* auth[13] */
6883 0x1, 0x1, 0x1, 0x1, /* auth[14] */
6886 static const char long_binary_sid[] = {
6887 0x1, /* revision number */
6889 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
6890 0x1, 0x1, 0x1, 0x1, /* auth[0] */
6891 0x1, 0x1, 0x1, 0x1, /* auth[1] */
6892 0x1, 0x1, 0x1, 0x1, /* auth[2] */
6893 0x1, 0x1, 0x1, 0x1, /* auth[3] */
6894 0x1, 0x1, 0x1, 0x1, /* auth[4] */
6895 0x1, 0x1, 0x1, 0x1, /* auth[5] */
6896 0x1, 0x1, 0x1, 0x1, /* auth[6] */
6897 0x1, 0x1, 0x1, 0x1, /* auth[7] */
6898 0x1, 0x1, 0x1, 0x1, /* auth[8] */
6899 0x1, 0x1, 0x1, 0x1, /* auth[9] */
6900 0x1, 0x1, 0x1, 0x1, /* auth[10] */
6901 0x1, 0x1, 0x1, 0x1, /* auth[11] */
6902 0x1, 0x1, 0x1, 0x1, /* auth[12] */
6903 0x1, 0x1, 0x1, 0x1, /* auth[13] */
6904 0x1, 0x1, 0x1, 0x1, /* auth[14] */
6905 0x1, 0x1, 0x1, 0x1, /* auth[15] */
6906 0x1, 0x1, 0x1, 0x1, /* auth[16] */
6907 0x1, 0x1, 0x1, 0x1, /* auth[17] */
6910 static const char long_binary_sid2[] = {
6911 0x1, /* revision number */
6913 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
6914 0x1, 0x1, 0x1, 0x1, /* auth[0] */
6915 0x1, 0x1, 0x1, 0x1, /* auth[1] */
6916 0x1, 0x1, 0x1, 0x1, /* auth[2] */
6917 0x1, 0x1, 0x1, 0x1, /* auth[3] */
6918 0x1, 0x1, 0x1, 0x1, /* auth[4] */
6919 0x1, 0x1, 0x1, 0x1, /* auth[5] */
6920 0x1, 0x1, 0x1, 0x1, /* auth[6] */
6921 0x1, 0x1, 0x1, 0x1, /* auth[7] */
6922 0x1, 0x1, 0x1, 0x1, /* auth[8] */
6923 0x1, 0x1, 0x1, 0x1, /* auth[9] */
6924 0x1, 0x1, 0x1, 0x1, /* auth[10] */
6925 0x1, 0x1, 0x1, 0x1, /* auth[11] */
6926 0x1, 0x1, 0x1, 0x1, /* auth[12] */
6927 0x1, 0x1, 0x1, 0x1, /* auth[13] */
6928 0x1, 0x1, 0x1, 0x1, /* auth[14] */
6929 0x1, 0x1, 0x1, 0x1, /* auth[15] */
6930 0x1, 0x1, 0x1, 0x1, /* auth[16] */
6931 0x1, 0x1, 0x1, 0x1, /* auth[17] */
6932 0x1, 0x1, 0x1, 0x1, /* auth[18] */
6933 0x1, 0x1, 0x1, 0x1, /* auth[19] */
6934 0x1, 0x1, 0x1, 0x1, /* auth[20] */
6935 0x1, 0x1, 0x1, 0x1, /* auth[21] */
6936 0x1, 0x1, 0x1, 0x1, /* auth[22] */
6937 0x1, 0x1, 0x1, 0x1, /* auth[23] */
6938 0x1, 0x1, 0x1, 0x1, /* auth[24] */
6939 0x1, 0x1, 0x1, 0x1, /* auth[25] */
6940 0x1, 0x1, 0x1, 0x1, /* auth[26] */
6941 0x1, 0x1, 0x1, 0x1, /* auth[27] */
6942 0x1, 0x1, 0x1, 0x1, /* auth[28] */
6943 0x1, 0x1, 0x1, 0x1, /* auth[29] */
6944 0x1, 0x1, 0x1, 0x1, /* auth[30] */
6945 0x1, 0x1, 0x1, 0x1, /* auth[31] */
6948 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
6951 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
6954 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
6960 /* Split a path name into filename and stream name components. Canonicalise
6961 * such that an implicit $DATA token is always explicit.
6963 * The "specification" of this function can be found in the
6964 * run_local_stream_name() function in torture.c, I've tried those
6965 * combinations against a W2k3 server.
6968 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6969 char **pbase, char **pstream)
6972 char *stream = NULL;
6973 char *sname; /* stream name */
6974 const char *stype; /* stream type */
6976 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6978 sname = strchr_m(fname, ':');
6980 if (lp_posix_pathnames() || (sname == NULL)) {
6981 if (pbase != NULL) {
6982 base = talloc_strdup(mem_ctx, fname);
6983 NT_STATUS_HAVE_NO_MEMORY(base);
6988 if (pbase != NULL) {
6989 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6990 NT_STATUS_HAVE_NO_MEMORY(base);
6995 stype = strchr_m(sname, ':');
6997 if (stype == NULL) {
6998 sname = talloc_strdup(mem_ctx, sname);
7002 if (StrCaseCmp(stype, ":$DATA") != 0) {
7004 * If there is an explicit stream type, so far we only
7005 * allow $DATA. Is there anything else allowed? -- vl
7007 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7009 return NT_STATUS_OBJECT_NAME_INVALID;
7011 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7015 if (sname == NULL) {
7017 return NT_STATUS_NO_MEMORY;
7020 if (sname[0] == '\0') {
7022 * no stream name, so no stream
7027 if (pstream != NULL) {
7028 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7029 if (stream == NULL) {
7032 return NT_STATUS_NO_MEMORY;
7035 * upper-case the type field
7037 strupper_m(strchr_m(stream, ':')+1);
7041 if (pbase != NULL) {
7044 if (pstream != NULL) {
7047 return NT_STATUS_OK;
7050 static bool test_stream_name(const char *fname, const char *expected_base,
7051 const char *expected_stream,
7052 NTSTATUS expected_status)
7056 char *stream = NULL;
7058 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7059 if (!NT_STATUS_EQUAL(status, expected_status)) {
7063 if (!NT_STATUS_IS_OK(status)) {
7067 if (base == NULL) goto error;
7069 if (strcmp(expected_base, base) != 0) goto error;
7071 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7072 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7074 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7078 TALLOC_FREE(stream);
7082 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7083 fname, expected_base ? expected_base : "<NULL>",
7084 expected_stream ? expected_stream : "<NULL>",
7085 nt_errstr(expected_status));
7086 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7087 base ? base : "<NULL>", stream ? stream : "<NULL>",
7090 TALLOC_FREE(stream);
7094 static bool run_local_stream_name(int dummy)
7098 ret &= test_stream_name(
7099 "bla", "bla", NULL, NT_STATUS_OK);
7100 ret &= test_stream_name(
7101 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7102 ret &= test_stream_name(
7103 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7104 ret &= test_stream_name(
7105 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7106 ret &= test_stream_name(
7107 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7108 ret &= test_stream_name(
7109 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7110 ret &= test_stream_name(
7111 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7112 ret &= test_stream_name(
7113 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7118 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7120 if (a.length != b.length) {
7121 printf("a.length=%d != b.length=%d\n",
7122 (int)a.length, (int)b.length);
7125 if (memcmp(a.data, b.data, a.length) != 0) {
7126 printf("a.data and b.data differ\n");
7132 static bool run_local_memcache(int dummy)
7134 struct memcache *cache;
7136 DATA_BLOB d1, d2, d3;
7137 DATA_BLOB v1, v2, v3;
7139 TALLOC_CTX *mem_ctx;
7141 size_t size1, size2;
7144 cache = memcache_init(NULL, 100);
7146 if (cache == NULL) {
7147 printf("memcache_init failed\n");
7151 d1 = data_blob_const("d1", 2);
7152 d2 = data_blob_const("d2", 2);
7153 d3 = data_blob_const("d3", 2);
7155 k1 = data_blob_const("d1", 2);
7156 k2 = data_blob_const("d2", 2);
7158 memcache_add(cache, STAT_CACHE, k1, d1);
7159 memcache_add(cache, GETWD_CACHE, k2, d2);
7161 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7162 printf("could not find k1\n");
7165 if (!data_blob_equal(d1, v1)) {
7169 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7170 printf("could not find k2\n");
7173 if (!data_blob_equal(d2, v2)) {
7177 memcache_add(cache, STAT_CACHE, k1, d3);
7179 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7180 printf("could not find replaced k1\n");
7183 if (!data_blob_equal(d3, v3)) {
7187 memcache_add(cache, GETWD_CACHE, k1, d1);
7189 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7190 printf("Did find k2, should have been purged\n");
7196 cache = memcache_init(NULL, 0);
7198 mem_ctx = talloc_init("foo");
7200 str1 = talloc_strdup(mem_ctx, "string1");
7201 str2 = talloc_strdup(mem_ctx, "string2");
7203 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7204 data_blob_string_const("torture"), &str1);
7205 size1 = talloc_total_size(cache);
7207 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7208 data_blob_string_const("torture"), &str2);
7209 size2 = talloc_total_size(cache);
7211 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7213 if (size2 > size1) {
7214 printf("memcache leaks memory!\n");
7224 static void wbclient_done(struct tevent_req *req)
7227 struct winbindd_response *wb_resp;
7228 int *i = (int *)tevent_req_callback_data_void(req);
7230 wbc_err = wb_trans_recv(req, req, &wb_resp);
7233 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7236 static bool run_local_wbclient(int dummy)
7238 struct event_context *ev;
7239 struct wb_context **wb_ctx;
7240 struct winbindd_request wb_req;
7241 bool result = false;
7244 BlockSignals(True, SIGPIPE);
7246 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7251 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7252 if (wb_ctx == NULL) {
7256 ZERO_STRUCT(wb_req);
7257 wb_req.cmd = WINBINDD_PING;
7259 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7261 for (i=0; i<nprocs; i++) {
7262 wb_ctx[i] = wb_context_init(ev, NULL);
7263 if (wb_ctx[i] == NULL) {
7266 for (j=0; j<torture_numops; j++) {
7267 struct tevent_req *req;
7268 req = wb_trans_send(ev, ev, wb_ctx[i],
7269 (j % 2) == 0, &wb_req);
7273 tevent_req_set_callback(req, wbclient_done, &i);
7279 while (i < nprocs * torture_numops) {
7280 event_loop_once(ev);
7289 static void getaddrinfo_finished(struct tevent_req *req)
7291 char *name = (char *)tevent_req_callback_data_void(req);
7292 struct addrinfo *ainfo;
7295 res = getaddrinfo_recv(req, &ainfo);
7297 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7300 d_printf("gai(%s) succeeded\n", name);
7301 freeaddrinfo(ainfo);
7304 static bool run_getaddrinfo_send(int dummy)
7306 TALLOC_CTX *frame = talloc_stackframe();
7307 struct fncall_context *ctx;
7308 struct tevent_context *ev;
7309 bool result = false;
7310 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7311 "www.slashdot.org", "heise.de" };
7312 struct tevent_req *reqs[4];
7315 ev = event_context_init(frame);
7320 ctx = fncall_context_init(frame, 4);
7322 for (i=0; i<ARRAY_SIZE(names); i++) {
7323 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7325 if (reqs[i] == NULL) {
7328 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7332 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7333 tevent_loop_once(ev);
7342 static bool dbtrans_inc(struct db_context *db)
7344 struct db_record *rec;
7349 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7351 printf(__location__ "fetch_lock failed\n");
7355 if (rec->value.dsize != sizeof(uint32_t)) {
7356 printf(__location__ "value.dsize = %d\n",
7357 (int)rec->value.dsize);
7361 val = (uint32_t *)rec->value.dptr;
7364 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7367 if (!NT_STATUS_IS_OK(status)) {
7368 printf(__location__ "store failed: %s\n",
7379 static bool run_local_dbtrans(int dummy)
7381 struct db_context *db;
7382 struct db_record *rec;
7387 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7388 O_RDWR|O_CREAT, 0600);
7390 printf("Could not open transtest.db\n");
7394 res = db->transaction_start(db);
7396 printf(__location__ "transaction_start failed\n");
7400 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7402 printf(__location__ "fetch_lock failed\n");
7406 if (rec->value.dptr == NULL) {
7408 status = rec->store(
7409 rec, make_tdb_data((uint8_t *)&initial,
7412 if (!NT_STATUS_IS_OK(status)) {
7413 printf(__location__ "store returned %s\n",
7421 res = db->transaction_commit(db);
7423 printf(__location__ "transaction_commit failed\n");
7431 res = db->transaction_start(db);
7433 printf(__location__ "transaction_start failed\n");
7437 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7438 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7442 for (i=0; i<10; i++) {
7443 if (!dbtrans_inc(db)) {
7448 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7449 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7453 if (val2 != val + 10) {
7454 printf(__location__ "val=%d, val2=%d\n",
7455 (int)val, (int)val2);
7459 printf("val2=%d\r", val2);
7461 res = db->transaction_commit(db);
7463 printf(__location__ "transaction_commit failed\n");
7473 * Just a dummy test to be run under a debugger. There's no real way
7474 * to inspect the tevent_select specific function from outside of
7478 static bool run_local_tevent_select(int dummy)
7480 struct tevent_context *ev;
7481 struct tevent_fd *fd1, *fd2;
7482 bool result = false;
7484 ev = tevent_context_init_byname(NULL, "select");
7486 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7490 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7492 d_fprintf(stderr, "tevent_add_fd failed\n");
7495 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7497 d_fprintf(stderr, "tevent_add_fd failed\n");
7502 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7504 d_fprintf(stderr, "tevent_add_fd failed\n");
7514 static double create_procs(bool (*fn)(int), bool *result)
7517 volatile pid_t *child_status;
7518 volatile bool *child_status_out;
7521 struct timeval start;
7525 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7526 if (!child_status) {
7527 printf("Failed to setup shared memory\n");
7531 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7532 if (!child_status_out) {
7533 printf("Failed to setup result status shared memory\n");
7537 for (i = 0; i < nprocs; i++) {
7538 child_status[i] = 0;
7539 child_status_out[i] = True;
7542 start = timeval_current();
7544 for (i=0;i<nprocs;i++) {
7547 pid_t mypid = getpid();
7548 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7550 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7553 if (torture_open_connection(¤t_cli, i)) break;
7555 printf("pid %d failed to start\n", (int)getpid());
7561 child_status[i] = getpid();
7563 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7565 child_status_out[i] = fn(i);
7572 for (i=0;i<nprocs;i++) {
7573 if (child_status[i]) synccount++;
7575 if (synccount == nprocs) break;
7577 } while (timeval_elapsed(&start) < 30);
7579 if (synccount != nprocs) {
7580 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7582 return timeval_elapsed(&start);
7585 /* start the client load */
7586 start = timeval_current();
7588 for (i=0;i<nprocs;i++) {
7589 child_status[i] = 0;
7592 printf("%d clients started\n", nprocs);
7594 for (i=0;i<nprocs;i++) {
7595 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7600 for (i=0;i<nprocs;i++) {
7601 if (!child_status_out[i]) {
7605 return timeval_elapsed(&start);
7608 #define FLAG_MULTIPROC 1
7615 {"FDPASS", run_fdpasstest, 0},
7616 {"LOCK1", run_locktest1, 0},
7617 {"LOCK2", run_locktest2, 0},
7618 {"LOCK3", run_locktest3, 0},
7619 {"LOCK4", run_locktest4, 0},
7620 {"LOCK5", run_locktest5, 0},
7621 {"LOCK6", run_locktest6, 0},
7622 {"LOCK7", run_locktest7, 0},
7623 {"LOCK8", run_locktest8, 0},
7624 {"LOCK9", run_locktest9, 0},
7625 {"UNLINK", run_unlinktest, 0},
7626 {"BROWSE", run_browsetest, 0},
7627 {"ATTR", run_attrtest, 0},
7628 {"TRANS2", run_trans2test, 0},
7629 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7630 {"TORTURE",run_torture, FLAG_MULTIPROC},
7631 {"RANDOMIPC", run_randomipc, 0},
7632 {"NEGNOWAIT", run_negprot_nowait, 0},
7633 {"NBENCH", run_nbench, 0},
7634 {"NBENCH2", run_nbench2, 0},
7635 {"OPLOCK1", run_oplock1, 0},
7636 {"OPLOCK2", run_oplock2, 0},
7637 {"OPLOCK3", run_oplock3, 0},
7638 {"DIR", run_dirtest, 0},
7639 {"DIR1", run_dirtest1, 0},
7640 {"DIR-CREATETIME", run_dir_createtime, 0},
7641 {"DENY1", torture_denytest1, 0},
7642 {"DENY2", torture_denytest2, 0},
7643 {"TCON", run_tcon_test, 0},
7644 {"TCONDEV", run_tcon_devtype_test, 0},
7645 {"RW1", run_readwritetest, 0},
7646 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7647 {"RW3", run_readwritelarge, 0},
7648 {"OPEN", run_opentest, 0},
7649 {"POSIX", run_simple_posix_open_test, 0},
7650 {"POSIX-APPEND", run_posix_append, 0},
7651 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7652 { "SHORTNAME-TEST", run_shortname_test, 0},
7654 {"OPENATTR", run_openattrtest, 0},
7656 {"XCOPY", run_xcopy, 0},
7657 {"RENAME", run_rename, 0},
7658 {"DELETE", run_deletetest, 0},
7659 {"PROPERTIES", run_properties, 0},
7660 {"MANGLE", torture_mangle, 0},
7661 {"MANGLE1", run_mangle1, 0},
7662 {"W2K", run_w2ktest, 0},
7663 {"TRANS2SCAN", torture_trans2_scan, 0},
7664 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7665 {"UTABLE", torture_utable, 0},
7666 {"CASETABLE", torture_casetable, 0},
7667 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7668 {"PIPE_NUMBER", run_pipe_number, 0},
7669 {"TCON2", run_tcon2_test, 0},
7670 {"IOCTL", torture_ioctl_test, 0},
7671 {"CHKPATH", torture_chkpath_test, 0},
7672 {"FDSESS", run_fdsesstest, 0},
7673 { "EATEST", run_eatest, 0},
7674 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7675 { "CHAIN1", run_chain1, 0},
7676 { "CHAIN2", run_chain2, 0},
7677 { "WINDOWS-WRITE", run_windows_write, 0},
7678 { "CLI_ECHO", run_cli_echo, 0},
7679 { "GETADDRINFO", run_getaddrinfo_send, 0},
7680 { "TLDAP", run_tldap },
7681 { "STREAMERROR", run_streamerror },
7682 { "NOTIFY-BENCH", run_notify_bench },
7683 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7684 { "LOCAL-GENCACHE", run_local_gencache, 0},
7685 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7686 { "LOCAL-BASE64", run_local_base64, 0},
7687 { "LOCAL-RBTREE", run_local_rbtree, 0},
7688 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7689 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7690 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7691 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
7692 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
7693 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7694 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
7699 /****************************************************************************
7700 run a specified test or "ALL"
7701 ****************************************************************************/
7702 static bool run_test(const char *name)
7709 if (strequal(name,"ALL")) {
7710 for (i=0;torture_ops[i].name;i++) {
7711 run_test(torture_ops[i].name);
7716 for (i=0;torture_ops[i].name;i++) {
7717 fstr_sprintf(randomfname, "\\XX%x",
7718 (unsigned)random());
7720 if (strequal(name, torture_ops[i].name)) {
7722 printf("Running %s\n", name);
7723 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7724 t = create_procs(torture_ops[i].fn, &result);
7727 printf("TEST %s FAILED!\n", name);
7730 struct timeval start;
7731 start = timeval_current();
7732 if (!torture_ops[i].fn(0)) {
7734 printf("TEST %s FAILED!\n", name);
7736 t = timeval_elapsed(&start);
7738 printf("%s took %g secs\n\n", name, t);
7743 printf("Did not find a test named %s\n", name);
7751 static void usage(void)
7755 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7756 printf("Please use samba4 torture.\n\n");
7758 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7760 printf("\t-d debuglevel\n");
7761 printf("\t-U user%%pass\n");
7762 printf("\t-k use kerberos\n");
7763 printf("\t-N numprocs\n");
7764 printf("\t-n my_netbios_name\n");
7765 printf("\t-W workgroup\n");
7766 printf("\t-o num_operations\n");
7767 printf("\t-O socket_options\n");
7768 printf("\t-m maximum protocol\n");
7769 printf("\t-L use oplocks\n");
7770 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7771 printf("\t-A showall\n");
7772 printf("\t-p port\n");
7773 printf("\t-s seed\n");
7774 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7777 printf("tests are:");
7778 for (i=0;torture_ops[i].name;i++) {
7779 printf(" %s", torture_ops[i].name);
7783 printf("default test is ALL\n");
7788 /****************************************************************************
7790 ****************************************************************************/
7791 int main(int argc,char *argv[])
7797 bool correct = True;
7798 TALLOC_CTX *frame = talloc_stackframe();
7799 int seed = time(NULL);
7803 #ifdef HAVE_SETBUFFER
7804 setbuffer(stdout, NULL, 0);
7809 setup_logging("smbtorture", true);
7811 if (is_default_dyn_CONFIGFILE()) {
7812 if(getenv("SMB_CONF_PATH")) {
7813 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7816 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7823 for(p = argv[1]; *p; p++)
7827 if (strncmp(argv[1], "//", 2)) {
7831 fstrcpy(host, &argv[1][2]);
7832 p = strchr_m(&host[2],'/');
7837 fstrcpy(share, p+1);
7839 fstrcpy(myname, get_myname(talloc_tos()));
7841 fprintf(stderr, "Failed to get my hostname.\n");
7845 if (*username == 0 && getenv("LOGNAME")) {
7846 fstrcpy(username,getenv("LOGNAME"));
7852 fstrcpy(workgroup, lp_workgroup());
7854 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7857 port_to_use = atoi(optarg);
7860 seed = atoi(optarg);
7863 fstrcpy(workgroup,optarg);
7866 max_protocol = interpret_protocol(optarg, max_protocol);
7869 nprocs = atoi(optarg);
7872 torture_numops = atoi(optarg);
7875 DEBUGLEVEL = atoi(optarg);
7884 local_path = optarg;
7887 torture_showall = True;
7890 fstrcpy(myname, optarg);
7893 client_txt = optarg;
7900 use_kerberos = True;
7902 d_printf("No kerberos support compiled in\n");
7908 fstrcpy(username,optarg);
7909 p = strchr_m(username,'%');
7912 fstrcpy(password, p+1);
7917 fstrcpy(multishare_conn_fname, optarg);
7918 use_multishare_conn = True;
7921 torture_blocksize = atoi(optarg);
7924 printf("Unknown option %c (%d)\n", (char)opt, opt);
7929 d_printf("using seed %d\n", seed);
7933 if(use_kerberos && !gotuser) gotpass = True;
7936 p = getpass("Password:");
7938 fstrcpy(password, p);
7943 printf("host=%s share=%s user=%s myname=%s\n",
7944 host, share, username, myname);
7946 if (argc == optind) {
7947 correct = run_test("ALL");
7949 for (i=optind;i<argc;i++) {
7950 if (!run_test(argv[i])) {