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 /* Create again to test open with O_TRUNC. */
5022 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5023 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5027 /* Test ftruncate - set file size. */
5028 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5029 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5033 /* Ensure st_size == 1000 */
5034 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5035 printf("stat failed (%s)\n", cli_errstr(cli1));
5039 if (sbuf.st_ex_size != 1000) {
5040 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5044 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5045 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5049 /* Re-open with O_TRUNC. */
5050 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5051 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5055 /* Ensure st_size == 0 */
5056 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5057 printf("stat failed (%s)\n", cli_errstr(cli1));
5061 if (sbuf.st_ex_size != 0) {
5062 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5066 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5067 printf("close failed (%s)\n", cli_errstr(cli1));
5071 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5072 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5076 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5077 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5078 dname, cli_errstr(cli1));
5082 cli_close(cli1, fnum1);
5084 /* What happens when we try and POSIX open a directory for write ? */
5085 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5086 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5089 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5090 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5095 /* Create the file. */
5096 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5097 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5101 /* Write some data into it. */
5102 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
5104 if (!NT_STATUS_IS_OK(status)) {
5105 printf("cli_write failed: %s\n", nt_errstr(status));
5109 cli_close(cli1, fnum1);
5111 /* Now create a hardlink. */
5112 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5113 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5117 /* Now create a symlink. */
5118 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5119 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5123 /* Open the hardlink for read. */
5124 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5125 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5129 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5130 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5134 if (memcmp(buf, "TEST DATA\n", 10)) {
5135 printf("invalid data read from hardlink\n");
5139 /* Do a POSIX lock/unlock. */
5140 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5141 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5145 /* Punch a hole in the locked area. */
5146 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5147 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5151 cli_close(cli1, fnum1);
5153 /* Open the symlink for read - this should fail. A POSIX
5154 client should not be doing opens on a symlink. */
5155 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5156 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5159 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5160 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5161 printf("POSIX open of %s should have failed "
5162 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5163 "failed with %s instead.\n",
5164 sname, cli_errstr(cli1));
5169 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5170 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5174 if (strcmp(namebuf, fname) != 0) {
5175 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5176 sname, fname, namebuf);
5180 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5181 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5185 printf("Simple POSIX open test passed\n");
5190 if (fnum1 != (uint16_t)-1) {
5191 cli_close(cli1, fnum1);
5192 fnum1 = (uint16_t)-1;
5195 cli_setatr(cli1, sname, 0, 0);
5196 cli_posix_unlink(cli1, sname);
5197 cli_setatr(cli1, hname, 0, 0);
5198 cli_posix_unlink(cli1, hname);
5199 cli_setatr(cli1, fname, 0, 0);
5200 cli_posix_unlink(cli1, fname);
5201 cli_setatr(cli1, dname, 0, 0);
5202 cli_posix_rmdir(cli1, dname);
5204 if (!torture_close_connection(cli1)) {
5212 static uint32 open_attrs_table[] = {
5213 FILE_ATTRIBUTE_NORMAL,
5214 FILE_ATTRIBUTE_ARCHIVE,
5215 FILE_ATTRIBUTE_READONLY,
5216 FILE_ATTRIBUTE_HIDDEN,
5217 FILE_ATTRIBUTE_SYSTEM,
5219 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5220 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5221 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5222 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5223 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5224 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5226 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5227 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5228 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5229 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5232 struct trunc_open_results {
5239 static struct trunc_open_results attr_results[] = {
5240 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5241 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5242 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5243 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5244 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5245 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5246 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5247 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5248 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5249 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5250 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5251 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5252 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5253 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5254 { 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 },
5255 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5256 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5257 { 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 },
5258 { 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 },
5259 { 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 },
5260 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5261 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5262 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5263 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5264 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5265 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5268 static bool run_openattrtest(int dummy)
5270 static struct cli_state *cli1;
5271 const char *fname = "\\openattr.file";
5273 bool correct = True;
5275 unsigned int i, j, k, l;
5277 printf("starting open attr test\n");
5279 if (!torture_open_connection(&cli1, 0)) {
5283 cli_sockopt(cli1, sockops);
5285 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5286 cli_setatr(cli1, fname, 0, 0);
5287 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5288 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5289 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5290 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5294 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5295 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5299 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5300 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5301 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5302 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5303 if (attr_results[l].num == k) {
5304 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5305 k, open_attrs_table[i],
5306 open_attrs_table[j],
5307 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5311 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5312 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5313 k, open_attrs_table[i], open_attrs_table[j],
5318 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5324 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5325 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5329 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5330 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5335 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5336 k, open_attrs_table[i], open_attrs_table[j], attr );
5339 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5340 if (attr_results[l].num == k) {
5341 if (attr != attr_results[l].result_attr ||
5342 open_attrs_table[i] != attr_results[l].init_attr ||
5343 open_attrs_table[j] != attr_results[l].trunc_attr) {
5344 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5345 open_attrs_table[i],
5346 open_attrs_table[j],
5348 attr_results[l].result_attr);
5358 cli_setatr(cli1, fname, 0, 0);
5359 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5361 printf("open attr test %s.\n", correct ? "passed" : "failed");
5363 if (!torture_close_connection(cli1)) {
5369 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5370 const char *name, void *state)
5372 int *matched = (int *)state;
5373 if (matched != NULL) {
5376 return NT_STATUS_OK;
5380 test directory listing speed
5382 static bool run_dirtest(int dummy)
5385 static struct cli_state *cli;
5387 struct timeval core_start;
5388 bool correct = True;
5391 printf("starting directory test\n");
5393 if (!torture_open_connection(&cli, 0)) {
5397 cli_sockopt(cli, sockops);
5400 for (i=0;i<torture_numops;i++) {
5402 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5403 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5404 fprintf(stderr,"Failed to open %s\n", fname);
5407 cli_close(cli, fnum);
5410 core_start = timeval_current();
5413 cli_list(cli, "a*.*", 0, list_fn, &matched);
5414 printf("Matched %d\n", matched);
5417 cli_list(cli, "b*.*", 0, list_fn, &matched);
5418 printf("Matched %d\n", matched);
5421 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5422 printf("Matched %d\n", matched);
5424 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5427 for (i=0;i<torture_numops;i++) {
5429 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5430 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5433 if (!torture_close_connection(cli)) {
5437 printf("finished dirtest\n");
5442 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5445 struct cli_state *pcli = (struct cli_state *)state;
5447 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5449 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5450 return NT_STATUS_OK;
5452 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5453 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5454 printf("del_fn: failed to rmdir %s\n,", fname );
5456 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5457 printf("del_fn: failed to unlink %s\n,", fname );
5459 return NT_STATUS_OK;
5464 sees what IOCTLs are supported
5466 bool torture_ioctl_test(int dummy)
5468 static struct cli_state *cli;
5469 uint16_t device, function;
5471 const char *fname = "\\ioctl.dat";
5475 if (!torture_open_connection(&cli, 0)) {
5479 printf("starting ioctl test\n");
5481 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5483 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5484 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5488 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5489 printf("ioctl device info: %s\n", nt_errstr(status));
5491 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5492 printf("ioctl job info: %s\n", nt_errstr(status));
5494 for (device=0;device<0x100;device++) {
5495 printf("ioctl test with device = 0x%x\n", device);
5496 for (function=0;function<0x100;function++) {
5497 uint32 code = (device<<16) | function;
5499 status = cli_raw_ioctl(cli, fnum, code, &blob);
5501 if (NT_STATUS_IS_OK(status)) {
5502 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5504 data_blob_free(&blob);
5509 if (!torture_close_connection(cli)) {
5518 tries varients of chkpath
5520 bool torture_chkpath_test(int dummy)
5522 static struct cli_state *cli;
5526 if (!torture_open_connection(&cli, 0)) {
5530 printf("starting chkpath test\n");
5532 /* cleanup from an old run */
5533 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5534 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5535 cli_rmdir(cli, "\\chkpath.dir");
5537 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5538 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5542 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5543 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5547 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5548 printf("open1 failed (%s)\n", cli_errstr(cli));
5551 cli_close(cli, fnum);
5553 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5554 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5558 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5559 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5563 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5564 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5565 NT_STATUS_NOT_A_DIRECTORY);
5567 printf("* chkpath on a file should fail\n");
5571 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5572 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5573 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5575 printf("* chkpath on a non existant file should fail\n");
5579 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5580 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5581 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5583 printf("* chkpath on a non existent component should fail\n");
5587 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5588 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5589 cli_rmdir(cli, "\\chkpath.dir");
5591 if (!torture_close_connection(cli)) {
5598 static bool run_eatest(int dummy)
5600 static struct cli_state *cli;
5601 const char *fname = "\\eatest.txt";
5602 bool correct = True;
5606 struct ea_struct *ea_list = NULL;
5607 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5610 printf("starting eatest\n");
5612 if (!torture_open_connection(&cli, 0)) {
5613 talloc_destroy(mem_ctx);
5617 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5618 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5619 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5620 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5621 0x4044, 0, &fnum))) {
5622 printf("open failed - %s\n", cli_errstr(cli));
5623 talloc_destroy(mem_ctx);
5627 for (i = 0; i < 10; i++) {
5628 fstring ea_name, ea_val;
5630 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5631 memset(ea_val, (char)i+1, i+1);
5632 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5633 if (!NT_STATUS_IS_OK(status)) {
5634 printf("ea_set of name %s failed - %s\n", ea_name,
5636 talloc_destroy(mem_ctx);
5641 cli_close(cli, fnum);
5642 for (i = 0; i < 10; i++) {
5643 fstring ea_name, ea_val;
5645 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5646 memset(ea_val, (char)i+1, i+1);
5647 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5648 if (!NT_STATUS_IS_OK(status)) {
5649 printf("ea_set of name %s failed - %s\n", ea_name,
5651 talloc_destroy(mem_ctx);
5656 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5657 if (!NT_STATUS_IS_OK(status)) {
5658 printf("ea_get list failed - %s\n", nt_errstr(status));
5662 printf("num_eas = %d\n", (int)num_eas);
5664 if (num_eas != 20) {
5665 printf("Should be 20 EA's stored... failing.\n");
5669 for (i = 0; i < num_eas; i++) {
5670 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5671 dump_data(0, ea_list[i].value.data,
5672 ea_list[i].value.length);
5675 /* Setting EA's to zero length deletes them. Test this */
5676 printf("Now deleting all EA's - case indepenent....\n");
5679 cli_set_ea_path(cli, fname, "", "", 0);
5681 for (i = 0; i < 20; i++) {
5683 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5684 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5685 if (!NT_STATUS_IS_OK(status)) {
5686 printf("ea_set of name %s failed - %s\n", ea_name,
5688 talloc_destroy(mem_ctx);
5694 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5695 if (!NT_STATUS_IS_OK(status)) {
5696 printf("ea_get list failed - %s\n", nt_errstr(status));
5700 printf("num_eas = %d\n", (int)num_eas);
5701 for (i = 0; i < num_eas; i++) {
5702 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5703 dump_data(0, ea_list[i].value.data,
5704 ea_list[i].value.length);
5708 printf("deleting EA's failed.\n");
5712 /* Try and delete a non existant EA. */
5713 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5714 if (!NT_STATUS_IS_OK(status)) {
5715 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5720 talloc_destroy(mem_ctx);
5721 if (!torture_close_connection(cli)) {
5728 static bool run_dirtest1(int dummy)
5731 static struct cli_state *cli;
5734 bool correct = True;
5736 printf("starting directory test\n");
5738 if (!torture_open_connection(&cli, 0)) {
5742 cli_sockopt(cli, sockops);
5744 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5745 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5746 cli_rmdir(cli, "\\LISTDIR");
5747 cli_mkdir(cli, "\\LISTDIR");
5749 /* Create 1000 files and 1000 directories. */
5750 for (i=0;i<1000;i++) {
5752 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5753 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5754 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5755 fprintf(stderr,"Failed to open %s\n", fname);
5758 cli_close(cli, fnum);
5760 for (i=0;i<1000;i++) {
5762 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5763 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5764 fprintf(stderr,"Failed to open %s\n", fname);
5769 /* Now ensure that doing an old list sees both files and directories. */
5771 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5772 printf("num_seen = %d\n", num_seen );
5773 /* We should see 100 files + 1000 directories + . and .. */
5774 if (num_seen != 2002)
5777 /* Ensure if we have the "must have" bits we only see the
5781 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5782 printf("num_seen = %d\n", num_seen );
5783 if (num_seen != 1002)
5787 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5788 printf("num_seen = %d\n", num_seen );
5789 if (num_seen != 1000)
5792 /* Delete everything. */
5793 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5794 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5795 cli_rmdir(cli, "\\LISTDIR");
5798 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5799 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5800 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5803 if (!torture_close_connection(cli)) {
5807 printf("finished dirtest1\n");
5812 static bool run_error_map_extract(int dummy) {
5814 static struct cli_state *c_dos;
5815 static struct cli_state *c_nt;
5820 uint32 flgs2, errnum;
5827 /* NT-Error connection */
5829 if (!(c_nt = open_nbt_connection())) {
5833 c_nt->use_spnego = False;
5835 status = cli_negprot(c_nt);
5837 if (!NT_STATUS_IS_OK(status)) {
5838 printf("%s rejected the NT-error negprot (%s)\n", host,
5844 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5846 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5850 /* DOS-Error connection */
5852 if (!(c_dos = open_nbt_connection())) {
5856 c_dos->use_spnego = False;
5857 c_dos->force_dos_errors = True;
5859 status = cli_negprot(c_dos);
5860 if (!NT_STATUS_IS_OK(status)) {
5861 printf("%s rejected the DOS-error negprot (%s)\n", host,
5863 cli_shutdown(c_dos);
5867 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5869 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5873 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5874 fstr_sprintf(user, "%X", error);
5876 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5877 password, strlen(password),
5878 password, strlen(password),
5880 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5883 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5885 /* Case #1: 32-bit NT errors */
5886 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5887 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5889 printf("/** Dos error on NT connection! (%s) */\n",
5891 nt_status = NT_STATUS(0xc0000000);
5894 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5895 password, strlen(password),
5896 password, strlen(password),
5898 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5900 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5902 /* Case #1: 32-bit NT errors */
5903 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5904 printf("/** NT error on DOS connection! (%s) */\n",
5906 errnum = errclass = 0;
5908 cli_dos_error(c_dos, &errclass, &errnum);
5911 if (NT_STATUS_V(nt_status) != error) {
5912 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5913 get_nt_error_c_code(NT_STATUS(error)),
5914 get_nt_error_c_code(nt_status));
5917 printf("\t{%s,\t%s,\t%s},\n",
5918 smb_dos_err_class(errclass),
5919 smb_dos_err_name(errclass, errnum),
5920 get_nt_error_c_code(NT_STATUS(error)));
5925 static bool run_sesssetup_bench(int dummy)
5927 static struct cli_state *c;
5928 const char *fname = "\\file.dat";
5933 if (!torture_open_connection(&c, 0)) {
5937 if (!NT_STATUS_IS_OK(cli_ntcreate(
5938 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5939 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5940 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5941 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5945 for (i=0; i<torture_numops; i++) {
5946 status = cli_session_setup(
5948 password, strlen(password),
5949 password, strlen(password),
5951 if (!NT_STATUS_IS_OK(status)) {
5952 d_printf("(%s) cli_session_setup failed: %s\n",
5953 __location__, nt_errstr(status));
5957 d_printf("\r%d ", (int)c->vuid);
5959 status = cli_ulogoff(c);
5960 if (!NT_STATUS_IS_OK(status)) {
5961 d_printf("(%s) cli_ulogoff failed: %s\n",
5962 __location__, nt_errstr(status));
5971 static bool subst_test(const char *str, const char *user, const char *domain,
5972 uid_t uid, gid_t gid, const char *expected)
5977 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5979 if (strcmp(subst, expected) != 0) {
5980 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5981 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5990 static void chain1_open_completion(struct tevent_req *req)
5994 status = cli_open_recv(req, &fnum);
5997 d_printf("cli_open_recv returned %s: %d\n",
5999 NT_STATUS_IS_OK(status) ? fnum : -1);
6002 static void chain1_write_completion(struct tevent_req *req)
6006 status = cli_write_andx_recv(req, &written);
6009 d_printf("cli_write_andx_recv returned %s: %d\n",
6011 NT_STATUS_IS_OK(status) ? (int)written : -1);
6014 static void chain1_close_completion(struct tevent_req *req)
6017 bool *done = (bool *)tevent_req_callback_data_void(req);
6019 status = cli_close_recv(req);
6024 d_printf("cli_close returned %s\n", nt_errstr(status));
6027 static bool run_chain1(int dummy)
6029 struct cli_state *cli1;
6030 struct event_context *evt = event_context_init(NULL);
6031 struct tevent_req *reqs[3], *smbreqs[3];
6033 const char *str = "foobar";
6036 printf("starting chain1 test\n");
6037 if (!torture_open_connection(&cli1, 0)) {
6041 cli_sockopt(cli1, sockops);
6043 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6044 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6045 if (reqs[0] == NULL) return false;
6046 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6049 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6050 (uint8_t *)str, 0, strlen(str)+1,
6051 smbreqs, 1, &smbreqs[1]);
6052 if (reqs[1] == NULL) return false;
6053 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6055 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6056 if (reqs[2] == NULL) return false;
6057 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6059 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6060 if (!NT_STATUS_IS_OK(status)) {
6065 event_loop_once(evt);
6068 torture_close_connection(cli1);
6072 static void chain2_sesssetup_completion(struct tevent_req *req)
6075 status = cli_session_setup_guest_recv(req);
6076 d_printf("sesssetup returned %s\n", nt_errstr(status));
6079 static void chain2_tcon_completion(struct tevent_req *req)
6081 bool *done = (bool *)tevent_req_callback_data_void(req);
6083 status = cli_tcon_andx_recv(req);
6084 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6088 static bool run_chain2(int dummy)
6090 struct cli_state *cli1;
6091 struct event_context *evt = event_context_init(NULL);
6092 struct tevent_req *reqs[2], *smbreqs[2];
6096 printf("starting chain2 test\n");
6097 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6098 port_to_use, Undefined, 0);
6099 if (!NT_STATUS_IS_OK(status)) {
6103 cli_sockopt(cli1, sockops);
6105 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6107 if (reqs[0] == NULL) return false;
6108 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6110 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6111 "?????", NULL, 0, &smbreqs[1]);
6112 if (reqs[1] == NULL) return false;
6113 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6115 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6116 if (!NT_STATUS_IS_OK(status)) {
6121 event_loop_once(evt);
6124 torture_close_connection(cli1);
6129 struct torture_createdel_state {
6130 struct tevent_context *ev;
6131 struct cli_state *cli;
6134 static void torture_createdel_created(struct tevent_req *subreq);
6135 static void torture_createdel_closed(struct tevent_req *subreq);
6137 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6138 struct tevent_context *ev,
6139 struct cli_state *cli,
6142 struct tevent_req *req, *subreq;
6143 struct torture_createdel_state *state;
6145 req = tevent_req_create(mem_ctx, &state,
6146 struct torture_createdel_state);
6153 subreq = cli_ntcreate_send(
6154 state, ev, cli, name, 0,
6155 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6156 FILE_ATTRIBUTE_NORMAL,
6157 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6158 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6160 if (tevent_req_nomem(subreq, req)) {
6161 return tevent_req_post(req, ev);
6163 tevent_req_set_callback(subreq, torture_createdel_created, req);
6167 static void torture_createdel_created(struct tevent_req *subreq)
6169 struct tevent_req *req = tevent_req_callback_data(
6170 subreq, struct tevent_req);
6171 struct torture_createdel_state *state = tevent_req_data(
6172 req, struct torture_createdel_state);
6176 status = cli_ntcreate_recv(subreq, &fnum);
6177 TALLOC_FREE(subreq);
6178 if (!NT_STATUS_IS_OK(status)) {
6179 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6180 nt_errstr(status)));
6181 tevent_req_nterror(req, status);
6185 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6186 if (tevent_req_nomem(subreq, req)) {
6189 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6192 static void torture_createdel_closed(struct tevent_req *subreq)
6194 struct tevent_req *req = tevent_req_callback_data(
6195 subreq, struct tevent_req);
6198 status = cli_close_recv(subreq);
6199 if (!NT_STATUS_IS_OK(status)) {
6200 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6201 tevent_req_nterror(req, status);
6204 tevent_req_done(req);
6207 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6209 return tevent_req_simple_recv_ntstatus(req);
6212 struct torture_createdels_state {
6213 struct tevent_context *ev;
6214 struct cli_state *cli;
6215 const char *base_name;
6219 struct tevent_req **reqs;
6222 static void torture_createdels_done(struct tevent_req *subreq);
6224 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6225 struct tevent_context *ev,
6226 struct cli_state *cli,
6227 const char *base_name,
6231 struct tevent_req *req;
6232 struct torture_createdels_state *state;
6235 req = tevent_req_create(mem_ctx, &state,
6236 struct torture_createdels_state);
6242 state->base_name = talloc_strdup(state, base_name);
6243 if (tevent_req_nomem(state->base_name, req)) {
6244 return tevent_req_post(req, ev);
6246 state->num_files = MAX(num_parallel, num_files);
6248 state->received = 0;
6250 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6251 if (tevent_req_nomem(state->reqs, req)) {
6252 return tevent_req_post(req, ev);
6255 for (i=0; i<num_parallel; i++) {
6258 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6260 if (tevent_req_nomem(name, req)) {
6261 return tevent_req_post(req, ev);
6263 state->reqs[i] = torture_createdel_send(
6264 state->reqs, state->ev, state->cli, name);
6265 if (tevent_req_nomem(state->reqs[i], req)) {
6266 return tevent_req_post(req, ev);
6268 name = talloc_move(state->reqs[i], &name);
6269 tevent_req_set_callback(state->reqs[i],
6270 torture_createdels_done, req);
6276 static void torture_createdels_done(struct tevent_req *subreq)
6278 struct tevent_req *req = tevent_req_callback_data(
6279 subreq, struct tevent_req);
6280 struct torture_createdels_state *state = tevent_req_data(
6281 req, struct torture_createdels_state);
6282 size_t num_parallel = talloc_array_length(state->reqs);
6287 status = torture_createdel_recv(subreq);
6288 if (!NT_STATUS_IS_OK(status)){
6289 DEBUG(10, ("torture_createdel_recv returned %s\n",
6290 nt_errstr(status)));
6291 TALLOC_FREE(subreq);
6292 tevent_req_nterror(req, status);
6296 for (i=0; i<num_parallel; i++) {
6297 if (subreq == state->reqs[i]) {
6301 if (i == num_parallel) {
6302 DEBUG(10, ("received something we did not send\n"));
6303 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6306 TALLOC_FREE(state->reqs[i]);
6308 if (state->sent >= state->num_files) {
6309 tevent_req_done(req);
6313 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6315 if (tevent_req_nomem(name, req)) {
6318 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6320 if (tevent_req_nomem(state->reqs[i], req)) {
6323 name = talloc_move(state->reqs[i], &name);
6324 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6328 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6330 return tevent_req_simple_recv_ntstatus(req);
6333 struct swallow_notify_state {
6334 struct tevent_context *ev;
6335 struct cli_state *cli;
6337 uint32_t completion_filter;
6339 bool (*fn)(uint32_t action, const char *name, void *priv);
6343 static void swallow_notify_done(struct tevent_req *subreq);
6345 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6346 struct tevent_context *ev,
6347 struct cli_state *cli,
6349 uint32_t completion_filter,
6351 bool (*fn)(uint32_t action,
6356 struct tevent_req *req, *subreq;
6357 struct swallow_notify_state *state;
6359 req = tevent_req_create(mem_ctx, &state,
6360 struct swallow_notify_state);
6367 state->completion_filter = completion_filter;
6368 state->recursive = recursive;
6372 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6373 0xffff, state->completion_filter,
6375 if (tevent_req_nomem(subreq, req)) {
6376 return tevent_req_post(req, ev);
6378 tevent_req_set_callback(subreq, swallow_notify_done, req);
6382 static void swallow_notify_done(struct tevent_req *subreq)
6384 struct tevent_req *req = tevent_req_callback_data(
6385 subreq, struct tevent_req);
6386 struct swallow_notify_state *state = tevent_req_data(
6387 req, struct swallow_notify_state);
6389 uint32_t i, num_changes;
6390 struct notify_change *changes;
6392 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6393 TALLOC_FREE(subreq);
6394 if (!NT_STATUS_IS_OK(status)) {
6395 DEBUG(10, ("cli_notify_recv returned %s\n",
6396 nt_errstr(status)));
6397 tevent_req_nterror(req, status);
6401 for (i=0; i<num_changes; i++) {
6402 state->fn(changes[i].action, changes[i].name, state->priv);
6404 TALLOC_FREE(changes);
6406 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6407 0xffff, state->completion_filter,
6409 if (tevent_req_nomem(subreq, req)) {
6412 tevent_req_set_callback(subreq, swallow_notify_done, req);
6415 static bool print_notifies(uint32_t action, const char *name, void *priv)
6417 if (DEBUGLEVEL > 5) {
6418 d_printf("%d %s\n", (int)action, name);
6423 static void notify_bench_done(struct tevent_req *req)
6425 int *num_finished = (int *)tevent_req_callback_data_void(req);
6429 static bool run_notify_bench(int dummy)
6431 const char *dname = "\\notify-bench";
6432 struct tevent_context *ev;
6435 struct tevent_req *req1;
6436 struct tevent_req *req2 = NULL;
6437 int i, num_unc_names;
6438 int num_finished = 0;
6440 printf("starting notify-bench test\n");
6442 if (use_multishare_conn) {
6444 unc_list = file_lines_load(multishare_conn_fname,
6445 &num_unc_names, 0, NULL);
6446 if (!unc_list || num_unc_names <= 0) {
6447 d_printf("Failed to load unc names list from '%s'\n",
6448 multishare_conn_fname);
6451 TALLOC_FREE(unc_list);
6456 ev = tevent_context_init(talloc_tos());
6458 d_printf("tevent_context_init failed\n");
6462 for (i=0; i<num_unc_names; i++) {
6463 struct cli_state *cli;
6466 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6468 if (base_fname == NULL) {
6472 if (!torture_open_connection(&cli, i)) {
6476 status = cli_ntcreate(cli, dname, 0,
6477 MAXIMUM_ALLOWED_ACCESS,
6478 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6480 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6483 if (!NT_STATUS_IS_OK(status)) {
6484 d_printf("Could not create %s: %s\n", dname,
6489 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6490 FILE_NOTIFY_CHANGE_FILE_NAME |
6491 FILE_NOTIFY_CHANGE_DIR_NAME |
6492 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6493 FILE_NOTIFY_CHANGE_LAST_WRITE,
6494 false, print_notifies, NULL);
6496 d_printf("Could not create notify request\n");
6500 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6501 base_fname, 10, torture_numops);
6503 d_printf("Could not create createdels request\n");
6506 TALLOC_FREE(base_fname);
6508 tevent_req_set_callback(req2, notify_bench_done,
6512 while (num_finished < num_unc_names) {
6514 ret = tevent_loop_once(ev);
6516 d_printf("tevent_loop_once failed\n");
6521 if (!tevent_req_poll(req2, ev)) {
6522 d_printf("tevent_req_poll failed\n");
6525 status = torture_createdels_recv(req2);
6526 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6531 static bool run_mangle1(int dummy)
6533 struct cli_state *cli;
6534 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6538 time_t change_time, access_time, write_time;
6542 printf("starting mangle1 test\n");
6543 if (!torture_open_connection(&cli, 0)) {
6547 cli_sockopt(cli, sockops);
6549 if (!NT_STATUS_IS_OK(cli_ntcreate(
6550 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6551 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6552 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6555 cli_close(cli, fnum);
6557 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6558 if (!NT_STATUS_IS_OK(status)) {
6559 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6563 d_printf("alt_name: %s\n", alt_name);
6565 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6566 d_printf("cli_open(%s) failed: %s\n", alt_name,
6570 cli_close(cli, fnum);
6572 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6573 &write_time, &size, &mode);
6574 if (!NT_STATUS_IS_OK(status)) {
6575 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6583 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6585 size_t *to_pull = (size_t *)priv;
6586 size_t thistime = *to_pull;
6588 thistime = MIN(thistime, n);
6589 if (thistime == 0) {
6593 memset(buf, 0, thistime);
6594 *to_pull -= thistime;
6598 static bool run_windows_write(int dummy)
6600 struct cli_state *cli1;
6604 const char *fname = "\\writetest.txt";
6605 struct timeval start_time;
6609 printf("starting windows_write test\n");
6610 if (!torture_open_connection(&cli1, 0)) {
6614 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6615 printf("open failed (%s)\n", cli_errstr(cli1));
6619 cli_sockopt(cli1, sockops);
6621 start_time = timeval_current();
6623 for (i=0; i<torture_numops; i++) {
6625 off_t start = i * torture_blocksize;
6627 size_t to_pull = torture_blocksize - 1;
6629 status = cli_writeall(cli1, fnum, 0, &c,
6630 start + torture_blocksize - 1, 1, NULL);
6631 if (!NT_STATUS_IS_OK(status)) {
6632 printf("cli_write failed: %s\n", nt_errstr(status));
6636 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6637 null_source, &to_pull);
6638 if (!NT_STATUS_IS_OK(status)) {
6639 printf("cli_push returned: %s\n", nt_errstr(status));
6644 seconds = timeval_elapsed(&start_time);
6645 kbytes = (double)torture_blocksize * torture_numops;
6648 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6649 (double)seconds, (int)(kbytes/seconds));
6653 cli_close(cli1, fnum);
6654 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6655 torture_close_connection(cli1);
6659 static bool run_cli_echo(int dummy)
6661 struct cli_state *cli;
6664 printf("starting cli_echo test\n");
6665 if (!torture_open_connection(&cli, 0)) {
6668 cli_sockopt(cli, sockops);
6670 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6672 d_printf("cli_echo returned %s\n", nt_errstr(status));
6674 torture_close_connection(cli);
6675 return NT_STATUS_IS_OK(status);
6678 static bool run_uid_regression_test(int dummy)
6680 static struct cli_state *cli;
6683 bool correct = True;
6686 printf("starting uid regression test\n");
6688 if (!torture_open_connection(&cli, 0)) {
6692 cli_sockopt(cli, sockops);
6694 /* Ok - now save then logoff our current user. */
6695 old_vuid = cli->vuid;
6697 status = cli_ulogoff(cli);
6698 if (!NT_STATUS_IS_OK(status)) {
6699 d_printf("(%s) cli_ulogoff failed: %s\n",
6700 __location__, nt_errstr(status));
6705 cli->vuid = old_vuid;
6707 /* Try an operation. */
6708 status = cli_mkdir(cli, "\\uid_reg_test");
6709 if (NT_STATUS_IS_OK(status)) {
6710 d_printf("(%s) cli_mkdir succeeded\n",
6715 /* Should be bad uid. */
6716 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6717 NT_STATUS_USER_SESSION_DELETED)) {
6723 old_cnum = cli->cnum;
6725 /* Now try a SMBtdis with the invald vuid set to zero. */
6728 /* This should succeed. */
6729 status = cli_tdis(cli);
6731 if (NT_STATUS_IS_OK(status)) {
6732 d_printf("First tdis with invalid vuid should succeed.\n");
6734 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6739 cli->vuid = old_vuid;
6740 cli->cnum = old_cnum;
6742 /* This should fail. */
6743 status = cli_tdis(cli);
6744 if (NT_STATUS_IS_OK(status)) {
6745 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6749 /* Should be bad tid. */
6750 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6751 NT_STATUS_NETWORK_NAME_DELETED)) {
6757 cli_rmdir(cli, "\\uid_reg_test");
6766 static const char *illegal_chars = "*\\/?<>|\":";
6767 static char force_shortname_chars[] = " +,.[];=\177";
6769 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6770 const char *mask, void *state)
6772 struct cli_state *pcli = (struct cli_state *)state;
6774 NTSTATUS status = NT_STATUS_OK;
6776 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6778 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6779 return NT_STATUS_OK;
6781 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
6782 status = cli_rmdir(pcli, fname);
6783 if (!NT_STATUS_IS_OK(status)) {
6784 printf("del_fn: failed to rmdir %s\n,", fname );
6787 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6788 if (!NT_STATUS_IS_OK(status)) {
6789 printf("del_fn: failed to unlink %s\n,", fname );
6801 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6802 const char *name, void *state)
6804 struct sn_state *s = (struct sn_state *)state;
6808 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6809 i, finfo->name, finfo->short_name);
6812 if (strchr(force_shortname_chars, i)) {
6813 if (!finfo->short_name[0]) {
6814 /* Shortname not created when it should be. */
6815 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6816 __location__, finfo->name, i);
6819 } else if (finfo->short_name[0]){
6820 /* Shortname created when it should not be. */
6821 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6822 __location__, finfo->short_name, finfo->name);
6826 return NT_STATUS_OK;
6829 static bool run_shortname_test(int dummy)
6831 static struct cli_state *cli;
6832 bool correct = True;
6837 printf("starting shortname test\n");
6839 if (!torture_open_connection(&cli, 0)) {
6843 cli_sockopt(cli, sockops);
6845 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6846 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6847 cli_rmdir(cli, "\\shortname");
6849 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6850 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6851 __location__, cli_errstr(cli));
6856 strlcpy(fname, "\\shortname\\", sizeof(fname));
6857 strlcat(fname, "test .txt", sizeof(fname));
6861 for (i = 32; i < 128; i++) {
6863 uint16_t fnum = (uint16_t)-1;
6867 if (strchr(illegal_chars, i)) {
6872 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6873 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6874 if (!NT_STATUS_IS_OK(status)) {
6875 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6876 __location__, fname, cli_errstr(cli));
6880 cli_close(cli, fnum);
6883 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6885 if (s.matched != 1) {
6886 d_printf("(%s) failed to list %s: %s\n",
6887 __location__, fname, cli_errstr(cli));
6891 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
6892 d_printf("(%s) failed to delete %s: %s\n",
6893 __location__, fname, cli_errstr(cli));
6906 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6907 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6908 cli_rmdir(cli, "\\shortname");
6909 torture_close_connection(cli);
6913 static void pagedsearch_cb(struct tevent_req *req)
6916 struct tldap_message *msg;
6919 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6920 if (rc != TLDAP_SUCCESS) {
6921 d_printf("tldap_search_paged_recv failed: %s\n",
6922 tldap_err2string(rc));
6925 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6929 if (!tldap_entry_dn(msg, &dn)) {
6930 d_printf("tldap_entry_dn failed\n");
6933 d_printf("%s\n", dn);
6937 static bool run_tldap(int dummy)
6939 struct tldap_context *ld;
6942 struct sockaddr_storage addr;
6943 struct tevent_context *ev;
6944 struct tevent_req *req;
6948 if (!resolve_name(host, &addr, 0, false)) {
6949 d_printf("could not find host %s\n", host);
6952 status = open_socket_out(&addr, 389, 9999, &fd);
6953 if (!NT_STATUS_IS_OK(status)) {
6954 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6958 ld = tldap_context_create(talloc_tos(), fd);
6961 d_printf("tldap_context_create failed\n");
6965 rc = tldap_fetch_rootdse(ld);
6966 if (rc != TLDAP_SUCCESS) {
6967 d_printf("tldap_fetch_rootdse failed: %s\n",
6968 tldap_errstr(talloc_tos(), ld, rc));
6972 basedn = tldap_talloc_single_attribute(
6973 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6974 if (basedn == NULL) {
6975 d_printf("no defaultNamingContext\n");
6978 d_printf("defaultNamingContext: %s\n", basedn);
6980 ev = tevent_context_init(talloc_tos());
6982 d_printf("tevent_context_init failed\n");
6986 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6987 TLDAP_SCOPE_SUB, "(objectclass=*)",
6989 NULL, 0, NULL, 0, 0, 0, 0, 5);
6991 d_printf("tldap_search_paged_send failed\n");
6994 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6996 tevent_req_poll(req, ev);
7000 /* test search filters against rootDSE */
7001 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7002 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7004 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7005 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7006 talloc_tos(), NULL, NULL);
7007 if (rc != TLDAP_SUCCESS) {
7008 d_printf("tldap_search with complex filter failed: %s\n",
7009 tldap_errstr(talloc_tos(), ld, rc));
7017 /* Torture test to ensure no regression of :
7018 https://bugzilla.samba.org/show_bug.cgi?id=7084
7021 static bool run_dir_createtime(int dummy)
7023 struct cli_state *cli;
7024 const char *dname = "\\testdir";
7025 const char *fname = "\\testdir\\testfile";
7027 struct timespec create_time;
7028 struct timespec create_time1;
7032 if (!torture_open_connection(&cli, 0)) {
7036 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7037 cli_rmdir(cli, dname);
7039 status = cli_mkdir(cli, dname);
7040 if (!NT_STATUS_IS_OK(status)) {
7041 printf("mkdir failed: %s\n", nt_errstr(status));
7045 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7047 if (!NT_STATUS_IS_OK(status)) {
7048 printf("cli_qpathinfo2 returned %s\n",
7053 /* Sleep 3 seconds, then create a file. */
7056 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7058 if (!NT_STATUS_IS_OK(status)) {
7059 printf("cli_open failed: %s\n", nt_errstr(status));
7063 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7065 if (!NT_STATUS_IS_OK(status)) {
7066 printf("cli_qpathinfo2 (2) returned %s\n",
7071 if (timespec_compare(&create_time1, &create_time)) {
7072 printf("run_dir_createtime: create time was updated (error)\n");
7074 printf("run_dir_createtime: create time was not updated (correct)\n");
7080 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7081 cli_rmdir(cli, dname);
7082 if (!torture_close_connection(cli)) {
7089 static bool run_streamerror(int dummy)
7091 struct cli_state *cli;
7092 const char *dname = "\\testdir";
7093 const char *streamname =
7094 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7096 time_t change_time, access_time, write_time;
7098 uint16_t mode, fnum;
7101 if (!torture_open_connection(&cli, 0)) {
7105 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7106 cli_rmdir(cli, dname);
7108 status = cli_mkdir(cli, dname);
7109 if (!NT_STATUS_IS_OK(status)) {
7110 printf("mkdir failed: %s\n", nt_errstr(status));
7114 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7116 status = cli_nt_error(cli);
7118 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7119 printf("pathinfo returned %s, expected "
7120 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7125 status = cli_ntcreate(cli, streamname, 0x16,
7126 FILE_READ_DATA|FILE_READ_EA|
7127 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7128 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7129 FILE_OPEN, 0, 0, &fnum);
7131 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7132 printf("ntcreate returned %s, expected "
7133 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7139 cli_rmdir(cli, dname);
7143 static bool run_local_substitute(int dummy)
7147 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7148 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7149 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7150 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7151 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7152 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7153 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7154 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7156 /* Different captialization rules in sub_basic... */
7158 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7164 static bool run_local_base64(int dummy)
7169 for (i=1; i<2000; i++) {
7170 DATA_BLOB blob1, blob2;
7173 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7175 generate_random_buffer(blob1.data, blob1.length);
7177 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7179 d_fprintf(stderr, "base64_encode_data_blob failed "
7180 "for %d bytes\n", i);
7183 blob2 = base64_decode_data_blob(b64);
7186 if (data_blob_cmp(&blob1, &blob2)) {
7187 d_fprintf(stderr, "data_blob_cmp failed for %d "
7191 TALLOC_FREE(blob1.data);
7192 data_blob_free(&blob2);
7197 static bool run_local_gencache(int dummy)
7203 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7204 d_printf("%s: gencache_set() failed\n", __location__);
7208 if (!gencache_get("foo", NULL, NULL)) {
7209 d_printf("%s: gencache_get() failed\n", __location__);
7213 if (!gencache_get("foo", &val, &tm)) {
7214 d_printf("%s: gencache_get() failed\n", __location__);
7218 if (strcmp(val, "bar") != 0) {
7219 d_printf("%s: gencache_get() returned %s, expected %s\n",
7220 __location__, val, "bar");
7227 if (!gencache_del("foo")) {
7228 d_printf("%s: gencache_del() failed\n", __location__);
7231 if (gencache_del("foo")) {
7232 d_printf("%s: second gencache_del() succeeded\n",
7237 if (gencache_get("foo", &val, &tm)) {
7238 d_printf("%s: gencache_get() on deleted entry "
7239 "succeeded\n", __location__);
7243 blob = data_blob_string_const_null("bar");
7244 tm = time(NULL) + 60;
7246 if (!gencache_set_data_blob("foo", &blob, tm)) {
7247 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7251 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7252 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7256 if (strcmp((const char *)blob.data, "bar") != 0) {
7257 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7258 __location__, (const char *)blob.data, "bar");
7259 data_blob_free(&blob);
7263 data_blob_free(&blob);
7265 if (!gencache_del("foo")) {
7266 d_printf("%s: gencache_del() failed\n", __location__);
7269 if (gencache_del("foo")) {
7270 d_printf("%s: second gencache_del() succeeded\n",
7275 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7276 d_printf("%s: gencache_get_data_blob() on deleted entry "
7277 "succeeded\n", __location__);
7284 static bool rbt_testval(struct db_context *db, const char *key,
7287 struct db_record *rec;
7288 TDB_DATA data = string_tdb_data(value);
7292 rec = db->fetch_locked(db, db, string_tdb_data(key));
7294 d_fprintf(stderr, "fetch_locked failed\n");
7297 status = rec->store(rec, data, 0);
7298 if (!NT_STATUS_IS_OK(status)) {
7299 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7304 rec = db->fetch_locked(db, db, string_tdb_data(key));
7306 d_fprintf(stderr, "second fetch_locked failed\n");
7309 if ((rec->value.dsize != data.dsize)
7310 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7311 d_fprintf(stderr, "Got wrong data back\n");
7321 static bool run_local_rbtree(int dummy)
7323 struct db_context *db;
7327 db = db_open_rbt(NULL);
7330 d_fprintf(stderr, "db_open_rbt failed\n");
7334 for (i=0; i<1000; i++) {
7337 if (asprintf(&key, "key%ld", random()) == -1) {
7340 if (asprintf(&value, "value%ld", random()) == -1) {
7345 if (!rbt_testval(db, key, value)) {
7352 if (asprintf(&value, "value%ld", random()) == -1) {
7357 if (!rbt_testval(db, key, value)) {
7376 local test for character set functions
7378 This is a very simple test for the functionality in convert_string_error()
7380 static bool run_local_convert_string(int dummy)
7382 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7383 const char *test_strings[2] = { "March", "M\303\244rz" };
7387 for (i=0; i<2; i++) {
7388 const char *str = test_strings[i];
7389 int len = strlen(str);
7390 size_t converted_size;
7393 memset(dst, 'X', sizeof(dst));
7395 /* first try with real source length */
7396 ret = convert_string_error(CH_UNIX, CH_UTF8,
7401 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7405 if (converted_size != len) {
7406 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7407 str, len, (int)converted_size);
7411 if (strncmp(str, dst, converted_size) != 0) {
7412 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7416 if (strlen(str) != converted_size) {
7417 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7418 (int)strlen(str), (int)converted_size);
7422 if (dst[converted_size] != 'X') {
7423 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7427 /* now with srclen==-1, this causes the nul to be
7429 ret = convert_string_error(CH_UNIX, CH_UTF8,
7434 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7438 if (converted_size != len+1) {
7439 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7440 str, len, (int)converted_size);
7444 if (strncmp(str, dst, converted_size) != 0) {
7445 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7449 if (len+1 != converted_size) {
7450 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7451 len+1, (int)converted_size);
7455 if (dst[converted_size] != 'X') {
7456 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7463 TALLOC_FREE(tmp_ctx);
7466 TALLOC_FREE(tmp_ctx);
7471 struct talloc_dict_test {
7475 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7477 int *count = (int *)priv;
7482 static bool run_local_talloc_dict(int dummy)
7484 struct talloc_dict *dict;
7485 struct talloc_dict_test *t;
7488 dict = talloc_dict_init(talloc_tos());
7493 t = talloc(talloc_tos(), struct talloc_dict_test);
7500 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7505 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7518 static bool run_local_string_to_sid(int dummy) {
7521 if (string_to_sid(&sid, "S--1-5-32-545")) {
7522 printf("allowing S--1-5-32-545\n");
7525 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7526 printf("allowing S-1-5-32-+545\n");
7529 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")) {
7530 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7533 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7534 printf("allowing S-1-5-32-545-abc\n");
7537 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7538 printf("could not parse S-1-5-32-545\n");
7541 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7542 printf("mis-parsed S-1-5-32-545 as %s\n",
7543 sid_string_tos(&sid));
7549 static bool run_local_binary_to_sid(int dummy) {
7550 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7551 static const char good_binary_sid[] = {
7552 0x1, /* revision number */
7554 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7555 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7556 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7557 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7558 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7559 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7560 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7561 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7562 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7563 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7564 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7565 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7566 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7567 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7568 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7569 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7572 static const char long_binary_sid[] = {
7573 0x1, /* revision number */
7575 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7576 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7577 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7578 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7579 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7580 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7581 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7582 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7583 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7584 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7585 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7586 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7587 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7588 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7589 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7590 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7591 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7592 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7593 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7596 static const char long_binary_sid2[] = {
7597 0x1, /* revision number */
7599 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7600 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7601 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7602 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7603 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7604 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7605 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7606 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7607 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7608 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7609 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7610 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7611 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7612 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7613 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7614 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7615 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7616 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7617 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7618 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7619 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7620 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7621 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7622 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7623 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7624 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7625 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7626 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7627 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7628 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7629 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7630 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7631 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7634 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7637 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7640 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7646 /* Split a path name into filename and stream name components. Canonicalise
7647 * such that an implicit $DATA token is always explicit.
7649 * The "specification" of this function can be found in the
7650 * run_local_stream_name() function in torture.c, I've tried those
7651 * combinations against a W2k3 server.
7654 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7655 char **pbase, char **pstream)
7658 char *stream = NULL;
7659 char *sname; /* stream name */
7660 const char *stype; /* stream type */
7662 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7664 sname = strchr_m(fname, ':');
7666 if (lp_posix_pathnames() || (sname == NULL)) {
7667 if (pbase != NULL) {
7668 base = talloc_strdup(mem_ctx, fname);
7669 NT_STATUS_HAVE_NO_MEMORY(base);
7674 if (pbase != NULL) {
7675 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7676 NT_STATUS_HAVE_NO_MEMORY(base);
7681 stype = strchr_m(sname, ':');
7683 if (stype == NULL) {
7684 sname = talloc_strdup(mem_ctx, sname);
7688 if (StrCaseCmp(stype, ":$DATA") != 0) {
7690 * If there is an explicit stream type, so far we only
7691 * allow $DATA. Is there anything else allowed? -- vl
7693 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7695 return NT_STATUS_OBJECT_NAME_INVALID;
7697 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7701 if (sname == NULL) {
7703 return NT_STATUS_NO_MEMORY;
7706 if (sname[0] == '\0') {
7708 * no stream name, so no stream
7713 if (pstream != NULL) {
7714 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7715 if (stream == NULL) {
7718 return NT_STATUS_NO_MEMORY;
7721 * upper-case the type field
7723 strupper_m(strchr_m(stream, ':')+1);
7727 if (pbase != NULL) {
7730 if (pstream != NULL) {
7733 return NT_STATUS_OK;
7736 static bool test_stream_name(const char *fname, const char *expected_base,
7737 const char *expected_stream,
7738 NTSTATUS expected_status)
7742 char *stream = NULL;
7744 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7745 if (!NT_STATUS_EQUAL(status, expected_status)) {
7749 if (!NT_STATUS_IS_OK(status)) {
7753 if (base == NULL) goto error;
7755 if (strcmp(expected_base, base) != 0) goto error;
7757 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7758 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7760 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7764 TALLOC_FREE(stream);
7768 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7769 fname, expected_base ? expected_base : "<NULL>",
7770 expected_stream ? expected_stream : "<NULL>",
7771 nt_errstr(expected_status));
7772 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7773 base ? base : "<NULL>", stream ? stream : "<NULL>",
7776 TALLOC_FREE(stream);
7780 static bool run_local_stream_name(int dummy)
7784 ret &= test_stream_name(
7785 "bla", "bla", NULL, NT_STATUS_OK);
7786 ret &= test_stream_name(
7787 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7788 ret &= test_stream_name(
7789 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7790 ret &= test_stream_name(
7791 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7792 ret &= test_stream_name(
7793 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7794 ret &= test_stream_name(
7795 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7796 ret &= test_stream_name(
7797 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7798 ret &= test_stream_name(
7799 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7804 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7806 if (a.length != b.length) {
7807 printf("a.length=%d != b.length=%d\n",
7808 (int)a.length, (int)b.length);
7811 if (memcmp(a.data, b.data, a.length) != 0) {
7812 printf("a.data and b.data differ\n");
7818 static bool run_local_memcache(int dummy)
7820 struct memcache *cache;
7822 DATA_BLOB d1, d2, d3;
7823 DATA_BLOB v1, v2, v3;
7825 TALLOC_CTX *mem_ctx;
7827 size_t size1, size2;
7830 cache = memcache_init(NULL, 100);
7832 if (cache == NULL) {
7833 printf("memcache_init failed\n");
7837 d1 = data_blob_const("d1", 2);
7838 d2 = data_blob_const("d2", 2);
7839 d3 = data_blob_const("d3", 2);
7841 k1 = data_blob_const("d1", 2);
7842 k2 = data_blob_const("d2", 2);
7844 memcache_add(cache, STAT_CACHE, k1, d1);
7845 memcache_add(cache, GETWD_CACHE, k2, d2);
7847 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7848 printf("could not find k1\n");
7851 if (!data_blob_equal(d1, v1)) {
7855 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7856 printf("could not find k2\n");
7859 if (!data_blob_equal(d2, v2)) {
7863 memcache_add(cache, STAT_CACHE, k1, d3);
7865 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7866 printf("could not find replaced k1\n");
7869 if (!data_blob_equal(d3, v3)) {
7873 memcache_add(cache, GETWD_CACHE, k1, d1);
7875 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7876 printf("Did find k2, should have been purged\n");
7882 cache = memcache_init(NULL, 0);
7884 mem_ctx = talloc_init("foo");
7886 str1 = talloc_strdup(mem_ctx, "string1");
7887 str2 = talloc_strdup(mem_ctx, "string2");
7889 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7890 data_blob_string_const("torture"), &str1);
7891 size1 = talloc_total_size(cache);
7893 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7894 data_blob_string_const("torture"), &str2);
7895 size2 = talloc_total_size(cache);
7897 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7899 if (size2 > size1) {
7900 printf("memcache leaks memory!\n");
7910 static void wbclient_done(struct tevent_req *req)
7913 struct winbindd_response *wb_resp;
7914 int *i = (int *)tevent_req_callback_data_void(req);
7916 wbc_err = wb_trans_recv(req, req, &wb_resp);
7919 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7922 static bool run_local_wbclient(int dummy)
7924 struct event_context *ev;
7925 struct wb_context **wb_ctx;
7926 struct winbindd_request wb_req;
7927 bool result = false;
7930 BlockSignals(True, SIGPIPE);
7932 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7937 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7938 if (wb_ctx == NULL) {
7942 ZERO_STRUCT(wb_req);
7943 wb_req.cmd = WINBINDD_PING;
7945 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7947 for (i=0; i<nprocs; i++) {
7948 wb_ctx[i] = wb_context_init(ev, NULL);
7949 if (wb_ctx[i] == NULL) {
7952 for (j=0; j<torture_numops; j++) {
7953 struct tevent_req *req;
7954 req = wb_trans_send(ev, ev, wb_ctx[i],
7955 (j % 2) == 0, &wb_req);
7959 tevent_req_set_callback(req, wbclient_done, &i);
7965 while (i < nprocs * torture_numops) {
7966 event_loop_once(ev);
7975 static void getaddrinfo_finished(struct tevent_req *req)
7977 char *name = (char *)tevent_req_callback_data_void(req);
7978 struct addrinfo *ainfo;
7981 res = getaddrinfo_recv(req, &ainfo);
7983 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7986 d_printf("gai(%s) succeeded\n", name);
7987 freeaddrinfo(ainfo);
7990 static bool run_getaddrinfo_send(int dummy)
7992 TALLOC_CTX *frame = talloc_stackframe();
7993 struct fncall_context *ctx;
7994 struct tevent_context *ev;
7995 bool result = false;
7996 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7997 "www.slashdot.org", "heise.de" };
7998 struct tevent_req *reqs[4];
8001 ev = event_context_init(frame);
8006 ctx = fncall_context_init(frame, 4);
8008 for (i=0; i<ARRAY_SIZE(names); i++) {
8009 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8011 if (reqs[i] == NULL) {
8014 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8018 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8019 tevent_loop_once(ev);
8028 static bool dbtrans_inc(struct db_context *db)
8030 struct db_record *rec;
8035 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8037 printf(__location__ "fetch_lock failed\n");
8041 if (rec->value.dsize != sizeof(uint32_t)) {
8042 printf(__location__ "value.dsize = %d\n",
8043 (int)rec->value.dsize);
8047 val = (uint32_t *)rec->value.dptr;
8050 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8053 if (!NT_STATUS_IS_OK(status)) {
8054 printf(__location__ "store failed: %s\n",
8065 static bool run_local_dbtrans(int dummy)
8067 struct db_context *db;
8068 struct db_record *rec;
8073 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8074 O_RDWR|O_CREAT, 0600);
8076 printf("Could not open transtest.db\n");
8080 res = db->transaction_start(db);
8082 printf(__location__ "transaction_start failed\n");
8086 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8088 printf(__location__ "fetch_lock failed\n");
8092 if (rec->value.dptr == NULL) {
8094 status = rec->store(
8095 rec, make_tdb_data((uint8_t *)&initial,
8098 if (!NT_STATUS_IS_OK(status)) {
8099 printf(__location__ "store returned %s\n",
8107 res = db->transaction_commit(db);
8109 printf(__location__ "transaction_commit failed\n");
8117 res = db->transaction_start(db);
8119 printf(__location__ "transaction_start failed\n");
8123 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8124 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8128 for (i=0; i<10; i++) {
8129 if (!dbtrans_inc(db)) {
8134 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8135 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8139 if (val2 != val + 10) {
8140 printf(__location__ "val=%d, val2=%d\n",
8141 (int)val, (int)val2);
8145 printf("val2=%d\r", val2);
8147 res = db->transaction_commit(db);
8149 printf(__location__ "transaction_commit failed\n");
8159 * Just a dummy test to be run under a debugger. There's no real way
8160 * to inspect the tevent_select specific function from outside of
8164 static bool run_local_tevent_select(int dummy)
8166 struct tevent_context *ev;
8167 struct tevent_fd *fd1, *fd2;
8168 bool result = false;
8170 ev = tevent_context_init_byname(NULL, "select");
8172 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8176 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8178 d_fprintf(stderr, "tevent_add_fd failed\n");
8181 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8183 d_fprintf(stderr, "tevent_add_fd failed\n");
8188 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8190 d_fprintf(stderr, "tevent_add_fd failed\n");
8200 static double create_procs(bool (*fn)(int), bool *result)
8203 volatile pid_t *child_status;
8204 volatile bool *child_status_out;
8207 struct timeval start;
8211 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8212 if (!child_status) {
8213 printf("Failed to setup shared memory\n");
8217 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8218 if (!child_status_out) {
8219 printf("Failed to setup result status shared memory\n");
8223 for (i = 0; i < nprocs; i++) {
8224 child_status[i] = 0;
8225 child_status_out[i] = True;
8228 start = timeval_current();
8230 for (i=0;i<nprocs;i++) {
8233 pid_t mypid = getpid();
8234 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8236 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8239 if (torture_open_connection(¤t_cli, i)) break;
8241 printf("pid %d failed to start\n", (int)getpid());
8247 child_status[i] = getpid();
8249 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8251 child_status_out[i] = fn(i);
8258 for (i=0;i<nprocs;i++) {
8259 if (child_status[i]) synccount++;
8261 if (synccount == nprocs) break;
8263 } while (timeval_elapsed(&start) < 30);
8265 if (synccount != nprocs) {
8266 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8268 return timeval_elapsed(&start);
8271 /* start the client load */
8272 start = timeval_current();
8274 for (i=0;i<nprocs;i++) {
8275 child_status[i] = 0;
8278 printf("%d clients started\n", nprocs);
8280 for (i=0;i<nprocs;i++) {
8281 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8286 for (i=0;i<nprocs;i++) {
8287 if (!child_status_out[i]) {
8291 return timeval_elapsed(&start);
8294 #define FLAG_MULTIPROC 1
8301 {"FDPASS", run_fdpasstest, 0},
8302 {"LOCK1", run_locktest1, 0},
8303 {"LOCK2", run_locktest2, 0},
8304 {"LOCK3", run_locktest3, 0},
8305 {"LOCK4", run_locktest4, 0},
8306 {"LOCK5", run_locktest5, 0},
8307 {"LOCK6", run_locktest6, 0},
8308 {"LOCK7", run_locktest7, 0},
8309 {"LOCK8", run_locktest8, 0},
8310 {"LOCK9", run_locktest9, 0},
8311 {"UNLINK", run_unlinktest, 0},
8312 {"BROWSE", run_browsetest, 0},
8313 {"ATTR", run_attrtest, 0},
8314 {"TRANS2", run_trans2test, 0},
8315 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8316 {"TORTURE",run_torture, FLAG_MULTIPROC},
8317 {"RANDOMIPC", run_randomipc, 0},
8318 {"NEGNOWAIT", run_negprot_nowait, 0},
8319 {"NBENCH", run_nbench, 0},
8320 {"NBENCH2", run_nbench2, 0},
8321 {"OPLOCK1", run_oplock1, 0},
8322 {"OPLOCK2", run_oplock2, 0},
8323 {"OPLOCK3", run_oplock3, 0},
8324 {"OPLOCK4", run_oplock4, 0},
8325 {"DIR", run_dirtest, 0},
8326 {"DIR1", run_dirtest1, 0},
8327 {"DIR-CREATETIME", run_dir_createtime, 0},
8328 {"DENY1", torture_denytest1, 0},
8329 {"DENY2", torture_denytest2, 0},
8330 {"TCON", run_tcon_test, 0},
8331 {"TCONDEV", run_tcon_devtype_test, 0},
8332 {"RW1", run_readwritetest, 0},
8333 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8334 {"RW3", run_readwritelarge, 0},
8335 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8336 {"OPEN", run_opentest, 0},
8337 {"POSIX", run_simple_posix_open_test, 0},
8338 {"POSIX-APPEND", run_posix_append, 0},
8339 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8340 {"ASYNC-ECHO", run_async_echo, 0},
8341 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8342 { "SHORTNAME-TEST", run_shortname_test, 0},
8343 { "ADDRCHANGE", run_addrchange, 0},
8345 {"OPENATTR", run_openattrtest, 0},
8347 {"XCOPY", run_xcopy, 0},
8348 {"RENAME", run_rename, 0},
8349 {"DELETE", run_deletetest, 0},
8350 {"DELETE-LN", run_deletetest_ln, 0},
8351 {"PROPERTIES", run_properties, 0},
8352 {"MANGLE", torture_mangle, 0},
8353 {"MANGLE1", run_mangle1, 0},
8354 {"W2K", run_w2ktest, 0},
8355 {"TRANS2SCAN", torture_trans2_scan, 0},
8356 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8357 {"UTABLE", torture_utable, 0},
8358 {"CASETABLE", torture_casetable, 0},
8359 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8360 {"PIPE_NUMBER", run_pipe_number, 0},
8361 {"TCON2", run_tcon2_test, 0},
8362 {"IOCTL", torture_ioctl_test, 0},
8363 {"CHKPATH", torture_chkpath_test, 0},
8364 {"FDSESS", run_fdsesstest, 0},
8365 { "EATEST", run_eatest, 0},
8366 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8367 { "CHAIN1", run_chain1, 0},
8368 { "CHAIN2", run_chain2, 0},
8369 { "WINDOWS-WRITE", run_windows_write, 0},
8370 { "CLI_ECHO", run_cli_echo, 0},
8371 { "GETADDRINFO", run_getaddrinfo_send, 0},
8372 { "TLDAP", run_tldap },
8373 { "STREAMERROR", run_streamerror },
8374 { "NOTIFY-BENCH", run_notify_bench },
8375 { "BAD-NBT-SESSION", run_bad_nbt_session },
8376 { "SMB-ANY-CONNECT", run_smb_any_connect },
8377 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8378 { "LOCAL-GENCACHE", run_local_gencache, 0},
8379 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8380 { "LOCAL-BASE64", run_local_base64, 0},
8381 { "LOCAL-RBTREE", run_local_rbtree, 0},
8382 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8383 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8384 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8385 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8386 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8387 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8388 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8389 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8394 /****************************************************************************
8395 run a specified test or "ALL"
8396 ****************************************************************************/
8397 static bool run_test(const char *name)
8404 if (strequal(name,"ALL")) {
8405 for (i=0;torture_ops[i].name;i++) {
8406 run_test(torture_ops[i].name);
8411 for (i=0;torture_ops[i].name;i++) {
8412 fstr_sprintf(randomfname, "\\XX%x",
8413 (unsigned)random());
8415 if (strequal(name, torture_ops[i].name)) {
8417 printf("Running %s\n", name);
8418 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8419 t = create_procs(torture_ops[i].fn, &result);
8422 printf("TEST %s FAILED!\n", name);
8425 struct timeval start;
8426 start = timeval_current();
8427 if (!torture_ops[i].fn(0)) {
8429 printf("TEST %s FAILED!\n", name);
8431 t = timeval_elapsed(&start);
8433 printf("%s took %g secs\n\n", name, t);
8438 printf("Did not find a test named %s\n", name);
8446 static void usage(void)
8450 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8451 printf("Please use samba4 torture.\n\n");
8453 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8455 printf("\t-d debuglevel\n");
8456 printf("\t-U user%%pass\n");
8457 printf("\t-k use kerberos\n");
8458 printf("\t-N numprocs\n");
8459 printf("\t-n my_netbios_name\n");
8460 printf("\t-W workgroup\n");
8461 printf("\t-o num_operations\n");
8462 printf("\t-O socket_options\n");
8463 printf("\t-m maximum protocol\n");
8464 printf("\t-L use oplocks\n");
8465 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8466 printf("\t-A showall\n");
8467 printf("\t-p port\n");
8468 printf("\t-s seed\n");
8469 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8472 printf("tests are:");
8473 for (i=0;torture_ops[i].name;i++) {
8474 printf(" %s", torture_ops[i].name);
8478 printf("default test is ALL\n");
8483 /****************************************************************************
8485 ****************************************************************************/
8486 int main(int argc,char *argv[])
8492 bool correct = True;
8493 TALLOC_CTX *frame = talloc_stackframe();
8494 int seed = time(NULL);
8496 #ifdef HAVE_SETBUFFER
8497 setbuffer(stdout, NULL, 0);
8500 setup_logging("smbtorture", DEBUG_STDOUT);
8504 if (is_default_dyn_CONFIGFILE()) {
8505 if(getenv("SMB_CONF_PATH")) {
8506 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8509 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8516 for(p = argv[1]; *p; p++)
8520 if (strncmp(argv[1], "//", 2)) {
8524 fstrcpy(host, &argv[1][2]);
8525 p = strchr_m(&host[2],'/');
8530 fstrcpy(share, p+1);
8532 fstrcpy(myname, get_myname(talloc_tos()));
8534 fprintf(stderr, "Failed to get my hostname.\n");
8538 if (*username == 0 && getenv("LOGNAME")) {
8539 fstrcpy(username,getenv("LOGNAME"));
8545 fstrcpy(workgroup, lp_workgroup());
8547 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8550 port_to_use = atoi(optarg);
8553 seed = atoi(optarg);
8556 fstrcpy(workgroup,optarg);
8559 max_protocol = interpret_protocol(optarg, max_protocol);
8562 nprocs = atoi(optarg);
8565 torture_numops = atoi(optarg);
8568 lp_set_cmdline("log level", optarg);
8577 local_path = optarg;
8580 torture_showall = True;
8583 fstrcpy(myname, optarg);
8586 client_txt = optarg;
8593 use_kerberos = True;
8595 d_printf("No kerberos support compiled in\n");
8601 fstrcpy(username,optarg);
8602 p = strchr_m(username,'%');
8605 fstrcpy(password, p+1);
8610 fstrcpy(multishare_conn_fname, optarg);
8611 use_multishare_conn = True;
8614 torture_blocksize = atoi(optarg);
8617 printf("Unknown option %c (%d)\n", (char)opt, opt);
8622 d_printf("using seed %d\n", seed);
8626 if(use_kerberos && !gotuser) gotpass = True;
8629 p = getpass("Password:");
8631 fstrcpy(password, p);
8636 printf("host=%s share=%s user=%s myname=%s\n",
8637 host, share, username, myname);
8639 if (argc == optind) {
8640 correct = run_test("ALL");
8642 for (i=optind;i<argc;i++) {
8643 if (!run_test(argv[i])) {