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"
33 static fstring host, workgroup, share, password, username, myname;
34 static int max_protocol = PROTOCOL_NT1;
35 static const char *sockops="TCP_NODELAY";
37 static int port_to_use=0;
38 int torture_numops=100;
39 int torture_blocksize=1024*1024;
40 static int procnum; /* records process count number when forking */
41 static struct cli_state *current_cli;
42 static fstring randomfname;
43 static bool use_oplocks;
44 static bool use_level_II_oplocks;
45 static const char *client_txt = "client_oplocks.txt";
46 static bool use_kerberos;
47 static fstring multishare_conn_fname;
48 static bool use_multishare_conn = False;
49 static bool do_encrypt;
50 static const char *local_path = NULL;
52 bool torture_showall = False;
54 static double create_procs(bool (*fn)(int), bool *result);
57 /* return a pointer to a anonymous shared memory segment of size "size"
58 which will persist across fork() but will disappear when all processes
61 The memory is not zeroed
63 This function uses system5 shared memory. It takes advantage of a property
64 that the memory is not destroyed if it is attached when the id is removed
66 void *shm_setup(int size)
72 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
74 printf("can't get shared memory\n");
77 shm_unlink("private");
78 if (ftruncate(shmid, size) == -1) {
79 printf("can't set shared memory size\n");
82 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
83 if (ret == MAP_FAILED) {
84 printf("can't map shared memory\n");
88 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
90 printf("can't get shared memory\n");
93 ret = (void *)shmat(shmid, 0, 0);
94 if (!ret || ret == (void *)-1) {
95 printf("can't attach to shared memory\n");
98 /* the following releases the ipc, but note that this process
99 and all its children will still have access to the memory, its
100 just that the shmid is no longer valid for other shm calls. This
101 means we don't leave behind lots of shm segments after we exit
103 See Stevens "advanced programming in unix env" for details
105 shmctl(shmid, IPC_RMID, 0);
111 /********************************************************************
112 Ensure a connection is encrypted.
113 ********************************************************************/
115 static bool force_cli_encryption(struct cli_state *c,
116 const char *sharename)
119 uint32 caplow, caphigh;
122 if (!SERVER_HAS_UNIX_CIFS(c)) {
123 d_printf("Encryption required and "
124 "server that doesn't support "
125 "UNIX extensions - failing connect\n");
129 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
131 if (!NT_STATUS_IS_OK(status)) {
132 d_printf("Encryption required and "
133 "can't get UNIX CIFS extensions "
134 "version from server: %s\n", nt_errstr(status));
138 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
139 d_printf("Encryption required and "
140 "share %s doesn't support "
141 "encryption.\n", sharename);
145 if (c->use_kerberos) {
146 status = cli_gss_smb_encryption_start(c);
148 status = cli_raw_ntlm_smb_encryption_start(c,
154 if (!NT_STATUS_IS_OK(status)) {
155 d_printf("Encryption required and "
156 "setup failed with error %s.\n",
165 static struct cli_state *open_nbt_connection(void)
167 struct nmb_name called, calling;
168 struct sockaddr_storage ss;
172 make_nmb_name(&calling, myname, 0x0);
173 make_nmb_name(&called , host, 0x20);
177 if (!(c = cli_initialise())) {
178 printf("Failed initialize cli_struct to connect with %s\n", host);
182 c->port = port_to_use;
184 status = cli_connect(c, host, &ss);
185 if (!NT_STATUS_IS_OK(status)) {
186 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
190 c->use_kerberos = use_kerberos;
192 c->timeout = 120000; /* set a really long timeout (2 minutes) */
193 if (use_oplocks) c->use_oplocks = True;
194 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
196 if (!cli_session_request(c, &calling, &called)) {
198 * Well, that failed, try *SMBSERVER ...
199 * However, we must reconnect as well ...
201 status = cli_connect(c, host, &ss);
202 if (!NT_STATUS_IS_OK(status)) {
203 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
207 make_nmb_name(&called, "*SMBSERVER", 0x20);
208 if (!cli_session_request(c, &calling, &called)) {
209 printf("%s rejected the session\n",host);
210 printf("We tried with a called name of %s & %s\n",
220 /* Insert a NULL at the first separator of the given path and return a pointer
221 * to the remainder of the string.
224 terminate_path_at_separator(char * path)
232 if ((p = strchr_m(path, '/'))) {
237 if ((p = strchr_m(path, '\\'))) {
247 parse a //server/share type UNC name
249 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
250 char **hostname, char **sharename)
254 *hostname = *sharename = NULL;
256 if (strncmp(unc_name, "\\\\", 2) &&
257 strncmp(unc_name, "//", 2)) {
261 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
262 p = terminate_path_at_separator(*hostname);
265 *sharename = talloc_strdup(mem_ctx, p);
266 terminate_path_at_separator(*sharename);
269 if (*hostname && *sharename) {
273 TALLOC_FREE(*hostname);
274 TALLOC_FREE(*sharename);
278 static bool torture_open_connection_share(struct cli_state **c,
279 const char *hostname,
280 const char *sharename)
287 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
289 flags |= CLI_FULL_CONNECTION_OPLOCKS;
290 if (use_level_II_oplocks)
291 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
293 status = cli_full_connection(c, myname,
294 hostname, NULL, port_to_use,
297 password, flags, Undefined, &retry);
298 if (!NT_STATUS_IS_OK(status)) {
299 printf("failed to open share connection: //%s/%s port:%d - %s\n",
300 hostname, sharename, port_to_use, nt_errstr(status));
304 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
307 return force_cli_encryption(*c,
313 bool torture_open_connection(struct cli_state **c, int conn_index)
315 char **unc_list = NULL;
316 int num_unc_names = 0;
319 if (use_multishare_conn==True) {
321 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
322 if (!unc_list || num_unc_names <= 0) {
323 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
327 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
329 printf("Failed to parse UNC name %s\n",
330 unc_list[conn_index % num_unc_names]);
331 TALLOC_FREE(unc_list);
335 result = torture_open_connection_share(c, h, s);
337 /* h, s were copied earlier */
338 TALLOC_FREE(unc_list);
342 return torture_open_connection_share(c, host, share);
345 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
347 uint16 old_vuid = cli->vuid;
348 fstring old_user_name;
349 size_t passlen = strlen(password);
353 fstrcpy(old_user_name, cli->user_name);
355 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
359 *new_vuid = cli->vuid;
360 cli->vuid = old_vuid;
361 status = cli_set_username(cli, old_user_name);
362 if (!NT_STATUS_IS_OK(status)) {
369 bool torture_close_connection(struct cli_state *c)
374 status = cli_tdis(c);
375 if (!NT_STATUS_IS_OK(status)) {
376 printf("tdis failed (%s)\n", nt_errstr(status));
386 /* check if the server produced the expected error code */
387 static bool check_error(int line, struct cli_state *c,
388 uint8 eclass, uint32 ecode, NTSTATUS nterr)
390 if (cli_is_dos_error(c)) {
394 /* Check DOS error */
396 cli_dos_error(c, &cclass, &num);
398 if (eclass != cclass || ecode != num) {
399 printf("unexpected error code class=%d code=%d\n",
400 (int)cclass, (int)num);
401 printf(" expected %d/%d %s (line=%d)\n",
402 (int)eclass, (int)ecode, nt_errstr(nterr), line);
411 status = cli_nt_error(c);
413 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
414 printf("unexpected error code %s\n", nt_errstr(status));
415 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
424 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
426 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
427 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
433 static bool rw_torture(struct cli_state *c)
435 const char *lockfname = "\\torture.lck";
439 pid_t pid2, pid = getpid();
445 memset(buf, '\0', sizeof(buf));
447 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
449 if (!NT_STATUS_IS_OK(status)) {
450 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
452 if (!NT_STATUS_IS_OK(status)) {
453 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
457 for (i=0;i<torture_numops;i++) {
458 unsigned n = (unsigned)sys_random()%10;
460 printf("%d\r", i); fflush(stdout);
462 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
464 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
468 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
469 printf("open failed (%s)\n", cli_errstr(c));
474 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
475 printf("write failed (%s)\n", cli_errstr(c));
480 if (cli_write(c, fnum, 0, (char *)buf,
481 sizeof(pid)+(j*sizeof(buf)),
482 sizeof(buf)) != sizeof(buf)) {
483 printf("write failed (%s)\n", cli_errstr(c));
490 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
491 printf("read failed (%s)\n", cli_errstr(c));
496 printf("data corruption!\n");
500 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
501 printf("close failed (%s)\n", cli_errstr(c));
505 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
506 printf("unlink failed (%s)\n", cli_errstr(c));
510 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
511 printf("unlock failed (%s)\n", cli_errstr(c));
517 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
524 static bool run_torture(int dummy)
526 struct cli_state *cli;
531 cli_sockopt(cli, sockops);
533 ret = rw_torture(cli);
535 if (!torture_close_connection(cli)) {
542 static bool rw_torture3(struct cli_state *c, char *lockfname)
544 uint16_t fnum = (uint16_t)-1;
549 unsigned countprev = 0;
555 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
557 SIVAL(buf, i, sys_random());
562 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
563 DENY_NONE, &fnum))) {
564 printf("first open read/write of %s failed (%s)\n",
565 lockfname, cli_errstr(c));
571 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
573 status = cli_open(c, lockfname, O_RDONLY,
575 if (!NT_STATUS_IS_OK(status)) {
580 if (!NT_STATUS_IS_OK(status)) {
581 printf("second open read-only of %s failed (%s)\n",
582 lockfname, cli_errstr(c));
588 for (count = 0; count < sizeof(buf); count += sent)
590 if (count >= countprev) {
591 printf("%d %8d\r", i, count);
594 countprev += (sizeof(buf) / 20);
599 sent = ((unsigned)sys_random()%(20))+ 1;
600 if (sent > sizeof(buf) - count)
602 sent = sizeof(buf) - count;
605 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
606 printf("write failed (%s)\n", cli_errstr(c));
612 sent = cli_read(c, fnum, buf_rd+count, count,
616 printf("read failed offset:%d size:%ld (%s)\n",
617 count, (unsigned long)sizeof(buf)-count,
624 if (memcmp(buf_rd+count, buf+count, sent) != 0)
626 printf("read/write compare failed\n");
627 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
636 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
637 printf("close failed (%s)\n", cli_errstr(c));
644 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
646 const char *lockfname = "\\torture2.lck";
655 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
656 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
659 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
660 DENY_NONE, &fnum1))) {
661 printf("first open read/write of %s failed (%s)\n",
662 lockfname, cli_errstr(c1));
665 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
666 DENY_NONE, &fnum2))) {
667 printf("second open read-only of %s failed (%s)\n",
668 lockfname, cli_errstr(c2));
669 cli_close(c1, fnum1);
673 for (i=0;i<torture_numops;i++)
675 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
677 printf("%d\r", i); fflush(stdout);
680 generate_random_buffer((unsigned char *)buf, buf_size);
682 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
683 printf("write failed (%s)\n", cli_errstr(c1));
688 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
689 printf("read failed (%s)\n", cli_errstr(c2));
690 printf("read %d, expected %ld\n", (int)bytes_read,
691 (unsigned long)buf_size);
696 if (memcmp(buf_rd, buf, buf_size) != 0)
698 printf("read/write compare failed\n");
704 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
705 printf("close failed (%s)\n", cli_errstr(c2));
708 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
709 printf("close failed (%s)\n", cli_errstr(c1));
713 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
714 printf("unlink failed (%s)\n", cli_errstr(c1));
721 static bool run_readwritetest(int dummy)
723 struct cli_state *cli1, *cli2;
724 bool test1, test2 = False;
726 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
729 cli_sockopt(cli1, sockops);
730 cli_sockopt(cli2, sockops);
732 printf("starting readwritetest\n");
734 test1 = rw_torture2(cli1, cli2);
735 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
738 test2 = rw_torture2(cli1, cli1);
739 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
742 if (!torture_close_connection(cli1)) {
746 if (!torture_close_connection(cli2)) {
750 return (test1 && test2);
753 static bool run_readwritemulti(int dummy)
755 struct cli_state *cli;
760 cli_sockopt(cli, sockops);
762 printf("run_readwritemulti: fname %s\n", randomfname);
763 test = rw_torture3(cli, randomfname);
765 if (!torture_close_connection(cli)) {
772 static bool run_readwritelarge(int dummy)
774 static struct cli_state *cli1;
776 const char *lockfname = "\\large.dat";
781 if (!torture_open_connection(&cli1, 0)) {
784 cli_sockopt(cli1, sockops);
785 memset(buf,'\0',sizeof(buf));
787 cli1->max_xmit = 128*1024;
789 printf("starting readwritelarge\n");
791 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
793 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
794 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
798 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
800 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
801 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
805 if (fsize == sizeof(buf))
806 printf("readwritelarge test 1 succeeded (size = %lx)\n",
807 (unsigned long)fsize);
809 printf("readwritelarge test 1 failed (size = %lx)\n",
810 (unsigned long)fsize);
814 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
815 printf("close failed (%s)\n", cli_errstr(cli1));
819 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
820 printf("unlink failed (%s)\n", cli_errstr(cli1));
824 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
825 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
829 cli1->max_xmit = 4*1024;
831 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
833 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
834 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
838 if (fsize == sizeof(buf))
839 printf("readwritelarge test 2 succeeded (size = %lx)\n",
840 (unsigned long)fsize);
842 printf("readwritelarge test 2 failed (size = %lx)\n",
843 (unsigned long)fsize);
848 /* ToDo - set allocation. JRA */
849 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
850 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
853 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
854 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
858 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
861 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
862 printf("close failed (%s)\n", cli_errstr(cli1));
866 if (!torture_close_connection(cli1)) {
875 #define ival(s) strtol(s, NULL, 0)
877 /* run a test that simulates an approximate netbench client load */
878 static bool run_netbench(int client)
880 struct cli_state *cli;
885 const char *params[20];
892 cli_sockopt(cli, sockops);
896 slprintf(cname,sizeof(cname)-1, "client%d", client);
898 f = fopen(client_txt, "r");
905 while (fgets(line, sizeof(line)-1, f)) {
909 line[strlen(line)-1] = 0;
911 /* printf("[%d] %s\n", line_count, line); */
913 all_string_sub(line,"client1", cname, sizeof(line));
915 /* parse the command parameters */
916 params[0] = strtok_r(line, " ", &saveptr);
918 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
924 if (!strncmp(params[0],"SMB", 3)) {
925 printf("ERROR: You are using a dbench 1 load file\n");
929 if (!strcmp(params[0],"NTCreateX")) {
930 nb_createx(params[1], ival(params[2]), ival(params[3]),
932 } else if (!strcmp(params[0],"Close")) {
933 nb_close(ival(params[1]));
934 } else if (!strcmp(params[0],"Rename")) {
935 nb_rename(params[1], params[2]);
936 } else if (!strcmp(params[0],"Unlink")) {
937 nb_unlink(params[1]);
938 } else if (!strcmp(params[0],"Deltree")) {
939 nb_deltree(params[1]);
940 } else if (!strcmp(params[0],"Rmdir")) {
942 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
943 nb_qpathinfo(params[1]);
944 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
945 nb_qfileinfo(ival(params[1]));
946 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
947 nb_qfsinfo(ival(params[1]));
948 } else if (!strcmp(params[0],"FIND_FIRST")) {
949 nb_findfirst(params[1]);
950 } else if (!strcmp(params[0],"WriteX")) {
951 nb_writex(ival(params[1]),
952 ival(params[2]), ival(params[3]), ival(params[4]));
953 } else if (!strcmp(params[0],"ReadX")) {
954 nb_readx(ival(params[1]),
955 ival(params[2]), ival(params[3]), ival(params[4]));
956 } else if (!strcmp(params[0],"Flush")) {
957 nb_flush(ival(params[1]));
959 printf("Unknown operation %s\n", params[0]);
967 if (!torture_close_connection(cli)) {
975 /* run a test that simulates an approximate netbench client load */
976 static bool run_nbench(int dummy)
985 signal(SIGALRM, nb_alarm);
987 t = create_procs(run_netbench, &correct);
990 printf("\nThroughput %g MB/sec\n",
991 1.0e-6 * nbio_total() / t);
997 This test checks for two things:
999 1) correct support for retaining locks over a close (ie. the server
1000 must not use posix semantics)
1001 2) support for lock timeouts
1003 static bool run_locktest1(int dummy)
1005 struct cli_state *cli1, *cli2;
1006 const char *fname = "\\lockt1.lck";
1007 uint16_t fnum1, fnum2, fnum3;
1009 unsigned lock_timeout;
1011 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1014 cli_sockopt(cli1, sockops);
1015 cli_sockopt(cli2, sockops);
1017 printf("starting locktest1\n");
1019 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1021 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1022 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1025 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1026 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1029 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1030 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1034 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1035 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1040 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1041 printf("lock2 succeeded! This is a locking bug\n");
1044 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1045 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1049 lock_timeout = (1 + (random() % 20));
1050 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1052 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1053 printf("lock3 succeeded! This is a locking bug\n");
1056 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1057 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1061 if (ABS(t2 - t1) < lock_timeout-1) {
1062 printf("error: This server appears not to support timed lock requests\n");
1065 printf("server slept for %u seconds for a %u second timeout\n",
1066 (unsigned int)(t2-t1), lock_timeout);
1068 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1069 printf("close1 failed (%s)\n", cli_errstr(cli1));
1073 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1074 printf("lock4 succeeded! This is a locking bug\n");
1077 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1078 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1081 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1082 printf("close2 failed (%s)\n", cli_errstr(cli1));
1086 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1087 printf("close3 failed (%s)\n", cli_errstr(cli2));
1091 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1092 printf("unlink failed (%s)\n", cli_errstr(cli1));
1097 if (!torture_close_connection(cli1)) {
1101 if (!torture_close_connection(cli2)) {
1105 printf("Passed locktest1\n");
1110 this checks to see if a secondary tconx can use open files from an
1113 static bool run_tcon_test(int dummy)
1115 static struct cli_state *cli;
1116 const char *fname = "\\tcontest.tmp";
1118 uint16 cnum1, cnum2, cnum3;
1119 uint16 vuid1, vuid2;
1124 memset(buf, '\0', sizeof(buf));
1126 if (!torture_open_connection(&cli, 0)) {
1129 cli_sockopt(cli, sockops);
1131 printf("starting tcontest\n");
1133 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1135 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1136 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1143 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1144 printf("initial write failed (%s)", cli_errstr(cli));
1148 status = cli_tcon_andx(cli, share, "?????",
1149 password, strlen(password)+1);
1150 if (!NT_STATUS_IS_OK(status)) {
1151 printf("%s refused 2nd tree connect (%s)\n", host,
1158 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1159 vuid2 = cli->vuid + 1;
1161 /* try a write with the wrong tid */
1164 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1165 printf("* server allows write with wrong TID\n");
1168 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1172 /* try a write with an invalid tid */
1175 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1176 printf("* server allows write with invalid TID\n");
1179 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1182 /* try a write with an invalid vuid */
1186 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1187 printf("* server allows write with invalid VUID\n");
1190 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1196 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1197 printf("close failed (%s)\n", cli_errstr(cli));
1203 status = cli_tdis(cli);
1204 if (!NT_STATUS_IS_OK(status)) {
1205 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1211 if (!torture_close_connection(cli)) {
1220 checks for old style tcon support
1222 static bool run_tcon2_test(int dummy)
1224 static struct cli_state *cli;
1225 uint16 cnum, max_xmit;
1229 if (!torture_open_connection(&cli, 0)) {
1232 cli_sockopt(cli, sockops);
1234 printf("starting tcon2 test\n");
1236 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1240 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1242 if (!NT_STATUS_IS_OK(status)) {
1243 printf("tcon2 failed : %s\n", cli_errstr(cli));
1245 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1246 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1249 if (!torture_close_connection(cli)) {
1253 printf("Passed tcon2 test\n");
1257 static bool tcon_devtest(struct cli_state *cli,
1258 const char *myshare, const char *devtype,
1259 const char *return_devtype,
1260 NTSTATUS expected_error)
1265 status = cli_tcon_andx(cli, myshare, devtype,
1266 password, strlen(password)+1);
1268 if (NT_STATUS_IS_OK(expected_error)) {
1269 if (NT_STATUS_IS_OK(status)) {
1270 if (strcmp(cli->dev, return_devtype) == 0) {
1273 printf("tconX to share %s with type %s "
1274 "succeeded but returned the wrong "
1275 "device type (got [%s] but should have got [%s])\n",
1276 myshare, devtype, cli->dev, return_devtype);
1280 printf("tconX to share %s with type %s "
1281 "should have succeeded but failed\n",
1287 if (NT_STATUS_IS_OK(status)) {
1288 printf("tconx to share %s with type %s "
1289 "should have failed but succeeded\n",
1293 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1297 printf("Returned unexpected error\n");
1306 checks for correct tconX support
1308 static bool run_tcon_devtype_test(int dummy)
1310 static struct cli_state *cli1 = NULL;
1316 status = cli_full_connection(&cli1, myname,
1317 host, NULL, port_to_use,
1319 username, workgroup,
1320 password, flags, Undefined, &retry);
1322 if (!NT_STATUS_IS_OK(status)) {
1323 printf("could not open connection\n");
1327 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1330 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1333 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1336 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1339 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1342 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1345 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1348 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1351 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1354 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1360 printf("Passed tcondevtest\n");
1367 This test checks that
1369 1) the server supports multiple locking contexts on the one SMB
1370 connection, distinguished by PID.
1372 2) the server correctly fails overlapping locks made by the same PID (this
1373 goes against POSIX behaviour, which is why it is tricky to implement)
1375 3) the server denies unlock requests by an incorrect client PID
1377 static bool run_locktest2(int dummy)
1379 static struct cli_state *cli;
1380 const char *fname = "\\lockt2.lck";
1381 uint16_t fnum1, fnum2, fnum3;
1382 bool correct = True;
1384 if (!torture_open_connection(&cli, 0)) {
1388 cli_sockopt(cli, sockops);
1390 printf("starting locktest2\n");
1392 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1396 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1397 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1401 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1402 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1408 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1409 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1415 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1416 printf("lock1 failed (%s)\n", cli_errstr(cli));
1420 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1421 printf("WRITE lock1 succeeded! This is a locking bug\n");
1424 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1425 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1428 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1429 printf("WRITE lock2 succeeded! This is a locking bug\n");
1432 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1433 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1436 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1437 printf("READ lock2 succeeded! This is a locking bug\n");
1440 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1441 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1444 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1445 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1448 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1449 printf("unlock at 100 succeeded! This is a locking bug\n");
1453 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1454 printf("unlock1 succeeded! This is a locking bug\n");
1457 if (!check_error(__LINE__, cli,
1459 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1462 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1463 printf("unlock2 succeeded! This is a locking bug\n");
1466 if (!check_error(__LINE__, cli,
1468 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1471 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1472 printf("lock3 succeeded! This is a locking bug\n");
1475 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1480 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1481 printf("close1 failed (%s)\n", cli_errstr(cli));
1485 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1486 printf("close2 failed (%s)\n", cli_errstr(cli));
1490 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1491 printf("close3 failed (%s)\n", cli_errstr(cli));
1495 if (!torture_close_connection(cli)) {
1499 printf("locktest2 finished\n");
1506 This test checks that
1508 1) the server supports the full offset range in lock requests
1510 static bool run_locktest3(int dummy)
1512 static struct cli_state *cli1, *cli2;
1513 const char *fname = "\\lockt3.lck";
1514 uint16_t fnum1, fnum2;
1517 bool correct = True;
1519 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1521 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1524 cli_sockopt(cli1, sockops);
1525 cli_sockopt(cli2, sockops);
1527 printf("starting locktest3\n");
1529 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1531 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1532 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1535 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1536 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1540 for (offset=i=0;i<torture_numops;i++) {
1542 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1543 printf("lock1 %d failed (%s)\n",
1549 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1550 printf("lock2 %d failed (%s)\n",
1557 for (offset=i=0;i<torture_numops;i++) {
1560 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1561 printf("error: lock1 %d succeeded!\n", i);
1565 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1566 printf("error: lock2 %d succeeded!\n", i);
1570 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1571 printf("error: lock3 %d succeeded!\n", i);
1575 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1576 printf("error: lock4 %d succeeded!\n", i);
1581 for (offset=i=0;i<torture_numops;i++) {
1584 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1585 printf("unlock1 %d failed (%s)\n",
1591 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1592 printf("unlock2 %d failed (%s)\n",
1599 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1600 printf("close1 failed (%s)\n", cli_errstr(cli1));
1604 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1605 printf("close2 failed (%s)\n", cli_errstr(cli2));
1609 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1610 printf("unlink failed (%s)\n", cli_errstr(cli1));
1614 if (!torture_close_connection(cli1)) {
1618 if (!torture_close_connection(cli2)) {
1622 printf("finished locktest3\n");
1627 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1628 printf("** "); correct = False; \
1632 looks at overlapping locks
1634 static bool run_locktest4(int dummy)
1636 static struct cli_state *cli1, *cli2;
1637 const char *fname = "\\lockt4.lck";
1638 uint16_t fnum1, fnum2, f;
1641 bool correct = True;
1643 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1647 cli_sockopt(cli1, sockops);
1648 cli_sockopt(cli2, sockops);
1650 printf("starting locktest4\n");
1652 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1654 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1655 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1657 memset(buf, 0, sizeof(buf));
1659 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1660 printf("Failed to create file\n");
1665 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1666 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1667 EXPECTED(ret, False);
1668 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1670 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1671 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1672 EXPECTED(ret, True);
1673 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1675 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1676 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1677 EXPECTED(ret, False);
1678 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1680 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1681 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1682 EXPECTED(ret, True);
1683 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1685 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1686 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1687 EXPECTED(ret, False);
1688 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1690 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1691 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1692 EXPECTED(ret, True);
1693 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1695 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1696 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1697 EXPECTED(ret, True);
1698 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1700 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1701 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1702 EXPECTED(ret, False);
1703 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1705 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1706 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1707 EXPECTED(ret, False);
1708 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1710 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1711 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1712 EXPECTED(ret, True);
1713 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1715 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1716 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1717 EXPECTED(ret, False);
1718 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1720 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1721 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1722 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1723 EXPECTED(ret, False);
1724 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1727 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1728 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1729 EXPECTED(ret, False);
1730 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1732 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1733 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1734 EXPECTED(ret, False);
1735 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1738 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1739 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1740 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1741 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1742 EXPECTED(ret, True);
1743 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1746 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1747 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1748 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1749 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1750 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1751 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1752 EXPECTED(ret, True);
1753 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1755 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1756 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1757 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1758 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1759 EXPECTED(ret, True);
1760 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1762 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1763 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1764 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1765 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1766 EXPECTED(ret, True);
1767 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1769 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1770 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1771 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1772 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1773 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1774 EXPECTED(ret, True);
1775 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1777 cli_close(cli1, fnum1);
1778 cli_close(cli2, fnum2);
1779 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1780 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1781 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1782 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1783 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1784 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1785 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1787 cli_close(cli1, fnum1);
1788 EXPECTED(ret, True);
1789 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1792 cli_close(cli1, fnum1);
1793 cli_close(cli2, fnum2);
1794 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1795 torture_close_connection(cli1);
1796 torture_close_connection(cli2);
1798 printf("finished locktest4\n");
1803 looks at lock upgrade/downgrade.
1805 static bool run_locktest5(int dummy)
1807 static struct cli_state *cli1, *cli2;
1808 const char *fname = "\\lockt5.lck";
1809 uint16_t fnum1, fnum2, fnum3;
1812 bool correct = True;
1814 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1818 cli_sockopt(cli1, sockops);
1819 cli_sockopt(cli2, sockops);
1821 printf("starting locktest5\n");
1823 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1825 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1826 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1827 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1829 memset(buf, 0, sizeof(buf));
1831 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1832 printf("Failed to create file\n");
1837 /* Check for NT bug... */
1838 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1839 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1840 cli_close(cli1, fnum1);
1841 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1842 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1843 EXPECTED(ret, True);
1844 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1845 cli_close(cli1, fnum1);
1846 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1847 cli_unlock(cli1, fnum3, 0, 1);
1849 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1850 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1851 EXPECTED(ret, True);
1852 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1854 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1855 EXPECTED(ret, False);
1857 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1859 /* Unlock the process 2 lock. */
1860 cli_unlock(cli2, fnum2, 0, 4);
1862 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1863 EXPECTED(ret, False);
1865 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1867 /* Unlock the process 1 fnum3 lock. */
1868 cli_unlock(cli1, fnum3, 0, 4);
1870 /* Stack 2 more locks here. */
1871 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1872 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1874 EXPECTED(ret, True);
1875 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1877 /* Unlock the first process lock, then check this was the WRITE lock that was
1880 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1881 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1883 EXPECTED(ret, True);
1884 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1886 /* Unlock the process 2 lock. */
1887 cli_unlock(cli2, fnum2, 0, 4);
1889 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1891 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1892 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1893 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1895 EXPECTED(ret, True);
1896 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1898 /* Ensure the next unlock fails. */
1899 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1900 EXPECTED(ret, False);
1901 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1903 /* Ensure connection 2 can get a write lock. */
1904 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1905 EXPECTED(ret, True);
1907 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1911 cli_close(cli1, fnum1);
1912 cli_close(cli2, fnum2);
1913 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1914 if (!torture_close_connection(cli1)) {
1917 if (!torture_close_connection(cli2)) {
1921 printf("finished locktest5\n");
1927 tries the unusual lockingX locktype bits
1929 static bool run_locktest6(int dummy)
1931 static struct cli_state *cli;
1932 const char *fname[1] = { "\\lock6.txt" };
1937 if (!torture_open_connection(&cli, 0)) {
1941 cli_sockopt(cli, sockops);
1943 printf("starting locktest6\n");
1946 printf("Testing %s\n", fname[i]);
1948 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1950 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1951 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1952 cli_close(cli, fnum);
1953 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1955 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1956 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1957 cli_close(cli, fnum);
1958 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1960 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1963 torture_close_connection(cli);
1965 printf("finished locktest6\n");
1969 static bool run_locktest7(int dummy)
1971 struct cli_state *cli1;
1972 const char *fname = "\\lockt7.lck";
1975 bool correct = False;
1977 if (!torture_open_connection(&cli1, 0)) {
1981 cli_sockopt(cli1, sockops);
1983 printf("starting locktest7\n");
1985 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1987 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1989 memset(buf, 0, sizeof(buf));
1991 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1992 printf("Failed to create file\n");
1996 cli_setpid(cli1, 1);
1998 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
1999 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2002 printf("pid1 successfully locked range 130:4 for READ\n");
2005 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2006 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2009 printf("pid1 successfully read the range 130:4\n");
2012 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2013 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2014 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2015 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2019 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2023 cli_setpid(cli1, 2);
2025 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2026 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2028 printf("pid2 successfully read the range 130:4\n");
2031 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2032 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2033 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2034 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2038 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2042 cli_setpid(cli1, 1);
2043 cli_unlock(cli1, fnum1, 130, 4);
2045 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2046 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2049 printf("pid1 successfully locked range 130:4 for WRITE\n");
2052 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2053 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2056 printf("pid1 successfully read the range 130:4\n");
2059 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2060 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2063 printf("pid1 successfully wrote to the range 130:4\n");
2066 cli_setpid(cli1, 2);
2068 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2069 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2070 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2071 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2075 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2079 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2080 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2081 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2082 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2086 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2090 cli_unlock(cli1, fnum1, 130, 0);
2094 cli_close(cli1, fnum1);
2095 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2096 torture_close_connection(cli1);
2098 printf("finished locktest7\n");
2103 * This demonstrates a problem with our use of GPFS share modes: A file
2104 * descriptor sitting in the pending close queue holding a GPFS share mode
2105 * blocks opening a file another time. Happens with Word 2007 temp files.
2106 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2107 * open is denied with NT_STATUS_SHARING_VIOLATION.
2110 static bool run_locktest8(int dummy)
2112 struct cli_state *cli1;
2113 const char *fname = "\\lockt8.lck";
2114 uint16_t fnum1, fnum2;
2116 bool correct = False;
2119 if (!torture_open_connection(&cli1, 0)) {
2123 cli_sockopt(cli1, sockops);
2125 printf("starting locktest8\n");
2127 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2129 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2131 if (!NT_STATUS_IS_OK(status)) {
2132 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2136 memset(buf, 0, sizeof(buf));
2138 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2139 if (!NT_STATUS_IS_OK(status)) {
2140 d_fprintf(stderr, "cli_open second time returned %s\n",
2145 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2146 printf("Unable to apply read lock on range 1:1, error was "
2147 "%s\n", cli_errstr(cli1));
2151 status = cli_close(cli1, fnum1);
2152 if (!NT_STATUS_IS_OK(status)) {
2153 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2157 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2158 if (!NT_STATUS_IS_OK(status)) {
2159 d_fprintf(stderr, "cli_open third time returned %s\n",
2167 cli_close(cli1, fnum1);
2168 cli_close(cli1, fnum2);
2169 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2170 torture_close_connection(cli1);
2172 printf("finished locktest8\n");
2177 * This test is designed to be run in conjunction with
2178 * external NFS or POSIX locks taken in the filesystem.
2179 * It checks that the smbd server will block until the
2180 * lock is released and then acquire it. JRA.
2183 static bool got_alarm;
2184 static int alarm_fd;
2186 static void alarm_handler(int dummy)
2191 static void alarm_handler_parent(int dummy)
2196 static void do_local_lock(int read_fd, int write_fd)
2201 const char *local_pathname = NULL;
2204 local_pathname = talloc_asprintf(talloc_tos(),
2205 "%s/lockt9.lck", local_path);
2206 if (!local_pathname) {
2207 printf("child: alloc fail\n");
2211 unlink(local_pathname);
2212 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2214 printf("child: open of %s failed %s.\n",
2215 local_pathname, strerror(errno));
2219 /* Now take a fcntl lock. */
2220 lock.l_type = F_WRLCK;
2221 lock.l_whence = SEEK_SET;
2224 lock.l_pid = getpid();
2226 ret = fcntl(fd,F_SETLK,&lock);
2228 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2229 local_pathname, strerror(errno));
2232 printf("child: got lock 0:4 on file %s.\n",
2237 CatchSignal(SIGALRM, alarm_handler);
2239 /* Signal the parent. */
2240 if (write(write_fd, &c, 1) != 1) {
2241 printf("child: start signal fail %s.\n",
2248 /* Wait for the parent to be ready. */
2249 if (read(read_fd, &c, 1) != 1) {
2250 printf("child: reply signal fail %s.\n",
2258 printf("child: released lock 0:4 on file %s.\n",
2264 static bool run_locktest9(int dummy)
2266 struct cli_state *cli1;
2267 const char *fname = "\\lockt9.lck";
2269 bool correct = False;
2270 int pipe_in[2], pipe_out[2];
2274 struct timeval start;
2278 printf("starting locktest9\n");
2280 if (local_path == NULL) {
2281 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2285 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2290 if (child_pid == -1) {
2294 if (child_pid == 0) {
2296 do_local_lock(pipe_out[0], pipe_in[1]);
2306 ret = read(pipe_in[0], &c, 1);
2308 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2313 if (!torture_open_connection(&cli1, 0)) {
2317 cli_sockopt(cli1, sockops);
2319 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2321 if (!NT_STATUS_IS_OK(status)) {
2322 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2326 /* Ensure the child has the lock. */
2327 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2328 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2331 d_printf("Child has the lock.\n");
2334 /* Tell the child to wait 5 seconds then exit. */
2335 ret = write(pipe_out[1], &c, 1);
2337 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2342 /* Wait 20 seconds for the lock. */
2343 alarm_fd = cli1->fd;
2344 CatchSignal(SIGALRM, alarm_handler_parent);
2347 start = timeval_current();
2349 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2350 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2351 "%s\n", cli_errstr(cli1));
2356 seconds = timeval_elapsed(&start);
2358 printf("Parent got the lock after %.2f seconds.\n",
2361 status = cli_close(cli1, fnum);
2362 if (!NT_STATUS_IS_OK(status)) {
2363 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2370 cli_close(cli1, fnum);
2371 torture_close_connection(cli1);
2375 printf("finished locktest9\n");
2380 test whether fnums and tids open on one VC are available on another (a major
2383 static bool run_fdpasstest(int dummy)
2385 struct cli_state *cli1, *cli2;
2386 const char *fname = "\\fdpass.tst";
2390 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2393 cli_sockopt(cli1, sockops);
2394 cli_sockopt(cli2, sockops);
2396 printf("starting fdpasstest\n");
2398 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2400 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2401 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2405 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2406 printf("write failed (%s)\n", cli_errstr(cli1));
2410 cli2->vuid = cli1->vuid;
2411 cli2->cnum = cli1->cnum;
2412 cli2->pid = cli1->pid;
2414 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2415 printf("read succeeded! nasty security hole [%s]\n",
2420 cli_close(cli1, fnum1);
2421 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2423 torture_close_connection(cli1);
2424 torture_close_connection(cli2);
2426 printf("finished fdpasstest\n");
2430 static bool run_fdsesstest(int dummy)
2432 struct cli_state *cli;
2437 const char *fname = "\\fdsess.tst";
2438 const char *fname1 = "\\fdsess1.tst";
2444 if (!torture_open_connection(&cli, 0))
2446 cli_sockopt(cli, sockops);
2448 if (!torture_cli_session_setup2(cli, &new_vuid))
2451 saved_cnum = cli->cnum;
2452 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2454 new_cnum = cli->cnum;
2455 cli->cnum = saved_cnum;
2457 printf("starting fdsesstest\n");
2459 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2460 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2462 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2463 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2467 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2468 printf("write failed (%s)\n", cli_errstr(cli));
2472 saved_vuid = cli->vuid;
2473 cli->vuid = new_vuid;
2475 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2476 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2480 /* Try to open a file with different vuid, samba cnum. */
2481 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2482 printf("create with different vuid, same cnum succeeded.\n");
2483 cli_close(cli, fnum2);
2484 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2486 printf("create with different vuid, same cnum failed.\n");
2487 printf("This will cause problems with service clients.\n");
2491 cli->vuid = saved_vuid;
2493 /* Try with same vuid, different cnum. */
2494 cli->cnum = new_cnum;
2496 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2497 printf("read succeeded with different cnum![%s]\n",
2502 cli->cnum = saved_cnum;
2503 cli_close(cli, fnum1);
2504 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2506 torture_close_connection(cli);
2508 printf("finished fdsesstest\n");
2513 This test checks that
2515 1) the server does not allow an unlink on a file that is open
2517 static bool run_unlinktest(int dummy)
2519 struct cli_state *cli;
2520 const char *fname = "\\unlink.tst";
2522 bool correct = True;
2524 if (!torture_open_connection(&cli, 0)) {
2528 cli_sockopt(cli, sockops);
2530 printf("starting unlink test\n");
2532 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2536 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2537 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2541 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2542 printf("error: server allowed unlink on an open file\n");
2545 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2546 NT_STATUS_SHARING_VIOLATION);
2549 cli_close(cli, fnum);
2550 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2552 if (!torture_close_connection(cli)) {
2556 printf("unlink test finished\n");
2563 test how many open files this server supports on the one socket
2565 static bool run_maxfidtest(int dummy)
2567 struct cli_state *cli;
2568 const char *ftemplate = "\\maxfid.%d.%d";
2570 uint16_t fnums[0x11000];
2573 bool correct = True;
2578 printf("failed to connect\n");
2582 cli_sockopt(cli, sockops);
2584 for (i=0; i<0x11000; i++) {
2585 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2586 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2587 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2588 printf("open of %s failed (%s)\n",
2589 fname, cli_errstr(cli));
2590 printf("maximum fnum is %d\n", i);
2598 printf("cleaning up\n");
2600 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2601 cli_close(cli, fnums[i]);
2602 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2603 printf("unlink of %s failed (%s)\n",
2604 fname, cli_errstr(cli));
2611 printf("maxfid test finished\n");
2612 if (!torture_close_connection(cli)) {
2618 /* generate a random buffer */
2619 static void rand_buf(char *buf, int len)
2622 *buf = (char)sys_random();
2627 /* send smb negprot commands, not reading the response */
2628 static bool run_negprot_nowait(int dummy)
2631 static struct cli_state *cli;
2632 bool correct = True;
2634 printf("starting negprot nowait test\n");
2636 if (!(cli = open_nbt_connection())) {
2640 for (i=0;i<50000;i++) {
2641 cli_negprot_sendsync(cli);
2644 if (!torture_close_connection(cli)) {
2648 printf("finished negprot nowait test\n");
2654 /* send random IPC commands */
2655 static bool run_randomipc(int dummy)
2657 char *rparam = NULL;
2659 unsigned int rdrcnt,rprcnt;
2661 int api, param_len, i;
2662 struct cli_state *cli;
2663 bool correct = True;
2666 printf("starting random ipc test\n");
2668 if (!torture_open_connection(&cli, 0)) {
2672 for (i=0;i<count;i++) {
2673 api = sys_random() % 500;
2674 param_len = (sys_random() % 64);
2676 rand_buf(param, param_len);
2681 param, param_len, 8,
2682 NULL, 0, BUFFER_SIZE,
2686 printf("%d/%d\r", i,count);
2689 printf("%d/%d\n", i, count);
2691 if (!torture_close_connection(cli)) {
2695 printf("finished random ipc test\n");
2702 static void browse_callback(const char *sname, uint32 stype,
2703 const char *comment, void *state)
2705 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2711 This test checks the browse list code
2714 static bool run_browsetest(int dummy)
2716 static struct cli_state *cli;
2717 bool correct = True;
2719 printf("starting browse test\n");
2721 if (!torture_open_connection(&cli, 0)) {
2725 printf("domain list:\n");
2726 cli_NetServerEnum(cli, cli->server_domain,
2727 SV_TYPE_DOMAIN_ENUM,
2728 browse_callback, NULL);
2730 printf("machine list:\n");
2731 cli_NetServerEnum(cli, cli->server_domain,
2733 browse_callback, NULL);
2735 if (!torture_close_connection(cli)) {
2739 printf("browse test finished\n");
2747 This checks how the getatr calls works
2749 static bool run_attrtest(int dummy)
2751 struct cli_state *cli;
2754 const char *fname = "\\attrib123456789.tst";
2755 bool correct = True;
2757 printf("starting attrib test\n");
2759 if (!torture_open_connection(&cli, 0)) {
2763 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2764 cli_open(cli, fname,
2765 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2766 cli_close(cli, fnum);
2767 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2768 printf("getatr failed (%s)\n", cli_errstr(cli));
2772 if (abs(t - time(NULL)) > 60*60*24*10) {
2773 printf("ERROR: SMBgetatr bug. time is %s",
2779 t2 = t-60*60*24; /* 1 day ago */
2781 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2782 printf("setatr failed (%s)\n", cli_errstr(cli));
2786 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2787 printf("getatr failed (%s)\n", cli_errstr(cli));
2792 printf("ERROR: getatr/setatr bug. times are\n%s",
2794 printf("%s", ctime(&t2));
2798 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2800 if (!torture_close_connection(cli)) {
2804 printf("attrib test finished\n");
2811 This checks a couple of trans2 calls
2813 static bool run_trans2test(int dummy)
2815 struct cli_state *cli;
2818 time_t c_time, a_time, m_time;
2819 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2820 const char *fname = "\\trans2.tst";
2821 const char *dname = "\\trans2";
2822 const char *fname2 = "\\trans2\\trans2.tst";
2824 bool correct = True;
2828 printf("starting trans2 test\n");
2830 if (!torture_open_connection(&cli, 0)) {
2834 status = cli_get_fs_attr_info(cli, &fs_attr);
2835 if (!NT_STATUS_IS_OK(status)) {
2836 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2841 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2842 cli_open(cli, fname,
2843 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2844 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2845 &m_time_ts, NULL)) {
2846 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2850 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2851 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2855 if (strcmp(pname, fname)) {
2856 printf("qfilename gave different name? [%s] [%s]\n",
2861 cli_close(cli, fnum);
2865 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2866 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2867 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2868 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2871 cli_close(cli, fnum);
2873 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
2875 if (!NT_STATUS_IS_OK(status)) {
2876 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
2879 if (c_time != m_time) {
2880 printf("create time=%s", ctime(&c_time));
2881 printf("modify time=%s", ctime(&m_time));
2882 printf("This system appears to have sticky create times\n");
2884 if (a_time % (60*60) == 0) {
2885 printf("access time=%s", ctime(&a_time));
2886 printf("This system appears to set a midnight access time\n");
2890 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2891 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2897 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2898 cli_open(cli, fname,
2899 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2900 cli_close(cli, fnum);
2901 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2902 &m_time_ts, &size, NULL, NULL);
2903 if (!NT_STATUS_IS_OK(status)) {
2904 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2907 if (w_time_ts.tv_sec < 60*60*24*2) {
2908 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2909 printf("This system appears to set a initial 0 write time\n");
2914 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2917 /* check if the server updates the directory modification time
2918 when creating a new file */
2919 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2920 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2924 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2925 &w_time_ts, &m_time_ts, &size, NULL, NULL);
2926 if (!NT_STATUS_IS_OK(status)) {
2927 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2931 cli_open(cli, fname2,
2932 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2933 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2934 cli_close(cli, fnum);
2935 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2936 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
2937 if (!NT_STATUS_IS_OK(status)) {
2938 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2941 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2943 printf("This system does not update directory modification times\n");
2947 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2948 cli_rmdir(cli, dname);
2950 if (!torture_close_connection(cli)) {
2954 printf("trans2 test finished\n");
2960 This checks new W2K calls.
2963 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2967 bool correct = True;
2969 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2970 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2973 printf("qfileinfo: level %d, len = %u\n", level, len);
2974 dump_data(0, (uint8 *)buf, len);
2981 static bool run_w2ktest(int dummy)
2983 struct cli_state *cli;
2985 const char *fname = "\\w2ktest\\w2k.tst";
2987 bool correct = True;
2989 printf("starting w2k test\n");
2991 if (!torture_open_connection(&cli, 0)) {
2995 cli_open(cli, fname,
2996 O_RDWR | O_CREAT , DENY_NONE, &fnum);
2998 for (level = 1004; level < 1040; level++) {
2999 new_trans(cli, fnum, level);
3002 cli_close(cli, fnum);
3004 if (!torture_close_connection(cli)) {
3008 printf("w2k test finished\n");
3015 this is a harness for some oplock tests
3017 static bool run_oplock1(int dummy)
3019 struct cli_state *cli1;
3020 const char *fname = "\\lockt1.lck";
3022 bool correct = True;
3024 printf("starting oplock test 1\n");
3026 if (!torture_open_connection(&cli1, 0)) {
3030 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3032 cli_sockopt(cli1, sockops);
3034 cli1->use_oplocks = True;
3036 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3037 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3041 cli1->use_oplocks = False;
3043 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3044 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3046 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3047 printf("close2 failed (%s)\n", cli_errstr(cli1));
3051 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3052 printf("unlink failed (%s)\n", cli_errstr(cli1));
3056 if (!torture_close_connection(cli1)) {
3060 printf("finished oplock test 1\n");
3065 static bool run_oplock2(int dummy)
3067 struct cli_state *cli1, *cli2;
3068 const char *fname = "\\lockt2.lck";
3069 uint16_t fnum1, fnum2;
3070 int saved_use_oplocks = use_oplocks;
3072 bool correct = True;
3073 volatile bool *shared_correct;
3075 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3076 *shared_correct = True;
3078 use_level_II_oplocks = True;
3081 printf("starting oplock test 2\n");
3083 if (!torture_open_connection(&cli1, 0)) {
3084 use_level_II_oplocks = False;
3085 use_oplocks = saved_use_oplocks;
3089 cli1->use_oplocks = True;
3090 cli1->use_level_II_oplocks = True;
3092 if (!torture_open_connection(&cli2, 1)) {
3093 use_level_II_oplocks = False;
3094 use_oplocks = saved_use_oplocks;
3098 cli2->use_oplocks = True;
3099 cli2->use_level_II_oplocks = True;
3101 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3103 cli_sockopt(cli1, sockops);
3104 cli_sockopt(cli2, sockops);
3106 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3107 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3111 /* Don't need the globals any more. */
3112 use_level_II_oplocks = False;
3113 use_oplocks = saved_use_oplocks;
3117 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3118 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3119 *shared_correct = False;
3125 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3126 printf("close2 failed (%s)\n", cli_errstr(cli1));
3127 *shared_correct = False;
3135 /* Ensure cli1 processes the break. Empty file should always return 0
3138 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3139 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3143 /* Should now be at level II. */
3144 /* Test if sending a write locks causes a break to none. */
3146 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3147 printf("lock failed (%s)\n", cli_errstr(cli1));
3151 cli_unlock(cli1, fnum1, 0, 4);
3155 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3156 printf("lock failed (%s)\n", cli_errstr(cli1));
3160 cli_unlock(cli1, fnum1, 0, 4);
3164 cli_read(cli1, fnum1, buf, 0, 4);
3167 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3168 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3173 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3174 printf("close1 failed (%s)\n", cli_errstr(cli1));
3180 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3181 printf("unlink failed (%s)\n", cli_errstr(cli1));
3185 if (!torture_close_connection(cli1)) {
3189 if (!*shared_correct) {
3193 printf("finished oplock test 2\n");
3198 /* handler for oplock 3 tests */
3199 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3201 printf("got oplock break fnum=%d level=%d\n",
3203 return cli_oplock_ack(cli, fnum, level);
3206 static bool run_oplock3(int dummy)
3208 struct cli_state *cli;
3209 const char *fname = "\\oplockt3.dat";
3211 char buf[4] = "abcd";
3212 bool correct = True;
3213 volatile bool *shared_correct;
3215 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3216 *shared_correct = True;
3218 printf("starting oplock test 3\n");
3223 use_level_II_oplocks = True;
3224 if (!torture_open_connection(&cli, 0)) {
3225 *shared_correct = False;
3229 /* try to trigger a oplock break in parent */
3230 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3231 cli_write(cli, fnum, 0, buf, 0, 4);
3237 use_level_II_oplocks = True;
3238 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3241 cli_oplock_handler(cli, oplock3_handler);
3242 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3243 cli_write(cli, fnum, 0, buf, 0, 4);
3244 cli_close(cli, fnum);
3245 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3246 cli->timeout = 20000;
3247 cli_receive_smb(cli);
3248 printf("finished oplock test 3\n");
3250 return (correct && *shared_correct);
3252 /* What are we looking for here? What's sucess and what's FAILURE? */
3258 Test delete on close semantics.
3260 static bool run_deletetest(int dummy)
3262 struct cli_state *cli1 = NULL;
3263 struct cli_state *cli2 = NULL;
3264 const char *fname = "\\delete.file";
3265 uint16_t fnum1 = (uint16_t)-1;
3266 uint16_t fnum2 = (uint16_t)-1;
3267 bool correct = True;
3269 printf("starting delete test\n");
3271 if (!torture_open_connection(&cli1, 0)) {
3275 cli_sockopt(cli1, sockops);
3277 /* Test 1 - this should delete the file on close. */
3279 cli_setatr(cli1, fname, 0, 0);
3280 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3282 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3283 0, FILE_OVERWRITE_IF,
3284 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3285 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3292 uint32 *accinfo = NULL;
3294 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3296 printf("access mode = 0x%lx\n", *accinfo);
3301 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3302 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3307 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3308 printf("[1] open of %s succeeded (should fail)\n", fname);
3313 printf("first delete on close test succeeded.\n");
3315 /* Test 2 - this should delete the file on close. */
3317 cli_setatr(cli1, fname, 0, 0);
3318 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3320 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3321 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3322 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3323 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3328 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3329 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3334 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3335 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3340 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3341 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3342 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3343 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3347 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3349 printf("second delete on close test succeeded.\n");
3352 cli_setatr(cli1, fname, 0, 0);
3353 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3355 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3356 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3357 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3362 /* This should fail with a sharing violation - open for delete is only compatible
3363 with SHARE_DELETE. */
3365 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3366 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3367 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3372 /* This should succeed. */
3374 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3375 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3376 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3381 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3382 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3387 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3388 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3393 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3394 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3399 /* This should fail - file should no longer be there. */
3401 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3402 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3403 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3404 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3406 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3410 printf("third delete on close test succeeded.\n");
3413 cli_setatr(cli1, fname, 0, 0);
3414 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3416 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3417 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3418 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3423 /* This should succeed. */
3424 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3425 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3426 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3431 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3432 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3437 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3438 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3443 /* This should fail - no more opens once delete on close set. */
3444 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3445 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3446 FILE_OPEN, 0, 0, &fnum2))) {
3447 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3451 printf("fourth delete on close test succeeded.\n");
3453 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3454 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3460 cli_setatr(cli1, fname, 0, 0);
3461 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3463 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3464 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3469 /* This should fail - only allowed on NT opens with DELETE access. */
3471 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3472 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3477 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3478 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3483 printf("fifth delete on close test succeeded.\n");
3486 cli_setatr(cli1, fname, 0, 0);
3487 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3489 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3490 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3491 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3492 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3497 /* This should fail - only allowed on NT opens with DELETE access. */
3499 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3500 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3505 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3506 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3511 printf("sixth delete on close test succeeded.\n");
3514 cli_setatr(cli1, fname, 0, 0);
3515 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3517 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3518 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3519 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3524 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3525 printf("[7] setting delete_on_close on file failed !\n");
3530 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3531 printf("[7] unsetting delete_on_close on file failed !\n");
3536 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3537 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3542 /* This next open should succeed - we reset the flag. */
3544 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3545 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3550 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3551 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3556 printf("seventh delete on close test succeeded.\n");
3559 cli_setatr(cli1, fname, 0, 0);
3560 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3562 if (!torture_open_connection(&cli2, 1)) {
3563 printf("[8] failed to open second connection.\n");
3568 cli_sockopt(cli1, sockops);
3570 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3571 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3572 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3573 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3578 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3579 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3580 FILE_OPEN, 0, 0, &fnum2))) {
3581 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3586 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3587 printf("[8] setting delete_on_close on file failed !\n");
3592 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3593 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3598 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3599 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3604 /* This should fail.. */
3605 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3606 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3610 printf("eighth delete on close test succeeded.\n");
3612 /* This should fail - we need to set DELETE_ACCESS. */
3613 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3614 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3615 printf("[9] open of %s succeeded should have failed!\n", fname);
3620 printf("ninth delete on close test succeeded.\n");
3622 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3623 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3624 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3629 /* This should delete the file. */
3630 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3631 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3636 /* This should fail.. */
3637 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3638 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3642 printf("tenth delete on close test succeeded.\n");
3644 cli_setatr(cli1, fname, 0, 0);
3645 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3647 /* What error do we get when attempting to open a read-only file with
3650 /* Create a readonly file. */
3651 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3652 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3653 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3658 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3659 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3664 /* Now try open for delete access. */
3665 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3666 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3667 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3668 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3669 cli_close(cli1, fnum1);
3673 NTSTATUS nterr = cli_nt_error(cli1);
3674 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3675 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3679 printf("eleventh delete on close test succeeded.\n");
3683 printf("finished delete test\n");
3686 /* FIXME: This will crash if we aborted before cli2 got
3687 * intialized, because these functions don't handle
3688 * uninitialized connections. */
3690 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3691 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3692 cli_setatr(cli1, fname, 0, 0);
3693 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3695 if (cli1 && !torture_close_connection(cli1)) {
3698 if (cli2 && !torture_close_connection(cli2)) {
3706 print out server properties
3708 static bool run_properties(int dummy)
3710 struct cli_state *cli;
3711 bool correct = True;
3713 printf("starting properties test\n");
3717 if (!torture_open_connection(&cli, 0)) {
3721 cli_sockopt(cli, sockops);
3723 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3725 if (!torture_close_connection(cli)) {
3734 /* FIRST_DESIRED_ACCESS 0xf019f */
3735 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3736 FILE_READ_EA| /* 0xf */ \
3737 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3738 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3739 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3740 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3741 /* SECOND_DESIRED_ACCESS 0xe0080 */
3742 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3743 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3744 WRITE_OWNER_ACCESS /* 0xe0000 */
3747 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3748 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3750 WRITE_OWNER_ACCESS /* */
3754 Test ntcreate calls made by xcopy
3756 static bool run_xcopy(int dummy)
3758 static struct cli_state *cli1;
3759 const char *fname = "\\test.txt";
3760 bool correct = True;
3761 uint16_t fnum1, fnum2;
3763 printf("starting xcopy test\n");
3765 if (!torture_open_connection(&cli1, 0)) {
3769 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3770 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3771 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3772 0x4044, 0, &fnum1))) {
3773 printf("First open failed - %s\n", cli_errstr(cli1));
3777 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3778 SECOND_DESIRED_ACCESS, 0,
3779 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3780 0x200000, 0, &fnum2))) {
3781 printf("second open failed - %s\n", cli_errstr(cli1));
3785 if (!torture_close_connection(cli1)) {
3793 Test rename on files open with share delete and no share delete.
3795 static bool run_rename(int dummy)
3797 static struct cli_state *cli1;
3798 const char *fname = "\\test.txt";
3799 const char *fname1 = "\\test1.txt";
3800 bool correct = True;
3805 printf("starting rename test\n");
3807 if (!torture_open_connection(&cli1, 0)) {
3811 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3812 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3813 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3814 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3815 printf("First open failed - %s\n", cli_errstr(cli1));
3819 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3820 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3822 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3826 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3827 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3831 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3832 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3833 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3835 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3837 FILE_SHARE_DELETE|FILE_SHARE_READ,
3839 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3840 if (!NT_STATUS_IS_OK(status)) {
3841 printf("Second open failed - %s\n", cli_errstr(cli1));
3845 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3846 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3849 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3852 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3853 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3857 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3858 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3860 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3861 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3862 printf("Third open failed - %s\n", cli_errstr(cli1));
3871 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3872 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3873 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3876 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3877 printf("[8] setting delete_on_close on file failed !\n");
3881 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3882 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3888 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3889 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3892 printf("Third rename succeeded (SHARE_NONE)\n");
3895 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3896 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3900 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3901 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3905 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3906 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3907 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3911 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3912 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3914 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3918 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3919 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3923 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3924 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3928 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3929 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3930 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3934 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3935 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3939 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3943 * Now check if the first name still exists ...
3946 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3947 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3948 printf("Opening original file after rename of open file fails: %s\n",
3952 printf("Opening original file after rename of open file works ...\n");
3953 (void)cli_close(cli1, fnum2);
3957 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3958 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3962 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
3963 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
3964 printf("getatr on file %s failed - %s ! \n",
3969 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
3970 printf("Renamed file %s has wrong attr 0x%x "
3971 "(should be 0x%x)\n",
3974 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
3977 printf("Renamed file %s has archive bit set\n", fname1);
3981 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3982 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3984 if (!torture_close_connection(cli1)) {
3991 static bool run_pipe_number(int dummy)
3993 struct cli_state *cli1;
3994 const char *pipe_name = "\\SPOOLSS";
3998 printf("starting pipenumber test\n");
3999 if (!torture_open_connection(&cli1, 0)) {
4003 cli_sockopt(cli1, sockops);
4005 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4006 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4007 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4011 printf("\r%6d", num_pipes);
4014 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4015 torture_close_connection(cli1);
4020 Test open mode returns on read-only files.
4022 static bool run_opentest(int dummy)
4024 static struct cli_state *cli1;
4025 static struct cli_state *cli2;
4026 const char *fname = "\\readonly.file";
4027 uint16_t fnum1, fnum2;
4030 bool correct = True;
4033 printf("starting open test\n");
4035 if (!torture_open_connection(&cli1, 0)) {
4039 cli_setatr(cli1, fname, 0, 0);
4040 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4042 cli_sockopt(cli1, sockops);
4044 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4045 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4049 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4050 printf("close2 failed (%s)\n", cli_errstr(cli1));
4054 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4055 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4059 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4060 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4064 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4065 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4067 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4068 NT_STATUS_ACCESS_DENIED)) {
4069 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4072 printf("finished open test 1\n");
4074 cli_close(cli1, fnum1);
4076 /* Now try not readonly and ensure ERRbadshare is returned. */
4078 cli_setatr(cli1, fname, 0, 0);
4080 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4081 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4085 /* This will fail - but the error should be ERRshare. */
4086 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4088 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4089 NT_STATUS_SHARING_VIOLATION)) {
4090 printf("correct error code ERRDOS/ERRbadshare returned\n");
4093 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4094 printf("close2 failed (%s)\n", cli_errstr(cli1));
4098 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4100 printf("finished open test 2\n");
4102 /* Test truncate open disposition on file opened for read. */
4104 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4105 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4109 /* write 20 bytes. */
4111 memset(buf, '\0', 20);
4113 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4114 printf("write failed (%s)\n", cli_errstr(cli1));
4118 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4119 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4123 /* Ensure size == 20. */
4124 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4125 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4130 printf("(3) file size != 20\n");
4134 /* Now test if we can truncate a file opened for readonly. */
4136 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4137 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4141 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4142 printf("close2 failed (%s)\n", cli_errstr(cli1));
4146 /* Ensure size == 0. */
4147 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4148 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4153 printf("(3) file size != 0\n");
4156 printf("finished open test 3\n");
4158 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4161 printf("testing ctemp\n");
4162 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4163 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4166 printf("ctemp gave path %s\n", tmp_path);
4167 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4168 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4170 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4171 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4174 /* Test the non-io opens... */
4176 if (!torture_open_connection(&cli2, 1)) {
4180 cli_setatr(cli2, fname, 0, 0);
4181 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4183 cli_sockopt(cli2, sockops);
4185 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4187 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4188 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4189 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4193 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4194 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4195 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4199 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4200 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4203 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4204 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4208 printf("non-io open test #1 passed.\n");
4210 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4212 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4214 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4215 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4216 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4220 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4221 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4222 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4226 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4227 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4230 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4231 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4235 printf("non-io open test #2 passed.\n");
4237 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4239 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4241 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4242 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4243 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4247 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4248 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4249 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4253 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4254 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4257 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4258 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4262 printf("non-io open test #3 passed.\n");
4264 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4266 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4268 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4269 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4270 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4274 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4275 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4276 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4280 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4282 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4283 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4287 printf("non-io open test #4 passed.\n");
4289 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4291 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4293 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4294 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4295 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4299 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4300 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4301 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4305 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4306 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4310 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4311 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4315 printf("non-io open test #5 passed.\n");
4317 printf("TEST #6 testing 1 non-io open, one io open\n");
4319 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4321 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4322 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4323 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4327 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4328 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4329 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4333 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4334 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4338 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4339 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4343 printf("non-io open test #6 passed.\n");
4345 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4347 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4349 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4350 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4351 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4355 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4356 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4357 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4361 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4363 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4364 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4368 printf("non-io open test #7 passed.\n");
4370 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4372 if (!torture_close_connection(cli1)) {
4375 if (!torture_close_connection(cli2)) {
4382 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4384 uint16 major, minor;
4385 uint32 caplow, caphigh;
4388 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4389 printf("Server doesn't support UNIX CIFS extensions.\n");
4390 return NT_STATUS_NOT_SUPPORTED;
4393 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4395 if (!NT_STATUS_IS_OK(status)) {
4396 printf("Server didn't return UNIX CIFS extensions: %s\n",
4401 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4403 if (!NT_STATUS_IS_OK(status)) {
4404 printf("Server doesn't support setting UNIX CIFS extensions: "
4405 "%s.\n", nt_errstr(status));
4409 return NT_STATUS_OK;
4413 Test POSIX open /mkdir calls.
4415 static bool run_simple_posix_open_test(int dummy)
4417 static struct cli_state *cli1;
4418 const char *fname = "posix:file";
4419 const char *hname = "posix:hlink";
4420 const char *sname = "posix:symlink";
4421 const char *dname = "posix:dir";
4424 uint16_t fnum1 = (uint16_t)-1;
4425 SMB_STRUCT_STAT sbuf;
4426 bool correct = false;
4429 printf("Starting simple POSIX open test\n");
4431 if (!torture_open_connection(&cli1, 0)) {
4435 cli_sockopt(cli1, sockops);
4437 status = torture_setup_unix_extensions(cli1);
4438 if (!NT_STATUS_IS_OK(status)) {
4442 cli_setatr(cli1, fname, 0, 0);
4443 cli_posix_unlink(cli1, fname);
4444 cli_setatr(cli1, dname, 0, 0);
4445 cli_posix_rmdir(cli1, dname);
4446 cli_setatr(cli1, hname, 0, 0);
4447 cli_posix_unlink(cli1, hname);
4448 cli_setatr(cli1, sname, 0, 0);
4449 cli_posix_unlink(cli1, sname);
4451 /* Create a directory. */
4452 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4453 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4457 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4458 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4462 /* Test ftruncate - set file size. */
4463 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4464 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4468 /* Ensure st_size == 1000 */
4469 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4470 printf("stat failed (%s)\n", cli_errstr(cli1));
4474 if (sbuf.st_ex_size != 1000) {
4475 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4479 /* Test ftruncate - set file size back to zero. */
4480 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4481 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4485 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4486 printf("close failed (%s)\n", cli_errstr(cli1));
4490 /* Now open the file again for read only. */
4491 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4492 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4496 /* Now unlink while open. */
4497 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4498 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4502 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4503 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4507 /* Ensure the file has gone. */
4508 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4509 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4513 /* What happens when we try and POSIX open a directory ? */
4514 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4515 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4518 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4519 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4524 /* Create the file. */
4525 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4526 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4530 /* Write some data into it. */
4531 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4532 printf("cli_write failed: %s\n", cli_errstr(cli1));
4536 cli_close(cli1, fnum1);
4538 /* Now create a hardlink. */
4539 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4540 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4544 /* Now create a symlink. */
4545 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4546 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4550 /* Open the hardlink for read. */
4551 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4552 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4556 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4557 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4561 if (memcmp(buf, "TEST DATA\n", 10)) {
4562 printf("invalid data read from hardlink\n");
4566 /* Do a POSIX lock/unlock. */
4567 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4568 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4572 /* Punch a hole in the locked area. */
4573 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4574 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4578 cli_close(cli1, fnum1);
4580 /* Open the symlink for read - this should fail. A POSIX
4581 client should not be doing opens on a symlink. */
4582 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4583 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4586 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4587 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4588 printf("POSIX open of %s should have failed "
4589 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4590 "failed with %s instead.\n",
4591 sname, cli_errstr(cli1));
4596 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4597 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4601 if (strcmp(namebuf, fname) != 0) {
4602 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4603 sname, fname, namebuf);
4607 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4608 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4612 printf("Simple POSIX open test passed\n");
4617 if (fnum1 != (uint16_t)-1) {
4618 cli_close(cli1, fnum1);
4619 fnum1 = (uint16_t)-1;
4622 cli_setatr(cli1, sname, 0, 0);
4623 cli_posix_unlink(cli1, sname);
4624 cli_setatr(cli1, hname, 0, 0);
4625 cli_posix_unlink(cli1, hname);
4626 cli_setatr(cli1, fname, 0, 0);
4627 cli_posix_unlink(cli1, fname);
4628 cli_setatr(cli1, dname, 0, 0);
4629 cli_posix_rmdir(cli1, dname);
4631 if (!torture_close_connection(cli1)) {
4639 static uint32 open_attrs_table[] = {
4640 FILE_ATTRIBUTE_NORMAL,
4641 FILE_ATTRIBUTE_ARCHIVE,
4642 FILE_ATTRIBUTE_READONLY,
4643 FILE_ATTRIBUTE_HIDDEN,
4644 FILE_ATTRIBUTE_SYSTEM,
4646 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4647 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4648 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4649 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4650 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4651 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4653 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4654 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4655 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4656 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4659 struct trunc_open_results {
4666 static struct trunc_open_results attr_results[] = {
4667 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4668 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4669 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4670 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4671 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4672 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4673 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4674 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4675 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4676 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4677 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4678 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4679 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4680 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4681 { 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 },
4682 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4683 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4684 { 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 },
4685 { 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 },
4686 { 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 },
4687 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4688 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4689 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4690 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4691 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4692 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4695 static bool run_openattrtest(int dummy)
4697 static struct cli_state *cli1;
4698 const char *fname = "\\openattr.file";
4700 bool correct = True;
4702 unsigned int i, j, k, l;
4704 printf("starting open attr test\n");
4706 if (!torture_open_connection(&cli1, 0)) {
4710 cli_sockopt(cli1, sockops);
4712 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4713 cli_setatr(cli1, fname, 0, 0);
4714 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4715 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4716 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4717 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4721 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4722 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4726 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4727 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4728 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4729 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4730 if (attr_results[l].num == k) {
4731 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4732 k, open_attrs_table[i],
4733 open_attrs_table[j],
4734 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4738 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4739 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4740 k, open_attrs_table[i], open_attrs_table[j],
4745 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4751 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4752 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4756 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4757 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4762 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4763 k, open_attrs_table[i], open_attrs_table[j], attr );
4766 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4767 if (attr_results[l].num == k) {
4768 if (attr != attr_results[l].result_attr ||
4769 open_attrs_table[i] != attr_results[l].init_attr ||
4770 open_attrs_table[j] != attr_results[l].trunc_attr) {
4771 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4772 open_attrs_table[i],
4773 open_attrs_table[j],
4775 attr_results[l].result_attr);
4785 cli_setatr(cli1, fname, 0, 0);
4786 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4788 printf("open attr test %s.\n", correct ? "passed" : "failed");
4790 if (!torture_close_connection(cli1)) {
4796 static void list_fn(const char *mnt, struct file_info *finfo,
4797 const char *name, void *state)
4799 int *matched = (int *)state;
4800 if (matched != NULL) {
4806 test directory listing speed
4808 static bool run_dirtest(int dummy)
4811 static struct cli_state *cli;
4813 struct timeval core_start;
4814 bool correct = True;
4817 printf("starting directory test\n");
4819 if (!torture_open_connection(&cli, 0)) {
4823 cli_sockopt(cli, sockops);
4826 for (i=0;i<torture_numops;i++) {
4828 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4829 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4830 fprintf(stderr,"Failed to open %s\n", fname);
4833 cli_close(cli, fnum);
4836 core_start = timeval_current();
4839 cli_list(cli, "a*.*", 0, list_fn, &matched);
4840 printf("Matched %d\n", matched);
4843 cli_list(cli, "b*.*", 0, list_fn, &matched);
4844 printf("Matched %d\n", matched);
4847 cli_list(cli, "xyzabc", 0, list_fn, &matched);
4848 printf("Matched %d\n", matched);
4850 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4853 for (i=0;i<torture_numops;i++) {
4855 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4856 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4859 if (!torture_close_connection(cli)) {
4863 printf("finished dirtest\n");
4868 static void del_fn(const char *mnt, struct file_info *finfo, const char *mask,
4871 struct cli_state *pcli = (struct cli_state *)state;
4873 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4875 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4878 if (finfo->mode & aDIR) {
4879 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4880 printf("del_fn: failed to rmdir %s\n,", fname );
4882 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4883 printf("del_fn: failed to unlink %s\n,", fname );
4889 sees what IOCTLs are supported
4891 bool torture_ioctl_test(int dummy)
4893 static struct cli_state *cli;
4894 uint16_t device, function;
4896 const char *fname = "\\ioctl.dat";
4900 if (!torture_open_connection(&cli, 0)) {
4904 printf("starting ioctl test\n");
4906 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4908 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4909 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4913 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4914 printf("ioctl device info: %s\n", nt_errstr(status));
4916 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4917 printf("ioctl job info: %s\n", nt_errstr(status));
4919 for (device=0;device<0x100;device++) {
4920 printf("ioctl test with device = 0x%x\n", device);
4921 for (function=0;function<0x100;function++) {
4922 uint32 code = (device<<16) | function;
4924 status = cli_raw_ioctl(cli, fnum, code, &blob);
4926 if (NT_STATUS_IS_OK(status)) {
4927 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4929 data_blob_free(&blob);
4934 if (!torture_close_connection(cli)) {
4943 tries varients of chkpath
4945 bool torture_chkpath_test(int dummy)
4947 static struct cli_state *cli;
4951 if (!torture_open_connection(&cli, 0)) {
4955 printf("starting chkpath test\n");
4957 /* cleanup from an old run */
4958 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4959 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4960 cli_rmdir(cli, "\\chkpath.dir");
4962 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4963 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4967 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4968 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4972 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4973 printf("open1 failed (%s)\n", cli_errstr(cli));
4976 cli_close(cli, fnum);
4978 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4979 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4983 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4984 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4988 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4989 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4990 NT_STATUS_NOT_A_DIRECTORY);
4992 printf("* chkpath on a file should fail\n");
4996 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4997 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
4998 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5000 printf("* chkpath on a non existant file should fail\n");
5004 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5005 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5006 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5008 printf("* chkpath on a non existent component should fail\n");
5012 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5013 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5014 cli_rmdir(cli, "\\chkpath.dir");
5016 if (!torture_close_connection(cli)) {
5023 static bool run_eatest(int dummy)
5025 static struct cli_state *cli;
5026 const char *fname = "\\eatest.txt";
5027 bool correct = True;
5031 struct ea_struct *ea_list = NULL;
5032 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5035 printf("starting eatest\n");
5037 if (!torture_open_connection(&cli, 0)) {
5038 talloc_destroy(mem_ctx);
5042 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5043 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5044 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5045 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5046 0x4044, 0, &fnum))) {
5047 printf("open failed - %s\n", cli_errstr(cli));
5048 talloc_destroy(mem_ctx);
5052 for (i = 0; i < 10; i++) {
5053 fstring ea_name, ea_val;
5055 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5056 memset(ea_val, (char)i+1, i+1);
5057 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5058 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5059 talloc_destroy(mem_ctx);
5064 cli_close(cli, fnum);
5065 for (i = 0; i < 10; i++) {
5066 fstring ea_name, ea_val;
5068 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5069 memset(ea_val, (char)i+1, i+1);
5070 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5071 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5072 talloc_destroy(mem_ctx);
5077 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5078 if (!NT_STATUS_IS_OK(status)) {
5079 printf("ea_get list failed - %s\n", nt_errstr(status));
5083 printf("num_eas = %d\n", (int)num_eas);
5085 if (num_eas != 20) {
5086 printf("Should be 20 EA's stored... failing.\n");
5090 for (i = 0; i < num_eas; i++) {
5091 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5092 dump_data(0, ea_list[i].value.data,
5093 ea_list[i].value.length);
5096 /* Setting EA's to zero length deletes them. Test this */
5097 printf("Now deleting all EA's - case indepenent....\n");
5100 cli_set_ea_path(cli, fname, "", "", 0);
5102 for (i = 0; i < 20; i++) {
5104 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5105 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5106 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5107 talloc_destroy(mem_ctx);
5113 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5114 if (!NT_STATUS_IS_OK(status)) {
5115 printf("ea_get list failed - %s\n", nt_errstr(status));
5119 printf("num_eas = %d\n", (int)num_eas);
5120 for (i = 0; i < num_eas; i++) {
5121 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5122 dump_data(0, ea_list[i].value.data,
5123 ea_list[i].value.length);
5127 printf("deleting EA's failed.\n");
5131 /* Try and delete a non existant EA. */
5132 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5133 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5137 talloc_destroy(mem_ctx);
5138 if (!torture_close_connection(cli)) {
5145 static bool run_dirtest1(int dummy)
5148 static struct cli_state *cli;
5151 bool correct = True;
5153 printf("starting directory test\n");
5155 if (!torture_open_connection(&cli, 0)) {
5159 cli_sockopt(cli, sockops);
5161 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5162 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5163 cli_rmdir(cli, "\\LISTDIR");
5164 cli_mkdir(cli, "\\LISTDIR");
5166 /* Create 1000 files and 1000 directories. */
5167 for (i=0;i<1000;i++) {
5169 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5170 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5171 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5172 fprintf(stderr,"Failed to open %s\n", fname);
5175 cli_close(cli, fnum);
5177 for (i=0;i<1000;i++) {
5179 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5180 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5181 fprintf(stderr,"Failed to open %s\n", fname);
5186 /* Now ensure that doing an old list sees both files and directories. */
5188 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5189 printf("num_seen = %d\n", num_seen );
5190 /* We should see 100 files + 1000 directories + . and .. */
5191 if (num_seen != 2002)
5194 /* Ensure if we have the "must have" bits we only see the
5198 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5199 printf("num_seen = %d\n", num_seen );
5200 if (num_seen != 1002)
5204 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5205 printf("num_seen = %d\n", num_seen );
5206 if (num_seen != 1000)
5209 /* Delete everything. */
5210 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5211 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5212 cli_rmdir(cli, "\\LISTDIR");
5215 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5216 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5217 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5220 if (!torture_close_connection(cli)) {
5224 printf("finished dirtest1\n");
5229 static bool run_error_map_extract(int dummy) {
5231 static struct cli_state *c_dos;
5232 static struct cli_state *c_nt;
5237 uint32 flgs2, errnum;
5244 /* NT-Error connection */
5246 if (!(c_nt = open_nbt_connection())) {
5250 c_nt->use_spnego = False;
5252 status = cli_negprot(c_nt);
5254 if (!NT_STATUS_IS_OK(status)) {
5255 printf("%s rejected the NT-error negprot (%s)\n", host,
5261 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5263 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5267 /* DOS-Error connection */
5269 if (!(c_dos = open_nbt_connection())) {
5273 c_dos->use_spnego = False;
5274 c_dos->force_dos_errors = True;
5276 status = cli_negprot(c_dos);
5277 if (!NT_STATUS_IS_OK(status)) {
5278 printf("%s rejected the DOS-error negprot (%s)\n", host,
5280 cli_shutdown(c_dos);
5284 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5286 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5290 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5291 fstr_sprintf(user, "%X", error);
5293 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5294 password, strlen(password),
5295 password, strlen(password),
5297 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5300 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5302 /* Case #1: 32-bit NT errors */
5303 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5304 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5306 printf("/** Dos error on NT connection! (%s) */\n",
5308 nt_status = NT_STATUS(0xc0000000);
5311 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5312 password, strlen(password),
5313 password, strlen(password),
5315 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5317 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5319 /* Case #1: 32-bit NT errors */
5320 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5321 printf("/** NT error on DOS connection! (%s) */\n",
5323 errnum = errclass = 0;
5325 cli_dos_error(c_dos, &errclass, &errnum);
5328 if (NT_STATUS_V(nt_status) != error) {
5329 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5330 get_nt_error_c_code(NT_STATUS(error)),
5331 get_nt_error_c_code(nt_status));
5334 printf("\t{%s,\t%s,\t%s},\n",
5335 smb_dos_err_class(errclass),
5336 smb_dos_err_name(errclass, errnum),
5337 get_nt_error_c_code(NT_STATUS(error)));
5342 static bool run_sesssetup_bench(int dummy)
5344 static struct cli_state *c;
5345 const char *fname = "\\file.dat";
5350 if (!torture_open_connection(&c, 0)) {
5354 if (!NT_STATUS_IS_OK(cli_ntcreate(
5355 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5356 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5357 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5358 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5362 for (i=0; i<torture_numops; i++) {
5363 status = cli_session_setup(
5365 password, strlen(password),
5366 password, strlen(password),
5368 if (!NT_STATUS_IS_OK(status)) {
5369 d_printf("(%s) cli_session_setup failed: %s\n",
5370 __location__, nt_errstr(status));
5374 d_printf("\r%d ", (int)c->vuid);
5376 status = cli_ulogoff(c);
5377 if (!NT_STATUS_IS_OK(status)) {
5378 d_printf("(%s) cli_ulogoff failed: %s\n",
5379 __location__, nt_errstr(status));
5388 static bool subst_test(const char *str, const char *user, const char *domain,
5389 uid_t uid, gid_t gid, const char *expected)
5394 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5396 if (strcmp(subst, expected) != 0) {
5397 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5398 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5407 static void chain1_open_completion(struct tevent_req *req)
5411 status = cli_open_recv(req, &fnum);
5414 d_printf("cli_open_recv returned %s: %d\n",
5416 NT_STATUS_IS_OK(status) ? fnum : -1);
5419 static void chain1_write_completion(struct tevent_req *req)
5423 status = cli_write_andx_recv(req, &written);
5426 d_printf("cli_write_andx_recv returned %s: %d\n",
5428 NT_STATUS_IS_OK(status) ? (int)written : -1);
5431 static void chain1_close_completion(struct tevent_req *req)
5434 bool *done = (bool *)tevent_req_callback_data_void(req);
5436 status = cli_close_recv(req);
5441 d_printf("cli_close returned %s\n", nt_errstr(status));
5444 static bool run_chain1(int dummy)
5446 struct cli_state *cli1;
5447 struct event_context *evt = event_context_init(NULL);
5448 struct tevent_req *reqs[3], *smbreqs[3];
5450 const char *str = "foobar";
5453 printf("starting chain1 test\n");
5454 if (!torture_open_connection(&cli1, 0)) {
5458 cli_sockopt(cli1, sockops);
5460 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5461 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5462 if (reqs[0] == NULL) return false;
5463 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5466 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5467 (uint8_t *)str, 0, strlen(str)+1,
5468 smbreqs, 1, &smbreqs[1]);
5469 if (reqs[1] == NULL) return false;
5470 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5472 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5473 if (reqs[2] == NULL) return false;
5474 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5476 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5477 if (!NT_STATUS_IS_OK(status)) {
5482 event_loop_once(evt);
5485 torture_close_connection(cli1);
5489 static void chain2_sesssetup_completion(struct tevent_req *req)
5492 status = cli_session_setup_guest_recv(req);
5493 d_printf("sesssetup returned %s\n", nt_errstr(status));
5496 static void chain2_tcon_completion(struct tevent_req *req)
5498 bool *done = (bool *)tevent_req_callback_data_void(req);
5500 status = cli_tcon_andx_recv(req);
5501 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5505 static bool run_chain2(int dummy)
5507 struct cli_state *cli1;
5508 struct event_context *evt = event_context_init(NULL);
5509 struct tevent_req *reqs[2], *smbreqs[2];
5513 printf("starting chain2 test\n");
5514 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5515 port_to_use, Undefined, 0, NULL);
5516 if (!NT_STATUS_IS_OK(status)) {
5520 cli_sockopt(cli1, sockops);
5522 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5524 if (reqs[0] == NULL) return false;
5525 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5527 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5528 "?????", NULL, 0, &smbreqs[1]);
5529 if (reqs[1] == NULL) return false;
5530 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5532 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5533 if (!NT_STATUS_IS_OK(status)) {
5538 event_loop_once(evt);
5541 torture_close_connection(cli1);
5546 struct torture_createdel_state {
5547 struct tevent_context *ev;
5548 struct cli_state *cli;
5551 static void torture_createdel_created(struct tevent_req *subreq);
5552 static void torture_createdel_closed(struct tevent_req *subreq);
5554 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5555 struct tevent_context *ev,
5556 struct cli_state *cli,
5559 struct tevent_req *req, *subreq;
5560 struct torture_createdel_state *state;
5562 req = tevent_req_create(mem_ctx, &state,
5563 struct torture_createdel_state);
5570 subreq = cli_ntcreate_send(
5571 state, ev, cli, name, 0,
5572 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5573 FILE_ATTRIBUTE_NORMAL,
5574 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5575 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5577 if (tevent_req_nomem(subreq, req)) {
5578 return tevent_req_post(req, ev);
5580 tevent_req_set_callback(subreq, torture_createdel_created, req);
5584 static void torture_createdel_created(struct tevent_req *subreq)
5586 struct tevent_req *req = tevent_req_callback_data(
5587 subreq, struct tevent_req);
5588 struct torture_createdel_state *state = tevent_req_data(
5589 req, struct torture_createdel_state);
5593 status = cli_ntcreate_recv(subreq, &fnum);
5594 TALLOC_FREE(subreq);
5595 if (!NT_STATUS_IS_OK(status)) {
5596 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5597 nt_errstr(status)));
5598 tevent_req_nterror(req, status);
5602 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5603 if (tevent_req_nomem(subreq, req)) {
5606 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5609 static void torture_createdel_closed(struct tevent_req *subreq)
5611 struct tevent_req *req = tevent_req_callback_data(
5612 subreq, struct tevent_req);
5615 status = cli_close_recv(subreq);
5616 if (!NT_STATUS_IS_OK(status)) {
5617 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5618 tevent_req_nterror(req, status);
5621 tevent_req_done(req);
5624 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5626 return tevent_req_simple_recv_ntstatus(req);
5629 struct torture_createdels_state {
5630 struct tevent_context *ev;
5631 struct cli_state *cli;
5632 const char *base_name;
5636 struct tevent_req **reqs;
5639 static void torture_createdels_done(struct tevent_req *subreq);
5641 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5642 struct tevent_context *ev,
5643 struct cli_state *cli,
5644 const char *base_name,
5648 struct tevent_req *req;
5649 struct torture_createdels_state *state;
5652 req = tevent_req_create(mem_ctx, &state,
5653 struct torture_createdels_state);
5659 state->base_name = talloc_strdup(state, base_name);
5660 if (tevent_req_nomem(state->base_name, req)) {
5661 return tevent_req_post(req, ev);
5663 state->num_files = MAX(num_parallel, num_files);
5665 state->received = 0;
5667 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5668 if (tevent_req_nomem(state->reqs, req)) {
5669 return tevent_req_post(req, ev);
5672 for (i=0; i<num_parallel; i++) {
5675 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5677 if (tevent_req_nomem(name, req)) {
5678 return tevent_req_post(req, ev);
5680 state->reqs[i] = torture_createdel_send(
5681 state->reqs, state->ev, state->cli, name);
5682 if (tevent_req_nomem(state->reqs[i], req)) {
5683 return tevent_req_post(req, ev);
5685 name = talloc_move(state->reqs[i], &name);
5686 tevent_req_set_callback(state->reqs[i],
5687 torture_createdels_done, req);
5693 static void torture_createdels_done(struct tevent_req *subreq)
5695 struct tevent_req *req = tevent_req_callback_data(
5696 subreq, struct tevent_req);
5697 struct torture_createdels_state *state = tevent_req_data(
5698 req, struct torture_createdels_state);
5699 size_t num_parallel = talloc_array_length(state->reqs);
5704 status = torture_createdel_recv(subreq);
5705 if (!NT_STATUS_IS_OK(status)){
5706 DEBUG(10, ("torture_createdel_recv returned %s\n",
5707 nt_errstr(status)));
5708 TALLOC_FREE(subreq);
5709 tevent_req_nterror(req, status);
5713 for (i=0; i<num_parallel; i++) {
5714 if (subreq == state->reqs[i]) {
5718 if (i == num_parallel) {
5719 DEBUG(10, ("received something we did not send\n"));
5720 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5723 TALLOC_FREE(state->reqs[i]);
5725 if (state->sent >= state->num_files) {
5726 tevent_req_done(req);
5730 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5732 if (tevent_req_nomem(name, req)) {
5735 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5737 if (tevent_req_nomem(state->reqs[i], req)) {
5740 name = talloc_move(state->reqs[i], &name);
5741 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5745 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5747 return tevent_req_simple_recv_ntstatus(req);
5750 struct swallow_notify_state {
5751 struct tevent_context *ev;
5752 struct cli_state *cli;
5754 uint32_t completion_filter;
5756 bool (*fn)(uint32_t action, const char *name, void *priv);
5760 static void swallow_notify_done(struct tevent_req *subreq);
5762 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5763 struct tevent_context *ev,
5764 struct cli_state *cli,
5766 uint32_t completion_filter,
5768 bool (*fn)(uint32_t action,
5773 struct tevent_req *req, *subreq;
5774 struct swallow_notify_state *state;
5776 req = tevent_req_create(mem_ctx, &state,
5777 struct swallow_notify_state);
5784 state->completion_filter = completion_filter;
5785 state->recursive = recursive;
5789 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5790 0xffff, state->completion_filter,
5792 if (tevent_req_nomem(subreq, req)) {
5793 return tevent_req_post(req, ev);
5795 tevent_req_set_callback(subreq, swallow_notify_done, req);
5799 static void swallow_notify_done(struct tevent_req *subreq)
5801 struct tevent_req *req = tevent_req_callback_data(
5802 subreq, struct tevent_req);
5803 struct swallow_notify_state *state = tevent_req_data(
5804 req, struct swallow_notify_state);
5806 uint32_t i, num_changes;
5807 struct notify_change *changes;
5809 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5810 TALLOC_FREE(subreq);
5811 if (!NT_STATUS_IS_OK(status)) {
5812 DEBUG(10, ("cli_notify_recv returned %s\n",
5813 nt_errstr(status)));
5814 tevent_req_nterror(req, status);
5818 for (i=0; i<num_changes; i++) {
5819 state->fn(changes[i].action, changes[i].name, state->priv);
5821 TALLOC_FREE(changes);
5823 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5824 0xffff, state->completion_filter,
5826 if (tevent_req_nomem(subreq, req)) {
5829 tevent_req_set_callback(subreq, swallow_notify_done, req);
5832 static bool print_notifies(uint32_t action, const char *name, void *priv)
5834 if (DEBUGLEVEL > 5) {
5835 d_printf("%d %s\n", (int)action, name);
5840 static void notify_bench_done(struct tevent_req *req)
5842 int *num_finished = (int *)tevent_req_callback_data_void(req);
5846 static bool run_notify_bench(int dummy)
5848 const char *dname = "\\notify-bench";
5849 struct tevent_context *ev;
5852 struct tevent_req *req1;
5853 struct tevent_req *req2 = NULL;
5854 int i, num_unc_names;
5855 int num_finished = 0;
5857 printf("starting notify-bench test\n");
5859 if (use_multishare_conn) {
5861 unc_list = file_lines_load(multishare_conn_fname,
5862 &num_unc_names, 0, NULL);
5863 if (!unc_list || num_unc_names <= 0) {
5864 d_printf("Failed to load unc names list from '%s'\n",
5865 multishare_conn_fname);
5868 TALLOC_FREE(unc_list);
5873 ev = tevent_context_init(talloc_tos());
5875 d_printf("tevent_context_init failed\n");
5879 for (i=0; i<num_unc_names; i++) {
5880 struct cli_state *cli;
5883 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5885 if (base_fname == NULL) {
5889 if (!torture_open_connection(&cli, i)) {
5893 status = cli_ntcreate(cli, dname, 0,
5894 MAXIMUM_ALLOWED_ACCESS,
5895 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5897 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5900 if (!NT_STATUS_IS_OK(status)) {
5901 d_printf("Could not create %s: %s\n", dname,
5906 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5907 FILE_NOTIFY_CHANGE_FILE_NAME |
5908 FILE_NOTIFY_CHANGE_DIR_NAME |
5909 FILE_NOTIFY_CHANGE_ATTRIBUTES |
5910 FILE_NOTIFY_CHANGE_LAST_WRITE,
5911 false, print_notifies, NULL);
5913 d_printf("Could not create notify request\n");
5917 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5918 base_fname, 10, torture_numops);
5920 d_printf("Could not create createdels request\n");
5923 TALLOC_FREE(base_fname);
5925 tevent_req_set_callback(req2, notify_bench_done,
5929 while (num_finished < num_unc_names) {
5931 ret = tevent_loop_once(ev);
5933 d_printf("tevent_loop_once failed\n");
5938 if (!tevent_req_poll(req2, ev)) {
5939 d_printf("tevent_req_poll failed\n");
5942 status = torture_createdels_recv(req2);
5943 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5948 static bool run_mangle1(int dummy)
5950 struct cli_state *cli;
5951 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5955 time_t change_time, access_time, write_time;
5959 printf("starting mangle1 test\n");
5960 if (!torture_open_connection(&cli, 0)) {
5964 cli_sockopt(cli, sockops);
5966 if (!NT_STATUS_IS_OK(cli_ntcreate(
5967 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5968 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5969 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5972 cli_close(cli, fnum);
5974 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5975 if (!NT_STATUS_IS_OK(status)) {
5976 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5980 d_printf("alt_name: %s\n", alt_name);
5982 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5983 d_printf("cli_open(%s) failed: %s\n", alt_name,
5987 cli_close(cli, fnum);
5989 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
5990 &write_time, &size, &mode);
5991 if (!NT_STATUS_IS_OK(status)) {
5992 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6000 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6002 size_t *to_pull = (size_t *)priv;
6003 size_t thistime = *to_pull;
6005 thistime = MIN(thistime, n);
6006 if (thistime == 0) {
6010 memset(buf, 0, thistime);
6011 *to_pull -= thistime;
6015 static bool run_windows_write(int dummy)
6017 struct cli_state *cli1;
6021 const char *fname = "\\writetest.txt";
6022 struct timeval start_time;
6026 printf("starting windows_write test\n");
6027 if (!torture_open_connection(&cli1, 0)) {
6031 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6032 printf("open failed (%s)\n", cli_errstr(cli1));
6036 cli_sockopt(cli1, sockops);
6038 start_time = timeval_current();
6040 for (i=0; i<torture_numops; i++) {
6042 off_t start = i * torture_blocksize;
6044 size_t to_pull = torture_blocksize - 1;
6046 if (cli_write(cli1, fnum, 0, &c,
6047 start + torture_blocksize - 1, 1) != 1) {
6048 printf("cli_write failed: %s\n", cli_errstr(cli1));
6052 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6053 null_source, &to_pull);
6054 if (!NT_STATUS_IS_OK(status)) {
6055 printf("cli_push returned: %s\n", nt_errstr(status));
6060 seconds = timeval_elapsed(&start_time);
6061 kbytes = (double)torture_blocksize * torture_numops;
6064 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6065 (double)seconds, (int)(kbytes/seconds));
6069 cli_close(cli1, fnum);
6070 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6071 torture_close_connection(cli1);
6075 static bool run_cli_echo(int dummy)
6077 struct cli_state *cli;
6080 printf("starting cli_echo test\n");
6081 if (!torture_open_connection(&cli, 0)) {
6084 cli_sockopt(cli, sockops);
6086 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6088 d_printf("cli_echo returned %s\n", nt_errstr(status));
6090 torture_close_connection(cli);
6091 return NT_STATUS_IS_OK(status);
6094 static bool run_uid_regression_test(int dummy)
6096 static struct cli_state *cli;
6099 bool correct = True;
6102 printf("starting uid regression test\n");
6104 if (!torture_open_connection(&cli, 0)) {
6108 cli_sockopt(cli, sockops);
6110 /* Ok - now save then logoff our current user. */
6111 old_vuid = cli->vuid;
6113 status = cli_ulogoff(cli);
6114 if (!NT_STATUS_IS_OK(status)) {
6115 d_printf("(%s) cli_ulogoff failed: %s\n",
6116 __location__, nt_errstr(status));
6121 cli->vuid = old_vuid;
6123 /* Try an operation. */
6124 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6125 /* We expect bad uid. */
6126 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6127 NT_STATUS_NO_SUCH_USER)) {
6132 old_cnum = cli->cnum;
6134 /* Now try a SMBtdis with the invald vuid set to zero. */
6137 /* This should succeed. */
6138 status = cli_tdis(cli);
6140 if (NT_STATUS_IS_OK(status)) {
6141 printf("First tdis with invalid vuid should succeed.\n");
6143 printf("First tdis failed (%s)\n", nt_errstr(status));
6146 cli->vuid = old_vuid;
6147 cli->cnum = old_cnum;
6149 /* This should fail. */
6150 status = cli_tdis(cli);
6151 if (NT_STATUS_IS_OK(status)) {
6152 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6154 /* Should be bad tid. */
6155 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6156 NT_STATUS_NETWORK_NAME_DELETED)) {
6161 cli_rmdir(cli, "\\uid_reg_test");
6170 static const char *illegal_chars = "*\\/?<>|\":";
6171 static char force_shortname_chars[] = " +,.[];=\177";
6173 static void shortname_del_fn(const char *mnt, struct file_info *finfo,
6174 const char *mask, void *state)
6176 struct cli_state *pcli = (struct cli_state *)state;
6178 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6180 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6183 if (finfo->mode & aDIR) {
6184 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6185 printf("del_fn: failed to rmdir %s\n,", fname );
6187 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6188 printf("del_fn: failed to unlink %s\n,", fname );
6198 static void shortname_list_fn(const char *mnt, struct file_info *finfo,
6199 const char *name, void *state)
6201 struct sn_state *s = (struct sn_state *)state;
6205 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6206 i, finfo->name, finfo->short_name);
6209 if (strchr(force_shortname_chars, i)) {
6210 if (!finfo->short_name[0]) {
6211 /* Shortname not created when it should be. */
6212 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6213 __location__, finfo->name, i);
6216 } else if (finfo->short_name[0]){
6217 /* Shortname created when it should not be. */
6218 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6219 __location__, finfo->short_name, finfo->name);
6225 static bool run_shortname_test(int dummy)
6227 static struct cli_state *cli;
6228 bool correct = True;
6233 printf("starting shortname test\n");
6235 if (!torture_open_connection(&cli, 0)) {
6239 cli_sockopt(cli, sockops);
6241 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6242 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6243 cli_rmdir(cli, "\\shortname");
6245 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6246 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6247 __location__, cli_errstr(cli));
6252 strlcpy(fname, "\\shortname\\", sizeof(fname));
6253 strlcat(fname, "test .txt", sizeof(fname));
6257 for (i = 32; i < 128; i++) {
6259 uint16_t fnum = (uint16_t)-1;
6263 if (strchr(illegal_chars, i)) {
6268 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6269 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6270 if (!NT_STATUS_IS_OK(status)) {
6271 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6272 __location__, fname, cli_errstr(cli));
6276 cli_close(cli, fnum);
6279 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6281 if (s.matched != 1) {
6282 d_printf("(%s) failed to list %s: %s\n",
6283 __location__, fname, cli_errstr(cli));
6287 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6288 d_printf("(%s) failed to delete %s: %s\n",
6289 __location__, fname, cli_errstr(cli));
6302 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6303 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6304 cli_rmdir(cli, "\\shortname");
6305 torture_close_connection(cli);
6309 static void pagedsearch_cb(struct tevent_req *req)
6312 struct tldap_message *msg;
6315 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6316 if (rc != TLDAP_SUCCESS) {
6317 d_printf("tldap_search_paged_recv failed: %s\n",
6318 tldap_err2string(rc));
6321 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6325 if (!tldap_entry_dn(msg, &dn)) {
6326 d_printf("tldap_entry_dn failed\n");
6329 d_printf("%s\n", dn);
6333 static bool run_tldap(int dummy)
6335 struct tldap_context *ld;
6338 struct sockaddr_storage addr;
6339 struct tevent_context *ev;
6340 struct tevent_req *req;
6344 if (!resolve_name(host, &addr, 0, false)) {
6345 d_printf("could not find host %s\n", host);
6348 status = open_socket_out(&addr, 389, 9999, &fd);
6349 if (!NT_STATUS_IS_OK(status)) {
6350 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6354 ld = tldap_context_create(talloc_tos(), fd);
6357 d_printf("tldap_context_create failed\n");
6361 rc = tldap_fetch_rootdse(ld);
6362 if (rc != TLDAP_SUCCESS) {
6363 d_printf("tldap_fetch_rootdse failed: %s\n",
6364 tldap_errstr(talloc_tos(), ld, rc));
6368 basedn = tldap_talloc_single_attribute(
6369 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6370 if (basedn == NULL) {
6371 d_printf("no defaultNamingContext\n");
6374 d_printf("defaultNamingContext: %s\n", basedn);
6376 ev = tevent_context_init(talloc_tos());
6378 d_printf("tevent_context_init failed\n");
6382 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6383 TLDAP_SCOPE_SUB, "(objectclass=*)",
6385 NULL, 0, NULL, 0, 0, 0, 0, 5);
6387 d_printf("tldap_search_paged_send failed\n");
6390 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6392 tevent_req_poll(req, ev);
6396 /* test search filters against rootDSE */
6397 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6398 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6400 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6401 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6402 talloc_tos(), NULL, NULL);
6403 if (rc != TLDAP_SUCCESS) {
6404 d_printf("tldap_search with complex filter failed: %s\n",
6405 tldap_errstr(talloc_tos(), ld, rc));
6413 /* Torture test to ensure no regression of :
6414 https://bugzilla.samba.org/show_bug.cgi?id=7084
6417 static bool run_dir_createtime(int dummy)
6419 struct cli_state *cli;
6420 const char *dname = "\\testdir";
6421 const char *fname = "\\testdir\\testfile";
6423 struct timespec create_time;
6424 struct timespec create_time1;
6428 if (!torture_open_connection(&cli, 0)) {
6432 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6433 cli_rmdir(cli, dname);
6435 status = cli_mkdir(cli, dname);
6436 if (!NT_STATUS_IS_OK(status)) {
6437 printf("mkdir failed: %s\n", nt_errstr(status));
6441 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6443 if (!NT_STATUS_IS_OK(status)) {
6444 printf("cli_qpathinfo2 returned %s\n",
6449 /* Sleep 3 seconds, then create a file. */
6452 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6454 if (!NT_STATUS_IS_OK(status)) {
6455 printf("cli_open failed: %s\n", nt_errstr(status));
6459 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6461 if (!NT_STATUS_IS_OK(status)) {
6462 printf("cli_qpathinfo2 (2) returned %s\n",
6467 if (timespec_compare(&create_time1, &create_time)) {
6468 printf("run_dir_createtime: create time was updated (error)\n");
6470 printf("run_dir_createtime: create time was not updated (correct)\n");
6476 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6477 cli_rmdir(cli, dname);
6478 if (!torture_close_connection(cli)) {
6485 static bool run_streamerror(int dummy)
6487 struct cli_state *cli;
6488 const char *dname = "\\testdir";
6489 const char *streamname =
6490 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6492 time_t change_time, access_time, write_time;
6494 uint16_t mode, fnum;
6497 if (!torture_open_connection(&cli, 0)) {
6501 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6502 cli_rmdir(cli, dname);
6504 status = cli_mkdir(cli, dname);
6505 if (!NT_STATUS_IS_OK(status)) {
6506 printf("mkdir failed: %s\n", nt_errstr(status));
6510 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6512 status = cli_nt_error(cli);
6514 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6515 printf("pathinfo returned %s, expected "
6516 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6521 status = cli_ntcreate(cli, streamname, 0x16,
6522 FILE_READ_DATA|FILE_READ_EA|
6523 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6524 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6525 FILE_OPEN, 0, 0, &fnum);
6527 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6528 printf("ntcreate returned %s, expected "
6529 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6535 cli_rmdir(cli, dname);
6539 static bool run_local_substitute(int dummy)
6543 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6544 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6545 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6546 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6547 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6548 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6549 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6550 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6552 /* Different captialization rules in sub_basic... */
6554 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6560 static bool run_local_base64(int dummy)
6565 for (i=1; i<2000; i++) {
6566 DATA_BLOB blob1, blob2;
6569 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6571 generate_random_buffer(blob1.data, blob1.length);
6573 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6575 d_fprintf(stderr, "base64_encode_data_blob failed "
6576 "for %d bytes\n", i);
6579 blob2 = base64_decode_data_blob(b64);
6582 if (data_blob_cmp(&blob1, &blob2)) {
6583 d_fprintf(stderr, "data_blob_cmp failed for %d "
6587 TALLOC_FREE(blob1.data);
6588 data_blob_free(&blob2);
6593 static bool run_local_gencache(int dummy)
6599 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6600 d_printf("%s: gencache_set() failed\n", __location__);
6604 if (!gencache_get("foo", NULL, NULL)) {
6605 d_printf("%s: gencache_get() failed\n", __location__);
6609 if (!gencache_get("foo", &val, &tm)) {
6610 d_printf("%s: gencache_get() failed\n", __location__);
6614 if (strcmp(val, "bar") != 0) {
6615 d_printf("%s: gencache_get() returned %s, expected %s\n",
6616 __location__, val, "bar");
6623 if (!gencache_del("foo")) {
6624 d_printf("%s: gencache_del() failed\n", __location__);
6627 if (gencache_del("foo")) {
6628 d_printf("%s: second gencache_del() succeeded\n",
6633 if (gencache_get("foo", &val, &tm)) {
6634 d_printf("%s: gencache_get() on deleted entry "
6635 "succeeded\n", __location__);
6639 blob = data_blob_string_const_null("bar");
6640 tm = time(NULL) + 60;
6642 if (!gencache_set_data_blob("foo", &blob, tm)) {
6643 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6647 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6648 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6652 if (strcmp((const char *)blob.data, "bar") != 0) {
6653 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6654 __location__, (const char *)blob.data, "bar");
6655 data_blob_free(&blob);
6659 data_blob_free(&blob);
6661 if (!gencache_del("foo")) {
6662 d_printf("%s: gencache_del() failed\n", __location__);
6665 if (gencache_del("foo")) {
6666 d_printf("%s: second gencache_del() succeeded\n",
6671 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6672 d_printf("%s: gencache_get_data_blob() on deleted entry "
6673 "succeeded\n", __location__);
6680 static bool rbt_testval(struct db_context *db, const char *key,
6683 struct db_record *rec;
6684 TDB_DATA data = string_tdb_data(value);
6688 rec = db->fetch_locked(db, db, string_tdb_data(key));
6690 d_fprintf(stderr, "fetch_locked failed\n");
6693 status = rec->store(rec, data, 0);
6694 if (!NT_STATUS_IS_OK(status)) {
6695 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6700 rec = db->fetch_locked(db, db, string_tdb_data(key));
6702 d_fprintf(stderr, "second fetch_locked failed\n");
6705 if ((rec->value.dsize != data.dsize)
6706 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6707 d_fprintf(stderr, "Got wrong data back\n");
6717 static bool run_local_rbtree(int dummy)
6719 struct db_context *db;
6723 db = db_open_rbt(NULL);
6726 d_fprintf(stderr, "db_open_rbt failed\n");
6730 for (i=0; i<1000; i++) {
6733 if (asprintf(&key, "key%ld", random()) == -1) {
6736 if (asprintf(&value, "value%ld", random()) == -1) {
6741 if (!rbt_testval(db, key, value)) {
6748 if (asprintf(&value, "value%ld", random()) == -1) {
6753 if (!rbt_testval(db, key, value)) {
6770 struct talloc_dict_test {
6774 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6776 int *count = (int *)priv;
6781 static bool run_local_talloc_dict(int dummy)
6783 struct talloc_dict *dict;
6784 struct talloc_dict_test *t;
6787 dict = talloc_dict_init(talloc_tos());
6792 t = talloc(talloc_tos(), struct talloc_dict_test);
6799 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6804 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6817 static bool run_local_string_to_sid(int dummy) {
6820 if (string_to_sid(&sid, "S--1-5-32-545")) {
6821 printf("allowing S--1-5-32-545\n");
6824 if (string_to_sid(&sid, "S-1-5-32-+545")) {
6825 printf("allowing S-1-5-32-+545\n");
6828 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")) {
6829 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6832 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
6833 printf("allowing S-1-5-32-545-abc\n");
6836 if (!string_to_sid(&sid, "S-1-5-32-545")) {
6837 printf("could not parse S-1-5-32-545\n");
6840 if (!sid_equal(&sid, &global_sid_Builtin_Users)) {
6841 printf("mis-parsed S-1-5-32-545 as %s\n",
6842 sid_string_tos(&sid));
6848 /* Split a path name into filename and stream name components. Canonicalise
6849 * such that an implicit $DATA token is always explicit.
6851 * The "specification" of this function can be found in the
6852 * run_local_stream_name() function in torture.c, I've tried those
6853 * combinations against a W2k3 server.
6856 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6857 char **pbase, char **pstream)
6860 char *stream = NULL;
6861 char *sname; /* stream name */
6862 const char *stype; /* stream type */
6864 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6866 sname = strchr_m(fname, ':');
6868 if (lp_posix_pathnames() || (sname == NULL)) {
6869 if (pbase != NULL) {
6870 base = talloc_strdup(mem_ctx, fname);
6871 NT_STATUS_HAVE_NO_MEMORY(base);
6876 if (pbase != NULL) {
6877 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6878 NT_STATUS_HAVE_NO_MEMORY(base);
6883 stype = strchr_m(sname, ':');
6885 if (stype == NULL) {
6886 sname = talloc_strdup(mem_ctx, sname);
6890 if (StrCaseCmp(stype, ":$DATA") != 0) {
6892 * If there is an explicit stream type, so far we only
6893 * allow $DATA. Is there anything else allowed? -- vl
6895 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6897 return NT_STATUS_OBJECT_NAME_INVALID;
6899 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6903 if (sname == NULL) {
6905 return NT_STATUS_NO_MEMORY;
6908 if (sname[0] == '\0') {
6910 * no stream name, so no stream
6915 if (pstream != NULL) {
6916 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6917 if (stream == NULL) {
6920 return NT_STATUS_NO_MEMORY;
6923 * upper-case the type field
6925 strupper_m(strchr_m(stream, ':')+1);
6929 if (pbase != NULL) {
6932 if (pstream != NULL) {
6935 return NT_STATUS_OK;
6938 static bool test_stream_name(const char *fname, const char *expected_base,
6939 const char *expected_stream,
6940 NTSTATUS expected_status)
6944 char *stream = NULL;
6946 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6947 if (!NT_STATUS_EQUAL(status, expected_status)) {
6951 if (!NT_STATUS_IS_OK(status)) {
6955 if (base == NULL) goto error;
6957 if (strcmp(expected_base, base) != 0) goto error;
6959 if ((expected_stream != NULL) && (stream == NULL)) goto error;
6960 if ((expected_stream == NULL) && (stream != NULL)) goto error;
6962 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6966 TALLOC_FREE(stream);
6970 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6971 fname, expected_base ? expected_base : "<NULL>",
6972 expected_stream ? expected_stream : "<NULL>",
6973 nt_errstr(expected_status));
6974 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6975 base ? base : "<NULL>", stream ? stream : "<NULL>",
6978 TALLOC_FREE(stream);
6982 static bool run_local_stream_name(int dummy)
6986 ret &= test_stream_name(
6987 "bla", "bla", NULL, NT_STATUS_OK);
6988 ret &= test_stream_name(
6989 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6990 ret &= test_stream_name(
6991 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6992 ret &= test_stream_name(
6993 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6994 ret &= test_stream_name(
6995 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6996 ret &= test_stream_name(
6997 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
6998 ret &= test_stream_name(
6999 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7000 ret &= test_stream_name(
7001 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7006 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7008 if (a.length != b.length) {
7009 printf("a.length=%d != b.length=%d\n",
7010 (int)a.length, (int)b.length);
7013 if (memcmp(a.data, b.data, a.length) != 0) {
7014 printf("a.data and b.data differ\n");
7020 static bool run_local_memcache(int dummy)
7022 struct memcache *cache;
7024 DATA_BLOB d1, d2, d3;
7025 DATA_BLOB v1, v2, v3;
7027 TALLOC_CTX *mem_ctx;
7029 size_t size1, size2;
7032 cache = memcache_init(NULL, 100);
7034 if (cache == NULL) {
7035 printf("memcache_init failed\n");
7039 d1 = data_blob_const("d1", 2);
7040 d2 = data_blob_const("d2", 2);
7041 d3 = data_blob_const("d3", 2);
7043 k1 = data_blob_const("d1", 2);
7044 k2 = data_blob_const("d2", 2);
7046 memcache_add(cache, STAT_CACHE, k1, d1);
7047 memcache_add(cache, GETWD_CACHE, k2, d2);
7049 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7050 printf("could not find k1\n");
7053 if (!data_blob_equal(d1, v1)) {
7057 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7058 printf("could not find k2\n");
7061 if (!data_blob_equal(d2, v2)) {
7065 memcache_add(cache, STAT_CACHE, k1, d3);
7067 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7068 printf("could not find replaced k1\n");
7071 if (!data_blob_equal(d3, v3)) {
7075 memcache_add(cache, GETWD_CACHE, k1, d1);
7077 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7078 printf("Did find k2, should have been purged\n");
7084 cache = memcache_init(NULL, 0);
7086 mem_ctx = talloc_init("foo");
7088 str1 = talloc_strdup(mem_ctx, "string1");
7089 str2 = talloc_strdup(mem_ctx, "string2");
7091 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7092 data_blob_string_const("torture"), &str1);
7093 size1 = talloc_total_size(cache);
7095 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7096 data_blob_string_const("torture"), &str2);
7097 size2 = talloc_total_size(cache);
7099 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7101 if (size2 > size1) {
7102 printf("memcache leaks memory!\n");
7112 static void wbclient_done(struct tevent_req *req)
7115 struct winbindd_response *wb_resp;
7116 int *i = (int *)tevent_req_callback_data_void(req);
7118 wbc_err = wb_trans_recv(req, req, &wb_resp);
7121 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7124 static bool run_local_wbclient(int dummy)
7126 struct event_context *ev;
7127 struct wb_context **wb_ctx;
7128 struct winbindd_request wb_req;
7129 bool result = false;
7132 BlockSignals(True, SIGPIPE);
7134 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7139 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7140 if (wb_ctx == NULL) {
7144 ZERO_STRUCT(wb_req);
7145 wb_req.cmd = WINBINDD_PING;
7147 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7149 for (i=0; i<nprocs; i++) {
7150 wb_ctx[i] = wb_context_init(ev, NULL);
7151 if (wb_ctx[i] == NULL) {
7154 for (j=0; j<torture_numops; j++) {
7155 struct tevent_req *req;
7156 req = wb_trans_send(ev, ev, wb_ctx[i],
7157 (j % 2) == 0, &wb_req);
7161 tevent_req_set_callback(req, wbclient_done, &i);
7167 while (i < nprocs * torture_numops) {
7168 event_loop_once(ev);
7177 static void getaddrinfo_finished(struct tevent_req *req)
7179 char *name = (char *)tevent_req_callback_data_void(req);
7180 struct addrinfo *ainfo;
7183 res = getaddrinfo_recv(req, &ainfo);
7185 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7188 d_printf("gai(%s) succeeded\n", name);
7189 freeaddrinfo(ainfo);
7192 static bool run_getaddrinfo_send(int dummy)
7194 TALLOC_CTX *frame = talloc_stackframe();
7195 struct fncall_context *ctx;
7196 struct tevent_context *ev;
7197 bool result = false;
7198 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7199 "www.slashdot.org", "heise.de" };
7200 struct tevent_req *reqs[4];
7203 ev = event_context_init(frame);
7208 ctx = fncall_context_init(frame, 4);
7210 for (i=0; i<ARRAY_SIZE(names); i++) {
7211 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7213 if (reqs[i] == NULL) {
7216 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7220 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7221 tevent_loop_once(ev);
7230 static bool dbtrans_inc(struct db_context *db)
7232 struct db_record *rec;
7237 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7239 printf(__location__ "fetch_lock failed\n");
7243 if (rec->value.dsize != sizeof(uint32_t)) {
7244 printf(__location__ "value.dsize = %d\n",
7245 (int)rec->value.dsize);
7249 val = (uint32_t *)rec->value.dptr;
7252 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7255 if (!NT_STATUS_IS_OK(status)) {
7256 printf(__location__ "store failed: %s\n",
7267 static bool run_local_dbtrans(int dummy)
7269 struct db_context *db;
7270 struct db_record *rec;
7275 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7276 O_RDWR|O_CREAT, 0600);
7278 printf("Could not open transtest.db\n");
7282 res = db->transaction_start(db);
7284 printf(__location__ "transaction_start failed\n");
7288 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7290 printf(__location__ "fetch_lock failed\n");
7294 if (rec->value.dptr == NULL) {
7296 status = rec->store(
7297 rec, make_tdb_data((uint8_t *)&initial,
7300 if (!NT_STATUS_IS_OK(status)) {
7301 printf(__location__ "store returned %s\n",
7309 res = db->transaction_commit(db);
7311 printf(__location__ "transaction_commit failed\n");
7319 res = db->transaction_start(db);
7321 printf(__location__ "transaction_start failed\n");
7325 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7326 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7330 for (i=0; i<10; i++) {
7331 if (!dbtrans_inc(db)) {
7336 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7337 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7341 if (val2 != val + 10) {
7342 printf(__location__ "val=%d, val2=%d\n",
7343 (int)val, (int)val2);
7347 printf("val2=%d\r", val2);
7349 res = db->transaction_commit(db);
7351 printf(__location__ "transaction_commit failed\n");
7361 * Just a dummy test to be run under a debugger. There's no real way
7362 * to inspect the tevent_select specific function from outside of
7366 static bool run_local_tevent_select(int dummy)
7368 struct tevent_context *ev;
7369 struct tevent_fd *fd1, *fd2;
7370 bool result = false;
7372 ev = tevent_context_init_byname(NULL, "select");
7374 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7378 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7380 d_fprintf(stderr, "tevent_add_fd failed\n");
7383 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7385 d_fprintf(stderr, "tevent_add_fd failed\n");
7390 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7392 d_fprintf(stderr, "tevent_add_fd failed\n");
7402 static double create_procs(bool (*fn)(int), bool *result)
7405 volatile pid_t *child_status;
7406 volatile bool *child_status_out;
7409 struct timeval start;
7413 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7414 if (!child_status) {
7415 printf("Failed to setup shared memory\n");
7419 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7420 if (!child_status_out) {
7421 printf("Failed to setup result status shared memory\n");
7425 for (i = 0; i < nprocs; i++) {
7426 child_status[i] = 0;
7427 child_status_out[i] = True;
7430 start = timeval_current();
7432 for (i=0;i<nprocs;i++) {
7435 pid_t mypid = getpid();
7436 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7438 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7441 if (torture_open_connection(¤t_cli, i)) break;
7443 printf("pid %d failed to start\n", (int)getpid());
7449 child_status[i] = getpid();
7451 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7453 child_status_out[i] = fn(i);
7460 for (i=0;i<nprocs;i++) {
7461 if (child_status[i]) synccount++;
7463 if (synccount == nprocs) break;
7465 } while (timeval_elapsed(&start) < 30);
7467 if (synccount != nprocs) {
7468 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7470 return timeval_elapsed(&start);
7473 /* start the client load */
7474 start = timeval_current();
7476 for (i=0;i<nprocs;i++) {
7477 child_status[i] = 0;
7480 printf("%d clients started\n", nprocs);
7482 for (i=0;i<nprocs;i++) {
7483 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7488 for (i=0;i<nprocs;i++) {
7489 if (!child_status_out[i]) {
7493 return timeval_elapsed(&start);
7496 #define FLAG_MULTIPROC 1
7503 {"FDPASS", run_fdpasstest, 0},
7504 {"LOCK1", run_locktest1, 0},
7505 {"LOCK2", run_locktest2, 0},
7506 {"LOCK3", run_locktest3, 0},
7507 {"LOCK4", run_locktest4, 0},
7508 {"LOCK5", run_locktest5, 0},
7509 {"LOCK6", run_locktest6, 0},
7510 {"LOCK7", run_locktest7, 0},
7511 {"LOCK8", run_locktest8, 0},
7512 {"LOCK9", run_locktest9, 0},
7513 {"UNLINK", run_unlinktest, 0},
7514 {"BROWSE", run_browsetest, 0},
7515 {"ATTR", run_attrtest, 0},
7516 {"TRANS2", run_trans2test, 0},
7517 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7518 {"TORTURE",run_torture, FLAG_MULTIPROC},
7519 {"RANDOMIPC", run_randomipc, 0},
7520 {"NEGNOWAIT", run_negprot_nowait, 0},
7521 {"NBENCH", run_nbench, 0},
7522 {"NBENCH2", run_nbench2, 0},
7523 {"OPLOCK1", run_oplock1, 0},
7524 {"OPLOCK2", run_oplock2, 0},
7525 {"OPLOCK3", run_oplock3, 0},
7526 {"DIR", run_dirtest, 0},
7527 {"DIR1", run_dirtest1, 0},
7528 {"DIR-CREATETIME", run_dir_createtime, 0},
7529 {"DENY1", torture_denytest1, 0},
7530 {"DENY2", torture_denytest2, 0},
7531 {"TCON", run_tcon_test, 0},
7532 {"TCONDEV", run_tcon_devtype_test, 0},
7533 {"RW1", run_readwritetest, 0},
7534 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7535 {"RW3", run_readwritelarge, 0},
7536 {"OPEN", run_opentest, 0},
7537 {"POSIX", run_simple_posix_open_test, 0},
7538 {"POSIX-APPEND", run_posix_append, 0},
7539 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7540 { "SHORTNAME-TEST", run_shortname_test, 0},
7542 {"OPENATTR", run_openattrtest, 0},
7544 {"XCOPY", run_xcopy, 0},
7545 {"RENAME", run_rename, 0},
7546 {"DELETE", run_deletetest, 0},
7547 {"PROPERTIES", run_properties, 0},
7548 {"MANGLE", torture_mangle, 0},
7549 {"MANGLE1", run_mangle1, 0},
7550 {"W2K", run_w2ktest, 0},
7551 {"TRANS2SCAN", torture_trans2_scan, 0},
7552 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7553 {"UTABLE", torture_utable, 0},
7554 {"CASETABLE", torture_casetable, 0},
7555 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7556 {"PIPE_NUMBER", run_pipe_number, 0},
7557 {"TCON2", run_tcon2_test, 0},
7558 {"IOCTL", torture_ioctl_test, 0},
7559 {"CHKPATH", torture_chkpath_test, 0},
7560 {"FDSESS", run_fdsesstest, 0},
7561 { "EATEST", run_eatest, 0},
7562 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7563 { "CHAIN1", run_chain1, 0},
7564 { "CHAIN2", run_chain2, 0},
7565 { "WINDOWS-WRITE", run_windows_write, 0},
7566 { "CLI_ECHO", run_cli_echo, 0},
7567 { "GETADDRINFO", run_getaddrinfo_send, 0},
7568 { "TLDAP", run_tldap },
7569 { "STREAMERROR", run_streamerror },
7570 { "NOTIFY-BENCH", run_notify_bench },
7571 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7572 { "LOCAL-GENCACHE", run_local_gencache, 0},
7573 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7574 { "LOCAL-BASE64", run_local_base64, 0},
7575 { "LOCAL-RBTREE", run_local_rbtree, 0},
7576 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7577 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7578 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7579 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
7580 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7581 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
7586 /****************************************************************************
7587 run a specified test or "ALL"
7588 ****************************************************************************/
7589 static bool run_test(const char *name)
7596 if (strequal(name,"ALL")) {
7597 for (i=0;torture_ops[i].name;i++) {
7598 run_test(torture_ops[i].name);
7603 for (i=0;torture_ops[i].name;i++) {
7604 fstr_sprintf(randomfname, "\\XX%x",
7605 (unsigned)random());
7607 if (strequal(name, torture_ops[i].name)) {
7609 printf("Running %s\n", name);
7610 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7611 t = create_procs(torture_ops[i].fn, &result);
7614 printf("TEST %s FAILED!\n", name);
7617 struct timeval start;
7618 start = timeval_current();
7619 if (!torture_ops[i].fn(0)) {
7621 printf("TEST %s FAILED!\n", name);
7623 t = timeval_elapsed(&start);
7625 printf("%s took %g secs\n\n", name, t);
7630 printf("Did not find a test named %s\n", name);
7638 static void usage(void)
7642 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7643 printf("Please use samba4 torture.\n\n");
7645 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7647 printf("\t-d debuglevel\n");
7648 printf("\t-U user%%pass\n");
7649 printf("\t-k use kerberos\n");
7650 printf("\t-N numprocs\n");
7651 printf("\t-n my_netbios_name\n");
7652 printf("\t-W workgroup\n");
7653 printf("\t-o num_operations\n");
7654 printf("\t-O socket_options\n");
7655 printf("\t-m maximum protocol\n");
7656 printf("\t-L use oplocks\n");
7657 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7658 printf("\t-A showall\n");
7659 printf("\t-p port\n");
7660 printf("\t-s seed\n");
7661 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7664 printf("tests are:");
7665 for (i=0;torture_ops[i].name;i++) {
7666 printf(" %s", torture_ops[i].name);
7670 printf("default test is ALL\n");
7675 /****************************************************************************
7677 ****************************************************************************/
7678 int main(int argc,char *argv[])
7684 bool correct = True;
7685 TALLOC_CTX *frame = talloc_stackframe();
7686 int seed = time(NULL);
7690 #ifdef HAVE_SETBUFFER
7691 setbuffer(stdout, NULL, 0);
7696 setup_logging("smbtorture", true);
7698 if (is_default_dyn_CONFIGFILE()) {
7699 if(getenv("SMB_CONF_PATH")) {
7700 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7703 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7710 for(p = argv[1]; *p; p++)
7714 if (strncmp(argv[1], "//", 2)) {
7718 fstrcpy(host, &argv[1][2]);
7719 p = strchr_m(&host[2],'/');
7724 fstrcpy(share, p+1);
7726 fstrcpy(myname, get_myname(talloc_tos()));
7728 fprintf(stderr, "Failed to get my hostname.\n");
7732 if (*username == 0 && getenv("LOGNAME")) {
7733 fstrcpy(username,getenv("LOGNAME"));
7739 fstrcpy(workgroup, lp_workgroup());
7741 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7744 port_to_use = atoi(optarg);
7747 seed = atoi(optarg);
7750 fstrcpy(workgroup,optarg);
7753 max_protocol = interpret_protocol(optarg, max_protocol);
7756 nprocs = atoi(optarg);
7759 torture_numops = atoi(optarg);
7762 DEBUGLEVEL = atoi(optarg);
7771 local_path = optarg;
7774 torture_showall = True;
7777 fstrcpy(myname, optarg);
7780 client_txt = optarg;
7787 use_kerberos = True;
7789 d_printf("No kerberos support compiled in\n");
7795 fstrcpy(username,optarg);
7796 p = strchr_m(username,'%');
7799 fstrcpy(password, p+1);
7804 fstrcpy(multishare_conn_fname, optarg);
7805 use_multishare_conn = True;
7808 torture_blocksize = atoi(optarg);
7811 printf("Unknown option %c (%d)\n", (char)opt, opt);
7816 d_printf("using seed %d\n", seed);
7820 if(use_kerberos && !gotuser) gotpass = True;
7823 p = getpass("Password:");
7825 fstrcpy(password, p);
7830 printf("host=%s share=%s user=%s myname=%s\n",
7831 host, share, username, myname);
7833 if (argc == optind) {
7834 correct = run_test("ALL");
7836 for (i=optind;i<argc;i++) {
7837 if (!run_test(argv[i])) {