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 "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
30 #include "nsswitch/winbind_client.h"
32 #include "talloc_dict.h"
33 #include "async_smb.h"
34 #include "libsmb/clirap.h"
36 #include "libsmb/nmblib.h"
37 #include "../lib/util/tevent_ntstatus.h"
42 static fstring host, workgroup, share, password, username, myname;
43 static int max_protocol = PROTOCOL_NT1;
44 static const char *sockops="TCP_NODELAY";
46 static int port_to_use=0;
47 int torture_numops=100;
48 int torture_blocksize=1024*1024;
49 static int procnum; /* records process count number when forking */
50 static struct cli_state *current_cli;
51 static fstring randomfname;
52 static bool use_oplocks;
53 static bool use_level_II_oplocks;
54 static const char *client_txt = "client_oplocks.txt";
55 static bool use_kerberos;
56 static fstring multishare_conn_fname;
57 static bool use_multishare_conn = False;
58 static bool do_encrypt;
59 static const char *local_path = NULL;
60 static int signing_state = Undefined;
62 bool torture_showall = False;
64 static double create_procs(bool (*fn)(int), bool *result);
67 /* return a pointer to a anonymous shared memory segment of size "size"
68 which will persist across fork() but will disappear when all processes
71 The memory is not zeroed
73 This function uses system5 shared memory. It takes advantage of a property
74 that the memory is not destroyed if it is attached when the id is removed
76 void *shm_setup(int size)
82 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
84 printf("can't get shared memory\n");
87 shm_unlink("private");
88 if (ftruncate(shmid, size) == -1) {
89 printf("can't set shared memory size\n");
92 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
93 if (ret == MAP_FAILED) {
94 printf("can't map shared memory\n");
98 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
100 printf("can't get shared memory\n");
103 ret = (void *)shmat(shmid, 0, 0);
104 if (!ret || ret == (void *)-1) {
105 printf("can't attach to shared memory\n");
108 /* the following releases the ipc, but note that this process
109 and all its children will still have access to the memory, its
110 just that the shmid is no longer valid for other shm calls. This
111 means we don't leave behind lots of shm segments after we exit
113 See Stevens "advanced programming in unix env" for details
115 shmctl(shmid, IPC_RMID, 0);
121 /********************************************************************
122 Ensure a connection is encrypted.
123 ********************************************************************/
125 static bool force_cli_encryption(struct cli_state *c,
126 const char *sharename)
129 uint32 caplow, caphigh;
132 if (!SERVER_HAS_UNIX_CIFS(c)) {
133 d_printf("Encryption required and "
134 "server that doesn't support "
135 "UNIX extensions - failing connect\n");
139 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
141 if (!NT_STATUS_IS_OK(status)) {
142 d_printf("Encryption required and "
143 "can't get UNIX CIFS extensions "
144 "version from server: %s\n", nt_errstr(status));
148 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
149 d_printf("Encryption required and "
150 "share %s doesn't support "
151 "encryption.\n", sharename);
155 if (c->use_kerberos) {
156 status = cli_gss_smb_encryption_start(c);
158 status = cli_raw_ntlm_smb_encryption_start(c,
164 if (!NT_STATUS_IS_OK(status)) {
165 d_printf("Encryption required and "
166 "setup failed with error %s.\n",
175 static struct cli_state *open_nbt_connection(void)
177 struct nmb_name called, calling;
178 struct sockaddr_storage ss;
182 make_nmb_name(&calling, myname, 0x0);
183 make_nmb_name(&called , host, 0x20);
187 if (!(c = cli_initialise_ex(signing_state))) {
188 printf("Failed initialize cli_struct to connect with %s\n", host);
192 c->port = port_to_use;
194 status = cli_connect(c, host, &ss);
195 if (!NT_STATUS_IS_OK(status)) {
196 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
200 c->use_kerberos = use_kerberos;
202 c->timeout = 120000; /* set a really long timeout (2 minutes) */
203 if (use_oplocks) c->use_oplocks = True;
204 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
206 if (!cli_session_request(c, &calling, &called)) {
208 * Well, that failed, try *SMBSERVER ...
209 * However, we must reconnect as well ...
211 status = cli_connect(c, host, &ss);
212 if (!NT_STATUS_IS_OK(status)) {
213 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
217 make_nmb_name(&called, "*SMBSERVER", 0x20);
218 if (!cli_session_request(c, &calling, &called)) {
219 printf("%s rejected the session\n",host);
220 printf("We tried with a called name of %s & %s\n",
230 /****************************************************************************
231 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
232 ****************************************************************************/
234 static bool cli_bad_session_request(struct cli_state *cli,
235 struct nmb_name *calling, struct nmb_name *called)
242 memcpy(&(cli->calling), calling, sizeof(*calling));
243 memcpy(&(cli->called ), called , sizeof(*called ));
245 /* put in the destination name */
247 tmp = name_mangle(talloc_tos(), cli->called.name,
248 cli->called.name_type);
254 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
256 memcpy(p, tmp, namelen);
261 /* Deliberately corrupt the name len (first byte) */
266 tmp = name_mangle(talloc_tos(), cli->calling.name,
267 cli->calling.name_type);
273 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
275 memcpy(p, tmp, namelen);
279 /* Deliberately corrupt the name len (first byte) */
282 /* send a session request (RFC 1002) */
283 /* setup the packet length
284 * Remove four bytes from the length count, since the length
285 * field in the NBT Session Service header counts the number
286 * of bytes which follow. The cli_send_smb() function knows
287 * about this and accounts for those four bytes.
291 _smb_setlen(cli->outbuf,len);
292 SCVAL(cli->outbuf,0,0x81);
295 DEBUG(5,("Sent session request\n"));
297 if (!cli_receive_smb(cli))
300 if (CVAL(cli->inbuf,0) != 0x82) {
301 /* This is the wrong place to put the error... JRA. */
302 cli->rap_error = CVAL(cli->inbuf,4);
308 static struct cli_state *open_bad_nbt_connection(void)
310 struct nmb_name called, calling;
311 struct sockaddr_storage ss;
315 make_nmb_name(&calling, myname, 0x0);
316 make_nmb_name(&called , host, 0x20);
320 if (!(c = cli_initialise_ex(signing_state))) {
321 printf("Failed initialize cli_struct to connect with %s\n", host);
327 status = cli_connect(c, host, &ss);
328 if (!NT_STATUS_IS_OK(status)) {
329 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
333 c->timeout = 4000; /* set a short timeout (4 seconds) */
335 if (!cli_bad_session_request(c, &calling, &called)) {
336 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
344 /* Insert a NULL at the first separator of the given path and return a pointer
345 * to the remainder of the string.
348 terminate_path_at_separator(char * path)
356 if ((p = strchr_m(path, '/'))) {
361 if ((p = strchr_m(path, '\\'))) {
371 parse a //server/share type UNC name
373 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
374 char **hostname, char **sharename)
378 *hostname = *sharename = NULL;
380 if (strncmp(unc_name, "\\\\", 2) &&
381 strncmp(unc_name, "//", 2)) {
385 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
386 p = terminate_path_at_separator(*hostname);
389 *sharename = talloc_strdup(mem_ctx, p);
390 terminate_path_at_separator(*sharename);
393 if (*hostname && *sharename) {
397 TALLOC_FREE(*hostname);
398 TALLOC_FREE(*sharename);
402 static bool torture_open_connection_share(struct cli_state **c,
403 const char *hostname,
404 const char *sharename)
410 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
412 flags |= CLI_FULL_CONNECTION_OPLOCKS;
413 if (use_level_II_oplocks)
414 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
416 status = cli_full_connection(c, myname,
417 hostname, NULL, port_to_use,
420 password, flags, signing_state);
421 if (!NT_STATUS_IS_OK(status)) {
422 printf("failed to open share connection: //%s/%s port:%d - %s\n",
423 hostname, sharename, port_to_use, nt_errstr(status));
427 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
430 return force_cli_encryption(*c,
436 bool torture_open_connection(struct cli_state **c, int conn_index)
438 char **unc_list = NULL;
439 int num_unc_names = 0;
442 if (use_multishare_conn==True) {
444 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
445 if (!unc_list || num_unc_names <= 0) {
446 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
450 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
452 printf("Failed to parse UNC name %s\n",
453 unc_list[conn_index % num_unc_names]);
454 TALLOC_FREE(unc_list);
458 result = torture_open_connection_share(c, h, s);
460 /* h, s were copied earlier */
461 TALLOC_FREE(unc_list);
465 return torture_open_connection_share(c, host, share);
468 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
470 uint16 old_vuid = cli->vuid;
471 fstring old_user_name;
472 size_t passlen = strlen(password);
476 fstrcpy(old_user_name, cli->user_name);
478 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
482 *new_vuid = cli->vuid;
483 cli->vuid = old_vuid;
484 status = cli_set_username(cli, old_user_name);
485 if (!NT_STATUS_IS_OK(status)) {
492 bool torture_close_connection(struct cli_state *c)
497 status = cli_tdis(c);
498 if (!NT_STATUS_IS_OK(status)) {
499 printf("tdis failed (%s)\n", nt_errstr(status));
509 /* check if the server produced the expected error code */
510 static bool check_error(int line, struct cli_state *c,
511 uint8 eclass, uint32 ecode, NTSTATUS nterr)
513 if (cli_is_dos_error(c)) {
517 /* Check DOS error */
519 cli_dos_error(c, &cclass, &num);
521 if (eclass != cclass || ecode != num) {
522 printf("unexpected error code class=%d code=%d\n",
523 (int)cclass, (int)num);
524 printf(" expected %d/%d %s (line=%d)\n",
525 (int)eclass, (int)ecode, nt_errstr(nterr), line);
534 status = cli_nt_error(c);
536 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
537 printf("unexpected error code %s\n", nt_errstr(status));
538 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
547 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
549 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
550 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
556 static bool rw_torture(struct cli_state *c)
558 const char *lockfname = "\\torture.lck";
562 pid_t pid2, pid = getpid();
568 memset(buf, '\0', sizeof(buf));
570 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
572 if (!NT_STATUS_IS_OK(status)) {
573 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
575 if (!NT_STATUS_IS_OK(status)) {
576 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
580 for (i=0;i<torture_numops;i++) {
581 unsigned n = (unsigned)sys_random()%10;
584 printf("%d\r", i); fflush(stdout);
586 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
588 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
592 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
593 printf("open failed (%s)\n", cli_errstr(c));
598 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
600 if (!NT_STATUS_IS_OK(status)) {
601 printf("write failed (%s)\n", nt_errstr(status));
606 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
607 sizeof(pid)+(j*sizeof(buf)),
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("write failed (%s)\n",
618 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
619 printf("read failed (%s)\n", cli_errstr(c));
624 printf("data corruption!\n");
628 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
629 printf("close failed (%s)\n", cli_errstr(c));
633 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
634 printf("unlink failed (%s)\n", cli_errstr(c));
638 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
639 printf("unlock failed (%s)\n", cli_errstr(c));
645 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
652 static bool run_torture(int dummy)
654 struct cli_state *cli;
659 cli_sockopt(cli, sockops);
661 ret = rw_torture(cli);
663 if (!torture_close_connection(cli)) {
670 static bool rw_torture3(struct cli_state *c, char *lockfname)
672 uint16_t fnum = (uint16_t)-1;
677 unsigned countprev = 0;
680 NTSTATUS status = NT_STATUS_OK;
683 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
685 SIVAL(buf, i, sys_random());
690 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
691 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
694 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
695 DENY_NONE, &fnum))) {
696 printf("first open read/write of %s failed (%s)\n",
697 lockfname, cli_errstr(c));
703 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
705 status = cli_open(c, lockfname, O_RDONLY,
707 if (!NT_STATUS_IS_OK(status)) {
712 if (!NT_STATUS_IS_OK(status)) {
713 printf("second open read-only of %s failed (%s)\n",
714 lockfname, cli_errstr(c));
720 for (count = 0; count < sizeof(buf); count += sent)
722 if (count >= countprev) {
723 printf("%d %8d\r", i, count);
726 countprev += (sizeof(buf) / 20);
731 sent = ((unsigned)sys_random()%(20))+ 1;
732 if (sent > sizeof(buf) - count)
734 sent = sizeof(buf) - count;
737 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
738 count, (size_t)sent, NULL);
739 if (!NT_STATUS_IS_OK(status)) {
740 printf("write failed (%s)\n",
747 sent = cli_read(c, fnum, buf_rd+count, count,
751 printf("read failed offset:%d size:%ld (%s)\n",
752 count, (unsigned long)sizeof(buf)-count,
759 if (memcmp(buf_rd+count, buf+count, sent) != 0)
761 printf("read/write compare failed\n");
762 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
771 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
772 printf("close failed (%s)\n", cli_errstr(c));
779 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
781 const char *lockfname = "\\torture2.lck";
790 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
791 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
794 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
795 DENY_NONE, &fnum1))) {
796 printf("first open read/write of %s failed (%s)\n",
797 lockfname, cli_errstr(c1));
800 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
801 DENY_NONE, &fnum2))) {
802 printf("second open read-only of %s failed (%s)\n",
803 lockfname, cli_errstr(c2));
804 cli_close(c1, fnum1);
808 for (i=0;i<torture_numops;i++)
811 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
813 printf("%d\r", i); fflush(stdout);
816 generate_random_buffer((unsigned char *)buf, buf_size);
818 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
820 if (!NT_STATUS_IS_OK(status)) {
821 printf("write failed (%s)\n", nt_errstr(status));
826 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
827 printf("read failed (%s)\n", cli_errstr(c2));
828 printf("read %d, expected %ld\n", (int)bytes_read,
829 (unsigned long)buf_size);
834 if (memcmp(buf_rd, buf, buf_size) != 0)
836 printf("read/write compare failed\n");
842 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
843 printf("close failed (%s)\n", cli_errstr(c2));
846 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
847 printf("close failed (%s)\n", cli_errstr(c1));
851 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
852 printf("unlink failed (%s)\n", cli_errstr(c1));
859 static bool run_readwritetest(int dummy)
861 struct cli_state *cli1, *cli2;
862 bool test1, test2 = False;
864 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
867 cli_sockopt(cli1, sockops);
868 cli_sockopt(cli2, sockops);
870 printf("starting readwritetest\n");
872 test1 = rw_torture2(cli1, cli2);
873 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
876 test2 = rw_torture2(cli1, cli1);
877 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
880 if (!torture_close_connection(cli1)) {
884 if (!torture_close_connection(cli2)) {
888 return (test1 && test2);
891 static bool run_readwritemulti(int dummy)
893 struct cli_state *cli;
898 cli_sockopt(cli, sockops);
900 printf("run_readwritemulti: fname %s\n", randomfname);
901 test = rw_torture3(cli, randomfname);
903 if (!torture_close_connection(cli)) {
910 static bool run_readwritelarge_internal(int max_xmit_k)
912 static struct cli_state *cli1;
914 const char *lockfname = "\\large.dat";
919 if (!torture_open_connection(&cli1, 0)) {
922 cli_sockopt(cli1, sockops);
923 memset(buf,'\0',sizeof(buf));
925 cli1->max_xmit = max_xmit_k*1024;
927 if (signing_state == Required) {
928 /* Horrible cheat to force
929 multiple signed outstanding
930 packets against a Samba server.
932 cli1->is_samba = false;
935 printf("starting readwritelarge_internal\n");
937 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
939 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
940 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
944 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
946 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
947 cli1, fnum1, NULL, &fsize, NULL, NULL,
948 NULL, NULL, NULL))) {
949 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
953 if (fsize == sizeof(buf))
954 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
955 (unsigned long)fsize);
957 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
958 (unsigned long)fsize);
962 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
963 printf("close failed (%s)\n", cli_errstr(cli1));
967 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
968 printf("unlink failed (%s)\n", cli_errstr(cli1));
972 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
973 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
977 cli1->max_xmit = 4*1024;
979 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
981 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
982 cli1, fnum1, NULL, &fsize, NULL, NULL,
983 NULL, NULL, NULL))) {
984 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
988 if (fsize == sizeof(buf))
989 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
990 (unsigned long)fsize);
992 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
993 (unsigned long)fsize);
998 /* ToDo - set allocation. JRA */
999 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1000 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1003 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1005 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1009 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1012 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1013 printf("close failed (%s)\n", cli_errstr(cli1));
1017 if (!torture_close_connection(cli1)) {
1023 static bool run_readwritelarge(int dummy)
1025 return run_readwritelarge_internal(128);
1028 static bool run_readwritelarge_signtest(int dummy)
1031 signing_state = Required;
1032 ret = run_readwritelarge_internal(2);
1033 signing_state = Undefined;
1040 #define ival(s) strtol(s, NULL, 0)
1042 /* run a test that simulates an approximate netbench client load */
1043 static bool run_netbench(int client)
1045 struct cli_state *cli;
1050 const char *params[20];
1051 bool correct = True;
1057 cli_sockopt(cli, sockops);
1061 slprintf(cname,sizeof(cname)-1, "client%d", client);
1063 f = fopen(client_txt, "r");
1070 while (fgets(line, sizeof(line)-1, f)) {
1074 line[strlen(line)-1] = 0;
1076 /* printf("[%d] %s\n", line_count, line); */
1078 all_string_sub(line,"client1", cname, sizeof(line));
1080 /* parse the command parameters */
1081 params[0] = strtok_r(line, " ", &saveptr);
1083 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1087 if (i < 2) continue;
1089 if (!strncmp(params[0],"SMB", 3)) {
1090 printf("ERROR: You are using a dbench 1 load file\n");
1094 if (!strcmp(params[0],"NTCreateX")) {
1095 nb_createx(params[1], ival(params[2]), ival(params[3]),
1097 } else if (!strcmp(params[0],"Close")) {
1098 nb_close(ival(params[1]));
1099 } else if (!strcmp(params[0],"Rename")) {
1100 nb_rename(params[1], params[2]);
1101 } else if (!strcmp(params[0],"Unlink")) {
1102 nb_unlink(params[1]);
1103 } else if (!strcmp(params[0],"Deltree")) {
1104 nb_deltree(params[1]);
1105 } else if (!strcmp(params[0],"Rmdir")) {
1106 nb_rmdir(params[1]);
1107 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1108 nb_qpathinfo(params[1]);
1109 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1110 nb_qfileinfo(ival(params[1]));
1111 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1112 nb_qfsinfo(ival(params[1]));
1113 } else if (!strcmp(params[0],"FIND_FIRST")) {
1114 nb_findfirst(params[1]);
1115 } else if (!strcmp(params[0],"WriteX")) {
1116 nb_writex(ival(params[1]),
1117 ival(params[2]), ival(params[3]), ival(params[4]));
1118 } else if (!strcmp(params[0],"ReadX")) {
1119 nb_readx(ival(params[1]),
1120 ival(params[2]), ival(params[3]), ival(params[4]));
1121 } else if (!strcmp(params[0],"Flush")) {
1122 nb_flush(ival(params[1]));
1124 printf("Unknown operation %s\n", params[0]);
1132 if (!torture_close_connection(cli)) {
1140 /* run a test that simulates an approximate netbench client load */
1141 static bool run_nbench(int dummy)
1144 bool correct = True;
1150 signal(SIGALRM, nb_alarm);
1152 t = create_procs(run_netbench, &correct);
1155 printf("\nThroughput %g MB/sec\n",
1156 1.0e-6 * nbio_total() / t);
1162 This test checks for two things:
1164 1) correct support for retaining locks over a close (ie. the server
1165 must not use posix semantics)
1166 2) support for lock timeouts
1168 static bool run_locktest1(int dummy)
1170 struct cli_state *cli1, *cli2;
1171 const char *fname = "\\lockt1.lck";
1172 uint16_t fnum1, fnum2, fnum3;
1174 unsigned lock_timeout;
1176 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1179 cli_sockopt(cli1, sockops);
1180 cli_sockopt(cli2, sockops);
1182 printf("starting locktest1\n");
1184 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1186 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1187 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1190 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1191 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1194 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1195 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1199 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1200 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1205 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1206 printf("lock2 succeeded! This is a locking bug\n");
1209 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1210 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1214 lock_timeout = (1 + (random() % 20));
1215 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1217 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1218 printf("lock3 succeeded! This is a locking bug\n");
1221 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1222 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1226 if (ABS(t2 - t1) < lock_timeout-1) {
1227 printf("error: This server appears not to support timed lock requests\n");
1230 printf("server slept for %u seconds for a %u second timeout\n",
1231 (unsigned int)(t2-t1), lock_timeout);
1233 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1234 printf("close1 failed (%s)\n", cli_errstr(cli1));
1238 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1239 printf("lock4 succeeded! This is a locking bug\n");
1242 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1243 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1246 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1247 printf("close2 failed (%s)\n", cli_errstr(cli1));
1251 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1252 printf("close3 failed (%s)\n", cli_errstr(cli2));
1256 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1257 printf("unlink failed (%s)\n", cli_errstr(cli1));
1262 if (!torture_close_connection(cli1)) {
1266 if (!torture_close_connection(cli2)) {
1270 printf("Passed locktest1\n");
1275 this checks to see if a secondary tconx can use open files from an
1278 static bool run_tcon_test(int dummy)
1280 static struct cli_state *cli;
1281 const char *fname = "\\tcontest.tmp";
1283 uint16 cnum1, cnum2, cnum3;
1284 uint16 vuid1, vuid2;
1289 memset(buf, '\0', sizeof(buf));
1291 if (!torture_open_connection(&cli, 0)) {
1294 cli_sockopt(cli, sockops);
1296 printf("starting tcontest\n");
1298 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1300 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1301 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1308 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1309 if (!NT_STATUS_IS_OK(status)) {
1310 printf("initial write failed (%s)", nt_errstr(status));
1314 status = cli_tcon_andx(cli, share, "?????",
1315 password, strlen(password)+1);
1316 if (!NT_STATUS_IS_OK(status)) {
1317 printf("%s refused 2nd tree connect (%s)\n", host,
1324 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1325 vuid2 = cli->vuid + 1;
1327 /* try a write with the wrong tid */
1330 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1331 if (NT_STATUS_IS_OK(status)) {
1332 printf("* server allows write with wrong TID\n");
1335 printf("server fails write with wrong TID : %s\n",
1340 /* try a write with an invalid tid */
1343 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1344 if (NT_STATUS_IS_OK(status)) {
1345 printf("* server allows write with invalid TID\n");
1348 printf("server fails write with invalid TID : %s\n",
1352 /* try a write with an invalid vuid */
1356 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1357 if (NT_STATUS_IS_OK(status)) {
1358 printf("* server allows write with invalid VUID\n");
1361 printf("server fails write with invalid VUID : %s\n",
1368 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1369 printf("close failed (%s)\n", cli_errstr(cli));
1375 status = cli_tdis(cli);
1376 if (!NT_STATUS_IS_OK(status)) {
1377 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1383 if (!torture_close_connection(cli)) {
1392 checks for old style tcon support
1394 static bool run_tcon2_test(int dummy)
1396 static struct cli_state *cli;
1397 uint16 cnum, max_xmit;
1401 if (!torture_open_connection(&cli, 0)) {
1404 cli_sockopt(cli, sockops);
1406 printf("starting tcon2 test\n");
1408 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1412 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1416 if (!NT_STATUS_IS_OK(status)) {
1417 printf("tcon2 failed : %s\n", nt_errstr(status));
1419 printf("tcon OK : max_xmit=%d cnum=%d\n",
1420 (int)max_xmit, (int)cnum);
1423 if (!torture_close_connection(cli)) {
1427 printf("Passed tcon2 test\n");
1431 static bool tcon_devtest(struct cli_state *cli,
1432 const char *myshare, const char *devtype,
1433 const char *return_devtype,
1434 NTSTATUS expected_error)
1439 status = cli_tcon_andx(cli, myshare, devtype,
1440 password, strlen(password)+1);
1442 if (NT_STATUS_IS_OK(expected_error)) {
1443 if (NT_STATUS_IS_OK(status)) {
1444 if (strcmp(cli->dev, return_devtype) == 0) {
1447 printf("tconX to share %s with type %s "
1448 "succeeded but returned the wrong "
1449 "device type (got [%s] but should have got [%s])\n",
1450 myshare, devtype, cli->dev, return_devtype);
1454 printf("tconX to share %s with type %s "
1455 "should have succeeded but failed\n",
1461 if (NT_STATUS_IS_OK(status)) {
1462 printf("tconx to share %s with type %s "
1463 "should have failed but succeeded\n",
1467 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1471 printf("Returned unexpected error\n");
1480 checks for correct tconX support
1482 static bool run_tcon_devtype_test(int dummy)
1484 static struct cli_state *cli1 = NULL;
1489 status = cli_full_connection(&cli1, myname,
1490 host, NULL, port_to_use,
1492 username, workgroup,
1493 password, flags, signing_state);
1495 if (!NT_STATUS_IS_OK(status)) {
1496 printf("could not open connection\n");
1500 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1503 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1506 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1509 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1512 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1515 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1518 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1521 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1524 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1527 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1533 printf("Passed tcondevtest\n");
1540 This test checks that
1542 1) the server supports multiple locking contexts on the one SMB
1543 connection, distinguished by PID.
1545 2) the server correctly fails overlapping locks made by the same PID (this
1546 goes against POSIX behaviour, which is why it is tricky to implement)
1548 3) the server denies unlock requests by an incorrect client PID
1550 static bool run_locktest2(int dummy)
1552 static struct cli_state *cli;
1553 const char *fname = "\\lockt2.lck";
1554 uint16_t fnum1, fnum2, fnum3;
1555 bool correct = True;
1557 if (!torture_open_connection(&cli, 0)) {
1561 cli_sockopt(cli, sockops);
1563 printf("starting locktest2\n");
1565 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1569 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1570 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1574 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1575 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1581 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1582 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1588 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1589 printf("lock1 failed (%s)\n", cli_errstr(cli));
1593 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1594 printf("WRITE lock1 succeeded! This is a locking bug\n");
1597 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1598 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1601 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1602 printf("WRITE lock2 succeeded! This is a locking bug\n");
1605 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1606 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1609 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1610 printf("READ lock2 succeeded! This is a locking bug\n");
1613 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1614 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1617 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1618 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1621 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1622 printf("unlock at 100 succeeded! This is a locking bug\n");
1626 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1627 printf("unlock1 succeeded! This is a locking bug\n");
1630 if (!check_error(__LINE__, cli,
1632 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1635 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1636 printf("unlock2 succeeded! This is a locking bug\n");
1639 if (!check_error(__LINE__, cli,
1641 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1644 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1645 printf("lock3 succeeded! This is a locking bug\n");
1648 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1653 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1654 printf("close1 failed (%s)\n", cli_errstr(cli));
1658 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1659 printf("close2 failed (%s)\n", cli_errstr(cli));
1663 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1664 printf("close3 failed (%s)\n", cli_errstr(cli));
1668 if (!torture_close_connection(cli)) {
1672 printf("locktest2 finished\n");
1679 This test checks that
1681 1) the server supports the full offset range in lock requests
1683 static bool run_locktest3(int dummy)
1685 static struct cli_state *cli1, *cli2;
1686 const char *fname = "\\lockt3.lck";
1687 uint16_t fnum1, fnum2;
1690 bool correct = True;
1692 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1694 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1697 cli_sockopt(cli1, sockops);
1698 cli_sockopt(cli2, sockops);
1700 printf("starting locktest3\n");
1702 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1704 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1705 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1708 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1709 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1713 for (offset=i=0;i<torture_numops;i++) {
1715 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1716 printf("lock1 %d failed (%s)\n",
1722 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1723 printf("lock2 %d failed (%s)\n",
1730 for (offset=i=0;i<torture_numops;i++) {
1733 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1734 printf("error: lock1 %d succeeded!\n", i);
1738 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1739 printf("error: lock2 %d succeeded!\n", i);
1743 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1744 printf("error: lock3 %d succeeded!\n", i);
1748 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1749 printf("error: lock4 %d succeeded!\n", i);
1754 for (offset=i=0;i<torture_numops;i++) {
1757 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1758 printf("unlock1 %d failed (%s)\n",
1764 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1765 printf("unlock2 %d failed (%s)\n",
1772 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1773 printf("close1 failed (%s)\n", cli_errstr(cli1));
1777 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1778 printf("close2 failed (%s)\n", cli_errstr(cli2));
1782 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1783 printf("unlink failed (%s)\n", cli_errstr(cli1));
1787 if (!torture_close_connection(cli1)) {
1791 if (!torture_close_connection(cli2)) {
1795 printf("finished locktest3\n");
1800 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1801 printf("** "); correct = False; \
1805 looks at overlapping locks
1807 static bool run_locktest4(int dummy)
1809 static struct cli_state *cli1, *cli2;
1810 const char *fname = "\\lockt4.lck";
1811 uint16_t fnum1, fnum2, f;
1814 bool correct = True;
1817 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1821 cli_sockopt(cli1, sockops);
1822 cli_sockopt(cli2, sockops);
1824 printf("starting locktest4\n");
1826 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1828 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1829 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1831 memset(buf, 0, sizeof(buf));
1833 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1835 if (!NT_STATUS_IS_OK(status)) {
1836 printf("Failed to create file: %s\n", nt_errstr(status));
1841 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1842 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1843 EXPECTED(ret, False);
1844 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1846 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1847 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1848 EXPECTED(ret, True);
1849 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1851 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1852 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1853 EXPECTED(ret, False);
1854 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1856 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1857 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1858 EXPECTED(ret, True);
1859 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1861 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1862 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1863 EXPECTED(ret, False);
1864 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1866 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1867 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1868 EXPECTED(ret, True);
1869 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1871 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1872 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1873 EXPECTED(ret, True);
1874 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1876 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1877 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1878 EXPECTED(ret, False);
1879 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1881 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1882 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1883 EXPECTED(ret, False);
1884 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1886 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1887 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1888 EXPECTED(ret, True);
1889 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1891 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1892 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1893 EXPECTED(ret, False);
1894 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1896 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1897 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1898 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1899 EXPECTED(ret, False);
1900 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1903 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1904 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1905 EXPECTED(ret, False);
1906 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1908 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1910 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1912 ret = NT_STATUS_IS_OK(status);
1914 EXPECTED(ret, False);
1915 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1918 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1919 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1920 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1921 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1922 EXPECTED(ret, True);
1923 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1926 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1927 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1928 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1929 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1930 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1932 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1933 EXPECTED(ret, True);
1934 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1936 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1937 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1938 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1940 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1941 EXPECTED(ret, True);
1942 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1944 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1945 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1946 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1948 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1949 EXPECTED(ret, True);
1950 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1952 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1953 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1954 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1955 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1957 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1958 EXPECTED(ret, True);
1959 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1961 cli_close(cli1, fnum1);
1962 cli_close(cli2, fnum2);
1963 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1964 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1965 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1966 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1967 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1968 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1969 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1971 cli_close(cli1, fnum1);
1972 EXPECTED(ret, True);
1973 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1976 cli_close(cli1, fnum1);
1977 cli_close(cli2, fnum2);
1978 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1979 torture_close_connection(cli1);
1980 torture_close_connection(cli2);
1982 printf("finished locktest4\n");
1987 looks at lock upgrade/downgrade.
1989 static bool run_locktest5(int dummy)
1991 static struct cli_state *cli1, *cli2;
1992 const char *fname = "\\lockt5.lck";
1993 uint16_t fnum1, fnum2, fnum3;
1996 bool correct = True;
1999 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2003 cli_sockopt(cli1, sockops);
2004 cli_sockopt(cli2, sockops);
2006 printf("starting locktest5\n");
2008 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2010 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2011 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2012 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2014 memset(buf, 0, sizeof(buf));
2016 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2018 if (!NT_STATUS_IS_OK(status)) {
2019 printf("Failed to create file: %s\n", nt_errstr(status));
2024 /* Check for NT bug... */
2025 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2026 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2027 cli_close(cli1, fnum1);
2028 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2029 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2030 EXPECTED(ret, True);
2031 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2032 cli_close(cli1, fnum1);
2033 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2034 cli_unlock(cli1, fnum3, 0, 1);
2036 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2037 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2038 EXPECTED(ret, True);
2039 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2041 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2042 EXPECTED(ret, False);
2044 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2046 /* Unlock the process 2 lock. */
2047 cli_unlock(cli2, fnum2, 0, 4);
2049 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2050 EXPECTED(ret, False);
2052 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2054 /* Unlock the process 1 fnum3 lock. */
2055 cli_unlock(cli1, fnum3, 0, 4);
2057 /* Stack 2 more locks here. */
2058 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2059 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2061 EXPECTED(ret, True);
2062 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2064 /* Unlock the first process lock, then check this was the WRITE lock that was
2067 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2068 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2070 EXPECTED(ret, True);
2071 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2073 /* Unlock the process 2 lock. */
2074 cli_unlock(cli2, fnum2, 0, 4);
2076 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2078 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2079 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2080 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2082 EXPECTED(ret, True);
2083 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2085 /* Ensure the next unlock fails. */
2086 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2087 EXPECTED(ret, False);
2088 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2090 /* Ensure connection 2 can get a write lock. */
2091 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2092 EXPECTED(ret, True);
2094 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2098 cli_close(cli1, fnum1);
2099 cli_close(cli2, fnum2);
2100 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2101 if (!torture_close_connection(cli1)) {
2104 if (!torture_close_connection(cli2)) {
2108 printf("finished locktest5\n");
2114 tries the unusual lockingX locktype bits
2116 static bool run_locktest6(int dummy)
2118 static struct cli_state *cli;
2119 const char *fname[1] = { "\\lock6.txt" };
2124 if (!torture_open_connection(&cli, 0)) {
2128 cli_sockopt(cli, sockops);
2130 printf("starting locktest6\n");
2133 printf("Testing %s\n", fname[i]);
2135 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2137 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2138 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2139 cli_close(cli, fnum);
2140 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2142 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2143 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2144 cli_close(cli, fnum);
2145 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2147 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2150 torture_close_connection(cli);
2152 printf("finished locktest6\n");
2156 static bool run_locktest7(int dummy)
2158 struct cli_state *cli1;
2159 const char *fname = "\\lockt7.lck";
2162 bool correct = False;
2165 if (!torture_open_connection(&cli1, 0)) {
2169 cli_sockopt(cli1, sockops);
2171 printf("starting locktest7\n");
2173 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2175 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2177 memset(buf, 0, sizeof(buf));
2179 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2181 if (!NT_STATUS_IS_OK(status)) {
2182 printf("Failed to create file: %s\n", nt_errstr(status));
2186 cli_setpid(cli1, 1);
2188 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2189 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2192 printf("pid1 successfully locked range 130:4 for READ\n");
2195 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2196 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2199 printf("pid1 successfully read the range 130:4\n");
2202 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2203 if (!NT_STATUS_IS_OK(status)) {
2204 printf("pid1 unable to write to the range 130:4, error was "
2205 "%s\n", nt_errstr(status));
2206 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2207 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2211 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2215 cli_setpid(cli1, 2);
2217 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2218 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2220 printf("pid2 successfully read the range 130:4\n");
2223 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2224 if (!NT_STATUS_IS_OK(status)) {
2225 printf("pid2 unable to write to the range 130:4, error was "
2226 "%s\n", nt_errstr(status));
2227 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2228 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2232 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2236 cli_setpid(cli1, 1);
2237 cli_unlock(cli1, fnum1, 130, 4);
2239 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2240 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2243 printf("pid1 successfully locked range 130:4 for WRITE\n");
2246 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2247 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2250 printf("pid1 successfully read the range 130:4\n");
2253 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2254 if (!NT_STATUS_IS_OK(status)) {
2255 printf("pid1 unable to write to the range 130:4, error was "
2256 "%s\n", nt_errstr(status));
2259 printf("pid1 successfully wrote to the range 130:4\n");
2262 cli_setpid(cli1, 2);
2264 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2265 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2266 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2267 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2271 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2275 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2276 if (!NT_STATUS_IS_OK(status)) {
2277 printf("pid2 unable to write to the range 130:4, error was "
2278 "%s\n", nt_errstr(status));
2279 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2280 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2284 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2288 cli_unlock(cli1, fnum1, 130, 0);
2292 cli_close(cli1, fnum1);
2293 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2294 torture_close_connection(cli1);
2296 printf("finished locktest7\n");
2301 * This demonstrates a problem with our use of GPFS share modes: A file
2302 * descriptor sitting in the pending close queue holding a GPFS share mode
2303 * blocks opening a file another time. Happens with Word 2007 temp files.
2304 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2305 * open is denied with NT_STATUS_SHARING_VIOLATION.
2308 static bool run_locktest8(int dummy)
2310 struct cli_state *cli1;
2311 const char *fname = "\\lockt8.lck";
2312 uint16_t fnum1, fnum2;
2314 bool correct = False;
2317 if (!torture_open_connection(&cli1, 0)) {
2321 cli_sockopt(cli1, sockops);
2323 printf("starting locktest8\n");
2325 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2327 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2329 if (!NT_STATUS_IS_OK(status)) {
2330 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2334 memset(buf, 0, sizeof(buf));
2336 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2337 if (!NT_STATUS_IS_OK(status)) {
2338 d_fprintf(stderr, "cli_open second time returned %s\n",
2343 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2344 printf("Unable to apply read lock on range 1:1, error was "
2345 "%s\n", cli_errstr(cli1));
2349 status = cli_close(cli1, fnum1);
2350 if (!NT_STATUS_IS_OK(status)) {
2351 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2355 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 d_fprintf(stderr, "cli_open third time returned %s\n",
2365 cli_close(cli1, fnum1);
2366 cli_close(cli1, fnum2);
2367 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2368 torture_close_connection(cli1);
2370 printf("finished locktest8\n");
2375 * This test is designed to be run in conjunction with
2376 * external NFS or POSIX locks taken in the filesystem.
2377 * It checks that the smbd server will block until the
2378 * lock is released and then acquire it. JRA.
2381 static bool got_alarm;
2382 static int alarm_fd;
2384 static void alarm_handler(int dummy)
2389 static void alarm_handler_parent(int dummy)
2394 static void do_local_lock(int read_fd, int write_fd)
2399 const char *local_pathname = NULL;
2402 local_pathname = talloc_asprintf(talloc_tos(),
2403 "%s/lockt9.lck", local_path);
2404 if (!local_pathname) {
2405 printf("child: alloc fail\n");
2409 unlink(local_pathname);
2410 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2412 printf("child: open of %s failed %s.\n",
2413 local_pathname, strerror(errno));
2417 /* Now take a fcntl lock. */
2418 lock.l_type = F_WRLCK;
2419 lock.l_whence = SEEK_SET;
2422 lock.l_pid = getpid();
2424 ret = fcntl(fd,F_SETLK,&lock);
2426 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2427 local_pathname, strerror(errno));
2430 printf("child: got lock 0:4 on file %s.\n",
2435 CatchSignal(SIGALRM, alarm_handler);
2437 /* Signal the parent. */
2438 if (write(write_fd, &c, 1) != 1) {
2439 printf("child: start signal fail %s.\n",
2446 /* Wait for the parent to be ready. */
2447 if (read(read_fd, &c, 1) != 1) {
2448 printf("child: reply signal fail %s.\n",
2456 printf("child: released lock 0:4 on file %s.\n",
2462 static bool run_locktest9(int dummy)
2464 struct cli_state *cli1;
2465 const char *fname = "\\lockt9.lck";
2467 bool correct = False;
2468 int pipe_in[2], pipe_out[2];
2472 struct timeval start;
2476 printf("starting locktest9\n");
2478 if (local_path == NULL) {
2479 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2483 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2488 if (child_pid == -1) {
2492 if (child_pid == 0) {
2494 do_local_lock(pipe_out[0], pipe_in[1]);
2504 ret = read(pipe_in[0], &c, 1);
2506 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2511 if (!torture_open_connection(&cli1, 0)) {
2515 cli_sockopt(cli1, sockops);
2517 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2519 if (!NT_STATUS_IS_OK(status)) {
2520 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2524 /* Ensure the child has the lock. */
2525 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2526 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2529 d_printf("Child has the lock.\n");
2532 /* Tell the child to wait 5 seconds then exit. */
2533 ret = write(pipe_out[1], &c, 1);
2535 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2540 /* Wait 20 seconds for the lock. */
2541 alarm_fd = cli1->fd;
2542 CatchSignal(SIGALRM, alarm_handler_parent);
2545 start = timeval_current();
2547 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2548 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2549 "%s\n", cli_errstr(cli1));
2554 seconds = timeval_elapsed(&start);
2556 printf("Parent got the lock after %.2f seconds.\n",
2559 status = cli_close(cli1, fnum);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2568 cli_close(cli1, fnum);
2569 torture_close_connection(cli1);
2573 printf("finished locktest9\n");
2578 test whether fnums and tids open on one VC are available on another (a major
2581 static bool run_fdpasstest(int dummy)
2583 struct cli_state *cli1, *cli2;
2584 const char *fname = "\\fdpass.tst";
2589 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2592 cli_sockopt(cli1, sockops);
2593 cli_sockopt(cli2, sockops);
2595 printf("starting fdpasstest\n");
2597 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2599 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2600 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2604 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"hello world\n", 0,
2606 if (!NT_STATUS_IS_OK(status)) {
2607 printf("write failed (%s)\n", nt_errstr(status));
2611 cli2->vuid = cli1->vuid;
2612 cli2->cnum = cli1->cnum;
2613 cli2->pid = cli1->pid;
2615 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2616 printf("read succeeded! nasty security hole [%s]\n",
2621 cli_close(cli1, fnum1);
2622 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2624 torture_close_connection(cli1);
2625 torture_close_connection(cli2);
2627 printf("finished fdpasstest\n");
2631 static bool run_fdsesstest(int dummy)
2633 struct cli_state *cli;
2638 const char *fname = "\\fdsess.tst";
2639 const char *fname1 = "\\fdsess1.tst";
2646 if (!torture_open_connection(&cli, 0))
2648 cli_sockopt(cli, sockops);
2650 if (!torture_cli_session_setup2(cli, &new_vuid))
2653 saved_cnum = cli->cnum;
2654 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2656 new_cnum = cli->cnum;
2657 cli->cnum = saved_cnum;
2659 printf("starting fdsesstest\n");
2661 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2662 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2664 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2665 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2669 status = cli_writeall(cli, fnum1, 0, (uint8_t *)"hello world\n", 0, 13,
2671 if (!NT_STATUS_IS_OK(status)) {
2672 printf("write failed (%s)\n", nt_errstr(status));
2676 saved_vuid = cli->vuid;
2677 cli->vuid = new_vuid;
2679 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2680 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2684 /* Try to open a file with different vuid, samba cnum. */
2685 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2686 printf("create with different vuid, same cnum succeeded.\n");
2687 cli_close(cli, fnum2);
2688 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2690 printf("create with different vuid, same cnum failed.\n");
2691 printf("This will cause problems with service clients.\n");
2695 cli->vuid = saved_vuid;
2697 /* Try with same vuid, different cnum. */
2698 cli->cnum = new_cnum;
2700 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2701 printf("read succeeded with different cnum![%s]\n",
2706 cli->cnum = saved_cnum;
2707 cli_close(cli, fnum1);
2708 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2710 torture_close_connection(cli);
2712 printf("finished fdsesstest\n");
2717 This test checks that
2719 1) the server does not allow an unlink on a file that is open
2721 static bool run_unlinktest(int dummy)
2723 struct cli_state *cli;
2724 const char *fname = "\\unlink.tst";
2726 bool correct = True;
2728 if (!torture_open_connection(&cli, 0)) {
2732 cli_sockopt(cli, sockops);
2734 printf("starting unlink test\n");
2736 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2740 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2741 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2745 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2746 printf("error: server allowed unlink on an open file\n");
2749 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2750 NT_STATUS_SHARING_VIOLATION);
2753 cli_close(cli, fnum);
2754 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2756 if (!torture_close_connection(cli)) {
2760 printf("unlink test finished\n");
2767 test how many open files this server supports on the one socket
2769 static bool run_maxfidtest(int dummy)
2771 struct cli_state *cli;
2772 const char *ftemplate = "\\maxfid.%d.%d";
2774 uint16_t fnums[0x11000];
2777 bool correct = True;
2782 printf("failed to connect\n");
2786 cli_sockopt(cli, sockops);
2788 for (i=0; i<0x11000; i++) {
2789 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2790 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2791 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2792 printf("open of %s failed (%s)\n",
2793 fname, cli_errstr(cli));
2794 printf("maximum fnum is %d\n", i);
2802 printf("cleaning up\n");
2804 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2805 cli_close(cli, fnums[i]);
2806 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2807 printf("unlink of %s failed (%s)\n",
2808 fname, cli_errstr(cli));
2815 printf("maxfid test finished\n");
2816 if (!torture_close_connection(cli)) {
2822 /* generate a random buffer */
2823 static void rand_buf(char *buf, int len)
2826 *buf = (char)sys_random();
2831 /* send smb negprot commands, not reading the response */
2832 static bool run_negprot_nowait(int dummy)
2834 struct tevent_context *ev;
2836 struct cli_state *cli;
2837 bool correct = True;
2839 printf("starting negprot nowait test\n");
2841 ev = tevent_context_init(talloc_tos());
2846 if (!(cli = open_nbt_connection())) {
2851 for (i=0;i<50000;i++) {
2852 struct tevent_req *req;
2854 req = cli_negprot_send(ev, ev, cli);
2859 if (!tevent_req_poll(req, ev)) {
2860 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2868 if (torture_close_connection(cli)) {
2872 printf("finished negprot nowait test\n");
2877 /* send smb negprot commands, not reading the response */
2878 static bool run_bad_nbt_session(int dummy)
2880 static struct cli_state *cli;
2882 printf("starting bad nbt session test\n");
2884 if (!(cli = open_bad_nbt_connection())) {
2889 printf("finished bad nbt session test\n");
2893 /* send random IPC commands */
2894 static bool run_randomipc(int dummy)
2896 char *rparam = NULL;
2898 unsigned int rdrcnt,rprcnt;
2900 int api, param_len, i;
2901 struct cli_state *cli;
2902 bool correct = True;
2905 printf("starting random ipc test\n");
2907 if (!torture_open_connection(&cli, 0)) {
2911 for (i=0;i<count;i++) {
2912 api = sys_random() % 500;
2913 param_len = (sys_random() % 64);
2915 rand_buf(param, param_len);
2920 param, param_len, 8,
2921 NULL, 0, BUFFER_SIZE,
2925 printf("%d/%d\r", i,count);
2928 printf("%d/%d\n", i, count);
2930 if (!torture_close_connection(cli)) {
2934 printf("finished random ipc test\n");
2941 static void browse_callback(const char *sname, uint32 stype,
2942 const char *comment, void *state)
2944 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2950 This test checks the browse list code
2953 static bool run_browsetest(int dummy)
2955 static struct cli_state *cli;
2956 bool correct = True;
2958 printf("starting browse test\n");
2960 if (!torture_open_connection(&cli, 0)) {
2964 printf("domain list:\n");
2965 cli_NetServerEnum(cli, cli->server_domain,
2966 SV_TYPE_DOMAIN_ENUM,
2967 browse_callback, NULL);
2969 printf("machine list:\n");
2970 cli_NetServerEnum(cli, cli->server_domain,
2972 browse_callback, NULL);
2974 if (!torture_close_connection(cli)) {
2978 printf("browse test finished\n");
2986 This checks how the getatr calls works
2988 static bool run_attrtest(int dummy)
2990 struct cli_state *cli;
2993 const char *fname = "\\attrib123456789.tst";
2994 bool correct = True;
2996 printf("starting attrib test\n");
2998 if (!torture_open_connection(&cli, 0)) {
3002 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3003 cli_open(cli, fname,
3004 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3005 cli_close(cli, fnum);
3006 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3007 printf("getatr failed (%s)\n", cli_errstr(cli));
3011 if (abs(t - time(NULL)) > 60*60*24*10) {
3012 printf("ERROR: SMBgetatr bug. time is %s",
3018 t2 = t-60*60*24; /* 1 day ago */
3020 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
3021 printf("setatr failed (%s)\n", cli_errstr(cli));
3025 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3026 printf("getatr failed (%s)\n", cli_errstr(cli));
3031 printf("ERROR: getatr/setatr bug. times are\n%s",
3033 printf("%s", ctime(&t2));
3037 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3039 if (!torture_close_connection(cli)) {
3043 printf("attrib test finished\n");
3050 This checks a couple of trans2 calls
3052 static bool run_trans2test(int dummy)
3054 struct cli_state *cli;
3057 time_t c_time, a_time, m_time;
3058 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3059 const char *fname = "\\trans2.tst";
3060 const char *dname = "\\trans2";
3061 const char *fname2 = "\\trans2\\trans2.tst";
3063 bool correct = True;
3067 printf("starting trans2 test\n");
3069 if (!torture_open_connection(&cli, 0)) {
3073 status = cli_get_fs_attr_info(cli, &fs_attr);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3080 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3081 cli_open(cli, fname,
3082 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3083 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3084 cli, fnum, NULL, &size, &c_time_ts,
3085 &a_time_ts, &w_time_ts,
3086 &m_time_ts, NULL))) {
3087 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3091 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3092 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3096 if (strcmp(pname, fname)) {
3097 printf("qfilename gave different name? [%s] [%s]\n",
3102 cli_close(cli, fnum);
3106 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3107 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3108 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3109 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3112 cli_close(cli, fnum);
3114 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3116 if (!NT_STATUS_IS_OK(status)) {
3117 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3120 if (c_time != m_time) {
3121 printf("create time=%s", ctime(&c_time));
3122 printf("modify time=%s", ctime(&m_time));
3123 printf("This system appears to have sticky create times\n");
3125 if (a_time % (60*60) == 0) {
3126 printf("access time=%s", ctime(&a_time));
3127 printf("This system appears to set a midnight access time\n");
3131 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3132 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3138 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3139 cli_open(cli, fname,
3140 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3141 cli_close(cli, fnum);
3142 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3143 &m_time_ts, &size, NULL, NULL);
3144 if (!NT_STATUS_IS_OK(status)) {
3145 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3148 if (w_time_ts.tv_sec < 60*60*24*2) {
3149 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3150 printf("This system appears to set a initial 0 write time\n");
3155 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3158 /* check if the server updates the directory modification time
3159 when creating a new file */
3160 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3161 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3165 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3166 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3167 if (!NT_STATUS_IS_OK(status)) {
3168 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3172 cli_open(cli, fname2,
3173 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3174 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3175 cli_close(cli, fnum);
3176 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3177 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3182 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3184 printf("This system does not update directory modification times\n");
3188 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3189 cli_rmdir(cli, dname);
3191 if (!torture_close_connection(cli)) {
3195 printf("trans2 test finished\n");
3201 This checks new W2K calls.
3204 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3206 uint8_t *buf = NULL;
3210 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3211 pcli->max_xmit, &buf, &len);
3212 if (!NT_STATUS_IS_OK(status)) {
3213 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3216 printf("qfileinfo: level %d, len = %u\n", level, len);
3217 dump_data(0, (uint8 *)buf, len);
3224 static bool run_w2ktest(int dummy)
3226 struct cli_state *cli;
3228 const char *fname = "\\w2ktest\\w2k.tst";
3230 bool correct = True;
3232 printf("starting w2k test\n");
3234 if (!torture_open_connection(&cli, 0)) {
3238 cli_open(cli, fname,
3239 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3241 for (level = 1004; level < 1040; level++) {
3242 new_trans(cli, fnum, level);
3245 cli_close(cli, fnum);
3247 if (!torture_close_connection(cli)) {
3251 printf("w2k test finished\n");
3258 this is a harness for some oplock tests
3260 static bool run_oplock1(int dummy)
3262 struct cli_state *cli1;
3263 const char *fname = "\\lockt1.lck";
3265 bool correct = True;
3267 printf("starting oplock test 1\n");
3269 if (!torture_open_connection(&cli1, 0)) {
3273 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3275 cli_sockopt(cli1, sockops);
3277 cli1->use_oplocks = True;
3279 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3280 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3284 cli1->use_oplocks = False;
3286 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3287 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3289 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3290 printf("close2 failed (%s)\n", cli_errstr(cli1));
3294 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3295 printf("unlink failed (%s)\n", cli_errstr(cli1));
3299 if (!torture_close_connection(cli1)) {
3303 printf("finished oplock test 1\n");
3308 static bool run_oplock2(int dummy)
3310 struct cli_state *cli1, *cli2;
3311 const char *fname = "\\lockt2.lck";
3312 uint16_t fnum1, fnum2;
3313 int saved_use_oplocks = use_oplocks;
3315 bool correct = True;
3316 volatile bool *shared_correct;
3318 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3319 *shared_correct = True;
3321 use_level_II_oplocks = True;
3324 printf("starting oplock test 2\n");
3326 if (!torture_open_connection(&cli1, 0)) {
3327 use_level_II_oplocks = False;
3328 use_oplocks = saved_use_oplocks;
3332 cli1->use_oplocks = True;
3333 cli1->use_level_II_oplocks = True;
3335 if (!torture_open_connection(&cli2, 1)) {
3336 use_level_II_oplocks = False;
3337 use_oplocks = saved_use_oplocks;
3341 cli2->use_oplocks = True;
3342 cli2->use_level_II_oplocks = True;
3344 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3346 cli_sockopt(cli1, sockops);
3347 cli_sockopt(cli2, sockops);
3349 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3350 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3354 /* Don't need the globals any more. */
3355 use_level_II_oplocks = False;
3356 use_oplocks = saved_use_oplocks;
3360 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3361 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3362 *shared_correct = False;
3368 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3369 printf("close2 failed (%s)\n", cli_errstr(cli1));
3370 *shared_correct = False;
3378 /* Ensure cli1 processes the break. Empty file should always return 0
3381 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3382 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3386 /* Should now be at level II. */
3387 /* Test if sending a write locks causes a break to none. */
3389 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3390 printf("lock failed (%s)\n", cli_errstr(cli1));
3394 cli_unlock(cli1, fnum1, 0, 4);
3398 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3399 printf("lock failed (%s)\n", cli_errstr(cli1));
3403 cli_unlock(cli1, fnum1, 0, 4);
3407 cli_read(cli1, fnum1, buf, 0, 4);
3409 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3410 printf("close1 failed (%s)\n", cli_errstr(cli1));
3416 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3417 printf("unlink failed (%s)\n", cli_errstr(cli1));
3421 if (!torture_close_connection(cli1)) {
3425 if (!*shared_correct) {
3429 printf("finished oplock test 2\n");
3434 /* handler for oplock 3 tests */
3435 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3437 printf("got oplock break fnum=%d level=%d\n",
3439 return cli_oplock_ack(cli, fnum, level);
3442 static bool run_oplock3(int dummy)
3444 struct cli_state *cli;
3445 const char *fname = "\\oplockt3.dat";
3447 char buf[4] = "abcd";
3448 bool correct = True;
3449 volatile bool *shared_correct;
3451 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3452 *shared_correct = True;
3454 printf("starting oplock test 3\n");
3459 use_level_II_oplocks = True;
3460 if (!torture_open_connection(&cli, 0)) {
3461 *shared_correct = False;
3465 /* try to trigger a oplock break in parent */
3466 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3467 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3473 use_level_II_oplocks = True;
3474 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3477 cli_oplock_handler(cli, oplock3_handler);
3478 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3479 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3480 cli_close(cli, fnum);
3481 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3482 cli->timeout = 20000;
3483 cli_receive_smb(cli);
3484 printf("finished oplock test 3\n");
3486 return (correct && *shared_correct);
3488 /* What are we looking for here? What's sucess and what's FAILURE? */
3491 /* handler for oplock 4 tests */
3492 bool *oplock4_shared_correct;
3494 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3496 printf("got oplock break fnum=%d level=%d\n",
3498 *oplock4_shared_correct = true;
3499 cli_oplock_ack(cli, fnum, level);
3500 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3503 static bool run_oplock4(int dummy)
3505 struct cli_state *cli1, *cli2;
3506 const char *fname = "\\lockt4.lck";
3507 const char *fname_ln = "\\lockt4_ln.lck";
3508 uint16_t fnum1, fnum2;
3509 int saved_use_oplocks = use_oplocks;
3511 bool correct = true;
3513 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3514 *oplock4_shared_correct = false;
3516 printf("starting oplock test 4\n");
3518 if (!torture_open_connection(&cli1, 0)) {
3519 use_level_II_oplocks = false;
3520 use_oplocks = saved_use_oplocks;
3524 if (!torture_open_connection(&cli2, 1)) {
3525 use_level_II_oplocks = false;
3526 use_oplocks = saved_use_oplocks;
3530 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3531 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3533 cli_sockopt(cli1, sockops);
3534 cli_sockopt(cli2, sockops);
3536 /* Create the file. */
3537 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3538 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3542 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3543 printf("close1 failed (%s)\n", cli_errstr(cli1));
3547 /* Now create a hardlink. */
3548 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3549 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3553 /* Prove that opening hardlinks cause deny modes to conflict. */
3554 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3555 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3559 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3560 if (NT_STATUS_IS_OK(status)) {
3561 printf("open of %s succeeded - should fail with sharing violation.\n",
3566 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3567 printf("open of %s should fail with sharing violation. Got %s\n",
3568 fname_ln, nt_errstr(status));
3572 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3573 printf("close1 failed (%s)\n", cli_errstr(cli1));
3577 cli1->use_oplocks = true;
3578 cli1->use_level_II_oplocks = true;
3580 cli2->use_oplocks = true;
3581 cli2->use_level_II_oplocks = true;
3583 cli_oplock_handler(cli1, oplock4_handler);
3584 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3585 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3591 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3592 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3593 *oplock4_shared_correct = false;
3597 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3598 printf("close2 failed (%s)\n", cli_errstr(cli1));
3599 *oplock4_shared_correct = false;
3607 /* Process the oplock break. */
3608 cli_receive_smb(cli1);
3610 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3611 printf("close1 failed (%s)\n", cli_errstr(cli1));
3615 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3616 printf("unlink failed (%s)\n", cli_errstr(cli1));
3619 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3620 printf("unlink failed (%s)\n", cli_errstr(cli1));
3624 if (!torture_close_connection(cli1)) {
3628 if (!*oplock4_shared_correct) {
3632 printf("finished oplock test 4\n");
3639 Test delete on close semantics.
3641 static bool run_deletetest(int dummy)
3643 struct cli_state *cli1 = NULL;
3644 struct cli_state *cli2 = NULL;
3645 const char *fname = "\\delete.file";
3646 uint16_t fnum1 = (uint16_t)-1;
3647 uint16_t fnum2 = (uint16_t)-1;
3648 bool correct = True;
3650 printf("starting delete test\n");
3652 if (!torture_open_connection(&cli1, 0)) {
3656 cli_sockopt(cli1, sockops);
3658 /* Test 1 - this should delete the file on close. */
3660 cli_setatr(cli1, fname, 0, 0);
3661 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3663 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3664 0, FILE_OVERWRITE_IF,
3665 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3666 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3671 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3672 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3677 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3678 printf("[1] open of %s succeeded (should fail)\n", fname);
3683 printf("first delete on close test succeeded.\n");
3685 /* Test 2 - this should delete the file on close. */
3687 cli_setatr(cli1, fname, 0, 0);
3688 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3690 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3691 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3692 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3693 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3698 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3699 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3704 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3705 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3710 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3711 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3712 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3713 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3717 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3719 printf("second delete on close test succeeded.\n");
3722 cli_setatr(cli1, fname, 0, 0);
3723 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3725 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3726 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3727 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3732 /* This should fail with a sharing violation - open for delete is only compatible
3733 with SHARE_DELETE. */
3735 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3736 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3737 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3742 /* This should succeed. */
3744 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3745 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3746 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3751 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3752 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3757 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3758 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3763 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3764 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3769 /* This should fail - file should no longer be there. */
3771 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3772 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3773 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3774 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3776 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3780 printf("third delete on close test succeeded.\n");
3783 cli_setatr(cli1, fname, 0, 0);
3784 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3786 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3787 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3788 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3793 /* This should succeed. */
3794 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3795 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3796 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3801 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3802 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3807 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3808 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3813 /* This should fail - no more opens once delete on close set. */
3814 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3815 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3816 FILE_OPEN, 0, 0, &fnum2))) {
3817 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3821 printf("fourth delete on close test succeeded.\n");
3823 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3824 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3830 cli_setatr(cli1, fname, 0, 0);
3831 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3833 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3834 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3839 /* This should fail - only allowed on NT opens with DELETE access. */
3841 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3842 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3847 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3848 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3853 printf("fifth delete on close test succeeded.\n");
3856 cli_setatr(cli1, fname, 0, 0);
3857 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3859 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3860 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3861 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3862 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3867 /* This should fail - only allowed on NT opens with DELETE access. */
3869 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3870 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3875 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3876 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3881 printf("sixth delete on close test succeeded.\n");
3884 cli_setatr(cli1, fname, 0, 0);
3885 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3887 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3888 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3889 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3894 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3895 printf("[7] setting delete_on_close on file failed !\n");
3900 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3901 printf("[7] unsetting delete_on_close on file failed !\n");
3906 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3907 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3912 /* This next open should succeed - we reset the flag. */
3914 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3915 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3920 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3921 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3926 printf("seventh delete on close test succeeded.\n");
3929 cli_setatr(cli1, fname, 0, 0);
3930 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3932 if (!torture_open_connection(&cli2, 1)) {
3933 printf("[8] failed to open second connection.\n");
3938 cli_sockopt(cli1, sockops);
3940 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3941 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3942 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3943 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3948 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3949 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3950 FILE_OPEN, 0, 0, &fnum2))) {
3951 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3956 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3957 printf("[8] setting delete_on_close on file failed !\n");
3962 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3963 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3968 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3969 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3974 /* This should fail.. */
3975 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3976 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3980 printf("eighth delete on close test succeeded.\n");
3982 /* This should fail - we need to set DELETE_ACCESS. */
3983 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3984 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3985 printf("[9] open of %s succeeded should have failed!\n", fname);
3990 printf("ninth delete on close test succeeded.\n");
3992 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3993 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3994 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3999 /* This should delete the file. */
4000 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4001 printf("[10] close failed (%s)\n", cli_errstr(cli1));
4006 /* This should fail.. */
4007 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4008 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4012 printf("tenth delete on close test succeeded.\n");
4014 cli_setatr(cli1, fname, 0, 0);
4015 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4017 /* What error do we get when attempting to open a read-only file with
4020 /* Create a readonly file. */
4021 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4022 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4023 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
4028 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4029 printf("[11] close failed (%s)\n", cli_errstr(cli1));
4034 /* Now try open for delete access. */
4035 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4036 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4037 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4038 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4039 cli_close(cli1, fnum1);
4043 NTSTATUS nterr = cli_nt_error(cli1);
4044 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4045 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4049 printf("eleventh delete on close test succeeded.\n");
4053 printf("finished delete test\n");
4056 /* FIXME: This will crash if we aborted before cli2 got
4057 * intialized, because these functions don't handle
4058 * uninitialized connections. */
4060 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4061 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4062 cli_setatr(cli1, fname, 0, 0);
4063 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4065 if (cli1 && !torture_close_connection(cli1)) {
4068 if (cli2 && !torture_close_connection(cli2)) {
4074 static bool run_deletetest_ln(int dummy)
4076 struct cli_state *cli;
4077 const char *fname = "\\delete1";
4078 const char *fname_ln = "\\delete1_ln";
4082 bool correct = true;
4085 printf("starting deletetest-ln\n");
4087 if (!torture_open_connection(&cli, 0)) {
4091 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4092 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4094 cli_sockopt(cli, sockops);
4096 /* Create the file. */
4097 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4098 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4102 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4103 printf("close1 failed (%s)\n", cli_errstr(cli));
4107 /* Now create a hardlink. */
4108 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4109 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4113 /* Open the original file. */
4114 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4115 FILE_ATTRIBUTE_NORMAL,
4116 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4117 FILE_OPEN_IF, 0, 0, &fnum);
4118 if (!NT_STATUS_IS_OK(status)) {
4119 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4123 /* Unlink the hard link path. */
4124 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4125 FILE_ATTRIBUTE_NORMAL,
4126 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4127 FILE_OPEN_IF, 0, 0, &fnum1);
4128 if (!NT_STATUS_IS_OK(status)) {
4129 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4132 status = cli_nt_delete_on_close(cli, fnum1, true);
4133 if (!NT_STATUS_IS_OK(status)) {
4134 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4135 __location__, fname_ln, nt_errstr(status));
4139 status = cli_close(cli, fnum1);
4140 if (!NT_STATUS_IS_OK(status)) {
4141 printf("close %s failed (%s)\n",
4142 fname_ln, nt_errstr(status));
4146 status = cli_close(cli, fnum);
4147 if (!NT_STATUS_IS_OK(status)) {
4148 printf("close %s failed (%s)\n",
4149 fname, nt_errstr(status));
4153 /* Ensure the original file is still there. */
4154 status = cli_getatr(cli, fname, NULL, NULL, &t);
4155 if (!NT_STATUS_IS_OK(status)) {
4156 printf("%s getatr on file %s failed (%s)\n",
4163 /* Ensure the link path is gone. */
4164 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4165 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4166 printf("%s, getatr for file %s returned wrong error code %s "
4167 "- should have been deleted\n",
4169 fname_ln, nt_errstr(status));
4173 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4174 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4176 if (!torture_close_connection(cli)) {
4180 printf("finished deletetest-ln\n");
4186 print out server properties
4188 static bool run_properties(int dummy)
4190 struct cli_state *cli;
4191 bool correct = True;
4193 printf("starting properties test\n");
4197 if (!torture_open_connection(&cli, 0)) {
4201 cli_sockopt(cli, sockops);
4203 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4205 if (!torture_close_connection(cli)) {
4214 /* FIRST_DESIRED_ACCESS 0xf019f */
4215 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4216 FILE_READ_EA| /* 0xf */ \
4217 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4218 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4219 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4220 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4221 /* SECOND_DESIRED_ACCESS 0xe0080 */
4222 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4223 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4224 WRITE_OWNER_ACCESS /* 0xe0000 */
4227 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4228 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4230 WRITE_OWNER_ACCESS /* */
4234 Test ntcreate calls made by xcopy
4236 static bool run_xcopy(int dummy)
4238 static struct cli_state *cli1;
4239 const char *fname = "\\test.txt";
4240 bool correct = True;
4241 uint16_t fnum1, fnum2;
4243 printf("starting xcopy test\n");
4245 if (!torture_open_connection(&cli1, 0)) {
4249 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4250 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4251 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4252 0x4044, 0, &fnum1))) {
4253 printf("First open failed - %s\n", cli_errstr(cli1));
4257 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4258 SECOND_DESIRED_ACCESS, 0,
4259 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4260 0x200000, 0, &fnum2))) {
4261 printf("second open failed - %s\n", cli_errstr(cli1));
4265 if (!torture_close_connection(cli1)) {
4273 Test rename on files open with share delete and no share delete.
4275 static bool run_rename(int dummy)
4277 static struct cli_state *cli1;
4278 const char *fname = "\\test.txt";
4279 const char *fname1 = "\\test1.txt";
4280 bool correct = True;
4285 printf("starting rename test\n");
4287 if (!torture_open_connection(&cli1, 0)) {
4291 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4292 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4293 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4294 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4295 printf("First open failed - %s\n", cli_errstr(cli1));
4299 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4300 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4302 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4306 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4307 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4311 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4312 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4313 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4315 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4317 FILE_SHARE_DELETE|FILE_SHARE_READ,
4319 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4320 if (!NT_STATUS_IS_OK(status)) {
4321 printf("Second open failed - %s\n", cli_errstr(cli1));
4325 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4326 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4329 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4332 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4333 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4337 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4338 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4340 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4341 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4342 printf("Third open failed - %s\n", cli_errstr(cli1));
4351 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4352 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4353 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4356 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4357 printf("[8] setting delete_on_close on file failed !\n");
4361 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4362 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4368 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4369 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4372 printf("Third rename succeeded (SHARE_NONE)\n");
4375 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4376 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4380 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4381 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4385 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4386 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4387 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4391 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4392 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4394 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4398 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4399 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4403 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4404 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4408 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4409 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4410 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4414 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4415 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4419 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4423 * Now check if the first name still exists ...
4426 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4427 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4428 printf("Opening original file after rename of open file fails: %s\n",
4432 printf("Opening original file after rename of open file works ...\n");
4433 (void)cli_close(cli1, fnum2);
4437 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4438 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4442 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4443 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4444 printf("getatr on file %s failed - %s ! \n",
4449 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4450 printf("Renamed file %s has wrong attr 0x%x "
4451 "(should be 0x%x)\n",
4454 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4457 printf("Renamed file %s has archive bit set\n", fname1);
4461 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4462 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4464 if (!torture_close_connection(cli1)) {
4471 static bool run_pipe_number(int dummy)
4473 struct cli_state *cli1;
4474 const char *pipe_name = "\\SPOOLSS";
4478 printf("starting pipenumber test\n");
4479 if (!torture_open_connection(&cli1, 0)) {
4483 cli_sockopt(cli1, sockops);
4485 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4486 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4487 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4491 printf("\r%6d", num_pipes);
4494 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4495 torture_close_connection(cli1);
4500 Test open mode returns on read-only files.
4502 static bool run_opentest(int dummy)
4504 static struct cli_state *cli1;
4505 static struct cli_state *cli2;
4506 const char *fname = "\\readonly.file";
4507 uint16_t fnum1, fnum2;
4510 bool correct = True;
4514 printf("starting open test\n");
4516 if (!torture_open_connection(&cli1, 0)) {
4520 cli_setatr(cli1, fname, 0, 0);
4521 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4523 cli_sockopt(cli1, sockops);
4525 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4526 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4530 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4531 printf("close2 failed (%s)\n", cli_errstr(cli1));
4535 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0))) {
4536 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4540 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4541 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4545 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4546 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4548 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4549 NT_STATUS_ACCESS_DENIED)) {
4550 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4553 printf("finished open test 1\n");
4555 cli_close(cli1, fnum1);
4557 /* Now try not readonly and ensure ERRbadshare is returned. */
4559 cli_setatr(cli1, fname, 0, 0);
4561 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4562 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4566 /* This will fail - but the error should be ERRshare. */
4567 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4569 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4570 NT_STATUS_SHARING_VIOLATION)) {
4571 printf("correct error code ERRDOS/ERRbadshare returned\n");
4574 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4575 printf("close2 failed (%s)\n", cli_errstr(cli1));
4579 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4581 printf("finished open test 2\n");
4583 /* Test truncate open disposition on file opened for read. */
4585 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4586 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4590 /* write 20 bytes. */
4592 memset(buf, '\0', 20);
4594 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4595 if (!NT_STATUS_IS_OK(status)) {
4596 printf("write failed (%s)\n", nt_errstr(status));
4600 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4601 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4605 /* Ensure size == 20. */
4606 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4607 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4612 printf("(3) file size != 20\n");
4616 /* Now test if we can truncate a file opened for readonly. */
4618 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4619 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4623 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4624 printf("close2 failed (%s)\n", cli_errstr(cli1));
4628 /* Ensure size == 0. */
4629 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4630 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4635 printf("(3) file size != 0\n");
4638 printf("finished open test 3\n");
4640 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4642 printf("Do ctemp tests\n");
4643 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4644 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4647 printf("ctemp gave path %s\n", tmp_path);
4648 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4649 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4651 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
4652 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4655 /* Test the non-io opens... */
4657 if (!torture_open_connection(&cli2, 1)) {
4661 cli_setatr(cli2, fname, 0, 0);
4662 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4664 cli_sockopt(cli2, sockops);
4666 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4668 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4669 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4670 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4674 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4675 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4676 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4680 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4681 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4684 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4685 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4689 printf("non-io open test #1 passed.\n");
4691 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4693 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4695 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4696 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4697 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4701 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4702 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4703 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4707 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4708 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4711 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4712 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4716 printf("non-io open test #2 passed.\n");
4718 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4720 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4722 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4723 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4724 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4728 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4729 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4730 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4734 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4735 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4738 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4739 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4743 printf("non-io open test #3 passed.\n");
4745 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4747 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4749 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4750 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4751 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4755 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4756 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4757 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4761 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4763 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4764 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4768 printf("non-io open test #4 passed.\n");
4770 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4772 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4774 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4775 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4776 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4780 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4781 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4782 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4786 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4787 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4791 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4792 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4796 printf("non-io open test #5 passed.\n");
4798 printf("TEST #6 testing 1 non-io open, one io open\n");
4800 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4802 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4803 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4804 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4808 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4809 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4810 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4814 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4815 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4819 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4820 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4824 printf("non-io open test #6 passed.\n");
4826 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4828 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4830 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4831 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4832 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4836 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4837 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4838 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4842 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4844 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4845 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4849 printf("non-io open test #7 passed.\n");
4851 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4853 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4854 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4855 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4856 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4857 if (!NT_STATUS_IS_OK(status)) {
4858 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4863 /* Write to ensure we have to update the file time. */
4864 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
4866 if (!NT_STATUS_IS_OK(status)) {
4867 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
4872 status = cli_close(cli1, fnum1);
4873 if (!NT_STATUS_IS_OK(status)) {
4874 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4880 if (!torture_close_connection(cli1)) {
4883 if (!torture_close_connection(cli2)) {
4890 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4892 uint16 major, minor;
4893 uint32 caplow, caphigh;
4896 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4897 printf("Server doesn't support UNIX CIFS extensions.\n");
4898 return NT_STATUS_NOT_SUPPORTED;
4901 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4903 if (!NT_STATUS_IS_OK(status)) {
4904 printf("Server didn't return UNIX CIFS extensions: %s\n",
4909 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4911 if (!NT_STATUS_IS_OK(status)) {
4912 printf("Server doesn't support setting UNIX CIFS extensions: "
4913 "%s.\n", nt_errstr(status));
4917 return NT_STATUS_OK;
4921 Test POSIX open /mkdir calls.
4923 static bool run_simple_posix_open_test(int dummy)
4925 static struct cli_state *cli1;
4926 const char *fname = "posix:file";
4927 const char *hname = "posix:hlink";
4928 const char *sname = "posix:symlink";
4929 const char *dname = "posix:dir";
4932 uint16_t fnum1 = (uint16_t)-1;
4933 SMB_STRUCT_STAT sbuf;
4934 bool correct = false;
4937 printf("Starting simple POSIX open test\n");
4939 if (!torture_open_connection(&cli1, 0)) {
4943 cli_sockopt(cli1, sockops);
4945 status = torture_setup_unix_extensions(cli1);
4946 if (!NT_STATUS_IS_OK(status)) {
4950 cli_setatr(cli1, fname, 0, 0);
4951 cli_posix_unlink(cli1, fname);
4952 cli_setatr(cli1, dname, 0, 0);
4953 cli_posix_rmdir(cli1, dname);
4954 cli_setatr(cli1, hname, 0, 0);
4955 cli_posix_unlink(cli1, hname);
4956 cli_setatr(cli1, sname, 0, 0);
4957 cli_posix_unlink(cli1, sname);
4959 /* Create a directory. */
4960 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4961 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4965 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4966 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4970 /* Test ftruncate - set file size. */
4971 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4972 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4976 /* Ensure st_size == 1000 */
4977 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4978 printf("stat failed (%s)\n", cli_errstr(cli1));
4982 if (sbuf.st_ex_size != 1000) {
4983 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4987 /* Test ftruncate - set file size back to zero. */
4988 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4989 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4993 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4994 printf("close failed (%s)\n", cli_errstr(cli1));
4998 /* Now open the file again for read only. */
4999 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5000 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
5004 /* Now unlink while open. */
5005 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5006 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5010 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5011 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5015 /* Ensure the file has gone. */
5016 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5017 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5021 /* What happens when we try and POSIX open a directory ? */
5022 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5023 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5026 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5027 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5032 /* Create the file. */
5033 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5034 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5038 /* Write some data into it. */
5039 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
5041 if (!NT_STATUS_IS_OK(status)) {
5042 printf("cli_write failed: %s\n", nt_errstr(status));
5046 cli_close(cli1, fnum1);
5048 /* Now create a hardlink. */
5049 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5050 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5054 /* Now create a symlink. */
5055 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5056 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5060 /* Open the hardlink for read. */
5061 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5062 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5066 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5067 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5071 if (memcmp(buf, "TEST DATA\n", 10)) {
5072 printf("invalid data read from hardlink\n");
5076 /* Do a POSIX lock/unlock. */
5077 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5078 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5082 /* Punch a hole in the locked area. */
5083 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5084 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5088 cli_close(cli1, fnum1);
5090 /* Open the symlink for read - this should fail. A POSIX
5091 client should not be doing opens on a symlink. */
5092 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5093 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5096 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5097 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5098 printf("POSIX open of %s should have failed "
5099 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5100 "failed with %s instead.\n",
5101 sname, cli_errstr(cli1));
5106 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5107 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5111 if (strcmp(namebuf, fname) != 0) {
5112 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5113 sname, fname, namebuf);
5117 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5118 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5122 printf("Simple POSIX open test passed\n");
5127 if (fnum1 != (uint16_t)-1) {
5128 cli_close(cli1, fnum1);
5129 fnum1 = (uint16_t)-1;
5132 cli_setatr(cli1, sname, 0, 0);
5133 cli_posix_unlink(cli1, sname);
5134 cli_setatr(cli1, hname, 0, 0);
5135 cli_posix_unlink(cli1, hname);
5136 cli_setatr(cli1, fname, 0, 0);
5137 cli_posix_unlink(cli1, fname);
5138 cli_setatr(cli1, dname, 0, 0);
5139 cli_posix_rmdir(cli1, dname);
5141 if (!torture_close_connection(cli1)) {
5149 static uint32 open_attrs_table[] = {
5150 FILE_ATTRIBUTE_NORMAL,
5151 FILE_ATTRIBUTE_ARCHIVE,
5152 FILE_ATTRIBUTE_READONLY,
5153 FILE_ATTRIBUTE_HIDDEN,
5154 FILE_ATTRIBUTE_SYSTEM,
5156 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5157 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5158 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5159 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5160 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5161 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5163 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5164 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5165 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5166 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5169 struct trunc_open_results {
5176 static struct trunc_open_results attr_results[] = {
5177 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5178 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5179 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5180 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5181 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5182 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5183 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5184 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5185 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5186 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5187 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5188 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5189 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5190 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5191 { 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 },
5192 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5193 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5194 { 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 },
5195 { 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 },
5196 { 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 },
5197 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5198 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5199 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5200 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5201 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5202 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5205 static bool run_openattrtest(int dummy)
5207 static struct cli_state *cli1;
5208 const char *fname = "\\openattr.file";
5210 bool correct = True;
5212 unsigned int i, j, k, l;
5214 printf("starting open attr test\n");
5216 if (!torture_open_connection(&cli1, 0)) {
5220 cli_sockopt(cli1, sockops);
5222 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5223 cli_setatr(cli1, fname, 0, 0);
5224 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5225 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5226 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5227 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5231 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5232 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5236 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5237 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5238 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5239 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5240 if (attr_results[l].num == k) {
5241 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5242 k, open_attrs_table[i],
5243 open_attrs_table[j],
5244 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5248 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5249 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5250 k, open_attrs_table[i], open_attrs_table[j],
5255 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5261 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5262 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5266 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5267 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5272 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5273 k, open_attrs_table[i], open_attrs_table[j], attr );
5276 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5277 if (attr_results[l].num == k) {
5278 if (attr != attr_results[l].result_attr ||
5279 open_attrs_table[i] != attr_results[l].init_attr ||
5280 open_attrs_table[j] != attr_results[l].trunc_attr) {
5281 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5282 open_attrs_table[i],
5283 open_attrs_table[j],
5285 attr_results[l].result_attr);
5295 cli_setatr(cli1, fname, 0, 0);
5296 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5298 printf("open attr test %s.\n", correct ? "passed" : "failed");
5300 if (!torture_close_connection(cli1)) {
5306 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5307 const char *name, void *state)
5309 int *matched = (int *)state;
5310 if (matched != NULL) {
5313 return NT_STATUS_OK;
5317 test directory listing speed
5319 static bool run_dirtest(int dummy)
5322 static struct cli_state *cli;
5324 struct timeval core_start;
5325 bool correct = True;
5328 printf("starting directory test\n");
5330 if (!torture_open_connection(&cli, 0)) {
5334 cli_sockopt(cli, sockops);
5337 for (i=0;i<torture_numops;i++) {
5339 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5340 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5341 fprintf(stderr,"Failed to open %s\n", fname);
5344 cli_close(cli, fnum);
5347 core_start = timeval_current();
5350 cli_list(cli, "a*.*", 0, list_fn, &matched);
5351 printf("Matched %d\n", matched);
5354 cli_list(cli, "b*.*", 0, list_fn, &matched);
5355 printf("Matched %d\n", matched);
5358 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5359 printf("Matched %d\n", matched);
5361 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5364 for (i=0;i<torture_numops;i++) {
5366 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5367 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5370 if (!torture_close_connection(cli)) {
5374 printf("finished dirtest\n");
5379 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5382 struct cli_state *pcli = (struct cli_state *)state;
5384 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5386 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5387 return NT_STATUS_OK;
5389 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5390 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5391 printf("del_fn: failed to rmdir %s\n,", fname );
5393 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5394 printf("del_fn: failed to unlink %s\n,", fname );
5396 return NT_STATUS_OK;
5401 sees what IOCTLs are supported
5403 bool torture_ioctl_test(int dummy)
5405 static struct cli_state *cli;
5406 uint16_t device, function;
5408 const char *fname = "\\ioctl.dat";
5412 if (!torture_open_connection(&cli, 0)) {
5416 printf("starting ioctl test\n");
5418 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5420 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5421 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5425 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5426 printf("ioctl device info: %s\n", nt_errstr(status));
5428 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5429 printf("ioctl job info: %s\n", nt_errstr(status));
5431 for (device=0;device<0x100;device++) {
5432 printf("ioctl test with device = 0x%x\n", device);
5433 for (function=0;function<0x100;function++) {
5434 uint32 code = (device<<16) | function;
5436 status = cli_raw_ioctl(cli, fnum, code, &blob);
5438 if (NT_STATUS_IS_OK(status)) {
5439 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5441 data_blob_free(&blob);
5446 if (!torture_close_connection(cli)) {
5455 tries varients of chkpath
5457 bool torture_chkpath_test(int dummy)
5459 static struct cli_state *cli;
5463 if (!torture_open_connection(&cli, 0)) {
5467 printf("starting chkpath test\n");
5469 /* cleanup from an old run */
5470 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5471 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5472 cli_rmdir(cli, "\\chkpath.dir");
5474 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5475 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5479 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5480 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5484 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5485 printf("open1 failed (%s)\n", cli_errstr(cli));
5488 cli_close(cli, fnum);
5490 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5491 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5495 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5496 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5500 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5501 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5502 NT_STATUS_NOT_A_DIRECTORY);
5504 printf("* chkpath on a file should fail\n");
5508 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5509 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5510 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5512 printf("* chkpath on a non existant file should fail\n");
5516 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5517 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5518 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5520 printf("* chkpath on a non existent component should fail\n");
5524 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5525 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5526 cli_rmdir(cli, "\\chkpath.dir");
5528 if (!torture_close_connection(cli)) {
5535 static bool run_eatest(int dummy)
5537 static struct cli_state *cli;
5538 const char *fname = "\\eatest.txt";
5539 bool correct = True;
5543 struct ea_struct *ea_list = NULL;
5544 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5547 printf("starting eatest\n");
5549 if (!torture_open_connection(&cli, 0)) {
5550 talloc_destroy(mem_ctx);
5554 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5555 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5556 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5557 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5558 0x4044, 0, &fnum))) {
5559 printf("open failed - %s\n", cli_errstr(cli));
5560 talloc_destroy(mem_ctx);
5564 for (i = 0; i < 10; i++) {
5565 fstring ea_name, ea_val;
5567 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5568 memset(ea_val, (char)i+1, i+1);
5569 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5570 if (!NT_STATUS_IS_OK(status)) {
5571 printf("ea_set of name %s failed - %s\n", ea_name,
5573 talloc_destroy(mem_ctx);
5578 cli_close(cli, fnum);
5579 for (i = 0; i < 10; i++) {
5580 fstring ea_name, ea_val;
5582 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5583 memset(ea_val, (char)i+1, i+1);
5584 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5585 if (!NT_STATUS_IS_OK(status)) {
5586 printf("ea_set of name %s failed - %s\n", ea_name,
5588 talloc_destroy(mem_ctx);
5593 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5594 if (!NT_STATUS_IS_OK(status)) {
5595 printf("ea_get list failed - %s\n", nt_errstr(status));
5599 printf("num_eas = %d\n", (int)num_eas);
5601 if (num_eas != 20) {
5602 printf("Should be 20 EA's stored... failing.\n");
5606 for (i = 0; i < num_eas; i++) {
5607 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5608 dump_data(0, ea_list[i].value.data,
5609 ea_list[i].value.length);
5612 /* Setting EA's to zero length deletes them. Test this */
5613 printf("Now deleting all EA's - case indepenent....\n");
5616 cli_set_ea_path(cli, fname, "", "", 0);
5618 for (i = 0; i < 20; i++) {
5620 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5621 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5622 if (!NT_STATUS_IS_OK(status)) {
5623 printf("ea_set of name %s failed - %s\n", ea_name,
5625 talloc_destroy(mem_ctx);
5631 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5632 if (!NT_STATUS_IS_OK(status)) {
5633 printf("ea_get list failed - %s\n", nt_errstr(status));
5637 printf("num_eas = %d\n", (int)num_eas);
5638 for (i = 0; i < num_eas; i++) {
5639 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5640 dump_data(0, ea_list[i].value.data,
5641 ea_list[i].value.length);
5645 printf("deleting EA's failed.\n");
5649 /* Try and delete a non existant EA. */
5650 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5651 if (!NT_STATUS_IS_OK(status)) {
5652 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5657 talloc_destroy(mem_ctx);
5658 if (!torture_close_connection(cli)) {
5665 static bool run_dirtest1(int dummy)
5668 static struct cli_state *cli;
5671 bool correct = True;
5673 printf("starting directory test\n");
5675 if (!torture_open_connection(&cli, 0)) {
5679 cli_sockopt(cli, sockops);
5681 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5682 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5683 cli_rmdir(cli, "\\LISTDIR");
5684 cli_mkdir(cli, "\\LISTDIR");
5686 /* Create 1000 files and 1000 directories. */
5687 for (i=0;i<1000;i++) {
5689 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5690 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5691 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5692 fprintf(stderr,"Failed to open %s\n", fname);
5695 cli_close(cli, fnum);
5697 for (i=0;i<1000;i++) {
5699 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5700 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5701 fprintf(stderr,"Failed to open %s\n", fname);
5706 /* Now ensure that doing an old list sees both files and directories. */
5708 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5709 printf("num_seen = %d\n", num_seen );
5710 /* We should see 100 files + 1000 directories + . and .. */
5711 if (num_seen != 2002)
5714 /* Ensure if we have the "must have" bits we only see the
5718 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5719 printf("num_seen = %d\n", num_seen );
5720 if (num_seen != 1002)
5724 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5725 printf("num_seen = %d\n", num_seen );
5726 if (num_seen != 1000)
5729 /* Delete everything. */
5730 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5731 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5732 cli_rmdir(cli, "\\LISTDIR");
5735 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5736 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5737 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5740 if (!torture_close_connection(cli)) {
5744 printf("finished dirtest1\n");
5749 static bool run_error_map_extract(int dummy) {
5751 static struct cli_state *c_dos;
5752 static struct cli_state *c_nt;
5757 uint32 flgs2, errnum;
5764 /* NT-Error connection */
5766 if (!(c_nt = open_nbt_connection())) {
5770 c_nt->use_spnego = False;
5772 status = cli_negprot(c_nt);
5774 if (!NT_STATUS_IS_OK(status)) {
5775 printf("%s rejected the NT-error negprot (%s)\n", host,
5781 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5783 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5787 /* DOS-Error connection */
5789 if (!(c_dos = open_nbt_connection())) {
5793 c_dos->use_spnego = False;
5794 c_dos->force_dos_errors = True;
5796 status = cli_negprot(c_dos);
5797 if (!NT_STATUS_IS_OK(status)) {
5798 printf("%s rejected the DOS-error negprot (%s)\n", host,
5800 cli_shutdown(c_dos);
5804 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5806 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5810 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5811 fstr_sprintf(user, "%X", error);
5813 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5814 password, strlen(password),
5815 password, strlen(password),
5817 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5820 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5822 /* Case #1: 32-bit NT errors */
5823 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5824 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5826 printf("/** Dos error on NT connection! (%s) */\n",
5828 nt_status = NT_STATUS(0xc0000000);
5831 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5832 password, strlen(password),
5833 password, strlen(password),
5835 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5837 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5839 /* Case #1: 32-bit NT errors */
5840 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5841 printf("/** NT error on DOS connection! (%s) */\n",
5843 errnum = errclass = 0;
5845 cli_dos_error(c_dos, &errclass, &errnum);
5848 if (NT_STATUS_V(nt_status) != error) {
5849 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5850 get_nt_error_c_code(NT_STATUS(error)),
5851 get_nt_error_c_code(nt_status));
5854 printf("\t{%s,\t%s,\t%s},\n",
5855 smb_dos_err_class(errclass),
5856 smb_dos_err_name(errclass, errnum),
5857 get_nt_error_c_code(NT_STATUS(error)));
5862 static bool run_sesssetup_bench(int dummy)
5864 static struct cli_state *c;
5865 const char *fname = "\\file.dat";
5870 if (!torture_open_connection(&c, 0)) {
5874 if (!NT_STATUS_IS_OK(cli_ntcreate(
5875 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5876 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5877 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5878 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5882 for (i=0; i<torture_numops; i++) {
5883 status = cli_session_setup(
5885 password, strlen(password),
5886 password, strlen(password),
5888 if (!NT_STATUS_IS_OK(status)) {
5889 d_printf("(%s) cli_session_setup failed: %s\n",
5890 __location__, nt_errstr(status));
5894 d_printf("\r%d ", (int)c->vuid);
5896 status = cli_ulogoff(c);
5897 if (!NT_STATUS_IS_OK(status)) {
5898 d_printf("(%s) cli_ulogoff failed: %s\n",
5899 __location__, nt_errstr(status));
5908 static bool subst_test(const char *str, const char *user, const char *domain,
5909 uid_t uid, gid_t gid, const char *expected)
5914 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5916 if (strcmp(subst, expected) != 0) {
5917 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5918 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5927 static void chain1_open_completion(struct tevent_req *req)
5931 status = cli_open_recv(req, &fnum);
5934 d_printf("cli_open_recv returned %s: %d\n",
5936 NT_STATUS_IS_OK(status) ? fnum : -1);
5939 static void chain1_write_completion(struct tevent_req *req)
5943 status = cli_write_andx_recv(req, &written);
5946 d_printf("cli_write_andx_recv returned %s: %d\n",
5948 NT_STATUS_IS_OK(status) ? (int)written : -1);
5951 static void chain1_close_completion(struct tevent_req *req)
5954 bool *done = (bool *)tevent_req_callback_data_void(req);
5956 status = cli_close_recv(req);
5961 d_printf("cli_close returned %s\n", nt_errstr(status));
5964 static bool run_chain1(int dummy)
5966 struct cli_state *cli1;
5967 struct event_context *evt = event_context_init(NULL);
5968 struct tevent_req *reqs[3], *smbreqs[3];
5970 const char *str = "foobar";
5973 printf("starting chain1 test\n");
5974 if (!torture_open_connection(&cli1, 0)) {
5978 cli_sockopt(cli1, sockops);
5980 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5981 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5982 if (reqs[0] == NULL) return false;
5983 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5986 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5987 (uint8_t *)str, 0, strlen(str)+1,
5988 smbreqs, 1, &smbreqs[1]);
5989 if (reqs[1] == NULL) return false;
5990 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5992 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5993 if (reqs[2] == NULL) return false;
5994 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5996 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5997 if (!NT_STATUS_IS_OK(status)) {
6002 event_loop_once(evt);
6005 torture_close_connection(cli1);
6009 static void chain2_sesssetup_completion(struct tevent_req *req)
6012 status = cli_session_setup_guest_recv(req);
6013 d_printf("sesssetup returned %s\n", nt_errstr(status));
6016 static void chain2_tcon_completion(struct tevent_req *req)
6018 bool *done = (bool *)tevent_req_callback_data_void(req);
6020 status = cli_tcon_andx_recv(req);
6021 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6025 static bool run_chain2(int dummy)
6027 struct cli_state *cli1;
6028 struct event_context *evt = event_context_init(NULL);
6029 struct tevent_req *reqs[2], *smbreqs[2];
6033 printf("starting chain2 test\n");
6034 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6035 port_to_use, Undefined, 0);
6036 if (!NT_STATUS_IS_OK(status)) {
6040 cli_sockopt(cli1, sockops);
6042 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6044 if (reqs[0] == NULL) return false;
6045 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6047 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6048 "?????", NULL, 0, &smbreqs[1]);
6049 if (reqs[1] == NULL) return false;
6050 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6052 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6053 if (!NT_STATUS_IS_OK(status)) {
6058 event_loop_once(evt);
6061 torture_close_connection(cli1);
6066 struct torture_createdel_state {
6067 struct tevent_context *ev;
6068 struct cli_state *cli;
6071 static void torture_createdel_created(struct tevent_req *subreq);
6072 static void torture_createdel_closed(struct tevent_req *subreq);
6074 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6075 struct tevent_context *ev,
6076 struct cli_state *cli,
6079 struct tevent_req *req, *subreq;
6080 struct torture_createdel_state *state;
6082 req = tevent_req_create(mem_ctx, &state,
6083 struct torture_createdel_state);
6090 subreq = cli_ntcreate_send(
6091 state, ev, cli, name, 0,
6092 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6093 FILE_ATTRIBUTE_NORMAL,
6094 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6095 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6097 if (tevent_req_nomem(subreq, req)) {
6098 return tevent_req_post(req, ev);
6100 tevent_req_set_callback(subreq, torture_createdel_created, req);
6104 static void torture_createdel_created(struct tevent_req *subreq)
6106 struct tevent_req *req = tevent_req_callback_data(
6107 subreq, struct tevent_req);
6108 struct torture_createdel_state *state = tevent_req_data(
6109 req, struct torture_createdel_state);
6113 status = cli_ntcreate_recv(subreq, &fnum);
6114 TALLOC_FREE(subreq);
6115 if (!NT_STATUS_IS_OK(status)) {
6116 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6117 nt_errstr(status)));
6118 tevent_req_nterror(req, status);
6122 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6123 if (tevent_req_nomem(subreq, req)) {
6126 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6129 static void torture_createdel_closed(struct tevent_req *subreq)
6131 struct tevent_req *req = tevent_req_callback_data(
6132 subreq, struct tevent_req);
6135 status = cli_close_recv(subreq);
6136 if (!NT_STATUS_IS_OK(status)) {
6137 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6138 tevent_req_nterror(req, status);
6141 tevent_req_done(req);
6144 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6146 return tevent_req_simple_recv_ntstatus(req);
6149 struct torture_createdels_state {
6150 struct tevent_context *ev;
6151 struct cli_state *cli;
6152 const char *base_name;
6156 struct tevent_req **reqs;
6159 static void torture_createdels_done(struct tevent_req *subreq);
6161 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6162 struct tevent_context *ev,
6163 struct cli_state *cli,
6164 const char *base_name,
6168 struct tevent_req *req;
6169 struct torture_createdels_state *state;
6172 req = tevent_req_create(mem_ctx, &state,
6173 struct torture_createdels_state);
6179 state->base_name = talloc_strdup(state, base_name);
6180 if (tevent_req_nomem(state->base_name, req)) {
6181 return tevent_req_post(req, ev);
6183 state->num_files = MAX(num_parallel, num_files);
6185 state->received = 0;
6187 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6188 if (tevent_req_nomem(state->reqs, req)) {
6189 return tevent_req_post(req, ev);
6192 for (i=0; i<num_parallel; i++) {
6195 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6197 if (tevent_req_nomem(name, req)) {
6198 return tevent_req_post(req, ev);
6200 state->reqs[i] = torture_createdel_send(
6201 state->reqs, state->ev, state->cli, name);
6202 if (tevent_req_nomem(state->reqs[i], req)) {
6203 return tevent_req_post(req, ev);
6205 name = talloc_move(state->reqs[i], &name);
6206 tevent_req_set_callback(state->reqs[i],
6207 torture_createdels_done, req);
6213 static void torture_createdels_done(struct tevent_req *subreq)
6215 struct tevent_req *req = tevent_req_callback_data(
6216 subreq, struct tevent_req);
6217 struct torture_createdels_state *state = tevent_req_data(
6218 req, struct torture_createdels_state);
6219 size_t num_parallel = talloc_array_length(state->reqs);
6224 status = torture_createdel_recv(subreq);
6225 if (!NT_STATUS_IS_OK(status)){
6226 DEBUG(10, ("torture_createdel_recv returned %s\n",
6227 nt_errstr(status)));
6228 TALLOC_FREE(subreq);
6229 tevent_req_nterror(req, status);
6233 for (i=0; i<num_parallel; i++) {
6234 if (subreq == state->reqs[i]) {
6238 if (i == num_parallel) {
6239 DEBUG(10, ("received something we did not send\n"));
6240 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6243 TALLOC_FREE(state->reqs[i]);
6245 if (state->sent >= state->num_files) {
6246 tevent_req_done(req);
6250 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6252 if (tevent_req_nomem(name, req)) {
6255 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6257 if (tevent_req_nomem(state->reqs[i], req)) {
6260 name = talloc_move(state->reqs[i], &name);
6261 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6265 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6267 return tevent_req_simple_recv_ntstatus(req);
6270 struct swallow_notify_state {
6271 struct tevent_context *ev;
6272 struct cli_state *cli;
6274 uint32_t completion_filter;
6276 bool (*fn)(uint32_t action, const char *name, void *priv);
6280 static void swallow_notify_done(struct tevent_req *subreq);
6282 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6283 struct tevent_context *ev,
6284 struct cli_state *cli,
6286 uint32_t completion_filter,
6288 bool (*fn)(uint32_t action,
6293 struct tevent_req *req, *subreq;
6294 struct swallow_notify_state *state;
6296 req = tevent_req_create(mem_ctx, &state,
6297 struct swallow_notify_state);
6304 state->completion_filter = completion_filter;
6305 state->recursive = recursive;
6309 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6310 0xffff, state->completion_filter,
6312 if (tevent_req_nomem(subreq, req)) {
6313 return tevent_req_post(req, ev);
6315 tevent_req_set_callback(subreq, swallow_notify_done, req);
6319 static void swallow_notify_done(struct tevent_req *subreq)
6321 struct tevent_req *req = tevent_req_callback_data(
6322 subreq, struct tevent_req);
6323 struct swallow_notify_state *state = tevent_req_data(
6324 req, struct swallow_notify_state);
6326 uint32_t i, num_changes;
6327 struct notify_change *changes;
6329 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6330 TALLOC_FREE(subreq);
6331 if (!NT_STATUS_IS_OK(status)) {
6332 DEBUG(10, ("cli_notify_recv returned %s\n",
6333 nt_errstr(status)));
6334 tevent_req_nterror(req, status);
6338 for (i=0; i<num_changes; i++) {
6339 state->fn(changes[i].action, changes[i].name, state->priv);
6341 TALLOC_FREE(changes);
6343 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6344 0xffff, state->completion_filter,
6346 if (tevent_req_nomem(subreq, req)) {
6349 tevent_req_set_callback(subreq, swallow_notify_done, req);
6352 static bool print_notifies(uint32_t action, const char *name, void *priv)
6354 if (DEBUGLEVEL > 5) {
6355 d_printf("%d %s\n", (int)action, name);
6360 static void notify_bench_done(struct tevent_req *req)
6362 int *num_finished = (int *)tevent_req_callback_data_void(req);
6366 static bool run_notify_bench(int dummy)
6368 const char *dname = "\\notify-bench";
6369 struct tevent_context *ev;
6372 struct tevent_req *req1;
6373 struct tevent_req *req2 = NULL;
6374 int i, num_unc_names;
6375 int num_finished = 0;
6377 printf("starting notify-bench test\n");
6379 if (use_multishare_conn) {
6381 unc_list = file_lines_load(multishare_conn_fname,
6382 &num_unc_names, 0, NULL);
6383 if (!unc_list || num_unc_names <= 0) {
6384 d_printf("Failed to load unc names list from '%s'\n",
6385 multishare_conn_fname);
6388 TALLOC_FREE(unc_list);
6393 ev = tevent_context_init(talloc_tos());
6395 d_printf("tevent_context_init failed\n");
6399 for (i=0; i<num_unc_names; i++) {
6400 struct cli_state *cli;
6403 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6405 if (base_fname == NULL) {
6409 if (!torture_open_connection(&cli, i)) {
6413 status = cli_ntcreate(cli, dname, 0,
6414 MAXIMUM_ALLOWED_ACCESS,
6415 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6417 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6420 if (!NT_STATUS_IS_OK(status)) {
6421 d_printf("Could not create %s: %s\n", dname,
6426 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6427 FILE_NOTIFY_CHANGE_FILE_NAME |
6428 FILE_NOTIFY_CHANGE_DIR_NAME |
6429 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6430 FILE_NOTIFY_CHANGE_LAST_WRITE,
6431 false, print_notifies, NULL);
6433 d_printf("Could not create notify request\n");
6437 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6438 base_fname, 10, torture_numops);
6440 d_printf("Could not create createdels request\n");
6443 TALLOC_FREE(base_fname);
6445 tevent_req_set_callback(req2, notify_bench_done,
6449 while (num_finished < num_unc_names) {
6451 ret = tevent_loop_once(ev);
6453 d_printf("tevent_loop_once failed\n");
6458 if (!tevent_req_poll(req2, ev)) {
6459 d_printf("tevent_req_poll failed\n");
6462 status = torture_createdels_recv(req2);
6463 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6468 static bool run_mangle1(int dummy)
6470 struct cli_state *cli;
6471 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6475 time_t change_time, access_time, write_time;
6479 printf("starting mangle1 test\n");
6480 if (!torture_open_connection(&cli, 0)) {
6484 cli_sockopt(cli, sockops);
6486 if (!NT_STATUS_IS_OK(cli_ntcreate(
6487 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6488 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6489 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6492 cli_close(cli, fnum);
6494 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6495 if (!NT_STATUS_IS_OK(status)) {
6496 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6500 d_printf("alt_name: %s\n", alt_name);
6502 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6503 d_printf("cli_open(%s) failed: %s\n", alt_name,
6507 cli_close(cli, fnum);
6509 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6510 &write_time, &size, &mode);
6511 if (!NT_STATUS_IS_OK(status)) {
6512 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6520 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6522 size_t *to_pull = (size_t *)priv;
6523 size_t thistime = *to_pull;
6525 thistime = MIN(thistime, n);
6526 if (thistime == 0) {
6530 memset(buf, 0, thistime);
6531 *to_pull -= thistime;
6535 static bool run_windows_write(int dummy)
6537 struct cli_state *cli1;
6541 const char *fname = "\\writetest.txt";
6542 struct timeval start_time;
6546 printf("starting windows_write test\n");
6547 if (!torture_open_connection(&cli1, 0)) {
6551 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6552 printf("open failed (%s)\n", cli_errstr(cli1));
6556 cli_sockopt(cli1, sockops);
6558 start_time = timeval_current();
6560 for (i=0; i<torture_numops; i++) {
6562 off_t start = i * torture_blocksize;
6564 size_t to_pull = torture_blocksize - 1;
6566 status = cli_writeall(cli1, fnum, 0, &c,
6567 start + torture_blocksize - 1, 1, NULL);
6568 if (!NT_STATUS_IS_OK(status)) {
6569 printf("cli_write failed: %s\n", nt_errstr(status));
6573 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6574 null_source, &to_pull);
6575 if (!NT_STATUS_IS_OK(status)) {
6576 printf("cli_push returned: %s\n", nt_errstr(status));
6581 seconds = timeval_elapsed(&start_time);
6582 kbytes = (double)torture_blocksize * torture_numops;
6585 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6586 (double)seconds, (int)(kbytes/seconds));
6590 cli_close(cli1, fnum);
6591 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6592 torture_close_connection(cli1);
6596 static bool run_cli_echo(int dummy)
6598 struct cli_state *cli;
6601 printf("starting cli_echo test\n");
6602 if (!torture_open_connection(&cli, 0)) {
6605 cli_sockopt(cli, sockops);
6607 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6609 d_printf("cli_echo returned %s\n", nt_errstr(status));
6611 torture_close_connection(cli);
6612 return NT_STATUS_IS_OK(status);
6615 static bool run_uid_regression_test(int dummy)
6617 static struct cli_state *cli;
6620 bool correct = True;
6623 printf("starting uid regression test\n");
6625 if (!torture_open_connection(&cli, 0)) {
6629 cli_sockopt(cli, sockops);
6631 /* Ok - now save then logoff our current user. */
6632 old_vuid = cli->vuid;
6634 status = cli_ulogoff(cli);
6635 if (!NT_STATUS_IS_OK(status)) {
6636 d_printf("(%s) cli_ulogoff failed: %s\n",
6637 __location__, nt_errstr(status));
6642 cli->vuid = old_vuid;
6644 /* Try an operation. */
6645 status = cli_mkdir(cli, "\\uid_reg_test");
6646 if (NT_STATUS_IS_OK(status)) {
6647 d_printf("(%s) cli_mkdir succeeded\n",
6652 /* Should be bad uid. */
6653 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6654 NT_STATUS_USER_SESSION_DELETED)) {
6660 old_cnum = cli->cnum;
6662 /* Now try a SMBtdis with the invald vuid set to zero. */
6665 /* This should succeed. */
6666 status = cli_tdis(cli);
6668 if (NT_STATUS_IS_OK(status)) {
6669 d_printf("First tdis with invalid vuid should succeed.\n");
6671 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6676 cli->vuid = old_vuid;
6677 cli->cnum = old_cnum;
6679 /* This should fail. */
6680 status = cli_tdis(cli);
6681 if (NT_STATUS_IS_OK(status)) {
6682 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6686 /* Should be bad tid. */
6687 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6688 NT_STATUS_NETWORK_NAME_DELETED)) {
6694 cli_rmdir(cli, "\\uid_reg_test");
6703 static const char *illegal_chars = "*\\/?<>|\":";
6704 static char force_shortname_chars[] = " +,.[];=\177";
6706 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6707 const char *mask, void *state)
6709 struct cli_state *pcli = (struct cli_state *)state;
6711 NTSTATUS status = NT_STATUS_OK;
6713 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6715 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6716 return NT_STATUS_OK;
6718 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
6719 status = cli_rmdir(pcli, fname);
6720 if (!NT_STATUS_IS_OK(status)) {
6721 printf("del_fn: failed to rmdir %s\n,", fname );
6724 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6725 if (!NT_STATUS_IS_OK(status)) {
6726 printf("del_fn: failed to unlink %s\n,", fname );
6738 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6739 const char *name, void *state)
6741 struct sn_state *s = (struct sn_state *)state;
6745 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6746 i, finfo->name, finfo->short_name);
6749 if (strchr(force_shortname_chars, i)) {
6750 if (!finfo->short_name[0]) {
6751 /* Shortname not created when it should be. */
6752 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6753 __location__, finfo->name, i);
6756 } else if (finfo->short_name[0]){
6757 /* Shortname created when it should not be. */
6758 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6759 __location__, finfo->short_name, finfo->name);
6763 return NT_STATUS_OK;
6766 static bool run_shortname_test(int dummy)
6768 static struct cli_state *cli;
6769 bool correct = True;
6774 printf("starting shortname test\n");
6776 if (!torture_open_connection(&cli, 0)) {
6780 cli_sockopt(cli, sockops);
6782 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6783 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6784 cli_rmdir(cli, "\\shortname");
6786 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6787 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6788 __location__, cli_errstr(cli));
6793 strlcpy(fname, "\\shortname\\", sizeof(fname));
6794 strlcat(fname, "test .txt", sizeof(fname));
6798 for (i = 32; i < 128; i++) {
6800 uint16_t fnum = (uint16_t)-1;
6804 if (strchr(illegal_chars, i)) {
6809 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6810 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6811 if (!NT_STATUS_IS_OK(status)) {
6812 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6813 __location__, fname, cli_errstr(cli));
6817 cli_close(cli, fnum);
6820 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6822 if (s.matched != 1) {
6823 d_printf("(%s) failed to list %s: %s\n",
6824 __location__, fname, cli_errstr(cli));
6828 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
6829 d_printf("(%s) failed to delete %s: %s\n",
6830 __location__, fname, cli_errstr(cli));
6843 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6844 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6845 cli_rmdir(cli, "\\shortname");
6846 torture_close_connection(cli);
6850 static void pagedsearch_cb(struct tevent_req *req)
6853 struct tldap_message *msg;
6856 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6857 if (rc != TLDAP_SUCCESS) {
6858 d_printf("tldap_search_paged_recv failed: %s\n",
6859 tldap_err2string(rc));
6862 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6866 if (!tldap_entry_dn(msg, &dn)) {
6867 d_printf("tldap_entry_dn failed\n");
6870 d_printf("%s\n", dn);
6874 static bool run_tldap(int dummy)
6876 struct tldap_context *ld;
6879 struct sockaddr_storage addr;
6880 struct tevent_context *ev;
6881 struct tevent_req *req;
6885 if (!resolve_name(host, &addr, 0, false)) {
6886 d_printf("could not find host %s\n", host);
6889 status = open_socket_out(&addr, 389, 9999, &fd);
6890 if (!NT_STATUS_IS_OK(status)) {
6891 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6895 ld = tldap_context_create(talloc_tos(), fd);
6898 d_printf("tldap_context_create failed\n");
6902 rc = tldap_fetch_rootdse(ld);
6903 if (rc != TLDAP_SUCCESS) {
6904 d_printf("tldap_fetch_rootdse failed: %s\n",
6905 tldap_errstr(talloc_tos(), ld, rc));
6909 basedn = tldap_talloc_single_attribute(
6910 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6911 if (basedn == NULL) {
6912 d_printf("no defaultNamingContext\n");
6915 d_printf("defaultNamingContext: %s\n", basedn);
6917 ev = tevent_context_init(talloc_tos());
6919 d_printf("tevent_context_init failed\n");
6923 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6924 TLDAP_SCOPE_SUB, "(objectclass=*)",
6926 NULL, 0, NULL, 0, 0, 0, 0, 5);
6928 d_printf("tldap_search_paged_send failed\n");
6931 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6933 tevent_req_poll(req, ev);
6937 /* test search filters against rootDSE */
6938 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6939 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6941 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6942 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6943 talloc_tos(), NULL, NULL);
6944 if (rc != TLDAP_SUCCESS) {
6945 d_printf("tldap_search with complex filter failed: %s\n",
6946 tldap_errstr(talloc_tos(), ld, rc));
6954 /* Torture test to ensure no regression of :
6955 https://bugzilla.samba.org/show_bug.cgi?id=7084
6958 static bool run_dir_createtime(int dummy)
6960 struct cli_state *cli;
6961 const char *dname = "\\testdir";
6962 const char *fname = "\\testdir\\testfile";
6964 struct timespec create_time;
6965 struct timespec create_time1;
6969 if (!torture_open_connection(&cli, 0)) {
6973 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6974 cli_rmdir(cli, dname);
6976 status = cli_mkdir(cli, dname);
6977 if (!NT_STATUS_IS_OK(status)) {
6978 printf("mkdir failed: %s\n", nt_errstr(status));
6982 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6984 if (!NT_STATUS_IS_OK(status)) {
6985 printf("cli_qpathinfo2 returned %s\n",
6990 /* Sleep 3 seconds, then create a file. */
6993 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6995 if (!NT_STATUS_IS_OK(status)) {
6996 printf("cli_open failed: %s\n", nt_errstr(status));
7000 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7002 if (!NT_STATUS_IS_OK(status)) {
7003 printf("cli_qpathinfo2 (2) returned %s\n",
7008 if (timespec_compare(&create_time1, &create_time)) {
7009 printf("run_dir_createtime: create time was updated (error)\n");
7011 printf("run_dir_createtime: create time was not updated (correct)\n");
7017 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7018 cli_rmdir(cli, dname);
7019 if (!torture_close_connection(cli)) {
7026 static bool run_streamerror(int dummy)
7028 struct cli_state *cli;
7029 const char *dname = "\\testdir";
7030 const char *streamname =
7031 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7033 time_t change_time, access_time, write_time;
7035 uint16_t mode, fnum;
7038 if (!torture_open_connection(&cli, 0)) {
7042 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7043 cli_rmdir(cli, dname);
7045 status = cli_mkdir(cli, dname);
7046 if (!NT_STATUS_IS_OK(status)) {
7047 printf("mkdir failed: %s\n", nt_errstr(status));
7051 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7053 status = cli_nt_error(cli);
7055 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7056 printf("pathinfo returned %s, expected "
7057 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7062 status = cli_ntcreate(cli, streamname, 0x16,
7063 FILE_READ_DATA|FILE_READ_EA|
7064 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7065 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7066 FILE_OPEN, 0, 0, &fnum);
7068 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7069 printf("ntcreate returned %s, expected "
7070 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7076 cli_rmdir(cli, dname);
7080 static bool run_local_substitute(int dummy)
7084 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7085 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7086 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7087 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7088 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7089 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7090 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7091 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7093 /* Different captialization rules in sub_basic... */
7095 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7101 static bool run_local_base64(int dummy)
7106 for (i=1; i<2000; i++) {
7107 DATA_BLOB blob1, blob2;
7110 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7112 generate_random_buffer(blob1.data, blob1.length);
7114 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7116 d_fprintf(stderr, "base64_encode_data_blob failed "
7117 "for %d bytes\n", i);
7120 blob2 = base64_decode_data_blob(b64);
7123 if (data_blob_cmp(&blob1, &blob2)) {
7124 d_fprintf(stderr, "data_blob_cmp failed for %d "
7128 TALLOC_FREE(blob1.data);
7129 data_blob_free(&blob2);
7134 static bool run_local_gencache(int dummy)
7140 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7141 d_printf("%s: gencache_set() failed\n", __location__);
7145 if (!gencache_get("foo", NULL, NULL)) {
7146 d_printf("%s: gencache_get() failed\n", __location__);
7150 if (!gencache_get("foo", &val, &tm)) {
7151 d_printf("%s: gencache_get() failed\n", __location__);
7155 if (strcmp(val, "bar") != 0) {
7156 d_printf("%s: gencache_get() returned %s, expected %s\n",
7157 __location__, val, "bar");
7164 if (!gencache_del("foo")) {
7165 d_printf("%s: gencache_del() failed\n", __location__);
7168 if (gencache_del("foo")) {
7169 d_printf("%s: second gencache_del() succeeded\n",
7174 if (gencache_get("foo", &val, &tm)) {
7175 d_printf("%s: gencache_get() on deleted entry "
7176 "succeeded\n", __location__);
7180 blob = data_blob_string_const_null("bar");
7181 tm = time(NULL) + 60;
7183 if (!gencache_set_data_blob("foo", &blob, tm)) {
7184 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7188 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7189 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7193 if (strcmp((const char *)blob.data, "bar") != 0) {
7194 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7195 __location__, (const char *)blob.data, "bar");
7196 data_blob_free(&blob);
7200 data_blob_free(&blob);
7202 if (!gencache_del("foo")) {
7203 d_printf("%s: gencache_del() failed\n", __location__);
7206 if (gencache_del("foo")) {
7207 d_printf("%s: second gencache_del() succeeded\n",
7212 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7213 d_printf("%s: gencache_get_data_blob() on deleted entry "
7214 "succeeded\n", __location__);
7221 static bool rbt_testval(struct db_context *db, const char *key,
7224 struct db_record *rec;
7225 TDB_DATA data = string_tdb_data(value);
7229 rec = db->fetch_locked(db, db, string_tdb_data(key));
7231 d_fprintf(stderr, "fetch_locked failed\n");
7234 status = rec->store(rec, data, 0);
7235 if (!NT_STATUS_IS_OK(status)) {
7236 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7241 rec = db->fetch_locked(db, db, string_tdb_data(key));
7243 d_fprintf(stderr, "second fetch_locked failed\n");
7246 if ((rec->value.dsize != data.dsize)
7247 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7248 d_fprintf(stderr, "Got wrong data back\n");
7258 static bool run_local_rbtree(int dummy)
7260 struct db_context *db;
7264 db = db_open_rbt(NULL);
7267 d_fprintf(stderr, "db_open_rbt failed\n");
7271 for (i=0; i<1000; i++) {
7274 if (asprintf(&key, "key%ld", random()) == -1) {
7277 if (asprintf(&value, "value%ld", random()) == -1) {
7282 if (!rbt_testval(db, key, value)) {
7289 if (asprintf(&value, "value%ld", random()) == -1) {
7294 if (!rbt_testval(db, key, value)) {
7313 local test for character set functions
7315 This is a very simple test for the functionality in convert_string_error()
7317 static bool run_local_convert_string(int dummy)
7319 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7320 const char *test_strings[2] = { "March", "M\303\244rz" };
7324 for (i=0; i<2; i++) {
7325 const char *str = test_strings[i];
7326 int len = strlen(str);
7327 size_t converted_size;
7330 memset(dst, 'X', sizeof(dst));
7332 /* first try with real source length */
7333 ret = convert_string_error(CH_UNIX, CH_UTF8,
7338 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7342 if (converted_size != len) {
7343 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7344 str, len, (int)converted_size);
7348 if (strncmp(str, dst, converted_size) != 0) {
7349 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7353 if (strlen(str) != converted_size) {
7354 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7355 (int)strlen(str), (int)converted_size);
7359 if (dst[converted_size] != 'X') {
7360 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7364 /* now with srclen==-1, this causes the nul to be
7366 ret = convert_string_error(CH_UNIX, CH_UTF8,
7371 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7375 if (converted_size != len+1) {
7376 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7377 str, len, (int)converted_size);
7381 if (strncmp(str, dst, converted_size) != 0) {
7382 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7386 if (len+1 != converted_size) {
7387 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7388 len+1, (int)converted_size);
7392 if (dst[converted_size] != 'X') {
7393 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7400 TALLOC_FREE(tmp_ctx);
7403 TALLOC_FREE(tmp_ctx);
7408 struct talloc_dict_test {
7412 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7414 int *count = (int *)priv;
7419 static bool run_local_talloc_dict(int dummy)
7421 struct talloc_dict *dict;
7422 struct talloc_dict_test *t;
7425 dict = talloc_dict_init(talloc_tos());
7430 t = talloc(talloc_tos(), struct talloc_dict_test);
7437 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7442 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7455 static bool run_local_string_to_sid(int dummy) {
7458 if (string_to_sid(&sid, "S--1-5-32-545")) {
7459 printf("allowing S--1-5-32-545\n");
7462 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7463 printf("allowing S-1-5-32-+545\n");
7466 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")) {
7467 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7470 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7471 printf("allowing S-1-5-32-545-abc\n");
7474 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7475 printf("could not parse S-1-5-32-545\n");
7478 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7479 printf("mis-parsed S-1-5-32-545 as %s\n",
7480 sid_string_tos(&sid));
7486 static bool run_local_binary_to_sid(int dummy) {
7487 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7488 static const char good_binary_sid[] = {
7489 0x1, /* revision number */
7491 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7492 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7493 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7494 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7495 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7496 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7497 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7498 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7499 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7500 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7501 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7502 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7503 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7504 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7505 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7506 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7509 static const char long_binary_sid[] = {
7510 0x1, /* revision number */
7512 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7513 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7514 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7515 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7516 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7517 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7518 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7519 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7520 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7521 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7522 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7523 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7524 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7525 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7526 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7527 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7528 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7529 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7530 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7533 static const char long_binary_sid2[] = {
7534 0x1, /* revision number */
7536 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7537 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7538 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7539 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7540 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7541 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7542 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7543 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7544 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7545 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7546 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7547 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7548 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7549 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7550 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7551 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7552 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7553 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7554 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7555 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7556 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7557 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7558 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7559 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7560 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7561 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7562 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7563 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7564 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7565 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7566 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7567 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7568 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7571 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7574 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7577 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7583 /* Split a path name into filename and stream name components. Canonicalise
7584 * such that an implicit $DATA token is always explicit.
7586 * The "specification" of this function can be found in the
7587 * run_local_stream_name() function in torture.c, I've tried those
7588 * combinations against a W2k3 server.
7591 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7592 char **pbase, char **pstream)
7595 char *stream = NULL;
7596 char *sname; /* stream name */
7597 const char *stype; /* stream type */
7599 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7601 sname = strchr_m(fname, ':');
7603 if (lp_posix_pathnames() || (sname == NULL)) {
7604 if (pbase != NULL) {
7605 base = talloc_strdup(mem_ctx, fname);
7606 NT_STATUS_HAVE_NO_MEMORY(base);
7611 if (pbase != NULL) {
7612 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7613 NT_STATUS_HAVE_NO_MEMORY(base);
7618 stype = strchr_m(sname, ':');
7620 if (stype == NULL) {
7621 sname = talloc_strdup(mem_ctx, sname);
7625 if (StrCaseCmp(stype, ":$DATA") != 0) {
7627 * If there is an explicit stream type, so far we only
7628 * allow $DATA. Is there anything else allowed? -- vl
7630 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7632 return NT_STATUS_OBJECT_NAME_INVALID;
7634 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7638 if (sname == NULL) {
7640 return NT_STATUS_NO_MEMORY;
7643 if (sname[0] == '\0') {
7645 * no stream name, so no stream
7650 if (pstream != NULL) {
7651 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7652 if (stream == NULL) {
7655 return NT_STATUS_NO_MEMORY;
7658 * upper-case the type field
7660 strupper_m(strchr_m(stream, ':')+1);
7664 if (pbase != NULL) {
7667 if (pstream != NULL) {
7670 return NT_STATUS_OK;
7673 static bool test_stream_name(const char *fname, const char *expected_base,
7674 const char *expected_stream,
7675 NTSTATUS expected_status)
7679 char *stream = NULL;
7681 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7682 if (!NT_STATUS_EQUAL(status, expected_status)) {
7686 if (!NT_STATUS_IS_OK(status)) {
7690 if (base == NULL) goto error;
7692 if (strcmp(expected_base, base) != 0) goto error;
7694 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7695 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7697 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7701 TALLOC_FREE(stream);
7705 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7706 fname, expected_base ? expected_base : "<NULL>",
7707 expected_stream ? expected_stream : "<NULL>",
7708 nt_errstr(expected_status));
7709 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7710 base ? base : "<NULL>", stream ? stream : "<NULL>",
7713 TALLOC_FREE(stream);
7717 static bool run_local_stream_name(int dummy)
7721 ret &= test_stream_name(
7722 "bla", "bla", NULL, NT_STATUS_OK);
7723 ret &= test_stream_name(
7724 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7725 ret &= test_stream_name(
7726 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7727 ret &= test_stream_name(
7728 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7729 ret &= test_stream_name(
7730 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7731 ret &= test_stream_name(
7732 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7733 ret &= test_stream_name(
7734 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7735 ret &= test_stream_name(
7736 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7741 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7743 if (a.length != b.length) {
7744 printf("a.length=%d != b.length=%d\n",
7745 (int)a.length, (int)b.length);
7748 if (memcmp(a.data, b.data, a.length) != 0) {
7749 printf("a.data and b.data differ\n");
7755 static bool run_local_memcache(int dummy)
7757 struct memcache *cache;
7759 DATA_BLOB d1, d2, d3;
7760 DATA_BLOB v1, v2, v3;
7762 TALLOC_CTX *mem_ctx;
7764 size_t size1, size2;
7767 cache = memcache_init(NULL, 100);
7769 if (cache == NULL) {
7770 printf("memcache_init failed\n");
7774 d1 = data_blob_const("d1", 2);
7775 d2 = data_blob_const("d2", 2);
7776 d3 = data_blob_const("d3", 2);
7778 k1 = data_blob_const("d1", 2);
7779 k2 = data_blob_const("d2", 2);
7781 memcache_add(cache, STAT_CACHE, k1, d1);
7782 memcache_add(cache, GETWD_CACHE, k2, d2);
7784 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7785 printf("could not find k1\n");
7788 if (!data_blob_equal(d1, v1)) {
7792 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7793 printf("could not find k2\n");
7796 if (!data_blob_equal(d2, v2)) {
7800 memcache_add(cache, STAT_CACHE, k1, d3);
7802 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7803 printf("could not find replaced k1\n");
7806 if (!data_blob_equal(d3, v3)) {
7810 memcache_add(cache, GETWD_CACHE, k1, d1);
7812 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7813 printf("Did find k2, should have been purged\n");
7819 cache = memcache_init(NULL, 0);
7821 mem_ctx = talloc_init("foo");
7823 str1 = talloc_strdup(mem_ctx, "string1");
7824 str2 = talloc_strdup(mem_ctx, "string2");
7826 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7827 data_blob_string_const("torture"), &str1);
7828 size1 = talloc_total_size(cache);
7830 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7831 data_blob_string_const("torture"), &str2);
7832 size2 = talloc_total_size(cache);
7834 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7836 if (size2 > size1) {
7837 printf("memcache leaks memory!\n");
7847 static void wbclient_done(struct tevent_req *req)
7850 struct winbindd_response *wb_resp;
7851 int *i = (int *)tevent_req_callback_data_void(req);
7853 wbc_err = wb_trans_recv(req, req, &wb_resp);
7856 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7859 static bool run_local_wbclient(int dummy)
7861 struct event_context *ev;
7862 struct wb_context **wb_ctx;
7863 struct winbindd_request wb_req;
7864 bool result = false;
7867 BlockSignals(True, SIGPIPE);
7869 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7874 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7875 if (wb_ctx == NULL) {
7879 ZERO_STRUCT(wb_req);
7880 wb_req.cmd = WINBINDD_PING;
7882 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7884 for (i=0; i<nprocs; i++) {
7885 wb_ctx[i] = wb_context_init(ev, NULL);
7886 if (wb_ctx[i] == NULL) {
7889 for (j=0; j<torture_numops; j++) {
7890 struct tevent_req *req;
7891 req = wb_trans_send(ev, ev, wb_ctx[i],
7892 (j % 2) == 0, &wb_req);
7896 tevent_req_set_callback(req, wbclient_done, &i);
7902 while (i < nprocs * torture_numops) {
7903 event_loop_once(ev);
7912 static void getaddrinfo_finished(struct tevent_req *req)
7914 char *name = (char *)tevent_req_callback_data_void(req);
7915 struct addrinfo *ainfo;
7918 res = getaddrinfo_recv(req, &ainfo);
7920 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7923 d_printf("gai(%s) succeeded\n", name);
7924 freeaddrinfo(ainfo);
7927 static bool run_getaddrinfo_send(int dummy)
7929 TALLOC_CTX *frame = talloc_stackframe();
7930 struct fncall_context *ctx;
7931 struct tevent_context *ev;
7932 bool result = false;
7933 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7934 "www.slashdot.org", "heise.de" };
7935 struct tevent_req *reqs[4];
7938 ev = event_context_init(frame);
7943 ctx = fncall_context_init(frame, 4);
7945 for (i=0; i<ARRAY_SIZE(names); i++) {
7946 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7948 if (reqs[i] == NULL) {
7951 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7955 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7956 tevent_loop_once(ev);
7965 static bool dbtrans_inc(struct db_context *db)
7967 struct db_record *rec;
7972 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7974 printf(__location__ "fetch_lock failed\n");
7978 if (rec->value.dsize != sizeof(uint32_t)) {
7979 printf(__location__ "value.dsize = %d\n",
7980 (int)rec->value.dsize);
7984 val = (uint32_t *)rec->value.dptr;
7987 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7990 if (!NT_STATUS_IS_OK(status)) {
7991 printf(__location__ "store failed: %s\n",
8002 static bool run_local_dbtrans(int dummy)
8004 struct db_context *db;
8005 struct db_record *rec;
8010 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8011 O_RDWR|O_CREAT, 0600);
8013 printf("Could not open transtest.db\n");
8017 res = db->transaction_start(db);
8019 printf(__location__ "transaction_start failed\n");
8023 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8025 printf(__location__ "fetch_lock failed\n");
8029 if (rec->value.dptr == NULL) {
8031 status = rec->store(
8032 rec, make_tdb_data((uint8_t *)&initial,
8035 if (!NT_STATUS_IS_OK(status)) {
8036 printf(__location__ "store returned %s\n",
8044 res = db->transaction_commit(db);
8046 printf(__location__ "transaction_commit failed\n");
8054 res = db->transaction_start(db);
8056 printf(__location__ "transaction_start failed\n");
8060 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8061 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8065 for (i=0; i<10; i++) {
8066 if (!dbtrans_inc(db)) {
8071 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8072 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8076 if (val2 != val + 10) {
8077 printf(__location__ "val=%d, val2=%d\n",
8078 (int)val, (int)val2);
8082 printf("val2=%d\r", val2);
8084 res = db->transaction_commit(db);
8086 printf(__location__ "transaction_commit failed\n");
8096 * Just a dummy test to be run under a debugger. There's no real way
8097 * to inspect the tevent_select specific function from outside of
8101 static bool run_local_tevent_select(int dummy)
8103 struct tevent_context *ev;
8104 struct tevent_fd *fd1, *fd2;
8105 bool result = false;
8107 ev = tevent_context_init_byname(NULL, "select");
8109 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8113 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8115 d_fprintf(stderr, "tevent_add_fd failed\n");
8118 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8120 d_fprintf(stderr, "tevent_add_fd failed\n");
8125 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8127 d_fprintf(stderr, "tevent_add_fd failed\n");
8137 static double create_procs(bool (*fn)(int), bool *result)
8140 volatile pid_t *child_status;
8141 volatile bool *child_status_out;
8144 struct timeval start;
8148 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8149 if (!child_status) {
8150 printf("Failed to setup shared memory\n");
8154 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8155 if (!child_status_out) {
8156 printf("Failed to setup result status shared memory\n");
8160 for (i = 0; i < nprocs; i++) {
8161 child_status[i] = 0;
8162 child_status_out[i] = True;
8165 start = timeval_current();
8167 for (i=0;i<nprocs;i++) {
8170 pid_t mypid = getpid();
8171 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8173 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8176 if (torture_open_connection(¤t_cli, i)) break;
8178 printf("pid %d failed to start\n", (int)getpid());
8184 child_status[i] = getpid();
8186 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8188 child_status_out[i] = fn(i);
8195 for (i=0;i<nprocs;i++) {
8196 if (child_status[i]) synccount++;
8198 if (synccount == nprocs) break;
8200 } while (timeval_elapsed(&start) < 30);
8202 if (synccount != nprocs) {
8203 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8205 return timeval_elapsed(&start);
8208 /* start the client load */
8209 start = timeval_current();
8211 for (i=0;i<nprocs;i++) {
8212 child_status[i] = 0;
8215 printf("%d clients started\n", nprocs);
8217 for (i=0;i<nprocs;i++) {
8218 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8223 for (i=0;i<nprocs;i++) {
8224 if (!child_status_out[i]) {
8228 return timeval_elapsed(&start);
8231 #define FLAG_MULTIPROC 1
8238 {"FDPASS", run_fdpasstest, 0},
8239 {"LOCK1", run_locktest1, 0},
8240 {"LOCK2", run_locktest2, 0},
8241 {"LOCK3", run_locktest3, 0},
8242 {"LOCK4", run_locktest4, 0},
8243 {"LOCK5", run_locktest5, 0},
8244 {"LOCK6", run_locktest6, 0},
8245 {"LOCK7", run_locktest7, 0},
8246 {"LOCK8", run_locktest8, 0},
8247 {"LOCK9", run_locktest9, 0},
8248 {"UNLINK", run_unlinktest, 0},
8249 {"BROWSE", run_browsetest, 0},
8250 {"ATTR", run_attrtest, 0},
8251 {"TRANS2", run_trans2test, 0},
8252 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8253 {"TORTURE",run_torture, FLAG_MULTIPROC},
8254 {"RANDOMIPC", run_randomipc, 0},
8255 {"NEGNOWAIT", run_negprot_nowait, 0},
8256 {"NBENCH", run_nbench, 0},
8257 {"NBENCH2", run_nbench2, 0},
8258 {"OPLOCK1", run_oplock1, 0},
8259 {"OPLOCK2", run_oplock2, 0},
8260 {"OPLOCK3", run_oplock3, 0},
8261 {"OPLOCK4", run_oplock4, 0},
8262 {"DIR", run_dirtest, 0},
8263 {"DIR1", run_dirtest1, 0},
8264 {"DIR-CREATETIME", run_dir_createtime, 0},
8265 {"DENY1", torture_denytest1, 0},
8266 {"DENY2", torture_denytest2, 0},
8267 {"TCON", run_tcon_test, 0},
8268 {"TCONDEV", run_tcon_devtype_test, 0},
8269 {"RW1", run_readwritetest, 0},
8270 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8271 {"RW3", run_readwritelarge, 0},
8272 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8273 {"OPEN", run_opentest, 0},
8274 {"POSIX", run_simple_posix_open_test, 0},
8275 {"POSIX-APPEND", run_posix_append, 0},
8276 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8277 {"ASYNC-ECHO", run_async_echo, 0},
8278 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8279 { "SHORTNAME-TEST", run_shortname_test, 0},
8280 { "ADDRCHANGE", run_addrchange, 0},
8282 {"OPENATTR", run_openattrtest, 0},
8284 {"XCOPY", run_xcopy, 0},
8285 {"RENAME", run_rename, 0},
8286 {"DELETE", run_deletetest, 0},
8287 {"DELETE-LN", run_deletetest_ln, 0},
8288 {"PROPERTIES", run_properties, 0},
8289 {"MANGLE", torture_mangle, 0},
8290 {"MANGLE1", run_mangle1, 0},
8291 {"W2K", run_w2ktest, 0},
8292 {"TRANS2SCAN", torture_trans2_scan, 0},
8293 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8294 {"UTABLE", torture_utable, 0},
8295 {"CASETABLE", torture_casetable, 0},
8296 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8297 {"PIPE_NUMBER", run_pipe_number, 0},
8298 {"TCON2", run_tcon2_test, 0},
8299 {"IOCTL", torture_ioctl_test, 0},
8300 {"CHKPATH", torture_chkpath_test, 0},
8301 {"FDSESS", run_fdsesstest, 0},
8302 { "EATEST", run_eatest, 0},
8303 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8304 { "CHAIN1", run_chain1, 0},
8305 { "CHAIN2", run_chain2, 0},
8306 { "WINDOWS-WRITE", run_windows_write, 0},
8307 { "CLI_ECHO", run_cli_echo, 0},
8308 { "GETADDRINFO", run_getaddrinfo_send, 0},
8309 { "TLDAP", run_tldap },
8310 { "STREAMERROR", run_streamerror },
8311 { "NOTIFY-BENCH", run_notify_bench },
8312 { "BAD-NBT-SESSION", run_bad_nbt_session },
8313 { "SMB-ANY-CONNECT", run_smb_any_connect },
8314 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8315 { "LOCAL-GENCACHE", run_local_gencache, 0},
8316 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8317 { "LOCAL-BASE64", run_local_base64, 0},
8318 { "LOCAL-RBTREE", run_local_rbtree, 0},
8319 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8320 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8321 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8322 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8323 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8324 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8325 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8326 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8331 /****************************************************************************
8332 run a specified test or "ALL"
8333 ****************************************************************************/
8334 static bool run_test(const char *name)
8341 if (strequal(name,"ALL")) {
8342 for (i=0;torture_ops[i].name;i++) {
8343 run_test(torture_ops[i].name);
8348 for (i=0;torture_ops[i].name;i++) {
8349 fstr_sprintf(randomfname, "\\XX%x",
8350 (unsigned)random());
8352 if (strequal(name, torture_ops[i].name)) {
8354 printf("Running %s\n", name);
8355 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8356 t = create_procs(torture_ops[i].fn, &result);
8359 printf("TEST %s FAILED!\n", name);
8362 struct timeval start;
8363 start = timeval_current();
8364 if (!torture_ops[i].fn(0)) {
8366 printf("TEST %s FAILED!\n", name);
8368 t = timeval_elapsed(&start);
8370 printf("%s took %g secs\n\n", name, t);
8375 printf("Did not find a test named %s\n", name);
8383 static void usage(void)
8387 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8388 printf("Please use samba4 torture.\n\n");
8390 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8392 printf("\t-d debuglevel\n");
8393 printf("\t-U user%%pass\n");
8394 printf("\t-k use kerberos\n");
8395 printf("\t-N numprocs\n");
8396 printf("\t-n my_netbios_name\n");
8397 printf("\t-W workgroup\n");
8398 printf("\t-o num_operations\n");
8399 printf("\t-O socket_options\n");
8400 printf("\t-m maximum protocol\n");
8401 printf("\t-L use oplocks\n");
8402 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8403 printf("\t-A showall\n");
8404 printf("\t-p port\n");
8405 printf("\t-s seed\n");
8406 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8409 printf("tests are:");
8410 for (i=0;torture_ops[i].name;i++) {
8411 printf(" %s", torture_ops[i].name);
8415 printf("default test is ALL\n");
8420 /****************************************************************************
8422 ****************************************************************************/
8423 int main(int argc,char *argv[])
8429 bool correct = True;
8430 TALLOC_CTX *frame = talloc_stackframe();
8431 int seed = time(NULL);
8433 #ifdef HAVE_SETBUFFER
8434 setbuffer(stdout, NULL, 0);
8437 setup_logging("smbtorture", DEBUG_STDOUT);
8441 if (is_default_dyn_CONFIGFILE()) {
8442 if(getenv("SMB_CONF_PATH")) {
8443 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8446 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8453 for(p = argv[1]; *p; p++)
8457 if (strncmp(argv[1], "//", 2)) {
8461 fstrcpy(host, &argv[1][2]);
8462 p = strchr_m(&host[2],'/');
8467 fstrcpy(share, p+1);
8469 fstrcpy(myname, get_myname(talloc_tos()));
8471 fprintf(stderr, "Failed to get my hostname.\n");
8475 if (*username == 0 && getenv("LOGNAME")) {
8476 fstrcpy(username,getenv("LOGNAME"));
8482 fstrcpy(workgroup, lp_workgroup());
8484 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8487 port_to_use = atoi(optarg);
8490 seed = atoi(optarg);
8493 fstrcpy(workgroup,optarg);
8496 max_protocol = interpret_protocol(optarg, max_protocol);
8499 nprocs = atoi(optarg);
8502 torture_numops = atoi(optarg);
8505 lp_set_cmdline("log level", optarg);
8514 local_path = optarg;
8517 torture_showall = True;
8520 fstrcpy(myname, optarg);
8523 client_txt = optarg;
8530 use_kerberos = True;
8532 d_printf("No kerberos support compiled in\n");
8538 fstrcpy(username,optarg);
8539 p = strchr_m(username,'%');
8542 fstrcpy(password, p+1);
8547 fstrcpy(multishare_conn_fname, optarg);
8548 use_multishare_conn = True;
8551 torture_blocksize = atoi(optarg);
8554 printf("Unknown option %c (%d)\n", (char)opt, opt);
8559 d_printf("using seed %d\n", seed);
8563 if(use_kerberos && !gotuser) gotpass = True;
8566 p = getpass("Password:");
8568 fstrcpy(password, p);
8573 printf("host=%s share=%s user=%s myname=%s\n",
8574 host, share, username, myname);
8576 if (argc == optind) {
8577 correct = run_test("ALL");
8579 for (i=optind;i<argc;i++) {
8580 if (!run_test(argv[i])) {