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;
63 bool torture_showall = False;
65 static double create_procs(bool (*fn)(int), bool *result);
68 /* return a pointer to a anonymous shared memory segment of size "size"
69 which will persist across fork() but will disappear when all processes
72 The memory is not zeroed
74 This function uses system5 shared memory. It takes advantage of a property
75 that the memory is not destroyed if it is attached when the id is removed
77 void *shm_setup(int size)
83 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
85 printf("can't get shared memory\n");
88 shm_unlink("private");
89 if (ftruncate(shmid, size) == -1) {
90 printf("can't set shared memory size\n");
93 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
94 if (ret == MAP_FAILED) {
95 printf("can't map shared memory\n");
99 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
101 printf("can't get shared memory\n");
104 ret = (void *)shmat(shmid, 0, 0);
105 if (!ret || ret == (void *)-1) {
106 printf("can't attach to shared memory\n");
109 /* the following releases the ipc, but note that this process
110 and all its children will still have access to the memory, its
111 just that the shmid is no longer valid for other shm calls. This
112 means we don't leave behind lots of shm segments after we exit
114 See Stevens "advanced programming in unix env" for details
116 shmctl(shmid, IPC_RMID, 0);
122 /********************************************************************
123 Ensure a connection is encrypted.
124 ********************************************************************/
126 static bool force_cli_encryption(struct cli_state *c,
127 const char *sharename)
130 uint32 caplow, caphigh;
133 if (!SERVER_HAS_UNIX_CIFS(c)) {
134 d_printf("Encryption required and "
135 "server that doesn't support "
136 "UNIX extensions - failing connect\n");
140 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
142 if (!NT_STATUS_IS_OK(status)) {
143 d_printf("Encryption required and "
144 "can't get UNIX CIFS extensions "
145 "version from server: %s\n", nt_errstr(status));
149 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
150 d_printf("Encryption required and "
151 "share %s doesn't support "
152 "encryption.\n", sharename);
156 if (c->use_kerberos) {
157 status = cli_gss_smb_encryption_start(c);
159 status = cli_raw_ntlm_smb_encryption_start(c,
165 if (!NT_STATUS_IS_OK(status)) {
166 d_printf("Encryption required and "
167 "setup failed with error %s.\n",
176 static struct cli_state *open_nbt_connection(void)
178 struct nmb_name called, calling;
179 struct sockaddr_storage ss;
183 make_nmb_name(&calling, myname, 0x0);
184 make_nmb_name(&called , host, 0x20);
188 if (!(c = cli_initialise_ex(signing_state))) {
189 printf("Failed initialize cli_struct to connect with %s\n", host);
193 c->port = port_to_use;
195 status = cli_connect(c, host, &ss);
196 if (!NT_STATUS_IS_OK(status)) {
197 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
201 c->use_kerberos = use_kerberos;
203 c->timeout = 120000; /* set a really long timeout (2 minutes) */
204 if (use_oplocks) c->use_oplocks = True;
205 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
207 if (!cli_session_request(c, &calling, &called)) {
209 * Well, that failed, try *SMBSERVER ...
210 * However, we must reconnect as well ...
212 status = cli_connect(c, host, &ss);
213 if (!NT_STATUS_IS_OK(status)) {
214 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
218 make_nmb_name(&called, "*SMBSERVER", 0x20);
219 if (!cli_session_request(c, &calling, &called)) {
220 printf("%s rejected the session\n",host);
221 printf("We tried with a called name of %s & %s\n",
231 /****************************************************************************
232 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
233 ****************************************************************************/
235 static bool cli_bad_session_request(struct cli_state *cli,
236 struct nmb_name *calling, struct nmb_name *called)
243 memcpy(&(cli->calling), calling, sizeof(*calling));
244 memcpy(&(cli->called ), called , sizeof(*called ));
246 /* put in the destination name */
248 tmp = name_mangle(talloc_tos(), cli->called.name,
249 cli->called.name_type);
255 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
257 memcpy(p, tmp, namelen);
262 /* Deliberately corrupt the name len (first byte) */
267 tmp = name_mangle(talloc_tos(), cli->calling.name,
268 cli->calling.name_type);
274 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
276 memcpy(p, tmp, namelen);
280 /* Deliberately corrupt the name len (first byte) */
283 /* send a session request (RFC 1002) */
284 /* setup the packet length
285 * Remove four bytes from the length count, since the length
286 * field in the NBT Session Service header counts the number
287 * of bytes which follow. The cli_send_smb() function knows
288 * about this and accounts for those four bytes.
292 _smb_setlen(cli->outbuf,len);
293 SCVAL(cli->outbuf,0,0x81);
296 DEBUG(5,("Sent session request\n"));
298 if (!cli_receive_smb(cli))
301 if (CVAL(cli->inbuf,0) != 0x82) {
302 /* This is the wrong place to put the error... JRA. */
303 cli->rap_error = CVAL(cli->inbuf,4);
309 static struct cli_state *open_bad_nbt_connection(void)
311 struct nmb_name called, calling;
312 struct sockaddr_storage ss;
316 make_nmb_name(&calling, myname, 0x0);
317 make_nmb_name(&called , host, 0x20);
321 if (!(c = cli_initialise_ex(signing_state))) {
322 printf("Failed initialize cli_struct to connect with %s\n", host);
328 status = cli_connect(c, host, &ss);
329 if (!NT_STATUS_IS_OK(status)) {
330 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
334 c->timeout = 4000; /* set a short timeout (4 seconds) */
336 if (!cli_bad_session_request(c, &calling, &called)) {
337 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
345 /* Insert a NULL at the first separator of the given path and return a pointer
346 * to the remainder of the string.
349 terminate_path_at_separator(char * path)
357 if ((p = strchr_m(path, '/'))) {
362 if ((p = strchr_m(path, '\\'))) {
372 parse a //server/share type UNC name
374 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
375 char **hostname, char **sharename)
379 *hostname = *sharename = NULL;
381 if (strncmp(unc_name, "\\\\", 2) &&
382 strncmp(unc_name, "//", 2)) {
386 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
387 p = terminate_path_at_separator(*hostname);
390 *sharename = talloc_strdup(mem_ctx, p);
391 terminate_path_at_separator(*sharename);
394 if (*hostname && *sharename) {
398 TALLOC_FREE(*hostname);
399 TALLOC_FREE(*sharename);
403 static bool torture_open_connection_share(struct cli_state **c,
404 const char *hostname,
405 const char *sharename)
411 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
413 flags |= CLI_FULL_CONNECTION_OPLOCKS;
414 if (use_level_II_oplocks)
415 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
417 status = cli_full_connection(c, myname,
418 hostname, NULL, port_to_use,
421 password, flags, signing_state);
422 if (!NT_STATUS_IS_OK(status)) {
423 printf("failed to open share connection: //%s/%s port:%d - %s\n",
424 hostname, sharename, port_to_use, nt_errstr(status));
428 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
431 return force_cli_encryption(*c,
437 bool torture_open_connection(struct cli_state **c, int conn_index)
439 char **unc_list = NULL;
440 int num_unc_names = 0;
443 if (use_multishare_conn==True) {
445 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
446 if (!unc_list || num_unc_names <= 0) {
447 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
451 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
453 printf("Failed to parse UNC name %s\n",
454 unc_list[conn_index % num_unc_names]);
455 TALLOC_FREE(unc_list);
459 result = torture_open_connection_share(c, h, s);
461 /* h, s were copied earlier */
462 TALLOC_FREE(unc_list);
466 return torture_open_connection_share(c, host, share);
469 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
471 uint16 old_vuid = cli->vuid;
472 fstring old_user_name;
473 size_t passlen = strlen(password);
477 fstrcpy(old_user_name, cli->user_name);
479 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
483 *new_vuid = cli->vuid;
484 cli->vuid = old_vuid;
485 status = cli_set_username(cli, old_user_name);
486 if (!NT_STATUS_IS_OK(status)) {
493 bool torture_close_connection(struct cli_state *c)
498 status = cli_tdis(c);
499 if (!NT_STATUS_IS_OK(status)) {
500 printf("tdis failed (%s)\n", nt_errstr(status));
510 /* check if the server produced the expected error code */
511 static bool check_error(int line, struct cli_state *c,
512 uint8 eclass, uint32 ecode, NTSTATUS nterr)
514 if (cli_is_dos_error(c)) {
518 /* Check DOS error */
520 cli_dos_error(c, &cclass, &num);
522 if (eclass != cclass || ecode != num) {
523 printf("unexpected error code class=%d code=%d\n",
524 (int)cclass, (int)num);
525 printf(" expected %d/%d %s (line=%d)\n",
526 (int)eclass, (int)ecode, nt_errstr(nterr), line);
535 status = cli_nt_error(c);
537 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
538 printf("unexpected error code %s\n", nt_errstr(status));
539 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
548 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
550 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
551 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
557 static bool rw_torture(struct cli_state *c)
559 const char *lockfname = "\\torture.lck";
563 pid_t pid2, pid = getpid();
569 memset(buf, '\0', sizeof(buf));
571 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
573 if (!NT_STATUS_IS_OK(status)) {
574 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
576 if (!NT_STATUS_IS_OK(status)) {
577 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
581 for (i=0;i<torture_numops;i++) {
582 unsigned n = (unsigned)sys_random()%10;
585 printf("%d\r", i); fflush(stdout);
587 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
589 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
593 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
594 printf("open failed (%s)\n", cli_errstr(c));
599 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
601 if (!NT_STATUS_IS_OK(status)) {
602 printf("write failed (%s)\n", nt_errstr(status));
607 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
608 sizeof(pid)+(j*sizeof(buf)),
610 if (!NT_STATUS_IS_OK(status)) {
611 printf("write failed (%s)\n",
619 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
620 printf("read failed (%s)\n", cli_errstr(c));
625 printf("data corruption!\n");
629 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
630 printf("close failed (%s)\n", cli_errstr(c));
634 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
635 printf("unlink failed (%s)\n", cli_errstr(c));
639 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
640 printf("unlock failed (%s)\n", cli_errstr(c));
646 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
653 static bool run_torture(int dummy)
655 struct cli_state *cli;
660 cli_sockopt(cli, sockops);
662 ret = rw_torture(cli);
664 if (!torture_close_connection(cli)) {
671 static bool rw_torture3(struct cli_state *c, char *lockfname)
673 uint16_t fnum = (uint16_t)-1;
678 unsigned countprev = 0;
681 NTSTATUS status = NT_STATUS_OK;
684 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
686 SIVAL(buf, i, sys_random());
691 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
692 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
695 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
696 DENY_NONE, &fnum))) {
697 printf("first open read/write of %s failed (%s)\n",
698 lockfname, cli_errstr(c));
704 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
706 status = cli_open(c, lockfname, O_RDONLY,
708 if (!NT_STATUS_IS_OK(status)) {
713 if (!NT_STATUS_IS_OK(status)) {
714 printf("second open read-only of %s failed (%s)\n",
715 lockfname, cli_errstr(c));
721 for (count = 0; count < sizeof(buf); count += sent)
723 if (count >= countprev) {
724 printf("%d %8d\r", i, count);
727 countprev += (sizeof(buf) / 20);
732 sent = ((unsigned)sys_random()%(20))+ 1;
733 if (sent > sizeof(buf) - count)
735 sent = sizeof(buf) - count;
738 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
739 count, (size_t)sent, NULL);
740 if (!NT_STATUS_IS_OK(status)) {
741 printf("write failed (%s)\n",
748 sent = cli_read(c, fnum, buf_rd+count, count,
752 printf("read failed offset:%d size:%ld (%s)\n",
753 count, (unsigned long)sizeof(buf)-count,
760 if (memcmp(buf_rd+count, buf+count, sent) != 0)
762 printf("read/write compare failed\n");
763 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
772 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
773 printf("close failed (%s)\n", cli_errstr(c));
780 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
782 const char *lockfname = "\\torture2.lck";
791 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
792 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
795 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
796 DENY_NONE, &fnum1))) {
797 printf("first open read/write of %s failed (%s)\n",
798 lockfname, cli_errstr(c1));
801 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
802 DENY_NONE, &fnum2))) {
803 printf("second open read-only of %s failed (%s)\n",
804 lockfname, cli_errstr(c2));
805 cli_close(c1, fnum1);
809 for (i=0;i<torture_numops;i++)
812 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
814 printf("%d\r", i); fflush(stdout);
817 generate_random_buffer((unsigned char *)buf, buf_size);
819 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
821 if (!NT_STATUS_IS_OK(status)) {
822 printf("write failed (%s)\n", nt_errstr(status));
827 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
828 printf("read failed (%s)\n", cli_errstr(c2));
829 printf("read %d, expected %ld\n", (int)bytes_read,
830 (unsigned long)buf_size);
835 if (memcmp(buf_rd, buf, buf_size) != 0)
837 printf("read/write compare failed\n");
843 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
844 printf("close failed (%s)\n", cli_errstr(c2));
847 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
848 printf("close failed (%s)\n", cli_errstr(c1));
852 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
853 printf("unlink failed (%s)\n", cli_errstr(c1));
860 static bool run_readwritetest(int dummy)
862 struct cli_state *cli1, *cli2;
863 bool test1, test2 = False;
865 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
868 cli_sockopt(cli1, sockops);
869 cli_sockopt(cli2, sockops);
871 printf("starting readwritetest\n");
873 test1 = rw_torture2(cli1, cli2);
874 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
877 test2 = rw_torture2(cli1, cli1);
878 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
881 if (!torture_close_connection(cli1)) {
885 if (!torture_close_connection(cli2)) {
889 return (test1 && test2);
892 static bool run_readwritemulti(int dummy)
894 struct cli_state *cli;
899 cli_sockopt(cli, sockops);
901 printf("run_readwritemulti: fname %s\n", randomfname);
902 test = rw_torture3(cli, randomfname);
904 if (!torture_close_connection(cli)) {
911 static bool run_readwritelarge_internal(int max_xmit_k)
913 static struct cli_state *cli1;
915 const char *lockfname = "\\large.dat";
920 if (!torture_open_connection(&cli1, 0)) {
923 cli_sockopt(cli1, sockops);
924 memset(buf,'\0',sizeof(buf));
926 cli1->max_xmit = max_xmit_k*1024;
928 if (signing_state == Required) {
929 /* Horrible cheat to force
930 multiple signed outstanding
931 packets against a Samba server.
933 cli1->is_samba = false;
936 printf("starting readwritelarge_internal\n");
938 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
940 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
941 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
945 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
947 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
948 cli1, fnum1, NULL, &fsize, NULL, NULL,
949 NULL, NULL, NULL))) {
950 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
954 if (fsize == sizeof(buf))
955 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
956 (unsigned long)fsize);
958 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
959 (unsigned long)fsize);
963 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
964 printf("close failed (%s)\n", cli_errstr(cli1));
968 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
969 printf("unlink failed (%s)\n", cli_errstr(cli1));
973 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
974 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
978 cli1->max_xmit = 4*1024;
980 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
982 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
983 cli1, fnum1, NULL, &fsize, NULL, NULL,
984 NULL, NULL, NULL))) {
985 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
989 if (fsize == sizeof(buf))
990 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
991 (unsigned long)fsize);
993 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
994 (unsigned long)fsize);
999 /* ToDo - set allocation. JRA */
1000 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1001 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1004 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1006 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1010 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1013 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1014 printf("close failed (%s)\n", cli_errstr(cli1));
1018 if (!torture_close_connection(cli1)) {
1024 static bool run_readwritelarge(int dummy)
1026 return run_readwritelarge_internal(128);
1029 static bool run_readwritelarge_signtest(int dummy)
1032 signing_state = Required;
1033 ret = run_readwritelarge_internal(2);
1034 signing_state = Undefined;
1041 #define ival(s) strtol(s, NULL, 0)
1043 /* run a test that simulates an approximate netbench client load */
1044 static bool run_netbench(int client)
1046 struct cli_state *cli;
1051 const char *params[20];
1052 bool correct = True;
1058 cli_sockopt(cli, sockops);
1062 slprintf(cname,sizeof(cname)-1, "client%d", client);
1064 f = fopen(client_txt, "r");
1071 while (fgets(line, sizeof(line)-1, f)) {
1075 line[strlen(line)-1] = 0;
1077 /* printf("[%d] %s\n", line_count, line); */
1079 all_string_sub(line,"client1", cname, sizeof(line));
1081 /* parse the command parameters */
1082 params[0] = strtok_r(line, " ", &saveptr);
1084 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1088 if (i < 2) continue;
1090 if (!strncmp(params[0],"SMB", 3)) {
1091 printf("ERROR: You are using a dbench 1 load file\n");
1095 if (!strcmp(params[0],"NTCreateX")) {
1096 nb_createx(params[1], ival(params[2]), ival(params[3]),
1098 } else if (!strcmp(params[0],"Close")) {
1099 nb_close(ival(params[1]));
1100 } else if (!strcmp(params[0],"Rename")) {
1101 nb_rename(params[1], params[2]);
1102 } else if (!strcmp(params[0],"Unlink")) {
1103 nb_unlink(params[1]);
1104 } else if (!strcmp(params[0],"Deltree")) {
1105 nb_deltree(params[1]);
1106 } else if (!strcmp(params[0],"Rmdir")) {
1107 nb_rmdir(params[1]);
1108 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1109 nb_qpathinfo(params[1]);
1110 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1111 nb_qfileinfo(ival(params[1]));
1112 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1113 nb_qfsinfo(ival(params[1]));
1114 } else if (!strcmp(params[0],"FIND_FIRST")) {
1115 nb_findfirst(params[1]);
1116 } else if (!strcmp(params[0],"WriteX")) {
1117 nb_writex(ival(params[1]),
1118 ival(params[2]), ival(params[3]), ival(params[4]));
1119 } else if (!strcmp(params[0],"ReadX")) {
1120 nb_readx(ival(params[1]),
1121 ival(params[2]), ival(params[3]), ival(params[4]));
1122 } else if (!strcmp(params[0],"Flush")) {
1123 nb_flush(ival(params[1]));
1125 printf("Unknown operation %s\n", params[0]);
1133 if (!torture_close_connection(cli)) {
1141 /* run a test that simulates an approximate netbench client load */
1142 static bool run_nbench(int dummy)
1145 bool correct = True;
1151 signal(SIGALRM, nb_alarm);
1153 t = create_procs(run_netbench, &correct);
1156 printf("\nThroughput %g MB/sec\n",
1157 1.0e-6 * nbio_total() / t);
1163 This test checks for two things:
1165 1) correct support for retaining locks over a close (ie. the server
1166 must not use posix semantics)
1167 2) support for lock timeouts
1169 static bool run_locktest1(int dummy)
1171 struct cli_state *cli1, *cli2;
1172 const char *fname = "\\lockt1.lck";
1173 uint16_t fnum1, fnum2, fnum3;
1175 unsigned lock_timeout;
1177 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1180 cli_sockopt(cli1, sockops);
1181 cli_sockopt(cli2, sockops);
1183 printf("starting locktest1\n");
1185 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1187 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1188 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1191 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1192 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1195 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1196 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1200 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1201 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1206 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1207 printf("lock2 succeeded! This is a locking bug\n");
1210 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1211 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1215 lock_timeout = (1 + (random() % 20));
1216 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1218 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1219 printf("lock3 succeeded! This is a locking bug\n");
1222 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1223 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1227 if (ABS(t2 - t1) < lock_timeout-1) {
1228 printf("error: This server appears not to support timed lock requests\n");
1231 printf("server slept for %u seconds for a %u second timeout\n",
1232 (unsigned int)(t2-t1), lock_timeout);
1234 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1235 printf("close1 failed (%s)\n", cli_errstr(cli1));
1239 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1240 printf("lock4 succeeded! This is a locking bug\n");
1243 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1244 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1247 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1248 printf("close2 failed (%s)\n", cli_errstr(cli1));
1252 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1253 printf("close3 failed (%s)\n", cli_errstr(cli2));
1257 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1258 printf("unlink failed (%s)\n", cli_errstr(cli1));
1263 if (!torture_close_connection(cli1)) {
1267 if (!torture_close_connection(cli2)) {
1271 printf("Passed locktest1\n");
1276 this checks to see if a secondary tconx can use open files from an
1279 static bool run_tcon_test(int dummy)
1281 static struct cli_state *cli;
1282 const char *fname = "\\tcontest.tmp";
1284 uint16 cnum1, cnum2, cnum3;
1285 uint16 vuid1, vuid2;
1290 memset(buf, '\0', sizeof(buf));
1292 if (!torture_open_connection(&cli, 0)) {
1295 cli_sockopt(cli, sockops);
1297 printf("starting tcontest\n");
1299 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1301 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1302 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1309 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1310 if (!NT_STATUS_IS_OK(status)) {
1311 printf("initial write failed (%s)", nt_errstr(status));
1315 status = cli_tcon_andx(cli, share, "?????",
1316 password, strlen(password)+1);
1317 if (!NT_STATUS_IS_OK(status)) {
1318 printf("%s refused 2nd tree connect (%s)\n", host,
1325 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1326 vuid2 = cli->vuid + 1;
1328 /* try a write with the wrong tid */
1331 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1332 if (NT_STATUS_IS_OK(status)) {
1333 printf("* server allows write with wrong TID\n");
1336 printf("server fails write with wrong TID : %s\n",
1341 /* try a write with an invalid tid */
1344 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1345 if (NT_STATUS_IS_OK(status)) {
1346 printf("* server allows write with invalid TID\n");
1349 printf("server fails write with invalid TID : %s\n",
1353 /* try a write with an invalid vuid */
1357 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1358 if (NT_STATUS_IS_OK(status)) {
1359 printf("* server allows write with invalid VUID\n");
1362 printf("server fails write with invalid VUID : %s\n",
1369 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1370 printf("close failed (%s)\n", cli_errstr(cli));
1376 status = cli_tdis(cli);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1384 if (!torture_close_connection(cli)) {
1393 checks for old style tcon support
1395 static bool run_tcon2_test(int dummy)
1397 static struct cli_state *cli;
1398 uint16 cnum, max_xmit;
1402 if (!torture_open_connection(&cli, 0)) {
1405 cli_sockopt(cli, sockops);
1407 printf("starting tcon2 test\n");
1409 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1413 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1417 if (!NT_STATUS_IS_OK(status)) {
1418 printf("tcon2 failed : %s\n", nt_errstr(status));
1420 printf("tcon OK : max_xmit=%d cnum=%d\n",
1421 (int)max_xmit, (int)cnum);
1424 if (!torture_close_connection(cli)) {
1428 printf("Passed tcon2 test\n");
1432 static bool tcon_devtest(struct cli_state *cli,
1433 const char *myshare, const char *devtype,
1434 const char *return_devtype,
1435 NTSTATUS expected_error)
1440 status = cli_tcon_andx(cli, myshare, devtype,
1441 password, strlen(password)+1);
1443 if (NT_STATUS_IS_OK(expected_error)) {
1444 if (NT_STATUS_IS_OK(status)) {
1445 if (strcmp(cli->dev, return_devtype) == 0) {
1448 printf("tconX to share %s with type %s "
1449 "succeeded but returned the wrong "
1450 "device type (got [%s] but should have got [%s])\n",
1451 myshare, devtype, cli->dev, return_devtype);
1455 printf("tconX to share %s with type %s "
1456 "should have succeeded but failed\n",
1462 if (NT_STATUS_IS_OK(status)) {
1463 printf("tconx to share %s with type %s "
1464 "should have failed but succeeded\n",
1468 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1472 printf("Returned unexpected error\n");
1481 checks for correct tconX support
1483 static bool run_tcon_devtype_test(int dummy)
1485 static struct cli_state *cli1 = NULL;
1490 status = cli_full_connection(&cli1, myname,
1491 host, NULL, port_to_use,
1493 username, workgroup,
1494 password, flags, signing_state);
1496 if (!NT_STATUS_IS_OK(status)) {
1497 printf("could not open connection\n");
1501 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1504 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1507 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1510 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1513 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1516 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1519 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1522 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1525 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1528 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1534 printf("Passed tcondevtest\n");
1541 This test checks that
1543 1) the server supports multiple locking contexts on the one SMB
1544 connection, distinguished by PID.
1546 2) the server correctly fails overlapping locks made by the same PID (this
1547 goes against POSIX behaviour, which is why it is tricky to implement)
1549 3) the server denies unlock requests by an incorrect client PID
1551 static bool run_locktest2(int dummy)
1553 static struct cli_state *cli;
1554 const char *fname = "\\lockt2.lck";
1555 uint16_t fnum1, fnum2, fnum3;
1556 bool correct = True;
1558 if (!torture_open_connection(&cli, 0)) {
1562 cli_sockopt(cli, sockops);
1564 printf("starting locktest2\n");
1566 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1570 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1571 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1575 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1576 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1582 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1583 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1589 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1590 printf("lock1 failed (%s)\n", cli_errstr(cli));
1594 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1595 printf("WRITE lock1 succeeded! This is a locking bug\n");
1598 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1599 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1602 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1603 printf("WRITE lock2 succeeded! This is a locking bug\n");
1606 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1607 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1610 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1611 printf("READ lock2 succeeded! This is a locking bug\n");
1614 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1615 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1618 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1619 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1622 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1623 printf("unlock at 100 succeeded! This is a locking bug\n");
1627 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1628 printf("unlock1 succeeded! This is a locking bug\n");
1631 if (!check_error(__LINE__, cli,
1633 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1636 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1637 printf("unlock2 succeeded! This is a locking bug\n");
1640 if (!check_error(__LINE__, cli,
1642 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1645 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1646 printf("lock3 succeeded! This is a locking bug\n");
1649 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1654 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1655 printf("close1 failed (%s)\n", cli_errstr(cli));
1659 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1660 printf("close2 failed (%s)\n", cli_errstr(cli));
1664 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1665 printf("close3 failed (%s)\n", cli_errstr(cli));
1669 if (!torture_close_connection(cli)) {
1673 printf("locktest2 finished\n");
1680 This test checks that
1682 1) the server supports the full offset range in lock requests
1684 static bool run_locktest3(int dummy)
1686 static struct cli_state *cli1, *cli2;
1687 const char *fname = "\\lockt3.lck";
1688 uint16_t fnum1, fnum2;
1691 bool correct = True;
1693 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1695 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1698 cli_sockopt(cli1, sockops);
1699 cli_sockopt(cli2, sockops);
1701 printf("starting locktest3\n");
1703 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1705 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1706 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1709 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1710 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1714 for (offset=i=0;i<torture_numops;i++) {
1716 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1717 printf("lock1 %d failed (%s)\n",
1723 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1724 printf("lock2 %d failed (%s)\n",
1731 for (offset=i=0;i<torture_numops;i++) {
1734 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1735 printf("error: lock1 %d succeeded!\n", i);
1739 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1740 printf("error: lock2 %d succeeded!\n", i);
1744 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1745 printf("error: lock3 %d succeeded!\n", i);
1749 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1750 printf("error: lock4 %d succeeded!\n", i);
1755 for (offset=i=0;i<torture_numops;i++) {
1758 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1759 printf("unlock1 %d failed (%s)\n",
1765 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1766 printf("unlock2 %d failed (%s)\n",
1773 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1774 printf("close1 failed (%s)\n", cli_errstr(cli1));
1778 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1779 printf("close2 failed (%s)\n", cli_errstr(cli2));
1783 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1784 printf("unlink failed (%s)\n", cli_errstr(cli1));
1788 if (!torture_close_connection(cli1)) {
1792 if (!torture_close_connection(cli2)) {
1796 printf("finished locktest3\n");
1801 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1802 printf("** "); correct = False; \
1806 looks at overlapping locks
1808 static bool run_locktest4(int dummy)
1810 static struct cli_state *cli1, *cli2;
1811 const char *fname = "\\lockt4.lck";
1812 uint16_t fnum1, fnum2, f;
1815 bool correct = True;
1818 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1822 cli_sockopt(cli1, sockops);
1823 cli_sockopt(cli2, sockops);
1825 printf("starting locktest4\n");
1827 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1829 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1830 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1832 memset(buf, 0, sizeof(buf));
1834 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1836 if (!NT_STATUS_IS_OK(status)) {
1837 printf("Failed to create file: %s\n", nt_errstr(status));
1842 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1843 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1844 EXPECTED(ret, False);
1845 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1847 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1848 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1849 EXPECTED(ret, True);
1850 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1852 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1853 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1854 EXPECTED(ret, False);
1855 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1857 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1858 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1859 EXPECTED(ret, True);
1860 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1862 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1863 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1864 EXPECTED(ret, False);
1865 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1867 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1868 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1869 EXPECTED(ret, True);
1870 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1872 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1873 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1874 EXPECTED(ret, True);
1875 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1877 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1878 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1879 EXPECTED(ret, False);
1880 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1882 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1883 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1884 EXPECTED(ret, False);
1885 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1887 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1888 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1889 EXPECTED(ret, True);
1890 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1892 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1893 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1894 EXPECTED(ret, False);
1895 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1897 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1898 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1899 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1900 EXPECTED(ret, False);
1901 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1904 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1905 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1906 EXPECTED(ret, False);
1907 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1909 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1911 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1913 ret = NT_STATUS_IS_OK(status);
1915 EXPECTED(ret, False);
1916 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1919 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1920 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1921 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1922 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1923 EXPECTED(ret, True);
1924 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1927 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1928 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1929 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1930 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1931 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1933 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1934 EXPECTED(ret, True);
1935 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1937 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1938 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1939 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1941 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1942 EXPECTED(ret, True);
1943 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1945 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1946 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1947 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1949 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1950 EXPECTED(ret, True);
1951 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1953 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1954 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1955 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1956 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1958 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1959 EXPECTED(ret, True);
1960 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1962 cli_close(cli1, fnum1);
1963 cli_close(cli2, fnum2);
1964 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1965 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1966 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1967 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1968 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1969 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1970 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1972 cli_close(cli1, fnum1);
1973 EXPECTED(ret, True);
1974 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1977 cli_close(cli1, fnum1);
1978 cli_close(cli2, fnum2);
1979 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1980 torture_close_connection(cli1);
1981 torture_close_connection(cli2);
1983 printf("finished locktest4\n");
1988 looks at lock upgrade/downgrade.
1990 static bool run_locktest5(int dummy)
1992 static struct cli_state *cli1, *cli2;
1993 const char *fname = "\\lockt5.lck";
1994 uint16_t fnum1, fnum2, fnum3;
1997 bool correct = True;
2000 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2004 cli_sockopt(cli1, sockops);
2005 cli_sockopt(cli2, sockops);
2007 printf("starting locktest5\n");
2009 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2011 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2012 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2013 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2015 memset(buf, 0, sizeof(buf));
2017 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2019 if (!NT_STATUS_IS_OK(status)) {
2020 printf("Failed to create file: %s\n", nt_errstr(status));
2025 /* Check for NT bug... */
2026 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2027 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2028 cli_close(cli1, fnum1);
2029 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2030 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2031 EXPECTED(ret, True);
2032 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2033 cli_close(cli1, fnum1);
2034 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2035 cli_unlock(cli1, fnum3, 0, 1);
2037 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2038 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2039 EXPECTED(ret, True);
2040 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2042 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2043 EXPECTED(ret, False);
2045 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2047 /* Unlock the process 2 lock. */
2048 cli_unlock(cli2, fnum2, 0, 4);
2050 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2051 EXPECTED(ret, False);
2053 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2055 /* Unlock the process 1 fnum3 lock. */
2056 cli_unlock(cli1, fnum3, 0, 4);
2058 /* Stack 2 more locks here. */
2059 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2060 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2062 EXPECTED(ret, True);
2063 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2065 /* Unlock the first process lock, then check this was the WRITE lock that was
2068 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2069 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2071 EXPECTED(ret, True);
2072 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2074 /* Unlock the process 2 lock. */
2075 cli_unlock(cli2, fnum2, 0, 4);
2077 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2079 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2080 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2081 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2083 EXPECTED(ret, True);
2084 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2086 /* Ensure the next unlock fails. */
2087 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2088 EXPECTED(ret, False);
2089 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2091 /* Ensure connection 2 can get a write lock. */
2092 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2093 EXPECTED(ret, True);
2095 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2099 cli_close(cli1, fnum1);
2100 cli_close(cli2, fnum2);
2101 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2102 if (!torture_close_connection(cli1)) {
2105 if (!torture_close_connection(cli2)) {
2109 printf("finished locktest5\n");
2115 tries the unusual lockingX locktype bits
2117 static bool run_locktest6(int dummy)
2119 static struct cli_state *cli;
2120 const char *fname[1] = { "\\lock6.txt" };
2125 if (!torture_open_connection(&cli, 0)) {
2129 cli_sockopt(cli, sockops);
2131 printf("starting locktest6\n");
2134 printf("Testing %s\n", fname[i]);
2136 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2138 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2139 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2140 cli_close(cli, fnum);
2141 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2143 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2144 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2145 cli_close(cli, fnum);
2146 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2148 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2151 torture_close_connection(cli);
2153 printf("finished locktest6\n");
2157 static bool run_locktest7(int dummy)
2159 struct cli_state *cli1;
2160 const char *fname = "\\lockt7.lck";
2163 bool correct = False;
2166 if (!torture_open_connection(&cli1, 0)) {
2170 cli_sockopt(cli1, sockops);
2172 printf("starting locktest7\n");
2174 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2176 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2178 memset(buf, 0, sizeof(buf));
2180 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2182 if (!NT_STATUS_IS_OK(status)) {
2183 printf("Failed to create file: %s\n", nt_errstr(status));
2187 cli_setpid(cli1, 1);
2189 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2190 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2193 printf("pid1 successfully locked range 130:4 for READ\n");
2196 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2197 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2200 printf("pid1 successfully read the range 130:4\n");
2203 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2204 if (!NT_STATUS_IS_OK(status)) {
2205 printf("pid1 unable to write to the range 130:4, error was "
2206 "%s\n", nt_errstr(status));
2207 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2208 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2212 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2216 cli_setpid(cli1, 2);
2218 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2219 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2221 printf("pid2 successfully read the range 130:4\n");
2224 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2225 if (!NT_STATUS_IS_OK(status)) {
2226 printf("pid2 unable to write to the range 130:4, error was "
2227 "%s\n", nt_errstr(status));
2228 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2229 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2233 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2237 cli_setpid(cli1, 1);
2238 cli_unlock(cli1, fnum1, 130, 4);
2240 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2241 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2244 printf("pid1 successfully locked range 130:4 for WRITE\n");
2247 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2248 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2251 printf("pid1 successfully read the range 130:4\n");
2254 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2255 if (!NT_STATUS_IS_OK(status)) {
2256 printf("pid1 unable to write to the range 130:4, error was "
2257 "%s\n", nt_errstr(status));
2260 printf("pid1 successfully wrote to the range 130:4\n");
2263 cli_setpid(cli1, 2);
2265 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2266 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2267 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2268 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2272 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2276 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2277 if (!NT_STATUS_IS_OK(status)) {
2278 printf("pid2 unable to write to the range 130:4, error was "
2279 "%s\n", nt_errstr(status));
2280 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2281 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2285 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2289 cli_unlock(cli1, fnum1, 130, 0);
2293 cli_close(cli1, fnum1);
2294 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2295 torture_close_connection(cli1);
2297 printf("finished locktest7\n");
2302 * This demonstrates a problem with our use of GPFS share modes: A file
2303 * descriptor sitting in the pending close queue holding a GPFS share mode
2304 * blocks opening a file another time. Happens with Word 2007 temp files.
2305 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2306 * open is denied with NT_STATUS_SHARING_VIOLATION.
2309 static bool run_locktest8(int dummy)
2311 struct cli_state *cli1;
2312 const char *fname = "\\lockt8.lck";
2313 uint16_t fnum1, fnum2;
2315 bool correct = False;
2318 if (!torture_open_connection(&cli1, 0)) {
2322 cli_sockopt(cli1, sockops);
2324 printf("starting locktest8\n");
2326 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2328 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2330 if (!NT_STATUS_IS_OK(status)) {
2331 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2335 memset(buf, 0, sizeof(buf));
2337 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2338 if (!NT_STATUS_IS_OK(status)) {
2339 d_fprintf(stderr, "cli_open second time returned %s\n",
2344 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2345 printf("Unable to apply read lock on range 1:1, error was "
2346 "%s\n", cli_errstr(cli1));
2350 status = cli_close(cli1, fnum1);
2351 if (!NT_STATUS_IS_OK(status)) {
2352 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2356 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2357 if (!NT_STATUS_IS_OK(status)) {
2358 d_fprintf(stderr, "cli_open third time returned %s\n",
2366 cli_close(cli1, fnum1);
2367 cli_close(cli1, fnum2);
2368 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2369 torture_close_connection(cli1);
2371 printf("finished locktest8\n");
2376 * This test is designed to be run in conjunction with
2377 * external NFS or POSIX locks taken in the filesystem.
2378 * It checks that the smbd server will block until the
2379 * lock is released and then acquire it. JRA.
2382 static bool got_alarm;
2383 static int alarm_fd;
2385 static void alarm_handler(int dummy)
2390 static void alarm_handler_parent(int dummy)
2395 static void do_local_lock(int read_fd, int write_fd)
2400 const char *local_pathname = NULL;
2403 local_pathname = talloc_asprintf(talloc_tos(),
2404 "%s/lockt9.lck", local_path);
2405 if (!local_pathname) {
2406 printf("child: alloc fail\n");
2410 unlink(local_pathname);
2411 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2413 printf("child: open of %s failed %s.\n",
2414 local_pathname, strerror(errno));
2418 /* Now take a fcntl lock. */
2419 lock.l_type = F_WRLCK;
2420 lock.l_whence = SEEK_SET;
2423 lock.l_pid = getpid();
2425 ret = fcntl(fd,F_SETLK,&lock);
2427 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2428 local_pathname, strerror(errno));
2431 printf("child: got lock 0:4 on file %s.\n",
2436 CatchSignal(SIGALRM, alarm_handler);
2438 /* Signal the parent. */
2439 if (write(write_fd, &c, 1) != 1) {
2440 printf("child: start signal fail %s.\n",
2447 /* Wait for the parent to be ready. */
2448 if (read(read_fd, &c, 1) != 1) {
2449 printf("child: reply signal fail %s.\n",
2457 printf("child: released lock 0:4 on file %s.\n",
2463 static bool run_locktest9(int dummy)
2465 struct cli_state *cli1;
2466 const char *fname = "\\lockt9.lck";
2468 bool correct = False;
2469 int pipe_in[2], pipe_out[2];
2473 struct timeval start;
2477 printf("starting locktest9\n");
2479 if (local_path == NULL) {
2480 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2484 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2489 if (child_pid == -1) {
2493 if (child_pid == 0) {
2495 do_local_lock(pipe_out[0], pipe_in[1]);
2505 ret = read(pipe_in[0], &c, 1);
2507 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2512 if (!torture_open_connection(&cli1, 0)) {
2516 cli_sockopt(cli1, sockops);
2518 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2520 if (!NT_STATUS_IS_OK(status)) {
2521 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2525 /* Ensure the child has the lock. */
2526 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2527 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2530 d_printf("Child has the lock.\n");
2533 /* Tell the child to wait 5 seconds then exit. */
2534 ret = write(pipe_out[1], &c, 1);
2536 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2541 /* Wait 20 seconds for the lock. */
2542 alarm_fd = cli1->fd;
2543 CatchSignal(SIGALRM, alarm_handler_parent);
2546 start = timeval_current();
2548 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2549 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2550 "%s\n", cli_errstr(cli1));
2555 seconds = timeval_elapsed(&start);
2557 printf("Parent got the lock after %.2f seconds.\n",
2560 status = cli_close(cli1, fnum);
2561 if (!NT_STATUS_IS_OK(status)) {
2562 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2569 cli_close(cli1, fnum);
2570 torture_close_connection(cli1);
2574 printf("finished locktest9\n");
2579 test whether fnums and tids open on one VC are available on another (a major
2582 static bool run_fdpasstest(int dummy)
2584 struct cli_state *cli1, *cli2;
2585 const char *fname = "\\fdpass.tst";
2590 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2593 cli_sockopt(cli1, sockops);
2594 cli_sockopt(cli2, sockops);
2596 printf("starting fdpasstest\n");
2598 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2600 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2601 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2605 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2607 if (!NT_STATUS_IS_OK(status)) {
2608 printf("write failed (%s)\n", nt_errstr(status));
2612 cli2->vuid = cli1->vuid;
2613 cli2->cnum = cli1->cnum;
2614 cli2->pid = cli1->pid;
2616 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2617 printf("read succeeded! nasty security hole [%s]\n",
2622 cli_close(cli1, fnum1);
2623 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2625 torture_close_connection(cli1);
2626 torture_close_connection(cli2);
2628 printf("finished fdpasstest\n");
2632 static bool run_fdsesstest(int dummy)
2634 struct cli_state *cli;
2639 const char *fname = "\\fdsess.tst";
2640 const char *fname1 = "\\fdsess1.tst";
2647 if (!torture_open_connection(&cli, 0))
2649 cli_sockopt(cli, sockops);
2651 if (!torture_cli_session_setup2(cli, &new_vuid))
2654 saved_cnum = cli->cnum;
2655 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2657 new_cnum = cli->cnum;
2658 cli->cnum = saved_cnum;
2660 printf("starting fdsesstest\n");
2662 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2663 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2665 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2666 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2670 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2672 if (!NT_STATUS_IS_OK(status)) {
2673 printf("write failed (%s)\n", nt_errstr(status));
2677 saved_vuid = cli->vuid;
2678 cli->vuid = new_vuid;
2680 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2681 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2685 /* Try to open a file with different vuid, samba cnum. */
2686 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2687 printf("create with different vuid, same cnum succeeded.\n");
2688 cli_close(cli, fnum2);
2689 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2691 printf("create with different vuid, same cnum failed.\n");
2692 printf("This will cause problems with service clients.\n");
2696 cli->vuid = saved_vuid;
2698 /* Try with same vuid, different cnum. */
2699 cli->cnum = new_cnum;
2701 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2702 printf("read succeeded with different cnum![%s]\n",
2707 cli->cnum = saved_cnum;
2708 cli_close(cli, fnum1);
2709 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2711 torture_close_connection(cli);
2713 printf("finished fdsesstest\n");
2718 This test checks that
2720 1) the server does not allow an unlink on a file that is open
2722 static bool run_unlinktest(int dummy)
2724 struct cli_state *cli;
2725 const char *fname = "\\unlink.tst";
2727 bool correct = True;
2729 if (!torture_open_connection(&cli, 0)) {
2733 cli_sockopt(cli, sockops);
2735 printf("starting unlink test\n");
2737 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2741 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2742 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2746 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2747 printf("error: server allowed unlink on an open file\n");
2750 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2751 NT_STATUS_SHARING_VIOLATION);
2754 cli_close(cli, fnum);
2755 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2757 if (!torture_close_connection(cli)) {
2761 printf("unlink test finished\n");
2768 test how many open files this server supports on the one socket
2770 static bool run_maxfidtest(int dummy)
2772 struct cli_state *cli;
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,"\\maxfid.%d.%d", 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,"\\maxfid.%d.%d", 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, (const 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, (const 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(talloc_tos(), NT_STATUS(error)),
5914 get_nt_error_c_code(talloc_tos(), 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(talloc_tos(), 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 (const 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,
8015 discard_const_p(void, names[i]));
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 { "NOTIFY-ONLINE", run_notify_online },
8378 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8379 { "LOCAL-GENCACHE", run_local_gencache, 0},
8380 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8381 { "LOCAL-BASE64", run_local_base64, 0},
8382 { "LOCAL-RBTREE", run_local_rbtree, 0},
8383 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8384 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8385 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8386 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8387 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8388 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8389 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8390 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8395 /****************************************************************************
8396 run a specified test or "ALL"
8397 ****************************************************************************/
8398 static bool run_test(const char *name)
8405 if (strequal(name,"ALL")) {
8406 for (i=0;torture_ops[i].name;i++) {
8407 run_test(torture_ops[i].name);
8412 for (i=0;torture_ops[i].name;i++) {
8413 fstr_sprintf(randomfname, "\\XX%x",
8414 (unsigned)random());
8416 if (strequal(name, torture_ops[i].name)) {
8418 printf("Running %s\n", name);
8419 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8420 t = create_procs(torture_ops[i].fn, &result);
8423 printf("TEST %s FAILED!\n", name);
8426 struct timeval start;
8427 start = timeval_current();
8428 if (!torture_ops[i].fn(0)) {
8430 printf("TEST %s FAILED!\n", name);
8432 t = timeval_elapsed(&start);
8434 printf("%s took %g secs\n\n", name, t);
8439 printf("Did not find a test named %s\n", name);
8447 static void usage(void)
8451 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8452 printf("Please use samba4 torture.\n\n");
8454 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8456 printf("\t-d debuglevel\n");
8457 printf("\t-U user%%pass\n");
8458 printf("\t-k use kerberos\n");
8459 printf("\t-N numprocs\n");
8460 printf("\t-n my_netbios_name\n");
8461 printf("\t-W workgroup\n");
8462 printf("\t-o num_operations\n");
8463 printf("\t-O socket_options\n");
8464 printf("\t-m maximum protocol\n");
8465 printf("\t-L use oplocks\n");
8466 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8467 printf("\t-A showall\n");
8468 printf("\t-p port\n");
8469 printf("\t-s seed\n");
8470 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8471 printf("\t-f filename filename to test\n");
8474 printf("tests are:");
8475 for (i=0;torture_ops[i].name;i++) {
8476 printf(" %s", torture_ops[i].name);
8480 printf("default test is ALL\n");
8485 /****************************************************************************
8487 ****************************************************************************/
8488 int main(int argc,char *argv[])
8494 bool correct = True;
8495 TALLOC_CTX *frame = talloc_stackframe();
8496 int seed = time(NULL);
8498 #ifdef HAVE_SETBUFFER
8499 setbuffer(stdout, NULL, 0);
8502 setup_logging("smbtorture", DEBUG_STDOUT);
8506 if (is_default_dyn_CONFIGFILE()) {
8507 if(getenv("SMB_CONF_PATH")) {
8508 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8511 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8518 for(p = argv[1]; *p; p++)
8522 if (strncmp(argv[1], "//", 2)) {
8526 fstrcpy(host, &argv[1][2]);
8527 p = strchr_m(&host[2],'/');
8532 fstrcpy(share, p+1);
8534 fstrcpy(myname, get_myname(talloc_tos()));
8536 fprintf(stderr, "Failed to get my hostname.\n");
8540 if (*username == 0 && getenv("LOGNAME")) {
8541 fstrcpy(username,getenv("LOGNAME"));
8547 fstrcpy(workgroup, lp_workgroup());
8549 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8553 port_to_use = atoi(optarg);
8556 seed = atoi(optarg);
8559 fstrcpy(workgroup,optarg);
8562 max_protocol = interpret_protocol(optarg, max_protocol);
8565 nprocs = atoi(optarg);
8568 torture_numops = atoi(optarg);
8571 lp_set_cmdline("log level", optarg);
8580 local_path = optarg;
8583 torture_showall = True;
8586 fstrcpy(myname, optarg);
8589 client_txt = optarg;
8596 use_kerberos = True;
8598 d_printf("No kerberos support compiled in\n");
8604 fstrcpy(username,optarg);
8605 p = strchr_m(username,'%');
8608 fstrcpy(password, p+1);
8613 fstrcpy(multishare_conn_fname, optarg);
8614 use_multishare_conn = True;
8617 torture_blocksize = atoi(optarg);
8620 test_filename = SMB_STRDUP(optarg);
8623 printf("Unknown option %c (%d)\n", (char)opt, opt);
8628 d_printf("using seed %d\n", seed);
8632 if(use_kerberos && !gotuser) gotpass = True;
8635 p = getpass("Password:");
8637 fstrcpy(password, p);
8642 printf("host=%s share=%s user=%s myname=%s\n",
8643 host, share, username, myname);
8645 if (argc == optind) {
8646 correct = run_test("ALL");
8648 for (i=optind;i<argc;i++) {
8649 if (!run_test(argv[i])) {