2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
30 #include "nsswitch/winbind_client.h"
32 #include "talloc_dict.h"
33 #include "async_smb.h"
34 #include "libsmb/clirap.h"
36 #include "libsmb/nmblib.h"
37 #include "../lib/util/tevent_ntstatus.h"
42 static fstring host, workgroup, share, password, username, myname;
43 static int max_protocol = PROTOCOL_NT1;
44 static const char *sockops="TCP_NODELAY";
46 static int port_to_use=0;
47 int torture_numops=100;
48 int torture_blocksize=1024*1024;
49 static int procnum; /* records process count number when forking */
50 static struct cli_state *current_cli;
51 static fstring randomfname;
52 static bool use_oplocks;
53 static bool use_level_II_oplocks;
54 static const char *client_txt = "client_oplocks.txt";
55 static bool use_kerberos;
56 static fstring multishare_conn_fname;
57 static bool use_multishare_conn = False;
58 static bool do_encrypt;
59 static const char *local_path = NULL;
60 static int signing_state = Undefined;
62 bool torture_showall = False;
64 static double create_procs(bool (*fn)(int), bool *result);
67 /* return a pointer to a anonymous shared memory segment of size "size"
68 which will persist across fork() but will disappear when all processes
71 The memory is not zeroed
73 This function uses system5 shared memory. It takes advantage of a property
74 that the memory is not destroyed if it is attached when the id is removed
76 void *shm_setup(int size)
82 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
84 printf("can't get shared memory\n");
87 shm_unlink("private");
88 if (ftruncate(shmid, size) == -1) {
89 printf("can't set shared memory size\n");
92 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
93 if (ret == MAP_FAILED) {
94 printf("can't map shared memory\n");
98 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
100 printf("can't get shared memory\n");
103 ret = (void *)shmat(shmid, 0, 0);
104 if (!ret || ret == (void *)-1) {
105 printf("can't attach to shared memory\n");
108 /* the following releases the ipc, but note that this process
109 and all its children will still have access to the memory, its
110 just that the shmid is no longer valid for other shm calls. This
111 means we don't leave behind lots of shm segments after we exit
113 See Stevens "advanced programming in unix env" for details
115 shmctl(shmid, IPC_RMID, 0);
121 /********************************************************************
122 Ensure a connection is encrypted.
123 ********************************************************************/
125 static bool force_cli_encryption(struct cli_state *c,
126 const char *sharename)
129 uint32 caplow, caphigh;
132 if (!SERVER_HAS_UNIX_CIFS(c)) {
133 d_printf("Encryption required and "
134 "server that doesn't support "
135 "UNIX extensions - failing connect\n");
139 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
141 if (!NT_STATUS_IS_OK(status)) {
142 d_printf("Encryption required and "
143 "can't get UNIX CIFS extensions "
144 "version from server: %s\n", nt_errstr(status));
148 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
149 d_printf("Encryption required and "
150 "share %s doesn't support "
151 "encryption.\n", sharename);
155 if (c->use_kerberos) {
156 status = cli_gss_smb_encryption_start(c);
158 status = cli_raw_ntlm_smb_encryption_start(c,
164 if (!NT_STATUS_IS_OK(status)) {
165 d_printf("Encryption required and "
166 "setup failed with error %s.\n",
175 static struct cli_state *open_nbt_connection(void)
177 struct nmb_name called, calling;
178 struct sockaddr_storage ss;
182 make_nmb_name(&calling, myname, 0x0);
183 make_nmb_name(&called , host, 0x20);
187 if (!(c = cli_initialise_ex(signing_state))) {
188 printf("Failed initialize cli_struct to connect with %s\n", host);
192 c->port = port_to_use;
194 status = cli_connect(c, host, &ss);
195 if (!NT_STATUS_IS_OK(status)) {
196 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
200 c->use_kerberos = use_kerberos;
202 c->timeout = 120000; /* set a really long timeout (2 minutes) */
203 if (use_oplocks) c->use_oplocks = True;
204 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
206 if (!cli_session_request(c, &calling, &called)) {
208 * Well, that failed, try *SMBSERVER ...
209 * However, we must reconnect as well ...
211 status = cli_connect(c, host, &ss);
212 if (!NT_STATUS_IS_OK(status)) {
213 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
217 make_nmb_name(&called, "*SMBSERVER", 0x20);
218 if (!cli_session_request(c, &calling, &called)) {
219 printf("%s rejected the session\n",host);
220 printf("We tried with a called name of %s & %s\n",
230 /****************************************************************************
231 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
232 ****************************************************************************/
234 static bool cli_bad_session_request(struct cli_state *cli,
235 struct nmb_name *calling, struct nmb_name *called)
242 memcpy(&(cli->calling), calling, sizeof(*calling));
243 memcpy(&(cli->called ), called , sizeof(*called ));
245 /* put in the destination name */
247 tmp = name_mangle(talloc_tos(), cli->called.name,
248 cli->called.name_type);
254 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
256 memcpy(p, tmp, namelen);
261 /* Deliberately corrupt the name len (first byte) */
266 tmp = name_mangle(talloc_tos(), cli->calling.name,
267 cli->calling.name_type);
273 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
275 memcpy(p, tmp, namelen);
279 /* Deliberately corrupt the name len (first byte) */
282 /* send a session request (RFC 1002) */
283 /* setup the packet length
284 * Remove four bytes from the length count, since the length
285 * field in the NBT Session Service header counts the number
286 * of bytes which follow. The cli_send_smb() function knows
287 * about this and accounts for those four bytes.
291 _smb_setlen(cli->outbuf,len);
292 SCVAL(cli->outbuf,0,0x81);
295 DEBUG(5,("Sent session request\n"));
297 if (!cli_receive_smb(cli))
300 if (CVAL(cli->inbuf,0) != 0x82) {
301 /* This is the wrong place to put the error... JRA. */
302 cli->rap_error = CVAL(cli->inbuf,4);
308 static struct cli_state *open_bad_nbt_connection(void)
310 struct nmb_name called, calling;
311 struct sockaddr_storage ss;
315 make_nmb_name(&calling, myname, 0x0);
316 make_nmb_name(&called , host, 0x20);
320 if (!(c = cli_initialise_ex(signing_state))) {
321 printf("Failed initialize cli_struct to connect with %s\n", host);
327 status = cli_connect(c, host, &ss);
328 if (!NT_STATUS_IS_OK(status)) {
329 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
333 c->timeout = 4000; /* set a short timeout (4 seconds) */
335 if (!cli_bad_session_request(c, &calling, &called)) {
336 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
344 /* Insert a NULL at the first separator of the given path and return a pointer
345 * to the remainder of the string.
348 terminate_path_at_separator(char * path)
356 if ((p = strchr_m(path, '/'))) {
361 if ((p = strchr_m(path, '\\'))) {
371 parse a //server/share type UNC name
373 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
374 char **hostname, char **sharename)
378 *hostname = *sharename = NULL;
380 if (strncmp(unc_name, "\\\\", 2) &&
381 strncmp(unc_name, "//", 2)) {
385 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
386 p = terminate_path_at_separator(*hostname);
389 *sharename = talloc_strdup(mem_ctx, p);
390 terminate_path_at_separator(*sharename);
393 if (*hostname && *sharename) {
397 TALLOC_FREE(*hostname);
398 TALLOC_FREE(*sharename);
402 static bool torture_open_connection_share(struct cli_state **c,
403 const char *hostname,
404 const char *sharename)
410 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
412 flags |= CLI_FULL_CONNECTION_OPLOCKS;
413 if (use_level_II_oplocks)
414 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
416 status = cli_full_connection(c, myname,
417 hostname, NULL, port_to_use,
420 password, flags, signing_state);
421 if (!NT_STATUS_IS_OK(status)) {
422 printf("failed to open share connection: //%s/%s port:%d - %s\n",
423 hostname, sharename, port_to_use, nt_errstr(status));
427 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
430 return force_cli_encryption(*c,
436 bool torture_open_connection(struct cli_state **c, int conn_index)
438 char **unc_list = NULL;
439 int num_unc_names = 0;
442 if (use_multishare_conn==True) {
444 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
445 if (!unc_list || num_unc_names <= 0) {
446 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
450 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
452 printf("Failed to parse UNC name %s\n",
453 unc_list[conn_index % num_unc_names]);
454 TALLOC_FREE(unc_list);
458 result = torture_open_connection_share(c, h, s);
460 /* h, s were copied earlier */
461 TALLOC_FREE(unc_list);
465 return torture_open_connection_share(c, host, share);
468 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
470 uint16 old_vuid = cli->vuid;
471 fstring old_user_name;
472 size_t passlen = strlen(password);
476 fstrcpy(old_user_name, cli->user_name);
478 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
482 *new_vuid = cli->vuid;
483 cli->vuid = old_vuid;
484 status = cli_set_username(cli, old_user_name);
485 if (!NT_STATUS_IS_OK(status)) {
492 bool torture_close_connection(struct cli_state *c)
497 status = cli_tdis(c);
498 if (!NT_STATUS_IS_OK(status)) {
499 printf("tdis failed (%s)\n", nt_errstr(status));
509 /* check if the server produced the expected error code */
510 static bool check_error(int line, struct cli_state *c,
511 uint8 eclass, uint32 ecode, NTSTATUS nterr)
513 if (cli_is_dos_error(c)) {
517 /* Check DOS error */
519 cli_dos_error(c, &cclass, &num);
521 if (eclass != cclass || ecode != num) {
522 printf("unexpected error code class=%d code=%d\n",
523 (int)cclass, (int)num);
524 printf(" expected %d/%d %s (line=%d)\n",
525 (int)eclass, (int)ecode, nt_errstr(nterr), line);
534 status = cli_nt_error(c);
536 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
537 printf("unexpected error code %s\n", nt_errstr(status));
538 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
547 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
549 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
550 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
556 static bool rw_torture(struct cli_state *c)
558 const char *lockfname = "\\torture.lck";
562 pid_t pid2, pid = getpid();
568 memset(buf, '\0', sizeof(buf));
570 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
572 if (!NT_STATUS_IS_OK(status)) {
573 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
575 if (!NT_STATUS_IS_OK(status)) {
576 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
580 for (i=0;i<torture_numops;i++) {
581 unsigned n = (unsigned)sys_random()%10;
584 printf("%d\r", i); fflush(stdout);
586 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
588 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
592 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
593 printf("open failed (%s)\n", cli_errstr(c));
598 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
600 if (!NT_STATUS_IS_OK(status)) {
601 printf("write failed (%s)\n", nt_errstr(status));
606 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
607 sizeof(pid)+(j*sizeof(buf)),
609 if (!NT_STATUS_IS_OK(status)) {
610 printf("write failed (%s)\n",
618 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
619 printf("read failed (%s)\n", cli_errstr(c));
624 printf("data corruption!\n");
628 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
629 printf("close failed (%s)\n", cli_errstr(c));
633 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
634 printf("unlink failed (%s)\n", cli_errstr(c));
638 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
639 printf("unlock failed (%s)\n", cli_errstr(c));
645 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
652 static bool run_torture(int dummy)
654 struct cli_state *cli;
659 cli_sockopt(cli, sockops);
661 ret = rw_torture(cli);
663 if (!torture_close_connection(cli)) {
670 static bool rw_torture3(struct cli_state *c, char *lockfname)
672 uint16_t fnum = (uint16_t)-1;
677 unsigned countprev = 0;
680 NTSTATUS status = NT_STATUS_OK;
683 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
685 SIVAL(buf, i, sys_random());
690 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
691 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
694 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
695 DENY_NONE, &fnum))) {
696 printf("first open read/write of %s failed (%s)\n",
697 lockfname, cli_errstr(c));
703 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
705 status = cli_open(c, lockfname, O_RDONLY,
707 if (!NT_STATUS_IS_OK(status)) {
712 if (!NT_STATUS_IS_OK(status)) {
713 printf("second open read-only of %s failed (%s)\n",
714 lockfname, cli_errstr(c));
720 for (count = 0; count < sizeof(buf); count += sent)
722 if (count >= countprev) {
723 printf("%d %8d\r", i, count);
726 countprev += (sizeof(buf) / 20);
731 sent = ((unsigned)sys_random()%(20))+ 1;
732 if (sent > sizeof(buf) - count)
734 sent = sizeof(buf) - count;
737 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
738 count, (size_t)sent, NULL);
739 if (!NT_STATUS_IS_OK(status)) {
740 printf("write failed (%s)\n",
747 sent = cli_read(c, fnum, buf_rd+count, count,
751 printf("read failed offset:%d size:%ld (%s)\n",
752 count, (unsigned long)sizeof(buf)-count,
759 if (memcmp(buf_rd+count, buf+count, sent) != 0)
761 printf("read/write compare failed\n");
762 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
771 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
772 printf("close failed (%s)\n", cli_errstr(c));
779 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
781 const char *lockfname = "\\torture2.lck";
790 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
791 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
794 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
795 DENY_NONE, &fnum1))) {
796 printf("first open read/write of %s failed (%s)\n",
797 lockfname, cli_errstr(c1));
800 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
801 DENY_NONE, &fnum2))) {
802 printf("second open read-only of %s failed (%s)\n",
803 lockfname, cli_errstr(c2));
804 cli_close(c1, fnum1);
808 for (i=0;i<torture_numops;i++)
811 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
813 printf("%d\r", i); fflush(stdout);
816 generate_random_buffer((unsigned char *)buf, buf_size);
818 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
820 if (!NT_STATUS_IS_OK(status)) {
821 printf("write failed (%s)\n", nt_errstr(status));
826 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
827 printf("read failed (%s)\n", cli_errstr(c2));
828 printf("read %d, expected %ld\n", (int)bytes_read,
829 (unsigned long)buf_size);
834 if (memcmp(buf_rd, buf, buf_size) != 0)
836 printf("read/write compare failed\n");
842 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
843 printf("close failed (%s)\n", cli_errstr(c2));
846 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
847 printf("close failed (%s)\n", cli_errstr(c1));
851 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
852 printf("unlink failed (%s)\n", cli_errstr(c1));
859 static bool run_readwritetest(int dummy)
861 struct cli_state *cli1, *cli2;
862 bool test1, test2 = False;
864 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
867 cli_sockopt(cli1, sockops);
868 cli_sockopt(cli2, sockops);
870 printf("starting readwritetest\n");
872 test1 = rw_torture2(cli1, cli2);
873 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
876 test2 = rw_torture2(cli1, cli1);
877 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
880 if (!torture_close_connection(cli1)) {
884 if (!torture_close_connection(cli2)) {
888 return (test1 && test2);
891 static bool run_readwritemulti(int dummy)
893 struct cli_state *cli;
898 cli_sockopt(cli, sockops);
900 printf("run_readwritemulti: fname %s\n", randomfname);
901 test = rw_torture3(cli, randomfname);
903 if (!torture_close_connection(cli)) {
910 static bool run_readwritelarge_internal(int max_xmit_k)
912 static struct cli_state *cli1;
914 const char *lockfname = "\\large.dat";
919 if (!torture_open_connection(&cli1, 0)) {
922 cli_sockopt(cli1, sockops);
923 memset(buf,'\0',sizeof(buf));
925 cli1->max_xmit = max_xmit_k*1024;
927 if (signing_state == Required) {
928 /* Horrible cheat to force
929 multiple signed outstanding
930 packets against a Samba server.
932 cli1->is_samba = false;
935 printf("starting readwritelarge_internal\n");
937 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
939 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
940 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
944 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
946 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
947 cli1, fnum1, NULL, &fsize, NULL, NULL,
948 NULL, NULL, NULL))) {
949 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
953 if (fsize == sizeof(buf))
954 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
955 (unsigned long)fsize);
957 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
958 (unsigned long)fsize);
962 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
963 printf("close failed (%s)\n", cli_errstr(cli1));
967 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
968 printf("unlink failed (%s)\n", cli_errstr(cli1));
972 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
973 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
977 cli1->max_xmit = 4*1024;
979 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
981 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
982 cli1, fnum1, NULL, &fsize, NULL, NULL,
983 NULL, NULL, NULL))) {
984 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
988 if (fsize == sizeof(buf))
989 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
990 (unsigned long)fsize);
992 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
993 (unsigned long)fsize);
998 /* ToDo - set allocation. JRA */
999 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1000 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1003 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1005 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1009 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1012 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1013 printf("close failed (%s)\n", cli_errstr(cli1));
1017 if (!torture_close_connection(cli1)) {
1023 static bool run_readwritelarge(int dummy)
1025 return run_readwritelarge_internal(128);
1028 static bool run_readwritelarge_signtest(int dummy)
1031 signing_state = Required;
1032 ret = run_readwritelarge_internal(2);
1033 signing_state = Undefined;
1040 #define ival(s) strtol(s, NULL, 0)
1042 /* run a test that simulates an approximate netbench client load */
1043 static bool run_netbench(int client)
1045 struct cli_state *cli;
1050 const char *params[20];
1051 bool correct = True;
1057 cli_sockopt(cli, sockops);
1061 slprintf(cname,sizeof(cname)-1, "client%d", client);
1063 f = fopen(client_txt, "r");
1070 while (fgets(line, sizeof(line)-1, f)) {
1074 line[strlen(line)-1] = 0;
1076 /* printf("[%d] %s\n", line_count, line); */
1078 all_string_sub(line,"client1", cname, sizeof(line));
1080 /* parse the command parameters */
1081 params[0] = strtok_r(line, " ", &saveptr);
1083 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1087 if (i < 2) continue;
1089 if (!strncmp(params[0],"SMB", 3)) {
1090 printf("ERROR: You are using a dbench 1 load file\n");
1094 if (!strcmp(params[0],"NTCreateX")) {
1095 nb_createx(params[1], ival(params[2]), ival(params[3]),
1097 } else if (!strcmp(params[0],"Close")) {
1098 nb_close(ival(params[1]));
1099 } else if (!strcmp(params[0],"Rename")) {
1100 nb_rename(params[1], params[2]);
1101 } else if (!strcmp(params[0],"Unlink")) {
1102 nb_unlink(params[1]);
1103 } else if (!strcmp(params[0],"Deltree")) {
1104 nb_deltree(params[1]);
1105 } else if (!strcmp(params[0],"Rmdir")) {
1106 nb_rmdir(params[1]);
1107 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1108 nb_qpathinfo(params[1]);
1109 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1110 nb_qfileinfo(ival(params[1]));
1111 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1112 nb_qfsinfo(ival(params[1]));
1113 } else if (!strcmp(params[0],"FIND_FIRST")) {
1114 nb_findfirst(params[1]);
1115 } else if (!strcmp(params[0],"WriteX")) {
1116 nb_writex(ival(params[1]),
1117 ival(params[2]), ival(params[3]), ival(params[4]));
1118 } else if (!strcmp(params[0],"ReadX")) {
1119 nb_readx(ival(params[1]),
1120 ival(params[2]), ival(params[3]), ival(params[4]));
1121 } else if (!strcmp(params[0],"Flush")) {
1122 nb_flush(ival(params[1]));
1124 printf("Unknown operation %s\n", params[0]);
1132 if (!torture_close_connection(cli)) {
1140 /* run a test that simulates an approximate netbench client load */
1141 static bool run_nbench(int dummy)
1144 bool correct = True;
1150 signal(SIGALRM, nb_alarm);
1152 t = create_procs(run_netbench, &correct);
1155 printf("\nThroughput %g MB/sec\n",
1156 1.0e-6 * nbio_total() / t);
1162 This test checks for two things:
1164 1) correct support for retaining locks over a close (ie. the server
1165 must not use posix semantics)
1166 2) support for lock timeouts
1168 static bool run_locktest1(int dummy)
1170 struct cli_state *cli1, *cli2;
1171 const char *fname = "\\lockt1.lck";
1172 uint16_t fnum1, fnum2, fnum3;
1174 unsigned lock_timeout;
1176 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1179 cli_sockopt(cli1, sockops);
1180 cli_sockopt(cli2, sockops);
1182 printf("starting locktest1\n");
1184 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1186 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1187 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1190 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1191 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1194 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1195 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1199 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1200 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1205 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1206 printf("lock2 succeeded! This is a locking bug\n");
1209 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1210 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1214 lock_timeout = (1 + (random() % 20));
1215 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1217 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1218 printf("lock3 succeeded! This is a locking bug\n");
1221 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1222 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1226 if (ABS(t2 - t1) < lock_timeout-1) {
1227 printf("error: This server appears not to support timed lock requests\n");
1230 printf("server slept for %u seconds for a %u second timeout\n",
1231 (unsigned int)(t2-t1), lock_timeout);
1233 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1234 printf("close1 failed (%s)\n", cli_errstr(cli1));
1238 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1239 printf("lock4 succeeded! This is a locking bug\n");
1242 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1243 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1246 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1247 printf("close2 failed (%s)\n", cli_errstr(cli1));
1251 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1252 printf("close3 failed (%s)\n", cli_errstr(cli2));
1256 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1257 printf("unlink failed (%s)\n", cli_errstr(cli1));
1262 if (!torture_close_connection(cli1)) {
1266 if (!torture_close_connection(cli2)) {
1270 printf("Passed locktest1\n");
1275 this checks to see if a secondary tconx can use open files from an
1278 static bool run_tcon_test(int dummy)
1280 static struct cli_state *cli;
1281 const char *fname = "\\tcontest.tmp";
1283 uint16 cnum1, cnum2, cnum3;
1284 uint16 vuid1, vuid2;
1289 memset(buf, '\0', sizeof(buf));
1291 if (!torture_open_connection(&cli, 0)) {
1294 cli_sockopt(cli, sockops);
1296 printf("starting tcontest\n");
1298 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1300 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1301 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1308 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1309 if (!NT_STATUS_IS_OK(status)) {
1310 printf("initial write failed (%s)", nt_errstr(status));
1314 status = cli_tcon_andx(cli, share, "?????",
1315 password, strlen(password)+1);
1316 if (!NT_STATUS_IS_OK(status)) {
1317 printf("%s refused 2nd tree connect (%s)\n", host,
1324 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1325 vuid2 = cli->vuid + 1;
1327 /* try a write with the wrong tid */
1330 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1331 if (NT_STATUS_IS_OK(status)) {
1332 printf("* server allows write with wrong TID\n");
1335 printf("server fails write with wrong TID : %s\n",
1340 /* try a write with an invalid tid */
1343 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1344 if (NT_STATUS_IS_OK(status)) {
1345 printf("* server allows write with invalid TID\n");
1348 printf("server fails write with invalid TID : %s\n",
1352 /* try a write with an invalid vuid */
1356 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1357 if (NT_STATUS_IS_OK(status)) {
1358 printf("* server allows write with invalid VUID\n");
1361 printf("server fails write with invalid VUID : %s\n",
1368 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1369 printf("close failed (%s)\n", cli_errstr(cli));
1375 status = cli_tdis(cli);
1376 if (!NT_STATUS_IS_OK(status)) {
1377 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1383 if (!torture_close_connection(cli)) {
1392 checks for old style tcon support
1394 static bool run_tcon2_test(int dummy)
1396 static struct cli_state *cli;
1397 uint16 cnum, max_xmit;
1401 if (!torture_open_connection(&cli, 0)) {
1404 cli_sockopt(cli, sockops);
1406 printf("starting tcon2 test\n");
1408 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1412 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1416 if (!NT_STATUS_IS_OK(status)) {
1417 printf("tcon2 failed : %s\n", nt_errstr(status));
1419 printf("tcon OK : max_xmit=%d cnum=%d\n",
1420 (int)max_xmit, (int)cnum);
1423 if (!torture_close_connection(cli)) {
1427 printf("Passed tcon2 test\n");
1431 static bool tcon_devtest(struct cli_state *cli,
1432 const char *myshare, const char *devtype,
1433 const char *return_devtype,
1434 NTSTATUS expected_error)
1439 status = cli_tcon_andx(cli, myshare, devtype,
1440 password, strlen(password)+1);
1442 if (NT_STATUS_IS_OK(expected_error)) {
1443 if (NT_STATUS_IS_OK(status)) {
1444 if (strcmp(cli->dev, return_devtype) == 0) {
1447 printf("tconX to share %s with type %s "
1448 "succeeded but returned the wrong "
1449 "device type (got [%s] but should have got [%s])\n",
1450 myshare, devtype, cli->dev, return_devtype);
1454 printf("tconX to share %s with type %s "
1455 "should have succeeded but failed\n",
1461 if (NT_STATUS_IS_OK(status)) {
1462 printf("tconx to share %s with type %s "
1463 "should have failed but succeeded\n",
1467 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1471 printf("Returned unexpected error\n");
1480 checks for correct tconX support
1482 static bool run_tcon_devtype_test(int dummy)
1484 static struct cli_state *cli1 = NULL;
1489 status = cli_full_connection(&cli1, myname,
1490 host, NULL, port_to_use,
1492 username, workgroup,
1493 password, flags, signing_state);
1495 if (!NT_STATUS_IS_OK(status)) {
1496 printf("could not open connection\n");
1500 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1503 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1506 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1509 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1512 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1515 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1518 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1521 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1524 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1527 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1533 printf("Passed tcondevtest\n");
1540 This test checks that
1542 1) the server supports multiple locking contexts on the one SMB
1543 connection, distinguished by PID.
1545 2) the server correctly fails overlapping locks made by the same PID (this
1546 goes against POSIX behaviour, which is why it is tricky to implement)
1548 3) the server denies unlock requests by an incorrect client PID
1550 static bool run_locktest2(int dummy)
1552 static struct cli_state *cli;
1553 const char *fname = "\\lockt2.lck";
1554 uint16_t fnum1, fnum2, fnum3;
1555 bool correct = True;
1557 if (!torture_open_connection(&cli, 0)) {
1561 cli_sockopt(cli, sockops);
1563 printf("starting locktest2\n");
1565 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1569 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1570 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1574 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1575 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1581 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1582 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1588 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1589 printf("lock1 failed (%s)\n", cli_errstr(cli));
1593 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1594 printf("WRITE lock1 succeeded! This is a locking bug\n");
1597 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1598 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1601 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1602 printf("WRITE lock2 succeeded! This is a locking bug\n");
1605 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1606 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1609 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1610 printf("READ lock2 succeeded! This is a locking bug\n");
1613 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1614 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1617 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1618 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1621 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1622 printf("unlock at 100 succeeded! This is a locking bug\n");
1626 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1627 printf("unlock1 succeeded! This is a locking bug\n");
1630 if (!check_error(__LINE__, cli,
1632 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1635 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1636 printf("unlock2 succeeded! This is a locking bug\n");
1639 if (!check_error(__LINE__, cli,
1641 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1644 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1645 printf("lock3 succeeded! This is a locking bug\n");
1648 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1653 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1654 printf("close1 failed (%s)\n", cli_errstr(cli));
1658 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1659 printf("close2 failed (%s)\n", cli_errstr(cli));
1663 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1664 printf("close3 failed (%s)\n", cli_errstr(cli));
1668 if (!torture_close_connection(cli)) {
1672 printf("locktest2 finished\n");
1679 This test checks that
1681 1) the server supports the full offset range in lock requests
1683 static bool run_locktest3(int dummy)
1685 static struct cli_state *cli1, *cli2;
1686 const char *fname = "\\lockt3.lck";
1687 uint16_t fnum1, fnum2;
1690 bool correct = True;
1692 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1694 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1697 cli_sockopt(cli1, sockops);
1698 cli_sockopt(cli2, sockops);
1700 printf("starting locktest3\n");
1702 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1704 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1705 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1708 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1709 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1713 for (offset=i=0;i<torture_numops;i++) {
1715 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1716 printf("lock1 %d failed (%s)\n",
1722 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1723 printf("lock2 %d failed (%s)\n",
1730 for (offset=i=0;i<torture_numops;i++) {
1733 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1734 printf("error: lock1 %d succeeded!\n", i);
1738 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1739 printf("error: lock2 %d succeeded!\n", i);
1743 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1744 printf("error: lock3 %d succeeded!\n", i);
1748 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1749 printf("error: lock4 %d succeeded!\n", i);
1754 for (offset=i=0;i<torture_numops;i++) {
1757 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1758 printf("unlock1 %d failed (%s)\n",
1764 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1765 printf("unlock2 %d failed (%s)\n",
1772 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1773 printf("close1 failed (%s)\n", cli_errstr(cli1));
1777 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1778 printf("close2 failed (%s)\n", cli_errstr(cli2));
1782 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
1783 printf("unlink failed (%s)\n", cli_errstr(cli1));
1787 if (!torture_close_connection(cli1)) {
1791 if (!torture_close_connection(cli2)) {
1795 printf("finished locktest3\n");
1800 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1801 printf("** "); correct = False; \
1805 looks at overlapping locks
1807 static bool run_locktest4(int dummy)
1809 static struct cli_state *cli1, *cli2;
1810 const char *fname = "\\lockt4.lck";
1811 uint16_t fnum1, fnum2, f;
1814 bool correct = True;
1817 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1821 cli_sockopt(cli1, sockops);
1822 cli_sockopt(cli2, sockops);
1824 printf("starting locktest4\n");
1826 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1828 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1829 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1831 memset(buf, 0, sizeof(buf));
1833 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1835 if (!NT_STATUS_IS_OK(status)) {
1836 printf("Failed to create file: %s\n", nt_errstr(status));
1841 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1842 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1843 EXPECTED(ret, False);
1844 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1846 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1847 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1848 EXPECTED(ret, True);
1849 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1851 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1852 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1853 EXPECTED(ret, False);
1854 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1856 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1857 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1858 EXPECTED(ret, True);
1859 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1861 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1862 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1863 EXPECTED(ret, False);
1864 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1866 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1867 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1868 EXPECTED(ret, True);
1869 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1871 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1872 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1873 EXPECTED(ret, True);
1874 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1876 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1877 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1878 EXPECTED(ret, False);
1879 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1881 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1882 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1883 EXPECTED(ret, False);
1884 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1886 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1887 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1888 EXPECTED(ret, True);
1889 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1891 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1892 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1893 EXPECTED(ret, False);
1894 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1896 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1897 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1898 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1899 EXPECTED(ret, False);
1900 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1903 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1904 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1905 EXPECTED(ret, False);
1906 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1908 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1910 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1912 ret = NT_STATUS_IS_OK(status);
1914 EXPECTED(ret, False);
1915 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1918 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1919 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1920 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1921 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1922 EXPECTED(ret, True);
1923 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1926 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1927 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1928 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1929 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1930 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1932 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1933 EXPECTED(ret, True);
1934 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1936 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1937 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1938 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1940 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1941 EXPECTED(ret, True);
1942 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1944 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1945 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1946 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1948 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1949 EXPECTED(ret, True);
1950 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1952 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1953 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1954 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1955 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1957 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1958 EXPECTED(ret, True);
1959 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1961 cli_close(cli1, fnum1);
1962 cli_close(cli2, fnum2);
1963 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1964 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1965 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1966 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1967 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1968 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1969 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1971 cli_close(cli1, fnum1);
1972 EXPECTED(ret, True);
1973 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1976 cli_close(cli1, fnum1);
1977 cli_close(cli2, fnum2);
1978 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1979 torture_close_connection(cli1);
1980 torture_close_connection(cli2);
1982 printf("finished locktest4\n");
1987 looks at lock upgrade/downgrade.
1989 static bool run_locktest5(int dummy)
1991 static struct cli_state *cli1, *cli2;
1992 const char *fname = "\\lockt5.lck";
1993 uint16_t fnum1, fnum2, fnum3;
1996 bool correct = True;
1999 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2003 cli_sockopt(cli1, sockops);
2004 cli_sockopt(cli2, sockops);
2006 printf("starting locktest5\n");
2008 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2010 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2011 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2012 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2014 memset(buf, 0, sizeof(buf));
2016 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2018 if (!NT_STATUS_IS_OK(status)) {
2019 printf("Failed to create file: %s\n", nt_errstr(status));
2024 /* Check for NT bug... */
2025 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2026 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2027 cli_close(cli1, fnum1);
2028 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2029 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2030 EXPECTED(ret, True);
2031 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2032 cli_close(cli1, fnum1);
2033 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2034 cli_unlock(cli1, fnum3, 0, 1);
2036 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2037 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2038 EXPECTED(ret, True);
2039 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2041 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2042 EXPECTED(ret, False);
2044 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2046 /* Unlock the process 2 lock. */
2047 cli_unlock(cli2, fnum2, 0, 4);
2049 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2050 EXPECTED(ret, False);
2052 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2054 /* Unlock the process 1 fnum3 lock. */
2055 cli_unlock(cli1, fnum3, 0, 4);
2057 /* Stack 2 more locks here. */
2058 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2059 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2061 EXPECTED(ret, True);
2062 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2064 /* Unlock the first process lock, then check this was the WRITE lock that was
2067 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2068 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2070 EXPECTED(ret, True);
2071 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2073 /* Unlock the process 2 lock. */
2074 cli_unlock(cli2, fnum2, 0, 4);
2076 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2078 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2079 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2080 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2082 EXPECTED(ret, True);
2083 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2085 /* Ensure the next unlock fails. */
2086 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2087 EXPECTED(ret, False);
2088 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2090 /* Ensure connection 2 can get a write lock. */
2091 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2092 EXPECTED(ret, True);
2094 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2098 cli_close(cli1, fnum1);
2099 cli_close(cli2, fnum2);
2100 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2101 if (!torture_close_connection(cli1)) {
2104 if (!torture_close_connection(cli2)) {
2108 printf("finished locktest5\n");
2114 tries the unusual lockingX locktype bits
2116 static bool run_locktest6(int dummy)
2118 static struct cli_state *cli;
2119 const char *fname[1] = { "\\lock6.txt" };
2124 if (!torture_open_connection(&cli, 0)) {
2128 cli_sockopt(cli, sockops);
2130 printf("starting locktest6\n");
2133 printf("Testing %s\n", fname[i]);
2135 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2137 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2138 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2139 cli_close(cli, fnum);
2140 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2142 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2143 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2144 cli_close(cli, fnum);
2145 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2147 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2150 torture_close_connection(cli);
2152 printf("finished locktest6\n");
2156 static bool run_locktest7(int dummy)
2158 struct cli_state *cli1;
2159 const char *fname = "\\lockt7.lck";
2162 bool correct = False;
2165 if (!torture_open_connection(&cli1, 0)) {
2169 cli_sockopt(cli1, sockops);
2171 printf("starting locktest7\n");
2173 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2175 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2177 memset(buf, 0, sizeof(buf));
2179 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2181 if (!NT_STATUS_IS_OK(status)) {
2182 printf("Failed to create file: %s\n", nt_errstr(status));
2186 cli_setpid(cli1, 1);
2188 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2189 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2192 printf("pid1 successfully locked range 130:4 for READ\n");
2195 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2196 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2199 printf("pid1 successfully read the range 130:4\n");
2202 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2203 if (!NT_STATUS_IS_OK(status)) {
2204 printf("pid1 unable to write to the range 130:4, error was "
2205 "%s\n", nt_errstr(status));
2206 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2207 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2211 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2215 cli_setpid(cli1, 2);
2217 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2218 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2220 printf("pid2 successfully read the range 130:4\n");
2223 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2224 if (!NT_STATUS_IS_OK(status)) {
2225 printf("pid2 unable to write to the range 130:4, error was "
2226 "%s\n", nt_errstr(status));
2227 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2228 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2232 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2236 cli_setpid(cli1, 1);
2237 cli_unlock(cli1, fnum1, 130, 4);
2239 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2240 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2243 printf("pid1 successfully locked range 130:4 for WRITE\n");
2246 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2247 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2250 printf("pid1 successfully read the range 130:4\n");
2253 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2254 if (!NT_STATUS_IS_OK(status)) {
2255 printf("pid1 unable to write to the range 130:4, error was "
2256 "%s\n", nt_errstr(status));
2259 printf("pid1 successfully wrote to the range 130:4\n");
2262 cli_setpid(cli1, 2);
2264 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2265 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2266 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2267 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2271 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2275 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2276 if (!NT_STATUS_IS_OK(status)) {
2277 printf("pid2 unable to write to the range 130:4, error was "
2278 "%s\n", nt_errstr(status));
2279 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2280 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2284 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2288 cli_unlock(cli1, fnum1, 130, 0);
2292 cli_close(cli1, fnum1);
2293 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2294 torture_close_connection(cli1);
2296 printf("finished locktest7\n");
2301 * This demonstrates a problem with our use of GPFS share modes: A file
2302 * descriptor sitting in the pending close queue holding a GPFS share mode
2303 * blocks opening a file another time. Happens with Word 2007 temp files.
2304 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2305 * open is denied with NT_STATUS_SHARING_VIOLATION.
2308 static bool run_locktest8(int dummy)
2310 struct cli_state *cli1;
2311 const char *fname = "\\lockt8.lck";
2312 uint16_t fnum1, fnum2;
2314 bool correct = False;
2317 if (!torture_open_connection(&cli1, 0)) {
2321 cli_sockopt(cli1, sockops);
2323 printf("starting locktest8\n");
2325 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2327 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2329 if (!NT_STATUS_IS_OK(status)) {
2330 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2334 memset(buf, 0, sizeof(buf));
2336 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2337 if (!NT_STATUS_IS_OK(status)) {
2338 d_fprintf(stderr, "cli_open second time returned %s\n",
2343 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2344 printf("Unable to apply read lock on range 1:1, error was "
2345 "%s\n", cli_errstr(cli1));
2349 status = cli_close(cli1, fnum1);
2350 if (!NT_STATUS_IS_OK(status)) {
2351 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2355 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 d_fprintf(stderr, "cli_open third time returned %s\n",
2365 cli_close(cli1, fnum1);
2366 cli_close(cli1, fnum2);
2367 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2368 torture_close_connection(cli1);
2370 printf("finished locktest8\n");
2375 * This test is designed to be run in conjunction with
2376 * external NFS or POSIX locks taken in the filesystem.
2377 * It checks that the smbd server will block until the
2378 * lock is released and then acquire it. JRA.
2381 static bool got_alarm;
2382 static int alarm_fd;
2384 static void alarm_handler(int dummy)
2389 static void alarm_handler_parent(int dummy)
2394 static void do_local_lock(int read_fd, int write_fd)
2399 const char *local_pathname = NULL;
2402 local_pathname = talloc_asprintf(talloc_tos(),
2403 "%s/lockt9.lck", local_path);
2404 if (!local_pathname) {
2405 printf("child: alloc fail\n");
2409 unlink(local_pathname);
2410 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2412 printf("child: open of %s failed %s.\n",
2413 local_pathname, strerror(errno));
2417 /* Now take a fcntl lock. */
2418 lock.l_type = F_WRLCK;
2419 lock.l_whence = SEEK_SET;
2422 lock.l_pid = getpid();
2424 ret = fcntl(fd,F_SETLK,&lock);
2426 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2427 local_pathname, strerror(errno));
2430 printf("child: got lock 0:4 on file %s.\n",
2435 CatchSignal(SIGALRM, alarm_handler);
2437 /* Signal the parent. */
2438 if (write(write_fd, &c, 1) != 1) {
2439 printf("child: start signal fail %s.\n",
2446 /* Wait for the parent to be ready. */
2447 if (read(read_fd, &c, 1) != 1) {
2448 printf("child: reply signal fail %s.\n",
2456 printf("child: released lock 0:4 on file %s.\n",
2462 static bool run_locktest9(int dummy)
2464 struct cli_state *cli1;
2465 const char *fname = "\\lockt9.lck";
2467 bool correct = False;
2468 int pipe_in[2], pipe_out[2];
2472 struct timeval start;
2476 printf("starting locktest9\n");
2478 if (local_path == NULL) {
2479 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2483 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2488 if (child_pid == -1) {
2492 if (child_pid == 0) {
2494 do_local_lock(pipe_out[0], pipe_in[1]);
2504 ret = read(pipe_in[0], &c, 1);
2506 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2511 if (!torture_open_connection(&cli1, 0)) {
2515 cli_sockopt(cli1, sockops);
2517 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2519 if (!NT_STATUS_IS_OK(status)) {
2520 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2524 /* Ensure the child has the lock. */
2525 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2526 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2529 d_printf("Child has the lock.\n");
2532 /* Tell the child to wait 5 seconds then exit. */
2533 ret = write(pipe_out[1], &c, 1);
2535 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2540 /* Wait 20 seconds for the lock. */
2541 alarm_fd = cli1->fd;
2542 CatchSignal(SIGALRM, alarm_handler_parent);
2545 start = timeval_current();
2547 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2548 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2549 "%s\n", cli_errstr(cli1));
2554 seconds = timeval_elapsed(&start);
2556 printf("Parent got the lock after %.2f seconds.\n",
2559 status = cli_close(cli1, fnum);
2560 if (!NT_STATUS_IS_OK(status)) {
2561 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2568 cli_close(cli1, fnum);
2569 torture_close_connection(cli1);
2573 printf("finished locktest9\n");
2578 test whether fnums and tids open on one VC are available on another (a major
2581 static bool run_fdpasstest(int dummy)
2583 struct cli_state *cli1, *cli2;
2584 const char *fname = "\\fdpass.tst";
2589 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2592 cli_sockopt(cli1, sockops);
2593 cli_sockopt(cli2, sockops);
2595 printf("starting fdpasstest\n");
2597 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2599 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2600 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2604 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"hello world\n", 0,
2606 if (!NT_STATUS_IS_OK(status)) {
2607 printf("write failed (%s)\n", nt_errstr(status));
2611 cli2->vuid = cli1->vuid;
2612 cli2->cnum = cli1->cnum;
2613 cli2->pid = cli1->pid;
2615 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2616 printf("read succeeded! nasty security hole [%s]\n",
2621 cli_close(cli1, fnum1);
2622 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2624 torture_close_connection(cli1);
2625 torture_close_connection(cli2);
2627 printf("finished fdpasstest\n");
2631 static bool run_fdsesstest(int dummy)
2633 struct cli_state *cli;
2638 const char *fname = "\\fdsess.tst";
2639 const char *fname1 = "\\fdsess1.tst";
2646 if (!torture_open_connection(&cli, 0))
2648 cli_sockopt(cli, sockops);
2650 if (!torture_cli_session_setup2(cli, &new_vuid))
2653 saved_cnum = cli->cnum;
2654 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2656 new_cnum = cli->cnum;
2657 cli->cnum = saved_cnum;
2659 printf("starting fdsesstest\n");
2661 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2662 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2664 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2665 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2669 status = cli_writeall(cli, fnum1, 0, (uint8_t *)"hello world\n", 0, 13,
2671 if (!NT_STATUS_IS_OK(status)) {
2672 printf("write failed (%s)\n", nt_errstr(status));
2676 saved_vuid = cli->vuid;
2677 cli->vuid = new_vuid;
2679 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2680 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2684 /* Try to open a file with different vuid, samba cnum. */
2685 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2686 printf("create with different vuid, same cnum succeeded.\n");
2687 cli_close(cli, fnum2);
2688 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2690 printf("create with different vuid, same cnum failed.\n");
2691 printf("This will cause problems with service clients.\n");
2695 cli->vuid = saved_vuid;
2697 /* Try with same vuid, different cnum. */
2698 cli->cnum = new_cnum;
2700 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2701 printf("read succeeded with different cnum![%s]\n",
2706 cli->cnum = saved_cnum;
2707 cli_close(cli, fnum1);
2708 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2710 torture_close_connection(cli);
2712 printf("finished fdsesstest\n");
2717 This test checks that
2719 1) the server does not allow an unlink on a file that is open
2721 static bool run_unlinktest(int dummy)
2723 struct cli_state *cli;
2724 const char *fname = "\\unlink.tst";
2726 bool correct = True;
2728 if (!torture_open_connection(&cli, 0)) {
2732 cli_sockopt(cli, sockops);
2734 printf("starting unlink test\n");
2736 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2740 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2741 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2745 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2746 printf("error: server allowed unlink on an open file\n");
2749 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2750 NT_STATUS_SHARING_VIOLATION);
2753 cli_close(cli, fnum);
2754 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2756 if (!torture_close_connection(cli)) {
2760 printf("unlink test finished\n");
2767 test how many open files this server supports on the one socket
2769 static bool run_maxfidtest(int dummy)
2771 struct cli_state *cli;
2772 const char *ftemplate = "\\maxfid.%d.%d";
2774 uint16_t fnums[0x11000];
2777 bool correct = True;
2782 printf("failed to connect\n");
2786 cli_sockopt(cli, sockops);
2788 for (i=0; i<0x11000; i++) {
2789 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2790 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2791 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2792 printf("open of %s failed (%s)\n",
2793 fname, cli_errstr(cli));
2794 printf("maximum fnum is %d\n", i);
2802 printf("cleaning up\n");
2804 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2805 cli_close(cli, fnums[i]);
2806 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2807 printf("unlink of %s failed (%s)\n",
2808 fname, cli_errstr(cli));
2815 printf("maxfid test finished\n");
2816 if (!torture_close_connection(cli)) {
2822 /* generate a random buffer */
2823 static void rand_buf(char *buf, int len)
2826 *buf = (char)sys_random();
2831 /* send smb negprot commands, not reading the response */
2832 static bool run_negprot_nowait(int dummy)
2834 struct tevent_context *ev;
2836 struct cli_state *cli;
2837 bool correct = True;
2839 printf("starting negprot nowait test\n");
2841 ev = tevent_context_init(talloc_tos());
2846 if (!(cli = open_nbt_connection())) {
2851 for (i=0;i<50000;i++) {
2852 struct tevent_req *req;
2854 req = cli_negprot_send(ev, ev, cli);
2859 if (!tevent_req_poll(req, ev)) {
2860 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2868 if (torture_close_connection(cli)) {
2872 printf("finished negprot nowait test\n");
2877 /* send smb negprot commands, not reading the response */
2878 static bool run_bad_nbt_session(int dummy)
2880 static struct cli_state *cli;
2882 printf("starting bad nbt session test\n");
2884 if (!(cli = open_bad_nbt_connection())) {
2889 printf("finished bad nbt session test\n");
2893 /* send random IPC commands */
2894 static bool run_randomipc(int dummy)
2896 char *rparam = NULL;
2898 unsigned int rdrcnt,rprcnt;
2900 int api, param_len, i;
2901 struct cli_state *cli;
2902 bool correct = True;
2905 printf("starting random ipc test\n");
2907 if (!torture_open_connection(&cli, 0)) {
2911 for (i=0;i<count;i++) {
2912 api = sys_random() % 500;
2913 param_len = (sys_random() % 64);
2915 rand_buf(param, param_len);
2920 param, param_len, 8,
2921 NULL, 0, BUFFER_SIZE,
2925 printf("%d/%d\r", i,count);
2928 printf("%d/%d\n", i, count);
2930 if (!torture_close_connection(cli)) {
2934 printf("finished random ipc test\n");
2941 static void browse_callback(const char *sname, uint32 stype,
2942 const char *comment, void *state)
2944 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2950 This test checks the browse list code
2953 static bool run_browsetest(int dummy)
2955 static struct cli_state *cli;
2956 bool correct = True;
2958 printf("starting browse test\n");
2960 if (!torture_open_connection(&cli, 0)) {
2964 printf("domain list:\n");
2965 cli_NetServerEnum(cli, cli->server_domain,
2966 SV_TYPE_DOMAIN_ENUM,
2967 browse_callback, NULL);
2969 printf("machine list:\n");
2970 cli_NetServerEnum(cli, cli->server_domain,
2972 browse_callback, NULL);
2974 if (!torture_close_connection(cli)) {
2978 printf("browse test finished\n");
2986 This checks how the getatr calls works
2988 static bool run_attrtest(int dummy)
2990 struct cli_state *cli;
2993 const char *fname = "\\attrib123456789.tst";
2994 bool correct = True;
2996 printf("starting attrib test\n");
2998 if (!torture_open_connection(&cli, 0)) {
3002 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3003 cli_open(cli, fname,
3004 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3005 cli_close(cli, fnum);
3006 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3007 printf("getatr failed (%s)\n", cli_errstr(cli));
3011 if (abs(t - time(NULL)) > 60*60*24*10) {
3012 printf("ERROR: SMBgetatr bug. time is %s",
3018 t2 = t-60*60*24; /* 1 day ago */
3020 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
3021 printf("setatr failed (%s)\n", cli_errstr(cli));
3025 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
3026 printf("getatr failed (%s)\n", cli_errstr(cli));
3031 printf("ERROR: getatr/setatr bug. times are\n%s",
3033 printf("%s", ctime(&t2));
3037 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3039 if (!torture_close_connection(cli)) {
3043 printf("attrib test finished\n");
3050 This checks a couple of trans2 calls
3052 static bool run_trans2test(int dummy)
3054 struct cli_state *cli;
3057 time_t c_time, a_time, m_time;
3058 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3059 const char *fname = "\\trans2.tst";
3060 const char *dname = "\\trans2";
3061 const char *fname2 = "\\trans2\\trans2.tst";
3063 bool correct = True;
3067 printf("starting trans2 test\n");
3069 if (!torture_open_connection(&cli, 0)) {
3073 status = cli_get_fs_attr_info(cli, &fs_attr);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3080 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3081 cli_open(cli, fname,
3082 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3083 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3084 cli, fnum, NULL, &size, &c_time_ts,
3085 &a_time_ts, &w_time_ts,
3086 &m_time_ts, NULL))) {
3087 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3091 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3092 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3096 if (strcmp(pname, fname)) {
3097 printf("qfilename gave different name? [%s] [%s]\n",
3102 cli_close(cli, fnum);
3106 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3107 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3108 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3109 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3112 cli_close(cli, fnum);
3114 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3116 if (!NT_STATUS_IS_OK(status)) {
3117 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3120 if (c_time != m_time) {
3121 printf("create time=%s", ctime(&c_time));
3122 printf("modify time=%s", ctime(&m_time));
3123 printf("This system appears to have sticky create times\n");
3125 if (a_time % (60*60) == 0) {
3126 printf("access time=%s", ctime(&a_time));
3127 printf("This system appears to set a midnight access time\n");
3131 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3132 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3138 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3139 cli_open(cli, fname,
3140 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3141 cli_close(cli, fnum);
3142 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3143 &m_time_ts, &size, NULL, NULL);
3144 if (!NT_STATUS_IS_OK(status)) {
3145 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3148 if (w_time_ts.tv_sec < 60*60*24*2) {
3149 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3150 printf("This system appears to set a initial 0 write time\n");
3155 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3158 /* check if the server updates the directory modification time
3159 when creating a new file */
3160 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3161 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3165 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3166 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3167 if (!NT_STATUS_IS_OK(status)) {
3168 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3172 cli_open(cli, fname2,
3173 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3174 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3175 cli_close(cli, fnum);
3176 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3177 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3182 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3184 printf("This system does not update directory modification times\n");
3188 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3189 cli_rmdir(cli, dname);
3191 if (!torture_close_connection(cli)) {
3195 printf("trans2 test finished\n");
3201 This checks new W2K calls.
3204 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3206 uint8_t *buf = NULL;
3210 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3211 pcli->max_xmit, &buf, &len);
3212 if (!NT_STATUS_IS_OK(status)) {
3213 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3216 printf("qfileinfo: level %d, len = %u\n", level, len);
3217 dump_data(0, (uint8 *)buf, len);
3224 static bool run_w2ktest(int dummy)
3226 struct cli_state *cli;
3228 const char *fname = "\\w2ktest\\w2k.tst";
3230 bool correct = True;
3232 printf("starting w2k test\n");
3234 if (!torture_open_connection(&cli, 0)) {
3238 cli_open(cli, fname,
3239 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3241 for (level = 1004; level < 1040; level++) {
3242 new_trans(cli, fnum, level);
3245 cli_close(cli, fnum);
3247 if (!torture_close_connection(cli)) {
3251 printf("w2k test finished\n");
3258 this is a harness for some oplock tests
3260 static bool run_oplock1(int dummy)
3262 struct cli_state *cli1;
3263 const char *fname = "\\lockt1.lck";
3265 bool correct = True;
3267 printf("starting oplock test 1\n");
3269 if (!torture_open_connection(&cli1, 0)) {
3273 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3275 cli_sockopt(cli1, sockops);
3277 cli1->use_oplocks = True;
3279 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3280 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3284 cli1->use_oplocks = False;
3286 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3287 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3289 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3290 printf("close2 failed (%s)\n", cli_errstr(cli1));
3294 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3295 printf("unlink failed (%s)\n", cli_errstr(cli1));
3299 if (!torture_close_connection(cli1)) {
3303 printf("finished oplock test 1\n");
3308 static bool run_oplock2(int dummy)
3310 struct cli_state *cli1, *cli2;
3311 const char *fname = "\\lockt2.lck";
3312 uint16_t fnum1, fnum2;
3313 int saved_use_oplocks = use_oplocks;
3315 bool correct = True;
3316 volatile bool *shared_correct;
3318 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3319 *shared_correct = True;
3321 use_level_II_oplocks = True;
3324 printf("starting oplock test 2\n");
3326 if (!torture_open_connection(&cli1, 0)) {
3327 use_level_II_oplocks = False;
3328 use_oplocks = saved_use_oplocks;
3332 cli1->use_oplocks = True;
3333 cli1->use_level_II_oplocks = True;
3335 if (!torture_open_connection(&cli2, 1)) {
3336 use_level_II_oplocks = False;
3337 use_oplocks = saved_use_oplocks;
3341 cli2->use_oplocks = True;
3342 cli2->use_level_II_oplocks = True;
3344 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3346 cli_sockopt(cli1, sockops);
3347 cli_sockopt(cli2, sockops);
3349 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3350 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3354 /* Don't need the globals any more. */
3355 use_level_II_oplocks = False;
3356 use_oplocks = saved_use_oplocks;
3360 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3361 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3362 *shared_correct = False;
3368 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3369 printf("close2 failed (%s)\n", cli_errstr(cli1));
3370 *shared_correct = False;
3378 /* Ensure cli1 processes the break. Empty file should always return 0
3381 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3382 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3386 /* Should now be at level II. */
3387 /* Test if sending a write locks causes a break to none. */
3389 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3390 printf("lock failed (%s)\n", cli_errstr(cli1));
3394 cli_unlock(cli1, fnum1, 0, 4);
3398 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3399 printf("lock failed (%s)\n", cli_errstr(cli1));
3403 cli_unlock(cli1, fnum1, 0, 4);
3407 cli_read(cli1, fnum1, buf, 0, 4);
3409 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3410 printf("close1 failed (%s)\n", cli_errstr(cli1));
3416 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3417 printf("unlink failed (%s)\n", cli_errstr(cli1));
3421 if (!torture_close_connection(cli1)) {
3425 if (!*shared_correct) {
3429 printf("finished oplock test 2\n");
3434 /* handler for oplock 3 tests */
3435 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3437 printf("got oplock break fnum=%d level=%d\n",
3439 return cli_oplock_ack(cli, fnum, level);
3442 static bool run_oplock3(int dummy)
3444 struct cli_state *cli;
3445 const char *fname = "\\oplockt3.dat";
3447 char buf[4] = "abcd";
3448 bool correct = True;
3449 volatile bool *shared_correct;
3451 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3452 *shared_correct = True;
3454 printf("starting oplock test 3\n");
3459 use_level_II_oplocks = True;
3460 if (!torture_open_connection(&cli, 0)) {
3461 *shared_correct = False;
3465 /* try to trigger a oplock break in parent */
3466 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3467 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3473 use_level_II_oplocks = True;
3474 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3477 cli_oplock_handler(cli, oplock3_handler);
3478 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3479 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3480 cli_close(cli, fnum);
3481 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3482 cli->timeout = 20000;
3483 cli_receive_smb(cli);
3484 printf("finished oplock test 3\n");
3486 return (correct && *shared_correct);
3488 /* What are we looking for here? What's sucess and what's FAILURE? */
3491 /* handler for oplock 4 tests */
3492 bool *oplock4_shared_correct;
3494 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3496 printf("got oplock break fnum=%d level=%d\n",
3498 *oplock4_shared_correct = true;
3499 cli_oplock_ack(cli, fnum, level);
3500 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3503 static bool run_oplock4(int dummy)
3505 struct cli_state *cli1, *cli2;
3506 const char *fname = "\\lockt4.lck";
3507 const char *fname_ln = "\\lockt4_ln.lck";
3508 uint16_t fnum1, fnum2;
3509 int saved_use_oplocks = use_oplocks;
3511 bool correct = true;
3513 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3514 *oplock4_shared_correct = false;
3516 printf("starting oplock test 4\n");
3518 if (!torture_open_connection(&cli1, 0)) {
3519 use_level_II_oplocks = false;
3520 use_oplocks = saved_use_oplocks;
3524 if (!torture_open_connection(&cli2, 1)) {
3525 use_level_II_oplocks = false;
3526 use_oplocks = saved_use_oplocks;
3530 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3531 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3533 cli_sockopt(cli1, sockops);
3534 cli_sockopt(cli2, sockops);
3536 /* Create the file. */
3537 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3538 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3542 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3543 printf("close1 failed (%s)\n", cli_errstr(cli1));
3547 /* Now create a hardlink. */
3548 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3549 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3553 /* Prove that opening hardlinks cause deny modes to conflict. */
3554 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3555 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3559 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3560 if (NT_STATUS_IS_OK(status)) {
3561 printf("open of %s succeeded - should fail with sharing violation.\n",
3566 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3567 printf("open of %s should fail with sharing violation. Got %s\n",
3568 fname_ln, nt_errstr(status));
3572 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3573 printf("close1 failed (%s)\n", cli_errstr(cli1));
3577 cli1->use_oplocks = true;
3578 cli1->use_level_II_oplocks = true;
3580 cli2->use_oplocks = true;
3581 cli2->use_level_II_oplocks = true;
3583 cli_oplock_handler(cli1, oplock4_handler);
3584 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3585 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3591 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3592 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3593 *oplock4_shared_correct = false;
3597 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3598 printf("close2 failed (%s)\n", cli_errstr(cli1));
3599 *oplock4_shared_correct = false;
3607 /* Process the oplock break. */
3608 cli_receive_smb(cli1);
3610 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3611 printf("close1 failed (%s)\n", cli_errstr(cli1));
3615 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3616 printf("unlink failed (%s)\n", cli_errstr(cli1));
3619 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
3620 printf("unlink failed (%s)\n", cli_errstr(cli1));
3624 if (!torture_close_connection(cli1)) {
3628 if (!*oplock4_shared_correct) {
3632 printf("finished oplock test 4\n");
3639 Test delete on close semantics.
3641 static bool run_deletetest(int dummy)
3643 struct cli_state *cli1 = NULL;
3644 struct cli_state *cli2 = NULL;
3645 const char *fname = "\\delete.file";
3646 uint16_t fnum1 = (uint16_t)-1;
3647 uint16_t fnum2 = (uint16_t)-1;
3648 bool correct = True;
3650 printf("starting delete test\n");
3652 if (!torture_open_connection(&cli1, 0)) {
3656 cli_sockopt(cli1, sockops);
3658 /* Test 1 - this should delete the file on close. */
3660 cli_setatr(cli1, fname, 0, 0);
3661 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3663 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3664 0, FILE_OVERWRITE_IF,
3665 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3666 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3671 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3672 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3677 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3678 printf("[1] open of %s succeeded (should fail)\n", fname);
3683 printf("first delete on close test succeeded.\n");
3685 /* Test 2 - this should delete the file on close. */
3687 cli_setatr(cli1, fname, 0, 0);
3688 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3690 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3691 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3692 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3693 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3698 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3699 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3704 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3705 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3710 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3711 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3712 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3713 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3717 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3719 printf("second delete on close test succeeded.\n");
3722 cli_setatr(cli1, fname, 0, 0);
3723 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3725 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3726 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3727 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3732 /* This should fail with a sharing violation - open for delete is only compatible
3733 with SHARE_DELETE. */
3735 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3736 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3737 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3742 /* This should succeed. */
3744 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3745 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3746 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3751 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3752 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3757 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3758 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3763 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3764 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3769 /* This should fail - file should no longer be there. */
3771 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3772 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3773 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3774 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3776 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3780 printf("third delete on close test succeeded.\n");
3783 cli_setatr(cli1, fname, 0, 0);
3784 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3786 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3787 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3788 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3793 /* This should succeed. */
3794 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3795 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3796 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3801 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3802 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3807 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3808 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3813 /* This should fail - no more opens once delete on close set. */
3814 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3815 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3816 FILE_OPEN, 0, 0, &fnum2))) {
3817 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3821 printf("fourth delete on close test succeeded.\n");
3823 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3824 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3830 cli_setatr(cli1, fname, 0, 0);
3831 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3833 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3834 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3839 /* This should fail - only allowed on NT opens with DELETE access. */
3841 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3842 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3847 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3848 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3853 printf("fifth delete on close test succeeded.\n");
3856 cli_setatr(cli1, fname, 0, 0);
3857 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3859 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3860 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3861 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3862 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3867 /* This should fail - only allowed on NT opens with DELETE access. */
3869 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3870 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3875 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3876 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3881 printf("sixth delete on close test succeeded.\n");
3884 cli_setatr(cli1, fname, 0, 0);
3885 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3887 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3888 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3889 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3894 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3895 printf("[7] setting delete_on_close on file failed !\n");
3900 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3901 printf("[7] unsetting delete_on_close on file failed !\n");
3906 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3907 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3912 /* This next open should succeed - we reset the flag. */
3914 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3915 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3920 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3921 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3926 printf("seventh delete on close test succeeded.\n");
3929 cli_setatr(cli1, fname, 0, 0);
3930 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3932 if (!torture_open_connection(&cli2, 1)) {
3933 printf("[8] failed to open second connection.\n");
3938 cli_sockopt(cli1, sockops);
3940 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3941 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3942 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3943 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3948 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3949 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3950 FILE_OPEN, 0, 0, &fnum2))) {
3951 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3956 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3957 printf("[8] setting delete_on_close on file failed !\n");
3962 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3963 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3968 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3969 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3974 /* This should fail.. */
3975 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3976 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3980 printf("eighth delete on close test succeeded.\n");
3982 /* This should fail - we need to set DELETE_ACCESS. */
3983 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3984 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3985 printf("[9] open of %s succeeded should have failed!\n", fname);
3990 printf("ninth delete on close test succeeded.\n");
3992 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3993 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3994 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3999 /* This should delete the file. */
4000 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4001 printf("[10] close failed (%s)\n", cli_errstr(cli1));
4006 /* This should fail.. */
4007 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4008 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4012 printf("tenth delete on close test succeeded.\n");
4014 cli_setatr(cli1, fname, 0, 0);
4015 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4017 /* What error do we get when attempting to open a read-only file with
4020 /* Create a readonly file. */
4021 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4022 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4023 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
4028 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4029 printf("[11] close failed (%s)\n", cli_errstr(cli1));
4034 /* Now try open for delete access. */
4035 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4036 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4037 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4038 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4039 cli_close(cli1, fnum1);
4043 NTSTATUS nterr = cli_nt_error(cli1);
4044 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4045 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4049 printf("eleventh delete on close test succeeded.\n");
4053 printf("finished delete test\n");
4056 /* FIXME: This will crash if we aborted before cli2 got
4057 * intialized, because these functions don't handle
4058 * uninitialized connections. */
4060 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4061 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4062 cli_setatr(cli1, fname, 0, 0);
4063 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4065 if (cli1 && !torture_close_connection(cli1)) {
4068 if (cli2 && !torture_close_connection(cli2)) {
4074 static bool run_deletetest_ln(int dummy)
4076 struct cli_state *cli;
4077 const char *fname = "\\delete1";
4078 const char *fname_ln = "\\delete1_ln";
4082 bool correct = true;
4085 printf("starting deletetest-ln\n");
4087 if (!torture_open_connection(&cli, 0)) {
4091 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4092 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4094 cli_sockopt(cli, sockops);
4096 /* Create the file. */
4097 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4098 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4102 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4103 printf("close1 failed (%s)\n", cli_errstr(cli));
4107 /* Now create a hardlink. */
4108 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4109 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4113 /* Open the original file. */
4114 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4115 FILE_ATTRIBUTE_NORMAL,
4116 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4117 FILE_OPEN_IF, 0, 0, &fnum);
4118 if (!NT_STATUS_IS_OK(status)) {
4119 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4123 /* Unlink the hard link path. */
4124 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4125 FILE_ATTRIBUTE_NORMAL,
4126 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4127 FILE_OPEN_IF, 0, 0, &fnum1);
4128 if (!NT_STATUS_IS_OK(status)) {
4129 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4132 status = cli_nt_delete_on_close(cli, fnum1, true);
4133 if (!NT_STATUS_IS_OK(status)) {
4134 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4135 __location__, fname_ln, nt_errstr(status));
4139 status = cli_close(cli, fnum1);
4140 if (!NT_STATUS_IS_OK(status)) {
4141 printf("close %s failed (%s)\n",
4142 fname_ln, nt_errstr(status));
4146 status = cli_close(cli, fnum);
4147 if (!NT_STATUS_IS_OK(status)) {
4148 printf("close %s failed (%s)\n",
4149 fname, nt_errstr(status));
4153 /* Ensure the original file is still there. */
4154 status = cli_getatr(cli, fname, NULL, NULL, &t);
4155 if (!NT_STATUS_IS_OK(status)) {
4156 printf("%s getatr on file %s failed (%s)\n",
4163 /* Ensure the link path is gone. */
4164 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4165 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4166 printf("%s, getatr for file %s returned wrong error code %s "
4167 "- should have been deleted\n",
4169 fname_ln, nt_errstr(status));
4173 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4174 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4176 if (!torture_close_connection(cli)) {
4180 printf("finished deletetest-ln\n");
4186 print out server properties
4188 static bool run_properties(int dummy)
4190 struct cli_state *cli;
4191 bool correct = True;
4193 printf("starting properties test\n");
4197 if (!torture_open_connection(&cli, 0)) {
4201 cli_sockopt(cli, sockops);
4203 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4205 if (!torture_close_connection(cli)) {
4214 /* FIRST_DESIRED_ACCESS 0xf019f */
4215 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4216 FILE_READ_EA| /* 0xf */ \
4217 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4218 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4219 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4220 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4221 /* SECOND_DESIRED_ACCESS 0xe0080 */
4222 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4223 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4224 WRITE_OWNER_ACCESS /* 0xe0000 */
4227 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4228 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4230 WRITE_OWNER_ACCESS /* */
4234 Test ntcreate calls made by xcopy
4236 static bool run_xcopy(int dummy)
4238 static struct cli_state *cli1;
4239 const char *fname = "\\test.txt";
4240 bool correct = True;
4241 uint16_t fnum1, fnum2;
4243 printf("starting xcopy test\n");
4245 if (!torture_open_connection(&cli1, 0)) {
4249 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4250 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4251 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4252 0x4044, 0, &fnum1))) {
4253 printf("First open failed - %s\n", cli_errstr(cli1));
4257 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4258 SECOND_DESIRED_ACCESS, 0,
4259 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4260 0x200000, 0, &fnum2))) {
4261 printf("second open failed - %s\n", cli_errstr(cli1));
4265 if (!torture_close_connection(cli1)) {
4273 Test rename on files open with share delete and no share delete.
4275 static bool run_rename(int dummy)
4277 static struct cli_state *cli1;
4278 const char *fname = "\\test.txt";
4279 const char *fname1 = "\\test1.txt";
4280 bool correct = True;
4285 printf("starting rename test\n");
4287 if (!torture_open_connection(&cli1, 0)) {
4291 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4292 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4293 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4294 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4295 printf("First open failed - %s\n", cli_errstr(cli1));
4299 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4300 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4302 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4306 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4307 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4311 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4312 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4313 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4315 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4317 FILE_SHARE_DELETE|FILE_SHARE_READ,
4319 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4320 if (!NT_STATUS_IS_OK(status)) {
4321 printf("Second open failed - %s\n", cli_errstr(cli1));
4325 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4326 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4329 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4332 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4333 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4337 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4338 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4340 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4341 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4342 printf("Third open failed - %s\n", cli_errstr(cli1));
4351 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4352 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4353 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4356 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4357 printf("[8] setting delete_on_close on file failed !\n");
4361 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4362 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4368 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4369 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4372 printf("Third rename succeeded (SHARE_NONE)\n");
4375 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4376 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4380 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4381 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4385 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4386 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4387 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4391 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4392 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4394 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4398 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4399 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4403 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4404 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4408 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4409 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4410 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4414 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4415 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4419 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4423 * Now check if the first name still exists ...
4426 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4427 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4428 printf("Opening original file after rename of open file fails: %s\n",
4432 printf("Opening original file after rename of open file works ...\n");
4433 (void)cli_close(cli1, fnum2);
4437 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4438 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4442 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4443 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4444 printf("getatr on file %s failed - %s ! \n",
4449 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4450 printf("Renamed file %s has wrong attr 0x%x "
4451 "(should be 0x%x)\n",
4454 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4457 printf("Renamed file %s has archive bit set\n", fname1);
4461 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4462 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4464 if (!torture_close_connection(cli1)) {
4471 static bool run_pipe_number(int dummy)
4473 struct cli_state *cli1;
4474 const char *pipe_name = "\\SPOOLSS";
4478 printf("starting pipenumber test\n");
4479 if (!torture_open_connection(&cli1, 0)) {
4483 cli_sockopt(cli1, sockops);
4485 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4486 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4487 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4491 printf("\r%6d", num_pipes);
4494 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4495 torture_close_connection(cli1);
4500 Test open mode returns on read-only files.
4502 static bool run_opentest(int dummy)
4504 static struct cli_state *cli1;
4505 static struct cli_state *cli2;
4506 const char *fname = "\\readonly.file";
4507 uint16_t fnum1, fnum2;
4510 bool correct = True;
4514 printf("starting open test\n");
4516 if (!torture_open_connection(&cli1, 0)) {
4520 cli_setatr(cli1, fname, 0, 0);
4521 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4523 cli_sockopt(cli1, sockops);
4525 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4526 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4530 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4531 printf("close2 failed (%s)\n", cli_errstr(cli1));
4535 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0))) {
4536 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4540 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4541 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4545 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4546 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4548 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4549 NT_STATUS_ACCESS_DENIED)) {
4550 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4553 printf("finished open test 1\n");
4555 cli_close(cli1, fnum1);
4557 /* Now try not readonly and ensure ERRbadshare is returned. */
4559 cli_setatr(cli1, fname, 0, 0);
4561 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4562 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4566 /* This will fail - but the error should be ERRshare. */
4567 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4569 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4570 NT_STATUS_SHARING_VIOLATION)) {
4571 printf("correct error code ERRDOS/ERRbadshare returned\n");
4574 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4575 printf("close2 failed (%s)\n", cli_errstr(cli1));
4579 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4581 printf("finished open test 2\n");
4583 /* Test truncate open disposition on file opened for read. */
4585 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4586 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4590 /* write 20 bytes. */
4592 memset(buf, '\0', 20);
4594 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4595 if (!NT_STATUS_IS_OK(status)) {
4596 printf("write failed (%s)\n", nt_errstr(status));
4600 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4601 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4605 /* Ensure size == 20. */
4606 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4607 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4612 printf("(3) file size != 20\n");
4616 /* Now test if we can truncate a file opened for readonly. */
4618 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4619 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4623 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4624 printf("close2 failed (%s)\n", cli_errstr(cli1));
4628 /* Ensure size == 0. */
4629 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4630 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4635 printf("(3) file size != 0\n");
4638 printf("finished open test 3\n");
4640 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4642 printf("Do ctemp tests\n");
4643 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4644 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4647 printf("ctemp gave path %s\n", tmp_path);
4648 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4649 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4651 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
4652 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4655 /* Test the non-io opens... */
4657 if (!torture_open_connection(&cli2, 1)) {
4661 cli_setatr(cli2, fname, 0, 0);
4662 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4664 cli_sockopt(cli2, sockops);
4666 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4668 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4669 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4670 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4674 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4675 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4676 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4680 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4681 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4684 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4685 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4689 printf("non-io open test #1 passed.\n");
4691 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4693 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4695 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4696 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4697 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4701 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4702 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4703 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4707 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4708 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4711 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4712 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4716 printf("non-io open test #2 passed.\n");
4718 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4720 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4722 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4723 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4724 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4728 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4729 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4730 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4734 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4735 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4738 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4739 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4743 printf("non-io open test #3 passed.\n");
4745 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4747 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4749 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4750 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4751 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4755 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4756 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4757 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4761 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4763 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4764 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4768 printf("non-io open test #4 passed.\n");
4770 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4772 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4774 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4775 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4776 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4780 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4781 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4782 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4786 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4787 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4791 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4792 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4796 printf("non-io open test #5 passed.\n");
4798 printf("TEST #6 testing 1 non-io open, one io open\n");
4800 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4802 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4803 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4804 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4808 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4809 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4810 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4814 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4815 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4819 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4820 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4824 printf("non-io open test #6 passed.\n");
4826 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4828 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4830 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4831 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4832 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4836 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4837 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4838 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4842 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4844 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4845 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4849 printf("non-io open test #7 passed.\n");
4851 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4853 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4854 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4855 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4856 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4857 if (!NT_STATUS_IS_OK(status)) {
4858 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4863 /* Write to ensure we have to update the file time. */
4864 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
4866 if (!NT_STATUS_IS_OK(status)) {
4867 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
4872 status = cli_close(cli1, fnum1);
4873 if (!NT_STATUS_IS_OK(status)) {
4874 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4880 if (!torture_close_connection(cli1)) {
4883 if (!torture_close_connection(cli2)) {
4890 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4892 uint16 major, minor;
4893 uint32 caplow, caphigh;
4896 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4897 printf("Server doesn't support UNIX CIFS extensions.\n");
4898 return NT_STATUS_NOT_SUPPORTED;
4901 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4903 if (!NT_STATUS_IS_OK(status)) {
4904 printf("Server didn't return UNIX CIFS extensions: %s\n",
4909 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4911 if (!NT_STATUS_IS_OK(status)) {
4912 printf("Server doesn't support setting UNIX CIFS extensions: "
4913 "%s.\n", nt_errstr(status));
4917 return NT_STATUS_OK;
4921 Test POSIX open /mkdir calls.
4923 static bool run_simple_posix_open_test(int dummy)
4925 static struct cli_state *cli1;
4926 const char *fname = "posix:file";
4927 const char *hname = "posix:hlink";
4928 const char *sname = "posix:symlink";
4929 const char *dname = "posix:dir";
4932 uint16_t fnum1 = (uint16_t)-1;
4933 SMB_STRUCT_STAT sbuf;
4934 bool correct = false;
4937 printf("Starting simple POSIX open test\n");
4939 if (!torture_open_connection(&cli1, 0)) {
4943 cli_sockopt(cli1, sockops);
4945 status = torture_setup_unix_extensions(cli1);
4946 if (!NT_STATUS_IS_OK(status)) {
4950 cli_setatr(cli1, fname, 0, 0);
4951 cli_posix_unlink(cli1, fname);
4952 cli_setatr(cli1, dname, 0, 0);
4953 cli_posix_rmdir(cli1, dname);
4954 cli_setatr(cli1, hname, 0, 0);
4955 cli_posix_unlink(cli1, hname);
4956 cli_setatr(cli1, sname, 0, 0);
4957 cli_posix_unlink(cli1, sname);
4959 /* Create a directory. */
4960 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4961 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4965 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4966 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4970 /* Test ftruncate - set file size. */
4971 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4972 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4976 /* Ensure st_size == 1000 */
4977 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4978 printf("stat failed (%s)\n", cli_errstr(cli1));
4982 if (sbuf.st_ex_size != 1000) {
4983 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4987 /* Test ftruncate - set file size back to zero. */
4988 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4989 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4993 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4994 printf("close failed (%s)\n", cli_errstr(cli1));
4998 /* Now open the file again for read only. */
4999 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5000 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
5004 /* Now unlink while open. */
5005 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5006 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5010 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5011 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5015 /* Ensure the file has gone. */
5016 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
5017 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5021 /* Create again to test open with O_TRUNC. */
5022 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5023 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5027 /* Test ftruncate - set file size. */
5028 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5029 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5033 /* Ensure st_size == 1000 */
5034 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5035 printf("stat failed (%s)\n", cli_errstr(cli1));
5039 if (sbuf.st_ex_size != 1000) {
5040 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5044 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5045 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5049 /* Re-open with O_TRUNC. */
5050 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5051 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5055 /* Ensure st_size == 0 */
5056 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5057 printf("stat failed (%s)\n", cli_errstr(cli1));
5061 if (sbuf.st_ex_size != 0) {
5062 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5066 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5067 printf("close failed (%s)\n", cli_errstr(cli1));
5071 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5072 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5076 /* What happens when we try and POSIX open a directory ? */
5077 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5078 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5081 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5082 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5087 /* Create the file. */
5088 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5089 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5093 /* Write some data into it. */
5094 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)"TEST DATA\n", 0, 10,
5096 if (!NT_STATUS_IS_OK(status)) {
5097 printf("cli_write failed: %s\n", nt_errstr(status));
5101 cli_close(cli1, fnum1);
5103 /* Now create a hardlink. */
5104 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5105 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5109 /* Now create a symlink. */
5110 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5111 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5115 /* Open the hardlink for read. */
5116 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5117 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5121 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5122 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5126 if (memcmp(buf, "TEST DATA\n", 10)) {
5127 printf("invalid data read from hardlink\n");
5131 /* Do a POSIX lock/unlock. */
5132 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5133 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5137 /* Punch a hole in the locked area. */
5138 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5139 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5143 cli_close(cli1, fnum1);
5145 /* Open the symlink for read - this should fail. A POSIX
5146 client should not be doing opens on a symlink. */
5147 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5148 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5151 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5152 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5153 printf("POSIX open of %s should have failed "
5154 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5155 "failed with %s instead.\n",
5156 sname, cli_errstr(cli1));
5161 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5162 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5166 if (strcmp(namebuf, fname) != 0) {
5167 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5168 sname, fname, namebuf);
5172 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5173 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5177 printf("Simple POSIX open test passed\n");
5182 if (fnum1 != (uint16_t)-1) {
5183 cli_close(cli1, fnum1);
5184 fnum1 = (uint16_t)-1;
5187 cli_setatr(cli1, sname, 0, 0);
5188 cli_posix_unlink(cli1, sname);
5189 cli_setatr(cli1, hname, 0, 0);
5190 cli_posix_unlink(cli1, hname);
5191 cli_setatr(cli1, fname, 0, 0);
5192 cli_posix_unlink(cli1, fname);
5193 cli_setatr(cli1, dname, 0, 0);
5194 cli_posix_rmdir(cli1, dname);
5196 if (!torture_close_connection(cli1)) {
5204 static uint32 open_attrs_table[] = {
5205 FILE_ATTRIBUTE_NORMAL,
5206 FILE_ATTRIBUTE_ARCHIVE,
5207 FILE_ATTRIBUTE_READONLY,
5208 FILE_ATTRIBUTE_HIDDEN,
5209 FILE_ATTRIBUTE_SYSTEM,
5211 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5212 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5213 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5214 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5215 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5216 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5218 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5219 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5220 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5221 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5224 struct trunc_open_results {
5231 static struct trunc_open_results attr_results[] = {
5232 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5233 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5234 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5235 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5236 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5237 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5238 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5239 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5240 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5241 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5242 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5243 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5244 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5245 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5246 { 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 },
5247 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5248 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5249 { 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 },
5250 { 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 },
5251 { 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 },
5252 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5253 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5254 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5255 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5256 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5257 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5260 static bool run_openattrtest(int dummy)
5262 static struct cli_state *cli1;
5263 const char *fname = "\\openattr.file";
5265 bool correct = True;
5267 unsigned int i, j, k, l;
5269 printf("starting open attr test\n");
5271 if (!torture_open_connection(&cli1, 0)) {
5275 cli_sockopt(cli1, sockops);
5277 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5278 cli_setatr(cli1, fname, 0, 0);
5279 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5280 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5281 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5282 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5286 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5287 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5291 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5292 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5293 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5294 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5295 if (attr_results[l].num == k) {
5296 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5297 k, open_attrs_table[i],
5298 open_attrs_table[j],
5299 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5303 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5304 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5305 k, open_attrs_table[i], open_attrs_table[j],
5310 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5316 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5317 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5321 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5322 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5327 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5328 k, open_attrs_table[i], open_attrs_table[j], attr );
5331 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5332 if (attr_results[l].num == k) {
5333 if (attr != attr_results[l].result_attr ||
5334 open_attrs_table[i] != attr_results[l].init_attr ||
5335 open_attrs_table[j] != attr_results[l].trunc_attr) {
5336 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5337 open_attrs_table[i],
5338 open_attrs_table[j],
5340 attr_results[l].result_attr);
5350 cli_setatr(cli1, fname, 0, 0);
5351 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5353 printf("open attr test %s.\n", correct ? "passed" : "failed");
5355 if (!torture_close_connection(cli1)) {
5361 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5362 const char *name, void *state)
5364 int *matched = (int *)state;
5365 if (matched != NULL) {
5368 return NT_STATUS_OK;
5372 test directory listing speed
5374 static bool run_dirtest(int dummy)
5377 static struct cli_state *cli;
5379 struct timeval core_start;
5380 bool correct = True;
5383 printf("starting directory test\n");
5385 if (!torture_open_connection(&cli, 0)) {
5389 cli_sockopt(cli, sockops);
5392 for (i=0;i<torture_numops;i++) {
5394 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5395 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5396 fprintf(stderr,"Failed to open %s\n", fname);
5399 cli_close(cli, fnum);
5402 core_start = timeval_current();
5405 cli_list(cli, "a*.*", 0, list_fn, &matched);
5406 printf("Matched %d\n", matched);
5409 cli_list(cli, "b*.*", 0, list_fn, &matched);
5410 printf("Matched %d\n", matched);
5413 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5414 printf("Matched %d\n", matched);
5416 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5419 for (i=0;i<torture_numops;i++) {
5421 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5422 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5425 if (!torture_close_connection(cli)) {
5429 printf("finished dirtest\n");
5434 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5437 struct cli_state *pcli = (struct cli_state *)state;
5439 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5441 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5442 return NT_STATUS_OK;
5444 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5445 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5446 printf("del_fn: failed to rmdir %s\n,", fname );
5448 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5449 printf("del_fn: failed to unlink %s\n,", fname );
5451 return NT_STATUS_OK;
5456 sees what IOCTLs are supported
5458 bool torture_ioctl_test(int dummy)
5460 static struct cli_state *cli;
5461 uint16_t device, function;
5463 const char *fname = "\\ioctl.dat";
5467 if (!torture_open_connection(&cli, 0)) {
5471 printf("starting ioctl test\n");
5473 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5475 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5476 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5480 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5481 printf("ioctl device info: %s\n", nt_errstr(status));
5483 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5484 printf("ioctl job info: %s\n", nt_errstr(status));
5486 for (device=0;device<0x100;device++) {
5487 printf("ioctl test with device = 0x%x\n", device);
5488 for (function=0;function<0x100;function++) {
5489 uint32 code = (device<<16) | function;
5491 status = cli_raw_ioctl(cli, fnum, code, &blob);
5493 if (NT_STATUS_IS_OK(status)) {
5494 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5496 data_blob_free(&blob);
5501 if (!torture_close_connection(cli)) {
5510 tries varients of chkpath
5512 bool torture_chkpath_test(int dummy)
5514 static struct cli_state *cli;
5518 if (!torture_open_connection(&cli, 0)) {
5522 printf("starting chkpath test\n");
5524 /* cleanup from an old run */
5525 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5526 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5527 cli_rmdir(cli, "\\chkpath.dir");
5529 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5530 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5534 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5535 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5539 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5540 printf("open1 failed (%s)\n", cli_errstr(cli));
5543 cli_close(cli, fnum);
5545 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5546 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5550 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5551 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5555 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5556 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5557 NT_STATUS_NOT_A_DIRECTORY);
5559 printf("* chkpath on a file should fail\n");
5563 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5564 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5565 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5567 printf("* chkpath on a non existant file should fail\n");
5571 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5572 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5573 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5575 printf("* chkpath on a non existent component should fail\n");
5579 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5580 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5581 cli_rmdir(cli, "\\chkpath.dir");
5583 if (!torture_close_connection(cli)) {
5590 static bool run_eatest(int dummy)
5592 static struct cli_state *cli;
5593 const char *fname = "\\eatest.txt";
5594 bool correct = True;
5598 struct ea_struct *ea_list = NULL;
5599 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5602 printf("starting eatest\n");
5604 if (!torture_open_connection(&cli, 0)) {
5605 talloc_destroy(mem_ctx);
5609 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5610 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5611 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5612 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5613 0x4044, 0, &fnum))) {
5614 printf("open failed - %s\n", cli_errstr(cli));
5615 talloc_destroy(mem_ctx);
5619 for (i = 0; i < 10; i++) {
5620 fstring ea_name, ea_val;
5622 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5623 memset(ea_val, (char)i+1, i+1);
5624 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5625 if (!NT_STATUS_IS_OK(status)) {
5626 printf("ea_set of name %s failed - %s\n", ea_name,
5628 talloc_destroy(mem_ctx);
5633 cli_close(cli, fnum);
5634 for (i = 0; i < 10; i++) {
5635 fstring ea_name, ea_val;
5637 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5638 memset(ea_val, (char)i+1, i+1);
5639 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5640 if (!NT_STATUS_IS_OK(status)) {
5641 printf("ea_set of name %s failed - %s\n", ea_name,
5643 talloc_destroy(mem_ctx);
5648 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5649 if (!NT_STATUS_IS_OK(status)) {
5650 printf("ea_get list failed - %s\n", nt_errstr(status));
5654 printf("num_eas = %d\n", (int)num_eas);
5656 if (num_eas != 20) {
5657 printf("Should be 20 EA's stored... failing.\n");
5661 for (i = 0; i < num_eas; i++) {
5662 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5663 dump_data(0, ea_list[i].value.data,
5664 ea_list[i].value.length);
5667 /* Setting EA's to zero length deletes them. Test this */
5668 printf("Now deleting all EA's - case indepenent....\n");
5671 cli_set_ea_path(cli, fname, "", "", 0);
5673 for (i = 0; i < 20; i++) {
5675 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5676 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5677 if (!NT_STATUS_IS_OK(status)) {
5678 printf("ea_set of name %s failed - %s\n", ea_name,
5680 talloc_destroy(mem_ctx);
5686 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5687 if (!NT_STATUS_IS_OK(status)) {
5688 printf("ea_get list failed - %s\n", nt_errstr(status));
5692 printf("num_eas = %d\n", (int)num_eas);
5693 for (i = 0; i < num_eas; i++) {
5694 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5695 dump_data(0, ea_list[i].value.data,
5696 ea_list[i].value.length);
5700 printf("deleting EA's failed.\n");
5704 /* Try and delete a non existant EA. */
5705 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5706 if (!NT_STATUS_IS_OK(status)) {
5707 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5712 talloc_destroy(mem_ctx);
5713 if (!torture_close_connection(cli)) {
5720 static bool run_dirtest1(int dummy)
5723 static struct cli_state *cli;
5726 bool correct = True;
5728 printf("starting directory test\n");
5730 if (!torture_open_connection(&cli, 0)) {
5734 cli_sockopt(cli, sockops);
5736 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5737 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5738 cli_rmdir(cli, "\\LISTDIR");
5739 cli_mkdir(cli, "\\LISTDIR");
5741 /* Create 1000 files and 1000 directories. */
5742 for (i=0;i<1000;i++) {
5744 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5745 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5746 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5747 fprintf(stderr,"Failed to open %s\n", fname);
5750 cli_close(cli, fnum);
5752 for (i=0;i<1000;i++) {
5754 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5755 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5756 fprintf(stderr,"Failed to open %s\n", fname);
5761 /* Now ensure that doing an old list sees both files and directories. */
5763 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5764 printf("num_seen = %d\n", num_seen );
5765 /* We should see 100 files + 1000 directories + . and .. */
5766 if (num_seen != 2002)
5769 /* Ensure if we have the "must have" bits we only see the
5773 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5774 printf("num_seen = %d\n", num_seen );
5775 if (num_seen != 1002)
5779 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
5780 printf("num_seen = %d\n", num_seen );
5781 if (num_seen != 1000)
5784 /* Delete everything. */
5785 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5786 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
5787 cli_rmdir(cli, "\\LISTDIR");
5790 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5791 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5792 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5795 if (!torture_close_connection(cli)) {
5799 printf("finished dirtest1\n");
5804 static bool run_error_map_extract(int dummy) {
5806 static struct cli_state *c_dos;
5807 static struct cli_state *c_nt;
5812 uint32 flgs2, errnum;
5819 /* NT-Error connection */
5821 if (!(c_nt = open_nbt_connection())) {
5825 c_nt->use_spnego = False;
5827 status = cli_negprot(c_nt);
5829 if (!NT_STATUS_IS_OK(status)) {
5830 printf("%s rejected the NT-error negprot (%s)\n", host,
5836 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5838 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5842 /* DOS-Error connection */
5844 if (!(c_dos = open_nbt_connection())) {
5848 c_dos->use_spnego = False;
5849 c_dos->force_dos_errors = True;
5851 status = cli_negprot(c_dos);
5852 if (!NT_STATUS_IS_OK(status)) {
5853 printf("%s rejected the DOS-error negprot (%s)\n", host,
5855 cli_shutdown(c_dos);
5859 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5861 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5865 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5866 fstr_sprintf(user, "%X", error);
5868 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5869 password, strlen(password),
5870 password, strlen(password),
5872 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5875 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5877 /* Case #1: 32-bit NT errors */
5878 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5879 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5881 printf("/** Dos error on NT connection! (%s) */\n",
5883 nt_status = NT_STATUS(0xc0000000);
5886 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5887 password, strlen(password),
5888 password, strlen(password),
5890 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5892 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5894 /* Case #1: 32-bit NT errors */
5895 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5896 printf("/** NT error on DOS connection! (%s) */\n",
5898 errnum = errclass = 0;
5900 cli_dos_error(c_dos, &errclass, &errnum);
5903 if (NT_STATUS_V(nt_status) != error) {
5904 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5905 get_nt_error_c_code(NT_STATUS(error)),
5906 get_nt_error_c_code(nt_status));
5909 printf("\t{%s,\t%s,\t%s},\n",
5910 smb_dos_err_class(errclass),
5911 smb_dos_err_name(errclass, errnum),
5912 get_nt_error_c_code(NT_STATUS(error)));
5917 static bool run_sesssetup_bench(int dummy)
5919 static struct cli_state *c;
5920 const char *fname = "\\file.dat";
5925 if (!torture_open_connection(&c, 0)) {
5929 if (!NT_STATUS_IS_OK(cli_ntcreate(
5930 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5931 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5932 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5933 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5937 for (i=0; i<torture_numops; i++) {
5938 status = cli_session_setup(
5940 password, strlen(password),
5941 password, strlen(password),
5943 if (!NT_STATUS_IS_OK(status)) {
5944 d_printf("(%s) cli_session_setup failed: %s\n",
5945 __location__, nt_errstr(status));
5949 d_printf("\r%d ", (int)c->vuid);
5951 status = cli_ulogoff(c);
5952 if (!NT_STATUS_IS_OK(status)) {
5953 d_printf("(%s) cli_ulogoff failed: %s\n",
5954 __location__, nt_errstr(status));
5963 static bool subst_test(const char *str, const char *user, const char *domain,
5964 uid_t uid, gid_t gid, const char *expected)
5969 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5971 if (strcmp(subst, expected) != 0) {
5972 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5973 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5982 static void chain1_open_completion(struct tevent_req *req)
5986 status = cli_open_recv(req, &fnum);
5989 d_printf("cli_open_recv returned %s: %d\n",
5991 NT_STATUS_IS_OK(status) ? fnum : -1);
5994 static void chain1_write_completion(struct tevent_req *req)
5998 status = cli_write_andx_recv(req, &written);
6001 d_printf("cli_write_andx_recv returned %s: %d\n",
6003 NT_STATUS_IS_OK(status) ? (int)written : -1);
6006 static void chain1_close_completion(struct tevent_req *req)
6009 bool *done = (bool *)tevent_req_callback_data_void(req);
6011 status = cli_close_recv(req);
6016 d_printf("cli_close returned %s\n", nt_errstr(status));
6019 static bool run_chain1(int dummy)
6021 struct cli_state *cli1;
6022 struct event_context *evt = event_context_init(NULL);
6023 struct tevent_req *reqs[3], *smbreqs[3];
6025 const char *str = "foobar";
6028 printf("starting chain1 test\n");
6029 if (!torture_open_connection(&cli1, 0)) {
6033 cli_sockopt(cli1, sockops);
6035 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6036 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6037 if (reqs[0] == NULL) return false;
6038 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6041 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6042 (uint8_t *)str, 0, strlen(str)+1,
6043 smbreqs, 1, &smbreqs[1]);
6044 if (reqs[1] == NULL) return false;
6045 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6047 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6048 if (reqs[2] == NULL) return false;
6049 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6051 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6052 if (!NT_STATUS_IS_OK(status)) {
6057 event_loop_once(evt);
6060 torture_close_connection(cli1);
6064 static void chain2_sesssetup_completion(struct tevent_req *req)
6067 status = cli_session_setup_guest_recv(req);
6068 d_printf("sesssetup returned %s\n", nt_errstr(status));
6071 static void chain2_tcon_completion(struct tevent_req *req)
6073 bool *done = (bool *)tevent_req_callback_data_void(req);
6075 status = cli_tcon_andx_recv(req);
6076 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6080 static bool run_chain2(int dummy)
6082 struct cli_state *cli1;
6083 struct event_context *evt = event_context_init(NULL);
6084 struct tevent_req *reqs[2], *smbreqs[2];
6088 printf("starting chain2 test\n");
6089 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6090 port_to_use, Undefined, 0);
6091 if (!NT_STATUS_IS_OK(status)) {
6095 cli_sockopt(cli1, sockops);
6097 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6099 if (reqs[0] == NULL) return false;
6100 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6102 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6103 "?????", NULL, 0, &smbreqs[1]);
6104 if (reqs[1] == NULL) return false;
6105 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6107 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6108 if (!NT_STATUS_IS_OK(status)) {
6113 event_loop_once(evt);
6116 torture_close_connection(cli1);
6121 struct torture_createdel_state {
6122 struct tevent_context *ev;
6123 struct cli_state *cli;
6126 static void torture_createdel_created(struct tevent_req *subreq);
6127 static void torture_createdel_closed(struct tevent_req *subreq);
6129 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6130 struct tevent_context *ev,
6131 struct cli_state *cli,
6134 struct tevent_req *req, *subreq;
6135 struct torture_createdel_state *state;
6137 req = tevent_req_create(mem_ctx, &state,
6138 struct torture_createdel_state);
6145 subreq = cli_ntcreate_send(
6146 state, ev, cli, name, 0,
6147 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6148 FILE_ATTRIBUTE_NORMAL,
6149 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6150 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6152 if (tevent_req_nomem(subreq, req)) {
6153 return tevent_req_post(req, ev);
6155 tevent_req_set_callback(subreq, torture_createdel_created, req);
6159 static void torture_createdel_created(struct tevent_req *subreq)
6161 struct tevent_req *req = tevent_req_callback_data(
6162 subreq, struct tevent_req);
6163 struct torture_createdel_state *state = tevent_req_data(
6164 req, struct torture_createdel_state);
6168 status = cli_ntcreate_recv(subreq, &fnum);
6169 TALLOC_FREE(subreq);
6170 if (!NT_STATUS_IS_OK(status)) {
6171 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6172 nt_errstr(status)));
6173 tevent_req_nterror(req, status);
6177 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6178 if (tevent_req_nomem(subreq, req)) {
6181 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6184 static void torture_createdel_closed(struct tevent_req *subreq)
6186 struct tevent_req *req = tevent_req_callback_data(
6187 subreq, struct tevent_req);
6190 status = cli_close_recv(subreq);
6191 if (!NT_STATUS_IS_OK(status)) {
6192 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6193 tevent_req_nterror(req, status);
6196 tevent_req_done(req);
6199 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6201 return tevent_req_simple_recv_ntstatus(req);
6204 struct torture_createdels_state {
6205 struct tevent_context *ev;
6206 struct cli_state *cli;
6207 const char *base_name;
6211 struct tevent_req **reqs;
6214 static void torture_createdels_done(struct tevent_req *subreq);
6216 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6217 struct tevent_context *ev,
6218 struct cli_state *cli,
6219 const char *base_name,
6223 struct tevent_req *req;
6224 struct torture_createdels_state *state;
6227 req = tevent_req_create(mem_ctx, &state,
6228 struct torture_createdels_state);
6234 state->base_name = talloc_strdup(state, base_name);
6235 if (tevent_req_nomem(state->base_name, req)) {
6236 return tevent_req_post(req, ev);
6238 state->num_files = MAX(num_parallel, num_files);
6240 state->received = 0;
6242 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6243 if (tevent_req_nomem(state->reqs, req)) {
6244 return tevent_req_post(req, ev);
6247 for (i=0; i<num_parallel; i++) {
6250 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6252 if (tevent_req_nomem(name, req)) {
6253 return tevent_req_post(req, ev);
6255 state->reqs[i] = torture_createdel_send(
6256 state->reqs, state->ev, state->cli, name);
6257 if (tevent_req_nomem(state->reqs[i], req)) {
6258 return tevent_req_post(req, ev);
6260 name = talloc_move(state->reqs[i], &name);
6261 tevent_req_set_callback(state->reqs[i],
6262 torture_createdels_done, req);
6268 static void torture_createdels_done(struct tevent_req *subreq)
6270 struct tevent_req *req = tevent_req_callback_data(
6271 subreq, struct tevent_req);
6272 struct torture_createdels_state *state = tevent_req_data(
6273 req, struct torture_createdels_state);
6274 size_t num_parallel = talloc_array_length(state->reqs);
6279 status = torture_createdel_recv(subreq);
6280 if (!NT_STATUS_IS_OK(status)){
6281 DEBUG(10, ("torture_createdel_recv returned %s\n",
6282 nt_errstr(status)));
6283 TALLOC_FREE(subreq);
6284 tevent_req_nterror(req, status);
6288 for (i=0; i<num_parallel; i++) {
6289 if (subreq == state->reqs[i]) {
6293 if (i == num_parallel) {
6294 DEBUG(10, ("received something we did not send\n"));
6295 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6298 TALLOC_FREE(state->reqs[i]);
6300 if (state->sent >= state->num_files) {
6301 tevent_req_done(req);
6305 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6307 if (tevent_req_nomem(name, req)) {
6310 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6312 if (tevent_req_nomem(state->reqs[i], req)) {
6315 name = talloc_move(state->reqs[i], &name);
6316 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6320 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6322 return tevent_req_simple_recv_ntstatus(req);
6325 struct swallow_notify_state {
6326 struct tevent_context *ev;
6327 struct cli_state *cli;
6329 uint32_t completion_filter;
6331 bool (*fn)(uint32_t action, const char *name, void *priv);
6335 static void swallow_notify_done(struct tevent_req *subreq);
6337 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6338 struct tevent_context *ev,
6339 struct cli_state *cli,
6341 uint32_t completion_filter,
6343 bool (*fn)(uint32_t action,
6348 struct tevent_req *req, *subreq;
6349 struct swallow_notify_state *state;
6351 req = tevent_req_create(mem_ctx, &state,
6352 struct swallow_notify_state);
6359 state->completion_filter = completion_filter;
6360 state->recursive = recursive;
6364 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6365 0xffff, state->completion_filter,
6367 if (tevent_req_nomem(subreq, req)) {
6368 return tevent_req_post(req, ev);
6370 tevent_req_set_callback(subreq, swallow_notify_done, req);
6374 static void swallow_notify_done(struct tevent_req *subreq)
6376 struct tevent_req *req = tevent_req_callback_data(
6377 subreq, struct tevent_req);
6378 struct swallow_notify_state *state = tevent_req_data(
6379 req, struct swallow_notify_state);
6381 uint32_t i, num_changes;
6382 struct notify_change *changes;
6384 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6385 TALLOC_FREE(subreq);
6386 if (!NT_STATUS_IS_OK(status)) {
6387 DEBUG(10, ("cli_notify_recv returned %s\n",
6388 nt_errstr(status)));
6389 tevent_req_nterror(req, status);
6393 for (i=0; i<num_changes; i++) {
6394 state->fn(changes[i].action, changes[i].name, state->priv);
6396 TALLOC_FREE(changes);
6398 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6399 0xffff, state->completion_filter,
6401 if (tevent_req_nomem(subreq, req)) {
6404 tevent_req_set_callback(subreq, swallow_notify_done, req);
6407 static bool print_notifies(uint32_t action, const char *name, void *priv)
6409 if (DEBUGLEVEL > 5) {
6410 d_printf("%d %s\n", (int)action, name);
6415 static void notify_bench_done(struct tevent_req *req)
6417 int *num_finished = (int *)tevent_req_callback_data_void(req);
6421 static bool run_notify_bench(int dummy)
6423 const char *dname = "\\notify-bench";
6424 struct tevent_context *ev;
6427 struct tevent_req *req1;
6428 struct tevent_req *req2 = NULL;
6429 int i, num_unc_names;
6430 int num_finished = 0;
6432 printf("starting notify-bench test\n");
6434 if (use_multishare_conn) {
6436 unc_list = file_lines_load(multishare_conn_fname,
6437 &num_unc_names, 0, NULL);
6438 if (!unc_list || num_unc_names <= 0) {
6439 d_printf("Failed to load unc names list from '%s'\n",
6440 multishare_conn_fname);
6443 TALLOC_FREE(unc_list);
6448 ev = tevent_context_init(talloc_tos());
6450 d_printf("tevent_context_init failed\n");
6454 for (i=0; i<num_unc_names; i++) {
6455 struct cli_state *cli;
6458 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6460 if (base_fname == NULL) {
6464 if (!torture_open_connection(&cli, i)) {
6468 status = cli_ntcreate(cli, dname, 0,
6469 MAXIMUM_ALLOWED_ACCESS,
6470 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6472 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6475 if (!NT_STATUS_IS_OK(status)) {
6476 d_printf("Could not create %s: %s\n", dname,
6481 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6482 FILE_NOTIFY_CHANGE_FILE_NAME |
6483 FILE_NOTIFY_CHANGE_DIR_NAME |
6484 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6485 FILE_NOTIFY_CHANGE_LAST_WRITE,
6486 false, print_notifies, NULL);
6488 d_printf("Could not create notify request\n");
6492 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6493 base_fname, 10, torture_numops);
6495 d_printf("Could not create createdels request\n");
6498 TALLOC_FREE(base_fname);
6500 tevent_req_set_callback(req2, notify_bench_done,
6504 while (num_finished < num_unc_names) {
6506 ret = tevent_loop_once(ev);
6508 d_printf("tevent_loop_once failed\n");
6513 if (!tevent_req_poll(req2, ev)) {
6514 d_printf("tevent_req_poll failed\n");
6517 status = torture_createdels_recv(req2);
6518 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6523 static bool run_mangle1(int dummy)
6525 struct cli_state *cli;
6526 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6530 time_t change_time, access_time, write_time;
6534 printf("starting mangle1 test\n");
6535 if (!torture_open_connection(&cli, 0)) {
6539 cli_sockopt(cli, sockops);
6541 if (!NT_STATUS_IS_OK(cli_ntcreate(
6542 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6543 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6544 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6547 cli_close(cli, fnum);
6549 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6550 if (!NT_STATUS_IS_OK(status)) {
6551 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6555 d_printf("alt_name: %s\n", alt_name);
6557 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6558 d_printf("cli_open(%s) failed: %s\n", alt_name,
6562 cli_close(cli, fnum);
6564 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6565 &write_time, &size, &mode);
6566 if (!NT_STATUS_IS_OK(status)) {
6567 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6575 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6577 size_t *to_pull = (size_t *)priv;
6578 size_t thistime = *to_pull;
6580 thistime = MIN(thistime, n);
6581 if (thistime == 0) {
6585 memset(buf, 0, thistime);
6586 *to_pull -= thistime;
6590 static bool run_windows_write(int dummy)
6592 struct cli_state *cli1;
6596 const char *fname = "\\writetest.txt";
6597 struct timeval start_time;
6601 printf("starting windows_write test\n");
6602 if (!torture_open_connection(&cli1, 0)) {
6606 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6607 printf("open failed (%s)\n", cli_errstr(cli1));
6611 cli_sockopt(cli1, sockops);
6613 start_time = timeval_current();
6615 for (i=0; i<torture_numops; i++) {
6617 off_t start = i * torture_blocksize;
6619 size_t to_pull = torture_blocksize - 1;
6621 status = cli_writeall(cli1, fnum, 0, &c,
6622 start + torture_blocksize - 1, 1, NULL);
6623 if (!NT_STATUS_IS_OK(status)) {
6624 printf("cli_write failed: %s\n", nt_errstr(status));
6628 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6629 null_source, &to_pull);
6630 if (!NT_STATUS_IS_OK(status)) {
6631 printf("cli_push returned: %s\n", nt_errstr(status));
6636 seconds = timeval_elapsed(&start_time);
6637 kbytes = (double)torture_blocksize * torture_numops;
6640 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6641 (double)seconds, (int)(kbytes/seconds));
6645 cli_close(cli1, fnum);
6646 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6647 torture_close_connection(cli1);
6651 static bool run_cli_echo(int dummy)
6653 struct cli_state *cli;
6656 printf("starting cli_echo test\n");
6657 if (!torture_open_connection(&cli, 0)) {
6660 cli_sockopt(cli, sockops);
6662 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6664 d_printf("cli_echo returned %s\n", nt_errstr(status));
6666 torture_close_connection(cli);
6667 return NT_STATUS_IS_OK(status);
6670 static bool run_uid_regression_test(int dummy)
6672 static struct cli_state *cli;
6675 bool correct = True;
6678 printf("starting uid regression test\n");
6680 if (!torture_open_connection(&cli, 0)) {
6684 cli_sockopt(cli, sockops);
6686 /* Ok - now save then logoff our current user. */
6687 old_vuid = cli->vuid;
6689 status = cli_ulogoff(cli);
6690 if (!NT_STATUS_IS_OK(status)) {
6691 d_printf("(%s) cli_ulogoff failed: %s\n",
6692 __location__, nt_errstr(status));
6697 cli->vuid = old_vuid;
6699 /* Try an operation. */
6700 status = cli_mkdir(cli, "\\uid_reg_test");
6701 if (NT_STATUS_IS_OK(status)) {
6702 d_printf("(%s) cli_mkdir succeeded\n",
6707 /* Should be bad uid. */
6708 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6709 NT_STATUS_USER_SESSION_DELETED)) {
6715 old_cnum = cli->cnum;
6717 /* Now try a SMBtdis with the invald vuid set to zero. */
6720 /* This should succeed. */
6721 status = cli_tdis(cli);
6723 if (NT_STATUS_IS_OK(status)) {
6724 d_printf("First tdis with invalid vuid should succeed.\n");
6726 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6731 cli->vuid = old_vuid;
6732 cli->cnum = old_cnum;
6734 /* This should fail. */
6735 status = cli_tdis(cli);
6736 if (NT_STATUS_IS_OK(status)) {
6737 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6741 /* Should be bad tid. */
6742 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6743 NT_STATUS_NETWORK_NAME_DELETED)) {
6749 cli_rmdir(cli, "\\uid_reg_test");
6758 static const char *illegal_chars = "*\\/?<>|\":";
6759 static char force_shortname_chars[] = " +,.[];=\177";
6761 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6762 const char *mask, void *state)
6764 struct cli_state *pcli = (struct cli_state *)state;
6766 NTSTATUS status = NT_STATUS_OK;
6768 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6770 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6771 return NT_STATUS_OK;
6773 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
6774 status = cli_rmdir(pcli, fname);
6775 if (!NT_STATUS_IS_OK(status)) {
6776 printf("del_fn: failed to rmdir %s\n,", fname );
6779 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6780 if (!NT_STATUS_IS_OK(status)) {
6781 printf("del_fn: failed to unlink %s\n,", fname );
6793 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6794 const char *name, void *state)
6796 struct sn_state *s = (struct sn_state *)state;
6800 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6801 i, finfo->name, finfo->short_name);
6804 if (strchr(force_shortname_chars, i)) {
6805 if (!finfo->short_name[0]) {
6806 /* Shortname not created when it should be. */
6807 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6808 __location__, finfo->name, i);
6811 } else if (finfo->short_name[0]){
6812 /* Shortname created when it should not be. */
6813 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6814 __location__, finfo->short_name, finfo->name);
6818 return NT_STATUS_OK;
6821 static bool run_shortname_test(int dummy)
6823 static struct cli_state *cli;
6824 bool correct = True;
6829 printf("starting shortname test\n");
6831 if (!torture_open_connection(&cli, 0)) {
6835 cli_sockopt(cli, sockops);
6837 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6838 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6839 cli_rmdir(cli, "\\shortname");
6841 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6842 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6843 __location__, cli_errstr(cli));
6848 strlcpy(fname, "\\shortname\\", sizeof(fname));
6849 strlcat(fname, "test .txt", sizeof(fname));
6853 for (i = 32; i < 128; i++) {
6855 uint16_t fnum = (uint16_t)-1;
6859 if (strchr(illegal_chars, i)) {
6864 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6865 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6866 if (!NT_STATUS_IS_OK(status)) {
6867 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6868 __location__, fname, cli_errstr(cli));
6872 cli_close(cli, fnum);
6875 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6877 if (s.matched != 1) {
6878 d_printf("(%s) failed to list %s: %s\n",
6879 __location__, fname, cli_errstr(cli));
6883 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
6884 d_printf("(%s) failed to delete %s: %s\n",
6885 __location__, fname, cli_errstr(cli));
6898 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6899 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
6900 cli_rmdir(cli, "\\shortname");
6901 torture_close_connection(cli);
6905 static void pagedsearch_cb(struct tevent_req *req)
6908 struct tldap_message *msg;
6911 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6912 if (rc != TLDAP_SUCCESS) {
6913 d_printf("tldap_search_paged_recv failed: %s\n",
6914 tldap_err2string(rc));
6917 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6921 if (!tldap_entry_dn(msg, &dn)) {
6922 d_printf("tldap_entry_dn failed\n");
6925 d_printf("%s\n", dn);
6929 static bool run_tldap(int dummy)
6931 struct tldap_context *ld;
6934 struct sockaddr_storage addr;
6935 struct tevent_context *ev;
6936 struct tevent_req *req;
6940 if (!resolve_name(host, &addr, 0, false)) {
6941 d_printf("could not find host %s\n", host);
6944 status = open_socket_out(&addr, 389, 9999, &fd);
6945 if (!NT_STATUS_IS_OK(status)) {
6946 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6950 ld = tldap_context_create(talloc_tos(), fd);
6953 d_printf("tldap_context_create failed\n");
6957 rc = tldap_fetch_rootdse(ld);
6958 if (rc != TLDAP_SUCCESS) {
6959 d_printf("tldap_fetch_rootdse failed: %s\n",
6960 tldap_errstr(talloc_tos(), ld, rc));
6964 basedn = tldap_talloc_single_attribute(
6965 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6966 if (basedn == NULL) {
6967 d_printf("no defaultNamingContext\n");
6970 d_printf("defaultNamingContext: %s\n", basedn);
6972 ev = tevent_context_init(talloc_tos());
6974 d_printf("tevent_context_init failed\n");
6978 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6979 TLDAP_SCOPE_SUB, "(objectclass=*)",
6981 NULL, 0, NULL, 0, 0, 0, 0, 5);
6983 d_printf("tldap_search_paged_send failed\n");
6986 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6988 tevent_req_poll(req, ev);
6992 /* test search filters against rootDSE */
6993 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6994 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6996 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6997 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6998 talloc_tos(), NULL, NULL);
6999 if (rc != TLDAP_SUCCESS) {
7000 d_printf("tldap_search with complex filter failed: %s\n",
7001 tldap_errstr(talloc_tos(), ld, rc));
7009 /* Torture test to ensure no regression of :
7010 https://bugzilla.samba.org/show_bug.cgi?id=7084
7013 static bool run_dir_createtime(int dummy)
7015 struct cli_state *cli;
7016 const char *dname = "\\testdir";
7017 const char *fname = "\\testdir\\testfile";
7019 struct timespec create_time;
7020 struct timespec create_time1;
7024 if (!torture_open_connection(&cli, 0)) {
7028 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7029 cli_rmdir(cli, dname);
7031 status = cli_mkdir(cli, dname);
7032 if (!NT_STATUS_IS_OK(status)) {
7033 printf("mkdir failed: %s\n", nt_errstr(status));
7037 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7039 if (!NT_STATUS_IS_OK(status)) {
7040 printf("cli_qpathinfo2 returned %s\n",
7045 /* Sleep 3 seconds, then create a file. */
7048 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7050 if (!NT_STATUS_IS_OK(status)) {
7051 printf("cli_open failed: %s\n", nt_errstr(status));
7055 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7057 if (!NT_STATUS_IS_OK(status)) {
7058 printf("cli_qpathinfo2 (2) returned %s\n",
7063 if (timespec_compare(&create_time1, &create_time)) {
7064 printf("run_dir_createtime: create time was updated (error)\n");
7066 printf("run_dir_createtime: create time was not updated (correct)\n");
7072 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7073 cli_rmdir(cli, dname);
7074 if (!torture_close_connection(cli)) {
7081 static bool run_streamerror(int dummy)
7083 struct cli_state *cli;
7084 const char *dname = "\\testdir";
7085 const char *streamname =
7086 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7088 time_t change_time, access_time, write_time;
7090 uint16_t mode, fnum;
7093 if (!torture_open_connection(&cli, 0)) {
7097 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7098 cli_rmdir(cli, dname);
7100 status = cli_mkdir(cli, dname);
7101 if (!NT_STATUS_IS_OK(status)) {
7102 printf("mkdir failed: %s\n", nt_errstr(status));
7106 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7108 status = cli_nt_error(cli);
7110 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7111 printf("pathinfo returned %s, expected "
7112 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7117 status = cli_ntcreate(cli, streamname, 0x16,
7118 FILE_READ_DATA|FILE_READ_EA|
7119 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7120 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7121 FILE_OPEN, 0, 0, &fnum);
7123 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7124 printf("ntcreate returned %s, expected "
7125 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7131 cli_rmdir(cli, dname);
7135 static bool run_local_substitute(int dummy)
7139 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7140 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7141 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7142 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7143 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7144 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7145 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7146 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7148 /* Different captialization rules in sub_basic... */
7150 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7156 static bool run_local_base64(int dummy)
7161 for (i=1; i<2000; i++) {
7162 DATA_BLOB blob1, blob2;
7165 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7167 generate_random_buffer(blob1.data, blob1.length);
7169 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7171 d_fprintf(stderr, "base64_encode_data_blob failed "
7172 "for %d bytes\n", i);
7175 blob2 = base64_decode_data_blob(b64);
7178 if (data_blob_cmp(&blob1, &blob2)) {
7179 d_fprintf(stderr, "data_blob_cmp failed for %d "
7183 TALLOC_FREE(blob1.data);
7184 data_blob_free(&blob2);
7189 static bool run_local_gencache(int dummy)
7195 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7196 d_printf("%s: gencache_set() failed\n", __location__);
7200 if (!gencache_get("foo", NULL, NULL)) {
7201 d_printf("%s: gencache_get() failed\n", __location__);
7205 if (!gencache_get("foo", &val, &tm)) {
7206 d_printf("%s: gencache_get() failed\n", __location__);
7210 if (strcmp(val, "bar") != 0) {
7211 d_printf("%s: gencache_get() returned %s, expected %s\n",
7212 __location__, val, "bar");
7219 if (!gencache_del("foo")) {
7220 d_printf("%s: gencache_del() failed\n", __location__);
7223 if (gencache_del("foo")) {
7224 d_printf("%s: second gencache_del() succeeded\n",
7229 if (gencache_get("foo", &val, &tm)) {
7230 d_printf("%s: gencache_get() on deleted entry "
7231 "succeeded\n", __location__);
7235 blob = data_blob_string_const_null("bar");
7236 tm = time(NULL) + 60;
7238 if (!gencache_set_data_blob("foo", &blob, tm)) {
7239 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7243 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7244 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7248 if (strcmp((const char *)blob.data, "bar") != 0) {
7249 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7250 __location__, (const char *)blob.data, "bar");
7251 data_blob_free(&blob);
7255 data_blob_free(&blob);
7257 if (!gencache_del("foo")) {
7258 d_printf("%s: gencache_del() failed\n", __location__);
7261 if (gencache_del("foo")) {
7262 d_printf("%s: second gencache_del() succeeded\n",
7267 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7268 d_printf("%s: gencache_get_data_blob() on deleted entry "
7269 "succeeded\n", __location__);
7276 static bool rbt_testval(struct db_context *db, const char *key,
7279 struct db_record *rec;
7280 TDB_DATA data = string_tdb_data(value);
7284 rec = db->fetch_locked(db, db, string_tdb_data(key));
7286 d_fprintf(stderr, "fetch_locked failed\n");
7289 status = rec->store(rec, data, 0);
7290 if (!NT_STATUS_IS_OK(status)) {
7291 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7296 rec = db->fetch_locked(db, db, string_tdb_data(key));
7298 d_fprintf(stderr, "second fetch_locked failed\n");
7301 if ((rec->value.dsize != data.dsize)
7302 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7303 d_fprintf(stderr, "Got wrong data back\n");
7313 static bool run_local_rbtree(int dummy)
7315 struct db_context *db;
7319 db = db_open_rbt(NULL);
7322 d_fprintf(stderr, "db_open_rbt failed\n");
7326 for (i=0; i<1000; i++) {
7329 if (asprintf(&key, "key%ld", random()) == -1) {
7332 if (asprintf(&value, "value%ld", random()) == -1) {
7337 if (!rbt_testval(db, key, value)) {
7344 if (asprintf(&value, "value%ld", random()) == -1) {
7349 if (!rbt_testval(db, key, value)) {
7368 local test for character set functions
7370 This is a very simple test for the functionality in convert_string_error()
7372 static bool run_local_convert_string(int dummy)
7374 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7375 const char *test_strings[2] = { "March", "M\303\244rz" };
7379 for (i=0; i<2; i++) {
7380 const char *str = test_strings[i];
7381 int len = strlen(str);
7382 size_t converted_size;
7385 memset(dst, 'X', sizeof(dst));
7387 /* first try with real source length */
7388 ret = convert_string_error(CH_UNIX, CH_UTF8,
7393 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7397 if (converted_size != len) {
7398 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7399 str, len, (int)converted_size);
7403 if (strncmp(str, dst, converted_size) != 0) {
7404 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7408 if (strlen(str) != converted_size) {
7409 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7410 (int)strlen(str), (int)converted_size);
7414 if (dst[converted_size] != 'X') {
7415 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7419 /* now with srclen==-1, this causes the nul to be
7421 ret = convert_string_error(CH_UNIX, CH_UTF8,
7426 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7430 if (converted_size != len+1) {
7431 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7432 str, len, (int)converted_size);
7436 if (strncmp(str, dst, converted_size) != 0) {
7437 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7441 if (len+1 != converted_size) {
7442 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7443 len+1, (int)converted_size);
7447 if (dst[converted_size] != 'X') {
7448 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7455 TALLOC_FREE(tmp_ctx);
7458 TALLOC_FREE(tmp_ctx);
7463 struct talloc_dict_test {
7467 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7469 int *count = (int *)priv;
7474 static bool run_local_talloc_dict(int dummy)
7476 struct talloc_dict *dict;
7477 struct talloc_dict_test *t;
7480 dict = talloc_dict_init(talloc_tos());
7485 t = talloc(talloc_tos(), struct talloc_dict_test);
7492 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7497 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7510 static bool run_local_string_to_sid(int dummy) {
7513 if (string_to_sid(&sid, "S--1-5-32-545")) {
7514 printf("allowing S--1-5-32-545\n");
7517 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7518 printf("allowing S-1-5-32-+545\n");
7521 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")) {
7522 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7525 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7526 printf("allowing S-1-5-32-545-abc\n");
7529 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7530 printf("could not parse S-1-5-32-545\n");
7533 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7534 printf("mis-parsed S-1-5-32-545 as %s\n",
7535 sid_string_tos(&sid));
7541 static bool run_local_binary_to_sid(int dummy) {
7542 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7543 static const char good_binary_sid[] = {
7544 0x1, /* revision number */
7546 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7547 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7548 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7549 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7550 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7551 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7552 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7553 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7554 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7555 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7556 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7557 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7558 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7559 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7560 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7561 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7564 static const char long_binary_sid[] = {
7565 0x1, /* revision number */
7567 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7568 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7569 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7570 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7571 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7572 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7573 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7574 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7575 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7576 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7577 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7578 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7579 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7580 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7581 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7582 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7583 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7584 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7585 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7588 static const char long_binary_sid2[] = {
7589 0x1, /* revision number */
7591 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7592 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7593 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7594 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7595 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7596 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7597 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7598 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7599 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7600 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7601 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7602 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7603 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7604 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7605 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7606 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7607 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7608 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7609 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7610 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7611 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7612 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7613 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7614 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7615 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7616 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7617 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7618 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7619 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7620 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7621 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7622 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7623 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7626 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7629 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7632 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7638 /* Split a path name into filename and stream name components. Canonicalise
7639 * such that an implicit $DATA token is always explicit.
7641 * The "specification" of this function can be found in the
7642 * run_local_stream_name() function in torture.c, I've tried those
7643 * combinations against a W2k3 server.
7646 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7647 char **pbase, char **pstream)
7650 char *stream = NULL;
7651 char *sname; /* stream name */
7652 const char *stype; /* stream type */
7654 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7656 sname = strchr_m(fname, ':');
7658 if (lp_posix_pathnames() || (sname == NULL)) {
7659 if (pbase != NULL) {
7660 base = talloc_strdup(mem_ctx, fname);
7661 NT_STATUS_HAVE_NO_MEMORY(base);
7666 if (pbase != NULL) {
7667 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7668 NT_STATUS_HAVE_NO_MEMORY(base);
7673 stype = strchr_m(sname, ':');
7675 if (stype == NULL) {
7676 sname = talloc_strdup(mem_ctx, sname);
7680 if (StrCaseCmp(stype, ":$DATA") != 0) {
7682 * If there is an explicit stream type, so far we only
7683 * allow $DATA. Is there anything else allowed? -- vl
7685 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7687 return NT_STATUS_OBJECT_NAME_INVALID;
7689 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7693 if (sname == NULL) {
7695 return NT_STATUS_NO_MEMORY;
7698 if (sname[0] == '\0') {
7700 * no stream name, so no stream
7705 if (pstream != NULL) {
7706 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7707 if (stream == NULL) {
7710 return NT_STATUS_NO_MEMORY;
7713 * upper-case the type field
7715 strupper_m(strchr_m(stream, ':')+1);
7719 if (pbase != NULL) {
7722 if (pstream != NULL) {
7725 return NT_STATUS_OK;
7728 static bool test_stream_name(const char *fname, const char *expected_base,
7729 const char *expected_stream,
7730 NTSTATUS expected_status)
7734 char *stream = NULL;
7736 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7737 if (!NT_STATUS_EQUAL(status, expected_status)) {
7741 if (!NT_STATUS_IS_OK(status)) {
7745 if (base == NULL) goto error;
7747 if (strcmp(expected_base, base) != 0) goto error;
7749 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7750 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7752 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7756 TALLOC_FREE(stream);
7760 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7761 fname, expected_base ? expected_base : "<NULL>",
7762 expected_stream ? expected_stream : "<NULL>",
7763 nt_errstr(expected_status));
7764 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7765 base ? base : "<NULL>", stream ? stream : "<NULL>",
7768 TALLOC_FREE(stream);
7772 static bool run_local_stream_name(int dummy)
7776 ret &= test_stream_name(
7777 "bla", "bla", NULL, NT_STATUS_OK);
7778 ret &= test_stream_name(
7779 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7780 ret &= test_stream_name(
7781 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7782 ret &= test_stream_name(
7783 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7784 ret &= test_stream_name(
7785 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7786 ret &= test_stream_name(
7787 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7788 ret &= test_stream_name(
7789 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7790 ret &= test_stream_name(
7791 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7796 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7798 if (a.length != b.length) {
7799 printf("a.length=%d != b.length=%d\n",
7800 (int)a.length, (int)b.length);
7803 if (memcmp(a.data, b.data, a.length) != 0) {
7804 printf("a.data and b.data differ\n");
7810 static bool run_local_memcache(int dummy)
7812 struct memcache *cache;
7814 DATA_BLOB d1, d2, d3;
7815 DATA_BLOB v1, v2, v3;
7817 TALLOC_CTX *mem_ctx;
7819 size_t size1, size2;
7822 cache = memcache_init(NULL, 100);
7824 if (cache == NULL) {
7825 printf("memcache_init failed\n");
7829 d1 = data_blob_const("d1", 2);
7830 d2 = data_blob_const("d2", 2);
7831 d3 = data_blob_const("d3", 2);
7833 k1 = data_blob_const("d1", 2);
7834 k2 = data_blob_const("d2", 2);
7836 memcache_add(cache, STAT_CACHE, k1, d1);
7837 memcache_add(cache, GETWD_CACHE, k2, d2);
7839 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7840 printf("could not find k1\n");
7843 if (!data_blob_equal(d1, v1)) {
7847 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7848 printf("could not find k2\n");
7851 if (!data_blob_equal(d2, v2)) {
7855 memcache_add(cache, STAT_CACHE, k1, d3);
7857 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7858 printf("could not find replaced k1\n");
7861 if (!data_blob_equal(d3, v3)) {
7865 memcache_add(cache, GETWD_CACHE, k1, d1);
7867 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7868 printf("Did find k2, should have been purged\n");
7874 cache = memcache_init(NULL, 0);
7876 mem_ctx = talloc_init("foo");
7878 str1 = talloc_strdup(mem_ctx, "string1");
7879 str2 = talloc_strdup(mem_ctx, "string2");
7881 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7882 data_blob_string_const("torture"), &str1);
7883 size1 = talloc_total_size(cache);
7885 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7886 data_blob_string_const("torture"), &str2);
7887 size2 = talloc_total_size(cache);
7889 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7891 if (size2 > size1) {
7892 printf("memcache leaks memory!\n");
7902 static void wbclient_done(struct tevent_req *req)
7905 struct winbindd_response *wb_resp;
7906 int *i = (int *)tevent_req_callback_data_void(req);
7908 wbc_err = wb_trans_recv(req, req, &wb_resp);
7911 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7914 static bool run_local_wbclient(int dummy)
7916 struct event_context *ev;
7917 struct wb_context **wb_ctx;
7918 struct winbindd_request wb_req;
7919 bool result = false;
7922 BlockSignals(True, SIGPIPE);
7924 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7929 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7930 if (wb_ctx == NULL) {
7934 ZERO_STRUCT(wb_req);
7935 wb_req.cmd = WINBINDD_PING;
7937 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7939 for (i=0; i<nprocs; i++) {
7940 wb_ctx[i] = wb_context_init(ev, NULL);
7941 if (wb_ctx[i] == NULL) {
7944 for (j=0; j<torture_numops; j++) {
7945 struct tevent_req *req;
7946 req = wb_trans_send(ev, ev, wb_ctx[i],
7947 (j % 2) == 0, &wb_req);
7951 tevent_req_set_callback(req, wbclient_done, &i);
7957 while (i < nprocs * torture_numops) {
7958 event_loop_once(ev);
7967 static void getaddrinfo_finished(struct tevent_req *req)
7969 char *name = (char *)tevent_req_callback_data_void(req);
7970 struct addrinfo *ainfo;
7973 res = getaddrinfo_recv(req, &ainfo);
7975 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7978 d_printf("gai(%s) succeeded\n", name);
7979 freeaddrinfo(ainfo);
7982 static bool run_getaddrinfo_send(int dummy)
7984 TALLOC_CTX *frame = talloc_stackframe();
7985 struct fncall_context *ctx;
7986 struct tevent_context *ev;
7987 bool result = false;
7988 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7989 "www.slashdot.org", "heise.de" };
7990 struct tevent_req *reqs[4];
7993 ev = event_context_init(frame);
7998 ctx = fncall_context_init(frame, 4);
8000 for (i=0; i<ARRAY_SIZE(names); i++) {
8001 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8003 if (reqs[i] == NULL) {
8006 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8010 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8011 tevent_loop_once(ev);
8020 static bool dbtrans_inc(struct db_context *db)
8022 struct db_record *rec;
8027 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8029 printf(__location__ "fetch_lock failed\n");
8033 if (rec->value.dsize != sizeof(uint32_t)) {
8034 printf(__location__ "value.dsize = %d\n",
8035 (int)rec->value.dsize);
8039 val = (uint32_t *)rec->value.dptr;
8042 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8045 if (!NT_STATUS_IS_OK(status)) {
8046 printf(__location__ "store failed: %s\n",
8057 static bool run_local_dbtrans(int dummy)
8059 struct db_context *db;
8060 struct db_record *rec;
8065 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8066 O_RDWR|O_CREAT, 0600);
8068 printf("Could not open transtest.db\n");
8072 res = db->transaction_start(db);
8074 printf(__location__ "transaction_start failed\n");
8078 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8080 printf(__location__ "fetch_lock failed\n");
8084 if (rec->value.dptr == NULL) {
8086 status = rec->store(
8087 rec, make_tdb_data((uint8_t *)&initial,
8090 if (!NT_STATUS_IS_OK(status)) {
8091 printf(__location__ "store returned %s\n",
8099 res = db->transaction_commit(db);
8101 printf(__location__ "transaction_commit failed\n");
8109 res = db->transaction_start(db);
8111 printf(__location__ "transaction_start failed\n");
8115 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8116 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8120 for (i=0; i<10; i++) {
8121 if (!dbtrans_inc(db)) {
8126 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8127 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8131 if (val2 != val + 10) {
8132 printf(__location__ "val=%d, val2=%d\n",
8133 (int)val, (int)val2);
8137 printf("val2=%d\r", val2);
8139 res = db->transaction_commit(db);
8141 printf(__location__ "transaction_commit failed\n");
8151 * Just a dummy test to be run under a debugger. There's no real way
8152 * to inspect the tevent_select specific function from outside of
8156 static bool run_local_tevent_select(int dummy)
8158 struct tevent_context *ev;
8159 struct tevent_fd *fd1, *fd2;
8160 bool result = false;
8162 ev = tevent_context_init_byname(NULL, "select");
8164 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8168 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8170 d_fprintf(stderr, "tevent_add_fd failed\n");
8173 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8175 d_fprintf(stderr, "tevent_add_fd failed\n");
8180 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8182 d_fprintf(stderr, "tevent_add_fd failed\n");
8192 static double create_procs(bool (*fn)(int), bool *result)
8195 volatile pid_t *child_status;
8196 volatile bool *child_status_out;
8199 struct timeval start;
8203 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8204 if (!child_status) {
8205 printf("Failed to setup shared memory\n");
8209 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8210 if (!child_status_out) {
8211 printf("Failed to setup result status shared memory\n");
8215 for (i = 0; i < nprocs; i++) {
8216 child_status[i] = 0;
8217 child_status_out[i] = True;
8220 start = timeval_current();
8222 for (i=0;i<nprocs;i++) {
8225 pid_t mypid = getpid();
8226 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8228 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8231 if (torture_open_connection(¤t_cli, i)) break;
8233 printf("pid %d failed to start\n", (int)getpid());
8239 child_status[i] = getpid();
8241 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8243 child_status_out[i] = fn(i);
8250 for (i=0;i<nprocs;i++) {
8251 if (child_status[i]) synccount++;
8253 if (synccount == nprocs) break;
8255 } while (timeval_elapsed(&start) < 30);
8257 if (synccount != nprocs) {
8258 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8260 return timeval_elapsed(&start);
8263 /* start the client load */
8264 start = timeval_current();
8266 for (i=0;i<nprocs;i++) {
8267 child_status[i] = 0;
8270 printf("%d clients started\n", nprocs);
8272 for (i=0;i<nprocs;i++) {
8273 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8278 for (i=0;i<nprocs;i++) {
8279 if (!child_status_out[i]) {
8283 return timeval_elapsed(&start);
8286 #define FLAG_MULTIPROC 1
8293 {"FDPASS", run_fdpasstest, 0},
8294 {"LOCK1", run_locktest1, 0},
8295 {"LOCK2", run_locktest2, 0},
8296 {"LOCK3", run_locktest3, 0},
8297 {"LOCK4", run_locktest4, 0},
8298 {"LOCK5", run_locktest5, 0},
8299 {"LOCK6", run_locktest6, 0},
8300 {"LOCK7", run_locktest7, 0},
8301 {"LOCK8", run_locktest8, 0},
8302 {"LOCK9", run_locktest9, 0},
8303 {"UNLINK", run_unlinktest, 0},
8304 {"BROWSE", run_browsetest, 0},
8305 {"ATTR", run_attrtest, 0},
8306 {"TRANS2", run_trans2test, 0},
8307 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8308 {"TORTURE",run_torture, FLAG_MULTIPROC},
8309 {"RANDOMIPC", run_randomipc, 0},
8310 {"NEGNOWAIT", run_negprot_nowait, 0},
8311 {"NBENCH", run_nbench, 0},
8312 {"NBENCH2", run_nbench2, 0},
8313 {"OPLOCK1", run_oplock1, 0},
8314 {"OPLOCK2", run_oplock2, 0},
8315 {"OPLOCK3", run_oplock3, 0},
8316 {"OPLOCK4", run_oplock4, 0},
8317 {"DIR", run_dirtest, 0},
8318 {"DIR1", run_dirtest1, 0},
8319 {"DIR-CREATETIME", run_dir_createtime, 0},
8320 {"DENY1", torture_denytest1, 0},
8321 {"DENY2", torture_denytest2, 0},
8322 {"TCON", run_tcon_test, 0},
8323 {"TCONDEV", run_tcon_devtype_test, 0},
8324 {"RW1", run_readwritetest, 0},
8325 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8326 {"RW3", run_readwritelarge, 0},
8327 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8328 {"OPEN", run_opentest, 0},
8329 {"POSIX", run_simple_posix_open_test, 0},
8330 {"POSIX-APPEND", run_posix_append, 0},
8331 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8332 {"ASYNC-ECHO", run_async_echo, 0},
8333 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8334 { "SHORTNAME-TEST", run_shortname_test, 0},
8335 { "ADDRCHANGE", run_addrchange, 0},
8337 {"OPENATTR", run_openattrtest, 0},
8339 {"XCOPY", run_xcopy, 0},
8340 {"RENAME", run_rename, 0},
8341 {"DELETE", run_deletetest, 0},
8342 {"DELETE-LN", run_deletetest_ln, 0},
8343 {"PROPERTIES", run_properties, 0},
8344 {"MANGLE", torture_mangle, 0},
8345 {"MANGLE1", run_mangle1, 0},
8346 {"W2K", run_w2ktest, 0},
8347 {"TRANS2SCAN", torture_trans2_scan, 0},
8348 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8349 {"UTABLE", torture_utable, 0},
8350 {"CASETABLE", torture_casetable, 0},
8351 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8352 {"PIPE_NUMBER", run_pipe_number, 0},
8353 {"TCON2", run_tcon2_test, 0},
8354 {"IOCTL", torture_ioctl_test, 0},
8355 {"CHKPATH", torture_chkpath_test, 0},
8356 {"FDSESS", run_fdsesstest, 0},
8357 { "EATEST", run_eatest, 0},
8358 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8359 { "CHAIN1", run_chain1, 0},
8360 { "CHAIN2", run_chain2, 0},
8361 { "WINDOWS-WRITE", run_windows_write, 0},
8362 { "CLI_ECHO", run_cli_echo, 0},
8363 { "GETADDRINFO", run_getaddrinfo_send, 0},
8364 { "TLDAP", run_tldap },
8365 { "STREAMERROR", run_streamerror },
8366 { "NOTIFY-BENCH", run_notify_bench },
8367 { "BAD-NBT-SESSION", run_bad_nbt_session },
8368 { "SMB-ANY-CONNECT", run_smb_any_connect },
8369 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8370 { "LOCAL-GENCACHE", run_local_gencache, 0},
8371 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8372 { "LOCAL-BASE64", run_local_base64, 0},
8373 { "LOCAL-RBTREE", run_local_rbtree, 0},
8374 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8375 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8376 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8377 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8378 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8379 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8380 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8381 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8386 /****************************************************************************
8387 run a specified test or "ALL"
8388 ****************************************************************************/
8389 static bool run_test(const char *name)
8396 if (strequal(name,"ALL")) {
8397 for (i=0;torture_ops[i].name;i++) {
8398 run_test(torture_ops[i].name);
8403 for (i=0;torture_ops[i].name;i++) {
8404 fstr_sprintf(randomfname, "\\XX%x",
8405 (unsigned)random());
8407 if (strequal(name, torture_ops[i].name)) {
8409 printf("Running %s\n", name);
8410 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8411 t = create_procs(torture_ops[i].fn, &result);
8414 printf("TEST %s FAILED!\n", name);
8417 struct timeval start;
8418 start = timeval_current();
8419 if (!torture_ops[i].fn(0)) {
8421 printf("TEST %s FAILED!\n", name);
8423 t = timeval_elapsed(&start);
8425 printf("%s took %g secs\n\n", name, t);
8430 printf("Did not find a test named %s\n", name);
8438 static void usage(void)
8442 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8443 printf("Please use samba4 torture.\n\n");
8445 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8447 printf("\t-d debuglevel\n");
8448 printf("\t-U user%%pass\n");
8449 printf("\t-k use kerberos\n");
8450 printf("\t-N numprocs\n");
8451 printf("\t-n my_netbios_name\n");
8452 printf("\t-W workgroup\n");
8453 printf("\t-o num_operations\n");
8454 printf("\t-O socket_options\n");
8455 printf("\t-m maximum protocol\n");
8456 printf("\t-L use oplocks\n");
8457 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8458 printf("\t-A showall\n");
8459 printf("\t-p port\n");
8460 printf("\t-s seed\n");
8461 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8464 printf("tests are:");
8465 for (i=0;torture_ops[i].name;i++) {
8466 printf(" %s", torture_ops[i].name);
8470 printf("default test is ALL\n");
8475 /****************************************************************************
8477 ****************************************************************************/
8478 int main(int argc,char *argv[])
8484 bool correct = True;
8485 TALLOC_CTX *frame = talloc_stackframe();
8486 int seed = time(NULL);
8488 #ifdef HAVE_SETBUFFER
8489 setbuffer(stdout, NULL, 0);
8492 setup_logging("smbtorture", DEBUG_STDOUT);
8496 if (is_default_dyn_CONFIGFILE()) {
8497 if(getenv("SMB_CONF_PATH")) {
8498 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8501 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8508 for(p = argv[1]; *p; p++)
8512 if (strncmp(argv[1], "//", 2)) {
8516 fstrcpy(host, &argv[1][2]);
8517 p = strchr_m(&host[2],'/');
8522 fstrcpy(share, p+1);
8524 fstrcpy(myname, get_myname(talloc_tos()));
8526 fprintf(stderr, "Failed to get my hostname.\n");
8530 if (*username == 0 && getenv("LOGNAME")) {
8531 fstrcpy(username,getenv("LOGNAME"));
8537 fstrcpy(workgroup, lp_workgroup());
8539 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8542 port_to_use = atoi(optarg);
8545 seed = atoi(optarg);
8548 fstrcpy(workgroup,optarg);
8551 max_protocol = interpret_protocol(optarg, max_protocol);
8554 nprocs = atoi(optarg);
8557 torture_numops = atoi(optarg);
8560 lp_set_cmdline("log level", optarg);
8569 local_path = optarg;
8572 torture_showall = True;
8575 fstrcpy(myname, optarg);
8578 client_txt = optarg;
8585 use_kerberos = True;
8587 d_printf("No kerberos support compiled in\n");
8593 fstrcpy(username,optarg);
8594 p = strchr_m(username,'%');
8597 fstrcpy(password, p+1);
8602 fstrcpy(multishare_conn_fname, optarg);
8603 use_multishare_conn = True;
8606 torture_blocksize = atoi(optarg);
8609 printf("Unknown option %c (%d)\n", (char)opt, opt);
8614 d_printf("using seed %d\n", seed);
8618 if(use_kerberos && !gotuser) gotpass = True;
8621 p = getpass("Password:");
8623 fstrcpy(password, p);
8628 printf("host=%s share=%s user=%s myname=%s\n",
8629 host, share, username, myname);
8631 if (argc == optind) {
8632 correct = run_test("ALL");
8634 for (i=optind;i<argc;i++) {
8635 if (!run_test(argv[i])) {