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/libsmb.h"
35 #include "libsmb/clirap.h"
37 #include "libsmb/nmblib.h"
38 #include "../lib/util/tevent_ntstatus.h"
44 static fstring host, workgroup, share, password, username, myname;
45 static int max_protocol = PROTOCOL_NT1;
46 static const char *sockops="TCP_NODELAY";
48 static int port_to_use=0;
49 int torture_numops=100;
50 int torture_blocksize=1024*1024;
51 static int procnum; /* records process count number when forking */
52 static struct cli_state *current_cli;
53 static fstring randomfname;
54 static bool use_oplocks;
55 static bool use_level_II_oplocks;
56 static const char *client_txt = "client_oplocks.txt";
57 static bool use_kerberos;
58 static fstring multishare_conn_fname;
59 static bool use_multishare_conn = False;
60 static bool do_encrypt;
61 static const char *local_path = NULL;
62 static int signing_state = Undefined;
65 bool torture_showall = False;
67 static double create_procs(bool (*fn)(int), bool *result);
70 /* return a pointer to a anonymous shared memory segment of size "size"
71 which will persist across fork() but will disappear when all processes
74 The memory is not zeroed
76 This function uses system5 shared memory. It takes advantage of a property
77 that the memory is not destroyed if it is attached when the id is removed
79 void *shm_setup(int size)
85 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
87 printf("can't get shared memory\n");
90 shm_unlink("private");
91 if (ftruncate(shmid, size) == -1) {
92 printf("can't set shared memory size\n");
95 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
96 if (ret == MAP_FAILED) {
97 printf("can't map shared memory\n");
101 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
103 printf("can't get shared memory\n");
106 ret = (void *)shmat(shmid, 0, 0);
107 if (!ret || ret == (void *)-1) {
108 printf("can't attach to shared memory\n");
111 /* the following releases the ipc, but note that this process
112 and all its children will still have access to the memory, its
113 just that the shmid is no longer valid for other shm calls. This
114 means we don't leave behind lots of shm segments after we exit
116 See Stevens "advanced programming in unix env" for details
118 shmctl(shmid, IPC_RMID, 0);
124 /********************************************************************
125 Ensure a connection is encrypted.
126 ********************************************************************/
128 static bool force_cli_encryption(struct cli_state *c,
129 const char *sharename)
132 uint32 caplow, caphigh;
135 if (!SERVER_HAS_UNIX_CIFS(c)) {
136 d_printf("Encryption required and "
137 "server that doesn't support "
138 "UNIX extensions - failing connect\n");
142 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
144 if (!NT_STATUS_IS_OK(status)) {
145 d_printf("Encryption required and "
146 "can't get UNIX CIFS extensions "
147 "version from server: %s\n", nt_errstr(status));
151 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
152 d_printf("Encryption required and "
153 "share %s doesn't support "
154 "encryption.\n", sharename);
158 if (c->use_kerberos) {
159 status = cli_gss_smb_encryption_start(c);
161 status = cli_raw_ntlm_smb_encryption_start(c,
167 if (!NT_STATUS_IS_OK(status)) {
168 d_printf("Encryption required and "
169 "setup failed with error %s.\n",
178 static struct cli_state *open_nbt_connection(void)
180 struct nmb_name called, calling;
181 struct sockaddr_storage ss;
185 make_nmb_name(&calling, myname, 0x0);
186 make_nmb_name(&called , host, 0x20);
190 if (!(c = cli_initialise_ex(signing_state))) {
191 printf("Failed initialize cli_struct to connect with %s\n", host);
195 c->port = port_to_use;
197 status = cli_connect(c, host, &ss);
198 if (!NT_STATUS_IS_OK(status)) {
199 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
203 c->use_kerberos = use_kerberos;
205 c->timeout = 120000; /* set a really long timeout (2 minutes) */
206 if (use_oplocks) c->use_oplocks = True;
207 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
209 if (!cli_session_request(c, &calling, &called)) {
211 * Well, that failed, try *SMBSERVER ...
212 * However, we must reconnect as well ...
214 status = cli_connect(c, host, &ss);
215 if (!NT_STATUS_IS_OK(status)) {
216 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
220 make_nmb_name(&called, "*SMBSERVER", 0x20);
221 if (!cli_session_request(c, &calling, &called)) {
222 printf("%s rejected the session\n",host);
223 printf("We tried with a called name of %s & %s\n",
233 /****************************************************************************
234 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
235 ****************************************************************************/
237 static bool cli_bad_session_request(struct cli_state *cli,
238 struct nmb_name *calling, struct nmb_name *called)
245 memcpy(&(cli->calling), calling, sizeof(*calling));
246 memcpy(&(cli->called ), called , sizeof(*called ));
248 /* put in the destination name */
250 tmp = name_mangle(talloc_tos(), cli->called.name,
251 cli->called.name_type);
257 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
259 memcpy(p, tmp, namelen);
264 /* Deliberately corrupt the name len (first byte) */
269 tmp = name_mangle(talloc_tos(), cli->calling.name,
270 cli->calling.name_type);
276 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
278 memcpy(p, tmp, namelen);
282 /* Deliberately corrupt the name len (first byte) */
285 /* send a session request (RFC 1002) */
286 /* setup the packet length
287 * Remove four bytes from the length count, since the length
288 * field in the NBT Session Service header counts the number
289 * of bytes which follow. The cli_send_smb() function knows
290 * about this and accounts for those four bytes.
294 _smb_setlen(cli->outbuf,len);
295 SCVAL(cli->outbuf,0,0x81);
298 DEBUG(5,("Sent session request\n"));
300 if (!cli_receive_smb(cli))
303 if (CVAL(cli->inbuf,0) != 0x82) {
304 /* This is the wrong place to put the error... JRA. */
305 cli->rap_error = CVAL(cli->inbuf,4);
311 static struct cli_state *open_bad_nbt_connection(void)
313 struct nmb_name called, calling;
314 struct sockaddr_storage ss;
318 make_nmb_name(&calling, myname, 0x0);
319 make_nmb_name(&called , host, 0x20);
323 if (!(c = cli_initialise_ex(signing_state))) {
324 printf("Failed initialize cli_struct to connect with %s\n", host);
330 status = cli_connect(c, host, &ss);
331 if (!NT_STATUS_IS_OK(status)) {
332 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
336 c->timeout = 4000; /* set a short timeout (4 seconds) */
338 if (!cli_bad_session_request(c, &calling, &called)) {
339 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
347 /* Insert a NULL at the first separator of the given path and return a pointer
348 * to the remainder of the string.
351 terminate_path_at_separator(char * path)
359 if ((p = strchr_m(path, '/'))) {
364 if ((p = strchr_m(path, '\\'))) {
374 parse a //server/share type UNC name
376 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
377 char **hostname, char **sharename)
381 *hostname = *sharename = NULL;
383 if (strncmp(unc_name, "\\\\", 2) &&
384 strncmp(unc_name, "//", 2)) {
388 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
389 p = terminate_path_at_separator(*hostname);
392 *sharename = talloc_strdup(mem_ctx, p);
393 terminate_path_at_separator(*sharename);
396 if (*hostname && *sharename) {
400 TALLOC_FREE(*hostname);
401 TALLOC_FREE(*sharename);
405 static bool torture_open_connection_share(struct cli_state **c,
406 const char *hostname,
407 const char *sharename)
413 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
415 flags |= CLI_FULL_CONNECTION_OPLOCKS;
416 if (use_level_II_oplocks)
417 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
419 status = cli_full_connection(c, myname,
420 hostname, NULL, port_to_use,
423 password, flags, signing_state);
424 if (!NT_STATUS_IS_OK(status)) {
425 printf("failed to open share connection: //%s/%s port:%d - %s\n",
426 hostname, sharename, port_to_use, nt_errstr(status));
430 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
433 return force_cli_encryption(*c,
439 bool torture_open_connection(struct cli_state **c, int conn_index)
441 char **unc_list = NULL;
442 int num_unc_names = 0;
445 if (use_multishare_conn==True) {
447 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
448 if (!unc_list || num_unc_names <= 0) {
449 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
453 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
455 printf("Failed to parse UNC name %s\n",
456 unc_list[conn_index % num_unc_names]);
457 TALLOC_FREE(unc_list);
461 result = torture_open_connection_share(c, h, s);
463 /* h, s were copied earlier */
464 TALLOC_FREE(unc_list);
468 return torture_open_connection_share(c, host, share);
471 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
473 uint16 old_vuid = cli->vuid;
474 fstring old_user_name;
475 size_t passlen = strlen(password);
479 fstrcpy(old_user_name, cli->user_name);
481 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
485 *new_vuid = cli->vuid;
486 cli->vuid = old_vuid;
487 status = cli_set_username(cli, old_user_name);
488 if (!NT_STATUS_IS_OK(status)) {
495 bool torture_close_connection(struct cli_state *c)
500 status = cli_tdis(c);
501 if (!NT_STATUS_IS_OK(status)) {
502 printf("tdis failed (%s)\n", nt_errstr(status));
512 /* check if the server produced the expected error code */
513 static bool check_error(int line, struct cli_state *c,
514 uint8 eclass, uint32 ecode, NTSTATUS nterr)
516 if (cli_is_dos_error(c)) {
520 /* Check DOS error */
522 cli_dos_error(c, &cclass, &num);
524 if (eclass != cclass || ecode != num) {
525 printf("unexpected error code class=%d code=%d\n",
526 (int)cclass, (int)num);
527 printf(" expected %d/%d %s (line=%d)\n",
528 (int)eclass, (int)ecode, nt_errstr(nterr), line);
537 status = cli_nt_error(c);
539 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
540 printf("unexpected error code %s\n", nt_errstr(status));
541 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
550 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
552 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
553 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
559 static bool rw_torture(struct cli_state *c)
561 const char *lockfname = "\\torture.lck";
565 pid_t pid2, pid = getpid();
571 memset(buf, '\0', sizeof(buf));
573 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
575 if (!NT_STATUS_IS_OK(status)) {
576 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
578 if (!NT_STATUS_IS_OK(status)) {
579 printf("open of %s failed (%s)\n",
580 lockfname, nt_errstr(status));
584 for (i=0;i<torture_numops;i++) {
585 unsigned n = (unsigned)sys_random()%10;
588 printf("%d\r", i); fflush(stdout);
590 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
592 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
596 status = cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC,
598 if (!NT_STATUS_IS_OK(status)) {
599 printf("open failed (%s)\n", nt_errstr(status));
604 status = cli_writeall(c, fnum, 0, (uint8_t *)&pid, 0,
606 if (!NT_STATUS_IS_OK(status)) {
607 printf("write failed (%s)\n", nt_errstr(status));
612 status = cli_writeall(c, fnum, 0, (uint8_t *)buf,
613 sizeof(pid)+(j*sizeof(buf)),
615 if (!NT_STATUS_IS_OK(status)) {
616 printf("write failed (%s)\n",
624 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
625 printf("read failed (%s)\n", cli_errstr(c));
630 printf("data corruption!\n");
634 status = cli_close(c, fnum);
635 if (!NT_STATUS_IS_OK(status)) {
636 printf("close failed (%s)\n", nt_errstr(status));
640 status = cli_unlink(c, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
641 if (!NT_STATUS_IS_OK(status)) {
642 printf("unlink failed (%s)\n", nt_errstr(status));
646 status = cli_unlock(c, fnum2, n*sizeof(int), sizeof(int));
647 if (!NT_STATUS_IS_OK(status)) {
648 printf("unlock failed (%s)\n", nt_errstr(status));
654 cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
661 static bool run_torture(int dummy)
663 struct cli_state *cli;
668 cli_sockopt(cli, sockops);
670 ret = rw_torture(cli);
672 if (!torture_close_connection(cli)) {
679 static bool rw_torture3(struct cli_state *c, char *lockfname)
681 uint16_t fnum = (uint16_t)-1;
686 unsigned countprev = 0;
689 NTSTATUS status = NT_STATUS_OK;
692 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
694 SIVAL(buf, i, sys_random());
699 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
700 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
703 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
705 if (!NT_STATUS_IS_OK(status)) {
706 printf("first open read/write of %s failed (%s)\n",
707 lockfname, nt_errstr(status));
713 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
715 status = cli_open(c, lockfname, O_RDONLY,
717 if (!NT_STATUS_IS_OK(status)) {
722 if (!NT_STATUS_IS_OK(status)) {
723 printf("second open read-only of %s failed (%s)\n",
724 lockfname, nt_errstr(status));
730 for (count = 0; count < sizeof(buf); count += sent)
732 if (count >= countprev) {
733 printf("%d %8d\r", i, count);
736 countprev += (sizeof(buf) / 20);
741 sent = ((unsigned)sys_random()%(20))+ 1;
742 if (sent > sizeof(buf) - count)
744 sent = sizeof(buf) - count;
747 status = cli_writeall(c, fnum, 0, (uint8_t *)buf+count,
748 count, (size_t)sent, NULL);
749 if (!NT_STATUS_IS_OK(status)) {
750 printf("write failed (%s)\n",
757 sent = cli_read(c, fnum, buf_rd+count, count,
761 printf("read failed offset:%d size:%ld (%s)\n",
762 count, (unsigned long)sizeof(buf)-count,
769 if (memcmp(buf_rd+count, buf+count, sent) != 0)
771 printf("read/write compare failed\n");
772 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
781 status = cli_close(c, fnum);
782 if (!NT_STATUS_IS_OK(status)) {
783 printf("close failed (%s)\n", nt_errstr(status));
790 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
792 const char *lockfname = "\\torture2.lck";
802 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
803 if (!NT_STATUS_IS_OK(status)) {
804 printf("unlink failed (%s) (normal, this file should not exist)\n", nt_errstr(status));
807 status = cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
809 if (!NT_STATUS_IS_OK(status)) {
810 printf("first open read/write of %s failed (%s)\n",
811 lockfname, nt_errstr(status));
815 status = cli_open(c2, lockfname, O_RDONLY, DENY_NONE, &fnum2);
816 if (!NT_STATUS_IS_OK(status)) {
817 printf("second open read-only of %s failed (%s)\n",
818 lockfname, nt_errstr(status));
819 cli_close(c1, fnum1);
823 for (i = 0; i < torture_numops; i++)
826 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
828 printf("%d\r", i); fflush(stdout);
831 generate_random_buffer((unsigned char *)buf, buf_size);
833 status = cli_writeall(c1, fnum1, 0, (uint8_t *)buf, 0,
835 if (!NT_STATUS_IS_OK(status)) {
836 printf("write failed (%s)\n", nt_errstr(status));
841 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
842 printf("read failed (%s)\n", cli_errstr(c2));
843 printf("read %d, expected %ld\n", (int)bytes_read,
844 (unsigned long)buf_size);
849 if (memcmp(buf_rd, buf, buf_size) != 0)
851 printf("read/write compare failed\n");
857 status = cli_close(c2, fnum2);
858 if (!NT_STATUS_IS_OK(status)) {
859 printf("close failed (%s)\n", nt_errstr(status));
863 status = cli_close(c1, fnum1);
864 if (!NT_STATUS_IS_OK(status)) {
865 printf("close failed (%s)\n", nt_errstr(status));
869 status = cli_unlink(c1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
870 if (!NT_STATUS_IS_OK(status)) {
871 printf("unlink failed (%s)\n", nt_errstr(status));
878 static bool run_readwritetest(int dummy)
880 struct cli_state *cli1, *cli2;
881 bool test1, test2 = False;
883 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
886 cli_sockopt(cli1, sockops);
887 cli_sockopt(cli2, sockops);
889 printf("starting readwritetest\n");
891 test1 = rw_torture2(cli1, cli2);
892 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
895 test2 = rw_torture2(cli1, cli1);
896 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
899 if (!torture_close_connection(cli1)) {
903 if (!torture_close_connection(cli2)) {
907 return (test1 && test2);
910 static bool run_readwritemulti(int dummy)
912 struct cli_state *cli;
917 cli_sockopt(cli, sockops);
919 printf("run_readwritemulti: fname %s\n", randomfname);
920 test = rw_torture3(cli, randomfname);
922 if (!torture_close_connection(cli)) {
929 static bool run_readwritelarge_internal(int max_xmit_k)
931 static struct cli_state *cli1;
933 const char *lockfname = "\\large.dat";
939 if (!torture_open_connection(&cli1, 0)) {
942 cli_sockopt(cli1, sockops);
943 memset(buf,'\0',sizeof(buf));
945 cli1->max_xmit = max_xmit_k*1024;
947 if (signing_state == Required) {
948 /* Horrible cheat to force
949 multiple signed outstanding
950 packets against a Samba server.
952 cli1->is_samba = false;
955 printf("starting readwritelarge_internal\n");
957 cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
959 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
961 if (!NT_STATUS_IS_OK(status)) {
962 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
966 cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf), NULL);
968 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
970 if (!NT_STATUS_IS_OK(status)) {
971 printf("qfileinfo failed (%s)\n", nt_errstr(status));
975 if (fsize == sizeof(buf))
976 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
977 (unsigned long)fsize);
979 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
980 (unsigned long)fsize);
984 status = cli_close(cli1, fnum1);
985 if (!NT_STATUS_IS_OK(status)) {
986 printf("close failed (%s)\n", nt_errstr(status));
990 status = cli_unlink(cli1, lockfname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
991 if (!NT_STATUS_IS_OK(status)) {
992 printf("unlink failed (%s)\n", nt_errstr(status));
996 status = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL,
998 if (!NT_STATUS_IS_OK(status)) {
999 printf("open read/write of %s failed (%s)\n", lockfname, nt_errstr(status));
1003 cli1->max_xmit = 4*1024;
1005 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
1007 status = cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL,
1009 if (!NT_STATUS_IS_OK(status)) {
1010 printf("qfileinfo failed (%s)\n", nt_errstr(status));
1014 if (fsize == sizeof(buf))
1015 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
1016 (unsigned long)fsize);
1018 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
1019 (unsigned long)fsize);
1024 /* ToDo - set allocation. JRA */
1025 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
1026 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
1029 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
1031 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
1035 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
1038 status = cli_close(cli1, fnum1);
1039 if (!NT_STATUS_IS_OK(status)) {
1040 printf("close failed (%s)\n", nt_errstr(status));
1044 if (!torture_close_connection(cli1)) {
1050 static bool run_readwritelarge(int dummy)
1052 return run_readwritelarge_internal(128);
1055 static bool run_readwritelarge_signtest(int dummy)
1058 signing_state = Required;
1059 ret = run_readwritelarge_internal(2);
1060 signing_state = Undefined;
1067 #define ival(s) strtol(s, NULL, 0)
1069 /* run a test that simulates an approximate netbench client load */
1070 static bool run_netbench(int client)
1072 struct cli_state *cli;
1077 const char *params[20];
1078 bool correct = True;
1084 cli_sockopt(cli, sockops);
1088 slprintf(cname,sizeof(cname)-1, "client%d", client);
1090 f = fopen(client_txt, "r");
1097 while (fgets(line, sizeof(line)-1, f)) {
1101 line[strlen(line)-1] = 0;
1103 /* printf("[%d] %s\n", line_count, line); */
1105 all_string_sub(line,"client1", cname, sizeof(line));
1107 /* parse the command parameters */
1108 params[0] = strtok_r(line, " ", &saveptr);
1110 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1114 if (i < 2) continue;
1116 if (!strncmp(params[0],"SMB", 3)) {
1117 printf("ERROR: You are using a dbench 1 load file\n");
1121 if (!strcmp(params[0],"NTCreateX")) {
1122 nb_createx(params[1], ival(params[2]), ival(params[3]),
1124 } else if (!strcmp(params[0],"Close")) {
1125 nb_close(ival(params[1]));
1126 } else if (!strcmp(params[0],"Rename")) {
1127 nb_rename(params[1], params[2]);
1128 } else if (!strcmp(params[0],"Unlink")) {
1129 nb_unlink(params[1]);
1130 } else if (!strcmp(params[0],"Deltree")) {
1131 nb_deltree(params[1]);
1132 } else if (!strcmp(params[0],"Rmdir")) {
1133 nb_rmdir(params[1]);
1134 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1135 nb_qpathinfo(params[1]);
1136 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1137 nb_qfileinfo(ival(params[1]));
1138 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1139 nb_qfsinfo(ival(params[1]));
1140 } else if (!strcmp(params[0],"FIND_FIRST")) {
1141 nb_findfirst(params[1]);
1142 } else if (!strcmp(params[0],"WriteX")) {
1143 nb_writex(ival(params[1]),
1144 ival(params[2]), ival(params[3]), ival(params[4]));
1145 } else if (!strcmp(params[0],"ReadX")) {
1146 nb_readx(ival(params[1]),
1147 ival(params[2]), ival(params[3]), ival(params[4]));
1148 } else if (!strcmp(params[0],"Flush")) {
1149 nb_flush(ival(params[1]));
1151 printf("Unknown operation %s\n", params[0]);
1159 if (!torture_close_connection(cli)) {
1167 /* run a test that simulates an approximate netbench client load */
1168 static bool run_nbench(int dummy)
1171 bool correct = True;
1177 signal(SIGALRM, nb_alarm);
1179 t = create_procs(run_netbench, &correct);
1182 printf("\nThroughput %g MB/sec\n",
1183 1.0e-6 * nbio_total() / t);
1189 This test checks for two things:
1191 1) correct support for retaining locks over a close (ie. the server
1192 must not use posix semantics)
1193 2) support for lock timeouts
1195 static bool run_locktest1(int dummy)
1197 struct cli_state *cli1, *cli2;
1198 const char *fname = "\\lockt1.lck";
1199 uint16_t fnum1, fnum2, fnum3;
1201 unsigned lock_timeout;
1204 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1207 cli_sockopt(cli1, sockops);
1208 cli_sockopt(cli2, sockops);
1210 printf("starting locktest1\n");
1212 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1214 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1216 if (!NT_STATUS_IS_OK(status)) {
1217 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1221 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1227 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3);
1228 if (!NT_STATUS_IS_OK(status)) {
1229 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1233 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1234 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1239 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1240 printf("lock2 succeeded! This is a locking bug\n");
1243 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1244 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1248 lock_timeout = (1 + (random() % 20));
1249 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1251 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1252 printf("lock3 succeeded! This is a locking bug\n");
1255 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1256 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1260 if (ABS(t2 - t1) < lock_timeout-1) {
1261 printf("error: This server appears not to support timed lock requests\n");
1264 printf("server slept for %u seconds for a %u second timeout\n",
1265 (unsigned int)(t2-t1), lock_timeout);
1267 status = cli_close(cli1, fnum2);
1268 if (!NT_STATUS_IS_OK(status)) {
1269 printf("close1 failed (%s)\n", nt_errstr(status));
1273 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1274 printf("lock4 succeeded! This is a locking bug\n");
1277 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1278 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1281 status = cli_close(cli1, fnum1);
1282 if (!NT_STATUS_IS_OK(status)) {
1283 printf("close2 failed (%s)\n", nt_errstr(status));
1287 status = cli_close(cli2, fnum3);
1288 if (!NT_STATUS_IS_OK(status)) {
1289 printf("close3 failed (%s)\n", nt_errstr(status));
1293 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1294 if (!NT_STATUS_IS_OK(status)) {
1295 printf("unlink failed (%s)\n", nt_errstr(status));
1300 if (!torture_close_connection(cli1)) {
1304 if (!torture_close_connection(cli2)) {
1308 printf("Passed locktest1\n");
1313 this checks to see if a secondary tconx can use open files from an
1316 static bool run_tcon_test(int dummy)
1318 static struct cli_state *cli;
1319 const char *fname = "\\tcontest.tmp";
1321 uint16 cnum1, cnum2, cnum3;
1322 uint16 vuid1, vuid2;
1327 memset(buf, '\0', sizeof(buf));
1329 if (!torture_open_connection(&cli, 0)) {
1332 cli_sockopt(cli, sockops);
1334 printf("starting tcontest\n");
1336 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1338 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1339 if (!NT_STATUS_IS_OK(status)) {
1340 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1347 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1348 if (!NT_STATUS_IS_OK(status)) {
1349 printf("initial write failed (%s)", nt_errstr(status));
1353 status = cli_tcon_andx(cli, share, "?????",
1354 password, strlen(password)+1);
1355 if (!NT_STATUS_IS_OK(status)) {
1356 printf("%s refused 2nd tree connect (%s)\n", host,
1363 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1364 vuid2 = cli->vuid + 1;
1366 /* try a write with the wrong tid */
1369 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1370 if (NT_STATUS_IS_OK(status)) {
1371 printf("* server allows write with wrong TID\n");
1374 printf("server fails write with wrong TID : %s\n",
1379 /* try a write with an invalid tid */
1382 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1383 if (NT_STATUS_IS_OK(status)) {
1384 printf("* server allows write with invalid TID\n");
1387 printf("server fails write with invalid TID : %s\n",
1391 /* try a write with an invalid vuid */
1395 status = cli_writeall(cli, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
1396 if (NT_STATUS_IS_OK(status)) {
1397 printf("* server allows write with invalid VUID\n");
1400 printf("server fails write with invalid VUID : %s\n",
1407 status = cli_close(cli, fnum1);
1408 if (!NT_STATUS_IS_OK(status)) {
1409 printf("close failed (%s)\n", nt_errstr(status));
1415 status = cli_tdis(cli);
1416 if (!NT_STATUS_IS_OK(status)) {
1417 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1423 if (!torture_close_connection(cli)) {
1432 checks for old style tcon support
1434 static bool run_tcon2_test(int dummy)
1436 static struct cli_state *cli;
1437 uint16 cnum, max_xmit;
1441 if (!torture_open_connection(&cli, 0)) {
1444 cli_sockopt(cli, sockops);
1446 printf("starting tcon2 test\n");
1448 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1452 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1456 if (!NT_STATUS_IS_OK(status)) {
1457 printf("tcon2 failed : %s\n", nt_errstr(status));
1459 printf("tcon OK : max_xmit=%d cnum=%d\n",
1460 (int)max_xmit, (int)cnum);
1463 if (!torture_close_connection(cli)) {
1467 printf("Passed tcon2 test\n");
1471 static bool tcon_devtest(struct cli_state *cli,
1472 const char *myshare, const char *devtype,
1473 const char *return_devtype,
1474 NTSTATUS expected_error)
1479 status = cli_tcon_andx(cli, myshare, devtype,
1480 password, strlen(password)+1);
1482 if (NT_STATUS_IS_OK(expected_error)) {
1483 if (NT_STATUS_IS_OK(status)) {
1484 if (strcmp(cli->dev, return_devtype) == 0) {
1487 printf("tconX to share %s with type %s "
1488 "succeeded but returned the wrong "
1489 "device type (got [%s] but should have got [%s])\n",
1490 myshare, devtype, cli->dev, return_devtype);
1494 printf("tconX to share %s with type %s "
1495 "should have succeeded but failed\n",
1501 if (NT_STATUS_IS_OK(status)) {
1502 printf("tconx to share %s with type %s "
1503 "should have failed but succeeded\n",
1507 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1511 printf("Returned unexpected error\n");
1520 checks for correct tconX support
1522 static bool run_tcon_devtype_test(int dummy)
1524 static struct cli_state *cli1 = NULL;
1529 status = cli_full_connection(&cli1, myname,
1530 host, NULL, port_to_use,
1532 username, workgroup,
1533 password, flags, signing_state);
1535 if (!NT_STATUS_IS_OK(status)) {
1536 printf("could not open connection\n");
1540 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1543 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1546 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1549 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1552 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1555 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1558 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1561 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1564 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1567 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1573 printf("Passed tcondevtest\n");
1580 This test checks that
1582 1) the server supports multiple locking contexts on the one SMB
1583 connection, distinguished by PID.
1585 2) the server correctly fails overlapping locks made by the same PID (this
1586 goes against POSIX behaviour, which is why it is tricky to implement)
1588 3) the server denies unlock requests by an incorrect client PID
1590 static bool run_locktest2(int dummy)
1592 static struct cli_state *cli;
1593 const char *fname = "\\lockt2.lck";
1594 uint16_t fnum1, fnum2, fnum3;
1595 bool correct = True;
1598 if (!torture_open_connection(&cli, 0)) {
1602 cli_sockopt(cli, sockops);
1604 printf("starting locktest2\n");
1606 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1610 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1611 if (!NT_STATUS_IS_OK(status)) {
1612 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1616 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2);
1617 if (!NT_STATUS_IS_OK(status)) {
1618 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1624 status = cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3);
1625 if (!NT_STATUS_IS_OK(status)) {
1626 printf("open3 of %s failed (%s)\n", fname, nt_errstr(status));
1632 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1633 printf("lock1 failed (%s)\n", cli_errstr(cli));
1637 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1638 printf("WRITE lock1 succeeded! This is a locking bug\n");
1641 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1642 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1645 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1646 printf("WRITE lock2 succeeded! This is a locking bug\n");
1649 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1650 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1653 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1654 printf("READ lock2 succeeded! This is a locking bug\n");
1657 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1658 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1661 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1662 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1665 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1666 printf("unlock at 100 succeeded! This is a locking bug\n");
1670 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1671 printf("unlock1 succeeded! This is a locking bug\n");
1674 if (!check_error(__LINE__, cli,
1676 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1679 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1680 printf("unlock2 succeeded! This is a locking bug\n");
1683 if (!check_error(__LINE__, cli,
1685 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1688 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1689 printf("lock3 succeeded! This is a locking bug\n");
1692 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1697 status = cli_close(cli, fnum1);
1698 if (!NT_STATUS_IS_OK(status)) {
1699 printf("close1 failed (%s)\n", nt_errstr(status));
1703 status = cli_close(cli, fnum2);
1704 if (!NT_STATUS_IS_OK(status)) {
1705 printf("close2 failed (%s)\n", nt_errstr(status));
1709 status = cli_close(cli, fnum3);
1710 if (!NT_STATUS_IS_OK(status)) {
1711 printf("close3 failed (%s)\n", nt_errstr(status));
1715 if (!torture_close_connection(cli)) {
1719 printf("locktest2 finished\n");
1726 This test checks that
1728 1) the server supports the full offset range in lock requests
1730 static bool run_locktest3(int dummy)
1732 static struct cli_state *cli1, *cli2;
1733 const char *fname = "\\lockt3.lck";
1734 uint16_t fnum1, fnum2;
1737 bool correct = True;
1740 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1742 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1745 cli_sockopt(cli1, sockops);
1746 cli_sockopt(cli2, sockops);
1748 printf("starting locktest3\n");
1750 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1752 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
1754 if (!NT_STATUS_IS_OK(status)) {
1755 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
1759 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1760 if (!NT_STATUS_IS_OK(status)) {
1761 printf("open2 of %s failed (%s)\n", fname, nt_errstr(status));
1765 for (offset=i=0;i<torture_numops;i++) {
1767 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1768 printf("lock1 %d failed (%s)\n",
1774 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1775 printf("lock2 %d failed (%s)\n",
1782 for (offset=i=0;i<torture_numops;i++) {
1785 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1786 printf("error: lock1 %d succeeded!\n", i);
1790 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1791 printf("error: lock2 %d succeeded!\n", i);
1795 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1796 printf("error: lock3 %d succeeded!\n", i);
1800 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1801 printf("error: lock4 %d succeeded!\n", i);
1806 for (offset=i=0;i<torture_numops;i++) {
1809 status = cli_unlock(cli1, fnum1, offset-1, 1);
1810 if (!NT_STATUS_IS_OK(status)) {
1811 printf("unlock1 %d failed (%s)\n",
1817 status = cli_unlock(cli2, fnum2, offset-2, 1);
1818 if (!NT_STATUS_IS_OK(status)) {
1819 printf("unlock2 %d failed (%s)\n",
1826 status = cli_close(cli1, fnum1);
1827 if (!NT_STATUS_IS_OK(status)) {
1828 printf("close1 failed (%s)\n", nt_errstr(status));
1832 status = cli_close(cli2, fnum2);
1833 if (!NT_STATUS_IS_OK(status)) {
1834 printf("close2 failed (%s)\n", nt_errstr(status));
1838 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1839 if (!NT_STATUS_IS_OK(status)) {
1840 printf("unlink failed (%s)\n", nt_errstr(status));
1844 if (!torture_close_connection(cli1)) {
1848 if (!torture_close_connection(cli2)) {
1852 printf("finished locktest3\n");
1857 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1858 printf("** "); correct = False; \
1862 looks at overlapping locks
1864 static bool run_locktest4(int dummy)
1866 static struct cli_state *cli1, *cli2;
1867 const char *fname = "\\lockt4.lck";
1868 uint16_t fnum1, fnum2, f;
1871 bool correct = True;
1874 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1878 cli_sockopt(cli1, sockops);
1879 cli_sockopt(cli2, sockops);
1881 printf("starting locktest4\n");
1883 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
1885 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1886 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1888 memset(buf, 0, sizeof(buf));
1890 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
1892 if (!NT_STATUS_IS_OK(status)) {
1893 printf("Failed to create file: %s\n", nt_errstr(status));
1898 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1899 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1900 EXPECTED(ret, False);
1901 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1903 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1904 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1905 EXPECTED(ret, True);
1906 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1908 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1909 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1910 EXPECTED(ret, False);
1911 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1913 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1914 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1915 EXPECTED(ret, True);
1916 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1918 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1919 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1920 EXPECTED(ret, False);
1921 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1923 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1924 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1925 EXPECTED(ret, True);
1926 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1928 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1929 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1930 EXPECTED(ret, True);
1931 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1933 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1934 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1935 EXPECTED(ret, False);
1936 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1938 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1939 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1940 EXPECTED(ret, False);
1941 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1943 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1944 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1945 EXPECTED(ret, True);
1946 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1948 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1949 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1950 EXPECTED(ret, False);
1951 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1953 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1954 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1955 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1956 EXPECTED(ret, False);
1957 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1960 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1961 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1962 EXPECTED(ret, False);
1963 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1965 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK);
1967 status = cli_writeall(cli2, fnum2, 0, (uint8_t *)buf, 130, 4,
1969 ret = NT_STATUS_IS_OK(status);
1971 EXPECTED(ret, False);
1972 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1975 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1976 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1977 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1978 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1979 EXPECTED(ret, True);
1980 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1983 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1984 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1985 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1986 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1987 !(NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1989 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1990 EXPECTED(ret, True);
1991 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1993 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1994 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1995 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
1997 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1998 EXPECTED(ret, True);
1999 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
2001 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
2002 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
2003 NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2005 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
2006 EXPECTED(ret, True);
2007 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
2009 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
2010 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
2011 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
2012 !NT_STATUS_IS_OK(cli_writeall(cli2, fnum2, 0, (uint8_t *)buf,
2014 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
2015 EXPECTED(ret, True);
2016 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
2018 cli_close(cli1, fnum1);
2019 cli_close(cli2, fnum2);
2020 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2021 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
2022 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2023 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
2024 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
2025 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
2026 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2028 cli_close(cli1, fnum1);
2029 EXPECTED(ret, True);
2030 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
2033 cli_close(cli1, fnum1);
2034 cli_close(cli2, fnum2);
2035 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2036 torture_close_connection(cli1);
2037 torture_close_connection(cli2);
2039 printf("finished locktest4\n");
2044 looks at lock upgrade/downgrade.
2046 static bool run_locktest5(int dummy)
2048 static struct cli_state *cli1, *cli2;
2049 const char *fname = "\\lockt5.lck";
2050 uint16_t fnum1, fnum2, fnum3;
2053 bool correct = True;
2056 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2060 cli_sockopt(cli1, sockops);
2061 cli_sockopt(cli2, sockops);
2063 printf("starting locktest5\n");
2065 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2067 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2068 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
2069 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
2071 memset(buf, 0, sizeof(buf));
2073 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2075 if (!NT_STATUS_IS_OK(status)) {
2076 printf("Failed to create file: %s\n", nt_errstr(status));
2081 /* Check for NT bug... */
2082 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
2083 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
2084 cli_close(cli1, fnum1);
2085 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2086 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
2087 EXPECTED(ret, True);
2088 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
2089 cli_close(cli1, fnum1);
2090 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2091 cli_unlock(cli1, fnum3, 0, 1);
2093 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2094 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2095 EXPECTED(ret, True);
2096 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2098 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2099 EXPECTED(ret, False);
2101 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2103 /* Unlock the process 2 lock. */
2104 cli_unlock(cli2, fnum2, 0, 4);
2106 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2107 EXPECTED(ret, False);
2109 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2111 /* Unlock the process 1 fnum3 lock. */
2112 cli_unlock(cli1, fnum3, 0, 4);
2114 /* Stack 2 more locks here. */
2115 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2116 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2118 EXPECTED(ret, True);
2119 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2121 /* Unlock the first process lock, then check this was the WRITE lock that was
2124 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2125 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2127 EXPECTED(ret, True);
2128 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2130 /* Unlock the process 2 lock. */
2131 cli_unlock(cli2, fnum2, 0, 4);
2133 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2135 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2136 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2137 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2139 EXPECTED(ret, True);
2140 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2142 /* Ensure the next unlock fails. */
2143 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2144 EXPECTED(ret, False);
2145 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2147 /* Ensure connection 2 can get a write lock. */
2148 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2149 EXPECTED(ret, True);
2151 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2155 cli_close(cli1, fnum1);
2156 cli_close(cli2, fnum2);
2157 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2158 if (!torture_close_connection(cli1)) {
2161 if (!torture_close_connection(cli2)) {
2165 printf("finished locktest5\n");
2171 tries the unusual lockingX locktype bits
2173 static bool run_locktest6(int dummy)
2175 static struct cli_state *cli;
2176 const char *fname[1] = { "\\lock6.txt" };
2181 if (!torture_open_connection(&cli, 0)) {
2185 cli_sockopt(cli, sockops);
2187 printf("starting locktest6\n");
2190 printf("Testing %s\n", fname[i]);
2192 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2194 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2195 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2196 cli_close(cli, fnum);
2197 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2199 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2200 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2201 cli_close(cli, fnum);
2202 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2204 cli_unlink(cli, fname[i], FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2207 torture_close_connection(cli);
2209 printf("finished locktest6\n");
2213 static bool run_locktest7(int dummy)
2215 struct cli_state *cli1;
2216 const char *fname = "\\lockt7.lck";
2219 bool correct = False;
2222 if (!torture_open_connection(&cli1, 0)) {
2226 cli_sockopt(cli1, sockops);
2228 printf("starting locktest7\n");
2230 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2232 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2234 memset(buf, 0, sizeof(buf));
2236 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, sizeof(buf),
2238 if (!NT_STATUS_IS_OK(status)) {
2239 printf("Failed to create file: %s\n", nt_errstr(status));
2243 cli_setpid(cli1, 1);
2245 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2246 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2249 printf("pid1 successfully locked range 130:4 for READ\n");
2252 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2253 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2256 printf("pid1 successfully read the range 130:4\n");
2259 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2260 if (!NT_STATUS_IS_OK(status)) {
2261 printf("pid1 unable to write to the range 130:4, error was "
2262 "%s\n", nt_errstr(status));
2263 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2264 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2268 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2272 cli_setpid(cli1, 2);
2274 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2275 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2277 printf("pid2 successfully read the range 130:4\n");
2280 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2281 if (!NT_STATUS_IS_OK(status)) {
2282 printf("pid2 unable to write to the range 130:4, error was "
2283 "%s\n", nt_errstr(status));
2284 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2285 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2289 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2293 cli_setpid(cli1, 1);
2294 cli_unlock(cli1, fnum1, 130, 4);
2296 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2297 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2300 printf("pid1 successfully locked range 130:4 for WRITE\n");
2303 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2304 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2307 printf("pid1 successfully read the range 130:4\n");
2310 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2311 if (!NT_STATUS_IS_OK(status)) {
2312 printf("pid1 unable to write to the range 130:4, error was "
2313 "%s\n", nt_errstr(status));
2316 printf("pid1 successfully wrote to the range 130:4\n");
2319 cli_setpid(cli1, 2);
2321 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2322 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2323 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2324 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2328 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2332 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 130, 4, NULL);
2333 if (!NT_STATUS_IS_OK(status)) {
2334 printf("pid2 unable to write to the range 130:4, error was "
2335 "%s\n", nt_errstr(status));
2336 if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
2337 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2341 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2345 cli_unlock(cli1, fnum1, 130, 0);
2349 cli_close(cli1, fnum1);
2350 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2351 torture_close_connection(cli1);
2353 printf("finished locktest7\n");
2358 * This demonstrates a problem with our use of GPFS share modes: A file
2359 * descriptor sitting in the pending close queue holding a GPFS share mode
2360 * blocks opening a file another time. Happens with Word 2007 temp files.
2361 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2362 * open is denied with NT_STATUS_SHARING_VIOLATION.
2365 static bool run_locktest8(int dummy)
2367 struct cli_state *cli1;
2368 const char *fname = "\\lockt8.lck";
2369 uint16_t fnum1, fnum2;
2371 bool correct = False;
2374 if (!torture_open_connection(&cli1, 0)) {
2378 cli_sockopt(cli1, sockops);
2380 printf("starting locktest8\n");
2382 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2384 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2386 if (!NT_STATUS_IS_OK(status)) {
2387 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2391 memset(buf, 0, sizeof(buf));
2393 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2394 if (!NT_STATUS_IS_OK(status)) {
2395 d_fprintf(stderr, "cli_open second time returned %s\n",
2400 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2401 printf("Unable to apply read lock on range 1:1, error was "
2402 "%s\n", cli_errstr(cli1));
2406 status = cli_close(cli1, fnum1);
2407 if (!NT_STATUS_IS_OK(status)) {
2408 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2412 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2413 if (!NT_STATUS_IS_OK(status)) {
2414 d_fprintf(stderr, "cli_open third time returned %s\n",
2422 cli_close(cli1, fnum1);
2423 cli_close(cli1, fnum2);
2424 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2425 torture_close_connection(cli1);
2427 printf("finished locktest8\n");
2432 * This test is designed to be run in conjunction with
2433 * external NFS or POSIX locks taken in the filesystem.
2434 * It checks that the smbd server will block until the
2435 * lock is released and then acquire it. JRA.
2438 static bool got_alarm;
2439 static int alarm_fd;
2441 static void alarm_handler(int dummy)
2446 static void alarm_handler_parent(int dummy)
2451 static void do_local_lock(int read_fd, int write_fd)
2456 const char *local_pathname = NULL;
2459 local_pathname = talloc_asprintf(talloc_tos(),
2460 "%s/lockt9.lck", local_path);
2461 if (!local_pathname) {
2462 printf("child: alloc fail\n");
2466 unlink(local_pathname);
2467 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2469 printf("child: open of %s failed %s.\n",
2470 local_pathname, strerror(errno));
2474 /* Now take a fcntl lock. */
2475 lock.l_type = F_WRLCK;
2476 lock.l_whence = SEEK_SET;
2479 lock.l_pid = getpid();
2481 ret = fcntl(fd,F_SETLK,&lock);
2483 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2484 local_pathname, strerror(errno));
2487 printf("child: got lock 0:4 on file %s.\n",
2492 CatchSignal(SIGALRM, alarm_handler);
2494 /* Signal the parent. */
2495 if (write(write_fd, &c, 1) != 1) {
2496 printf("child: start signal fail %s.\n",
2503 /* Wait for the parent to be ready. */
2504 if (read(read_fd, &c, 1) != 1) {
2505 printf("child: reply signal fail %s.\n",
2513 printf("child: released lock 0:4 on file %s.\n",
2519 static bool run_locktest9(int dummy)
2521 struct cli_state *cli1;
2522 const char *fname = "\\lockt9.lck";
2524 bool correct = False;
2525 int pipe_in[2], pipe_out[2];
2529 struct timeval start;
2533 printf("starting locktest9\n");
2535 if (local_path == NULL) {
2536 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2540 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2545 if (child_pid == -1) {
2549 if (child_pid == 0) {
2551 do_local_lock(pipe_out[0], pipe_in[1]);
2561 ret = read(pipe_in[0], &c, 1);
2563 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2568 if (!torture_open_connection(&cli1, 0)) {
2572 cli_sockopt(cli1, sockops);
2574 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2576 if (!NT_STATUS_IS_OK(status)) {
2577 d_fprintf(stderr, "cli_open returned %s\n", nt_errstr(status));
2581 /* Ensure the child has the lock. */
2582 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2583 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2586 d_printf("Child has the lock.\n");
2589 /* Tell the child to wait 5 seconds then exit. */
2590 ret = write(pipe_out[1], &c, 1);
2592 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2597 /* Wait 20 seconds for the lock. */
2598 alarm_fd = cli1->fd;
2599 CatchSignal(SIGALRM, alarm_handler_parent);
2602 start = timeval_current();
2604 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2605 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2606 "%s\n", cli_errstr(cli1));
2611 seconds = timeval_elapsed(&start);
2613 printf("Parent got the lock after %.2f seconds.\n",
2616 status = cli_close(cli1, fnum);
2617 if (!NT_STATUS_IS_OK(status)) {
2618 d_fprintf(stderr, "cli_close(fnum1) %s\n", nt_errstr(status));
2625 cli_close(cli1, fnum);
2626 torture_close_connection(cli1);
2630 printf("finished locktest9\n");
2635 test whether fnums and tids open on one VC are available on another (a major
2638 static bool run_fdpasstest(int dummy)
2640 struct cli_state *cli1, *cli2;
2641 const char *fname = "\\fdpass.tst";
2646 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2649 cli_sockopt(cli1, sockops);
2650 cli_sockopt(cli2, sockops);
2652 printf("starting fdpasstest\n");
2654 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2656 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
2658 if (!NT_STATUS_IS_OK(status)) {
2659 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2663 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"hello world\n", 0,
2665 if (!NT_STATUS_IS_OK(status)) {
2666 printf("write failed (%s)\n", nt_errstr(status));
2670 cli2->vuid = cli1->vuid;
2671 cli2->cnum = cli1->cnum;
2672 cli2->pid = cli1->pid;
2674 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2675 printf("read succeeded! nasty security hole [%s]\n",
2680 cli_close(cli1, fnum1);
2681 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2683 torture_close_connection(cli1);
2684 torture_close_connection(cli2);
2686 printf("finished fdpasstest\n");
2690 static bool run_fdsesstest(int dummy)
2692 struct cli_state *cli;
2697 const char *fname = "\\fdsess.tst";
2698 const char *fname1 = "\\fdsess1.tst";
2705 if (!torture_open_connection(&cli, 0))
2707 cli_sockopt(cli, sockops);
2709 if (!torture_cli_session_setup2(cli, &new_vuid))
2712 saved_cnum = cli->cnum;
2713 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2715 new_cnum = cli->cnum;
2716 cli->cnum = saved_cnum;
2718 printf("starting fdsesstest\n");
2720 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2721 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2723 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2724 if (!NT_STATUS_IS_OK(status)) {
2725 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2729 status = cli_writeall(cli, fnum1, 0, (const uint8_t *)"hello world\n", 0, 13,
2731 if (!NT_STATUS_IS_OK(status)) {
2732 printf("write failed (%s)\n", nt_errstr(status));
2736 saved_vuid = cli->vuid;
2737 cli->vuid = new_vuid;
2739 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2740 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2744 /* Try to open a file with different vuid, samba cnum. */
2745 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2746 printf("create with different vuid, same cnum succeeded.\n");
2747 cli_close(cli, fnum2);
2748 cli_unlink(cli, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2750 printf("create with different vuid, same cnum failed.\n");
2751 printf("This will cause problems with service clients.\n");
2755 cli->vuid = saved_vuid;
2757 /* Try with same vuid, different cnum. */
2758 cli->cnum = new_cnum;
2760 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2761 printf("read succeeded with different cnum![%s]\n",
2766 cli->cnum = saved_cnum;
2767 cli_close(cli, fnum1);
2768 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2770 torture_close_connection(cli);
2772 printf("finished fdsesstest\n");
2777 This test checks that
2779 1) the server does not allow an unlink on a file that is open
2781 static bool run_unlinktest(int dummy)
2783 struct cli_state *cli;
2784 const char *fname = "\\unlink.tst";
2786 bool correct = True;
2789 if (!torture_open_connection(&cli, 0)) {
2793 cli_sockopt(cli, sockops);
2795 printf("starting unlink test\n");
2797 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2801 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2802 if (!NT_STATUS_IS_OK(status)) {
2803 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
2807 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN))) {
2808 printf("error: server allowed unlink on an open file\n");
2811 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2812 NT_STATUS_SHARING_VIOLATION);
2815 cli_close(cli, fnum);
2816 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2818 if (!torture_close_connection(cli)) {
2822 printf("unlink test finished\n");
2829 test how many open files this server supports on the one socket
2831 static bool run_maxfidtest(int dummy)
2833 struct cli_state *cli;
2835 uint16_t fnums[0x11000];
2838 bool correct = True;
2844 printf("failed to connect\n");
2848 cli_sockopt(cli, sockops);
2850 for (i=0; i<0x11000; i++) {
2851 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2852 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_TRUNC, DENY_NONE,
2854 if (!NT_STATUS_IS_OK(status)) {
2855 printf("open of %s failed (%s)\n",
2856 fname, nt_errstr(status));
2857 printf("maximum fnum is %d\n", i);
2865 printf("cleaning up\n");
2867 slprintf(fname,sizeof(fname)-1,"\\maxfid.%d.%d", i,(int)getpid());
2868 cli_close(cli, fnums[i]);
2870 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
2871 if (!NT_STATUS_IS_OK(status)) {
2872 printf("unlink of %s failed (%s)\n",
2873 fname, nt_errstr(status));
2880 printf("maxfid test finished\n");
2881 if (!torture_close_connection(cli)) {
2887 /* generate a random buffer */
2888 static void rand_buf(char *buf, int len)
2891 *buf = (char)sys_random();
2896 /* send smb negprot commands, not reading the response */
2897 static bool run_negprot_nowait(int dummy)
2899 struct tevent_context *ev;
2901 struct cli_state *cli;
2902 bool correct = True;
2904 printf("starting negprot nowait test\n");
2906 ev = tevent_context_init(talloc_tos());
2911 if (!(cli = open_nbt_connection())) {
2916 for (i=0;i<50000;i++) {
2917 struct tevent_req *req;
2919 req = cli_negprot_send(ev, ev, cli);
2924 if (!tevent_req_poll(req, ev)) {
2925 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2933 if (torture_close_connection(cli)) {
2937 printf("finished negprot nowait test\n");
2942 /* send smb negprot commands, not reading the response */
2943 static bool run_bad_nbt_session(int dummy)
2945 static struct cli_state *cli;
2947 printf("starting bad nbt session test\n");
2949 if (!(cli = open_bad_nbt_connection())) {
2954 printf("finished bad nbt session test\n");
2958 /* send random IPC commands */
2959 static bool run_randomipc(int dummy)
2961 char *rparam = NULL;
2963 unsigned int rdrcnt,rprcnt;
2965 int api, param_len, i;
2966 struct cli_state *cli;
2967 bool correct = True;
2970 printf("starting random ipc test\n");
2972 if (!torture_open_connection(&cli, 0)) {
2976 for (i=0;i<count;i++) {
2977 api = sys_random() % 500;
2978 param_len = (sys_random() % 64);
2980 rand_buf(param, param_len);
2985 param, param_len, 8,
2986 NULL, 0, BUFFER_SIZE,
2990 printf("%d/%d\r", i,count);
2993 printf("%d/%d\n", i, count);
2995 if (!torture_close_connection(cli)) {
2999 printf("finished random ipc test\n");
3006 static void browse_callback(const char *sname, uint32 stype,
3007 const char *comment, void *state)
3009 printf("\t%20.20s %08x %s\n", sname, stype, comment);
3015 This test checks the browse list code
3018 static bool run_browsetest(int dummy)
3020 static struct cli_state *cli;
3021 bool correct = True;
3023 printf("starting browse test\n");
3025 if (!torture_open_connection(&cli, 0)) {
3029 printf("domain list:\n");
3030 cli_NetServerEnum(cli, cli->server_domain,
3031 SV_TYPE_DOMAIN_ENUM,
3032 browse_callback, NULL);
3034 printf("machine list:\n");
3035 cli_NetServerEnum(cli, cli->server_domain,
3037 browse_callback, NULL);
3039 if (!torture_close_connection(cli)) {
3043 printf("browse test finished\n");
3051 This checks how the getatr calls works
3053 static bool run_attrtest(int dummy)
3055 struct cli_state *cli;
3058 const char *fname = "\\attrib123456789.tst";
3059 bool correct = True;
3062 printf("starting attrib test\n");
3064 if (!torture_open_connection(&cli, 0)) {
3068 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3069 cli_open(cli, fname,
3070 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3071 cli_close(cli, fnum);
3073 status = cli_getatr(cli, fname, NULL, NULL, &t);
3074 if (!NT_STATUS_IS_OK(status)) {
3075 printf("getatr failed (%s)\n", nt_errstr(status));
3079 if (abs(t - time(NULL)) > 60*60*24*10) {
3080 printf("ERROR: SMBgetatr bug. time is %s",
3086 t2 = t-60*60*24; /* 1 day ago */
3088 status = cli_setatr(cli, fname, 0, t2);
3089 if (!NT_STATUS_IS_OK(status)) {
3090 printf("setatr failed (%s)\n", nt_errstr(status));
3094 status = cli_getatr(cli, fname, NULL, NULL, &t);
3095 if (!NT_STATUS_IS_OK(status)) {
3096 printf("getatr failed (%s)\n", nt_errstr(status));
3101 printf("ERROR: getatr/setatr bug. times are\n%s",
3103 printf("%s", ctime(&t2));
3107 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3109 if (!torture_close_connection(cli)) {
3113 printf("attrib test finished\n");
3120 This checks a couple of trans2 calls
3122 static bool run_trans2test(int dummy)
3124 struct cli_state *cli;
3127 time_t c_time, a_time, m_time;
3128 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3129 const char *fname = "\\trans2.tst";
3130 const char *dname = "\\trans2";
3131 const char *fname2 = "\\trans2\\trans2.tst";
3133 bool correct = True;
3137 printf("starting trans2 test\n");
3139 if (!torture_open_connection(&cli, 0)) {
3143 status = cli_get_fs_attr_info(cli, &fs_attr);
3144 if (!NT_STATUS_IS_OK(status)) {
3145 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3150 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3151 cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3152 status = cli_qfileinfo_basic(cli, fnum, NULL, &size, &c_time_ts,
3153 &a_time_ts, &w_time_ts, &m_time_ts, NULL);
3154 if (!NT_STATUS_IS_OK(status)) {
3155 printf("ERROR: qfileinfo failed (%s)\n", nt_errstr(status));
3159 status = cli_qfilename(cli, fnum, pname, sizeof(pname));
3160 if (!NT_STATUS_IS_OK(status)) {
3161 printf("ERROR: qfilename failed (%s)\n", nt_errstr(status));
3165 if (strcmp(pname, fname)) {
3166 printf("qfilename gave different name? [%s] [%s]\n",
3171 cli_close(cli, fnum);
3175 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3176 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_NONE,
3178 if (!NT_STATUS_IS_OK(status)) {
3179 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3182 cli_close(cli, fnum);
3184 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3186 if (!NT_STATUS_IS_OK(status)) {
3187 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3190 if (c_time != m_time) {
3191 printf("create time=%s", ctime(&c_time));
3192 printf("modify time=%s", ctime(&m_time));
3193 printf("This system appears to have sticky create times\n");
3195 if (a_time % (60*60) == 0) {
3196 printf("access time=%s", ctime(&a_time));
3197 printf("This system appears to set a midnight access time\n");
3201 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3202 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3208 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3209 cli_open(cli, fname,
3210 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3211 cli_close(cli, fnum);
3212 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3213 &m_time_ts, &size, NULL, NULL);
3214 if (!NT_STATUS_IS_OK(status)) {
3215 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3218 if (w_time_ts.tv_sec < 60*60*24*2) {
3219 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3220 printf("This system appears to set a initial 0 write time\n");
3225 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3228 /* check if the server updates the directory modification time
3229 when creating a new file */
3230 status = cli_mkdir(cli, dname);
3231 if (!NT_STATUS_IS_OK(status)) {
3232 printf("ERROR: mkdir failed (%s)\n", nt_errstr(status));
3236 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3237 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3238 if (!NT_STATUS_IS_OK(status)) {
3239 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3243 cli_open(cli, fname2,
3244 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3245 cli_writeall(cli, fnum, 0, (uint8_t *)&fnum, 0, sizeof(fnum), NULL);
3246 cli_close(cli, fnum);
3247 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3248 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3249 if (!NT_STATUS_IS_OK(status)) {
3250 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3253 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3255 printf("This system does not update directory modification times\n");
3259 cli_unlink(cli, fname2, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3260 cli_rmdir(cli, dname);
3262 if (!torture_close_connection(cli)) {
3266 printf("trans2 test finished\n");
3272 This checks new W2K calls.
3275 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3277 uint8_t *buf = NULL;
3281 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3282 pcli->max_xmit, &buf, &len);
3283 if (!NT_STATUS_IS_OK(status)) {
3284 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3287 printf("qfileinfo: level %d, len = %u\n", level, len);
3288 dump_data(0, (uint8 *)buf, len);
3295 static bool run_w2ktest(int dummy)
3297 struct cli_state *cli;
3299 const char *fname = "\\w2ktest\\w2k.tst";
3301 bool correct = True;
3303 printf("starting w2k test\n");
3305 if (!torture_open_connection(&cli, 0)) {
3309 cli_open(cli, fname,
3310 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3312 for (level = 1004; level < 1040; level++) {
3313 new_trans(cli, fnum, level);
3316 cli_close(cli, fnum);
3318 if (!torture_close_connection(cli)) {
3322 printf("w2k test finished\n");
3329 this is a harness for some oplock tests
3331 static bool run_oplock1(int dummy)
3333 struct cli_state *cli1;
3334 const char *fname = "\\lockt1.lck";
3336 bool correct = True;
3339 printf("starting oplock test 1\n");
3341 if (!torture_open_connection(&cli1, 0)) {
3345 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3347 cli_sockopt(cli1, sockops);
3349 cli1->use_oplocks = True;
3351 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3353 if (!NT_STATUS_IS_OK(status)) {
3354 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3358 cli1->use_oplocks = False;
3360 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3361 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3363 status = cli_close(cli1, fnum1);
3364 if (!NT_STATUS_IS_OK(status)) {
3365 printf("close2 failed (%s)\n", nt_errstr(status));
3369 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3370 if (!NT_STATUS_IS_OK(status)) {
3371 printf("unlink failed (%s)\n", nt_errstr(status));
3375 if (!torture_close_connection(cli1)) {
3379 printf("finished oplock test 1\n");
3384 static bool run_oplock2(int dummy)
3386 struct cli_state *cli1, *cli2;
3387 const char *fname = "\\lockt2.lck";
3388 uint16_t fnum1, fnum2;
3389 int saved_use_oplocks = use_oplocks;
3391 bool correct = True;
3392 volatile bool *shared_correct;
3395 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3396 *shared_correct = True;
3398 use_level_II_oplocks = True;
3401 printf("starting oplock test 2\n");
3403 if (!torture_open_connection(&cli1, 0)) {
3404 use_level_II_oplocks = False;
3405 use_oplocks = saved_use_oplocks;
3409 cli1->use_oplocks = True;
3410 cli1->use_level_II_oplocks = True;
3412 if (!torture_open_connection(&cli2, 1)) {
3413 use_level_II_oplocks = False;
3414 use_oplocks = saved_use_oplocks;
3418 cli2->use_oplocks = True;
3419 cli2->use_level_II_oplocks = True;
3421 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3423 cli_sockopt(cli1, sockops);
3424 cli_sockopt(cli2, sockops);
3426 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3428 if (!NT_STATUS_IS_OK(status)) {
3429 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3433 /* Don't need the globals any more. */
3434 use_level_II_oplocks = False;
3435 use_oplocks = saved_use_oplocks;
3439 status = cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
3440 if (!NT_STATUS_IS_OK(status)) {
3441 printf("second open of %s failed (%s)\n", fname, nt_errstr(status));
3442 *shared_correct = False;
3448 status = cli_close(cli2, fnum2);
3449 if (!NT_STATUS_IS_OK(status)) {
3450 printf("close2 failed (%s)\n", nt_errstr(status));
3451 *shared_correct = False;
3459 /* Ensure cli1 processes the break. Empty file should always return 0
3462 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3463 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3467 /* Should now be at level II. */
3468 /* Test if sending a write locks causes a break to none. */
3470 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3471 printf("lock failed (%s)\n", cli_errstr(cli1));
3475 cli_unlock(cli1, fnum1, 0, 4);
3479 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3480 printf("lock failed (%s)\n", cli_errstr(cli1));
3484 cli_unlock(cli1, fnum1, 0, 4);
3488 cli_read(cli1, fnum1, buf, 0, 4);
3490 status = cli_close(cli1, fnum1);
3491 if (!NT_STATUS_IS_OK(status)) {
3492 printf("close1 failed (%s)\n", nt_errstr(status));
3498 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3499 if (!NT_STATUS_IS_OK(status)) {
3500 printf("unlink failed (%s)\n", nt_errstr(status));
3504 if (!torture_close_connection(cli1)) {
3508 if (!*shared_correct) {
3512 printf("finished oplock test 2\n");
3517 /* handler for oplock 3 tests */
3518 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3520 printf("got oplock break fnum=%d level=%d\n",
3522 return cli_oplock_ack(cli, fnum, level);
3525 static bool run_oplock3(int dummy)
3527 struct cli_state *cli;
3528 const char *fname = "\\oplockt3.dat";
3530 char buf[4] = "abcd";
3531 bool correct = True;
3532 volatile bool *shared_correct;
3534 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3535 *shared_correct = True;
3537 printf("starting oplock test 3\n");
3542 use_level_II_oplocks = True;
3543 if (!torture_open_connection(&cli, 0)) {
3544 *shared_correct = False;
3548 /* try to trigger a oplock break in parent */
3549 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3550 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3556 use_level_II_oplocks = True;
3557 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3560 cli_oplock_handler(cli, oplock3_handler);
3561 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3562 cli_writeall(cli, fnum, 0, (uint8_t *)buf, 0, 4, NULL);
3563 cli_close(cli, fnum);
3564 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3565 cli->timeout = 20000;
3566 cli_receive_smb(cli);
3567 printf("finished oplock test 3\n");
3569 return (correct && *shared_correct);
3571 /* What are we looking for here? What's sucess and what's FAILURE? */
3574 /* handler for oplock 4 tests */
3575 bool *oplock4_shared_correct;
3577 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3579 printf("got oplock break fnum=%d level=%d\n",
3581 *oplock4_shared_correct = true;
3582 cli_oplock_ack(cli, fnum, level);
3583 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3586 static bool run_oplock4(int dummy)
3588 struct cli_state *cli1, *cli2;
3589 const char *fname = "\\lockt4.lck";
3590 const char *fname_ln = "\\lockt4_ln.lck";
3591 uint16_t fnum1, fnum2;
3592 int saved_use_oplocks = use_oplocks;
3594 bool correct = true;
3596 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3597 *oplock4_shared_correct = false;
3599 printf("starting oplock test 4\n");
3601 if (!torture_open_connection(&cli1, 0)) {
3602 use_level_II_oplocks = false;
3603 use_oplocks = saved_use_oplocks;
3607 if (!torture_open_connection(&cli2, 1)) {
3608 use_level_II_oplocks = false;
3609 use_oplocks = saved_use_oplocks;
3613 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3614 cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3616 cli_sockopt(cli1, sockops);
3617 cli_sockopt(cli2, sockops);
3619 /* Create the file. */
3620 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE,
3622 if (!NT_STATUS_IS_OK(status)) {
3623 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3627 status = cli_close(cli1, fnum1);
3628 if (!NT_STATUS_IS_OK(status)) {
3629 printf("close1 failed (%s)\n", nt_errstr(status));
3633 /* Now create a hardlink. */
3634 status = cli_nt_hardlink(cli1, fname, fname_ln);
3635 if (!NT_STATUS_IS_OK(status)) {
3636 printf("nt hardlink failed (%s)\n", nt_errstr(status));
3640 /* Prove that opening hardlinks cause deny modes to conflict. */
3641 status = cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1);
3642 if (!NT_STATUS_IS_OK(status)) {
3643 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3647 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3648 if (NT_STATUS_IS_OK(status)) {
3649 printf("open of %s succeeded - should fail with sharing violation.\n",
3654 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3655 printf("open of %s should fail with sharing violation. Got %s\n",
3656 fname_ln, nt_errstr(status));
3660 status = cli_close(cli1, fnum1);
3661 if (!NT_STATUS_IS_OK(status)) {
3662 printf("close1 failed (%s)\n", nt_errstr(status));
3666 cli1->use_oplocks = true;
3667 cli1->use_level_II_oplocks = true;
3669 cli2->use_oplocks = true;
3670 cli2->use_level_II_oplocks = true;
3672 cli_oplock_handler(cli1, oplock4_handler);
3674 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
3675 if (!NT_STATUS_IS_OK(status)) {
3676 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
3682 status = cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3683 if (!NT_STATUS_IS_OK(status)) {
3684 printf("open of %s failed (%s)\n", fname_ln, nt_errstr(status));
3685 *oplock4_shared_correct = false;
3689 status = cli_close(cli2, fnum2);
3690 if (!NT_STATUS_IS_OK(status)) {
3691 printf("close2 failed (%s)\n", nt_errstr(status));
3692 *oplock4_shared_correct = false;
3700 /* Process the oplock break. */
3701 cli_receive_smb(cli1);
3703 status = cli_close(cli1, fnum1);
3704 if (!NT_STATUS_IS_OK(status)) {
3705 printf("close1 failed (%s)\n", nt_errstr(status));
3709 status = cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3710 if (!NT_STATUS_IS_OK(status)) {
3711 printf("unlink failed (%s)\n", nt_errstr(status));
3715 status = cli_unlink(cli1, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3716 if (!NT_STATUS_IS_OK(status)) {
3717 printf("unlink failed (%s)\n", nt_errstr(status));
3721 if (!torture_close_connection(cli1)) {
3725 if (!*oplock4_shared_correct) {
3729 printf("finished oplock test 4\n");
3736 Test delete on close semantics.
3738 static bool run_deletetest(int dummy)
3740 struct cli_state *cli1 = NULL;
3741 struct cli_state *cli2 = NULL;
3742 const char *fname = "\\delete.file";
3743 uint16_t fnum1 = (uint16_t)-1;
3744 uint16_t fnum2 = (uint16_t)-1;
3745 bool correct = True;
3748 printf("starting delete test\n");
3750 if (!torture_open_connection(&cli1, 0)) {
3754 cli_sockopt(cli1, sockops);
3756 /* Test 1 - this should delete the file on close. */
3758 cli_setatr(cli1, fname, 0, 0);
3759 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3761 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
3762 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
3763 FILE_DELETE_ON_CLOSE, 0, &fnum1);
3764 if (!NT_STATUS_IS_OK(status)) {
3765 printf("[1] open of %s failed (%s)\n", fname, nt_errstr(status));
3770 status = cli_close(cli1, fnum1);
3771 if (!NT_STATUS_IS_OK(status)) {
3772 printf("[1] close failed (%s)\n", nt_errstr(status));
3777 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3778 printf("[1] open of %s succeeded (should fail)\n", fname);
3783 printf("first delete on close test succeeded.\n");
3785 /* Test 2 - this should delete the file on close. */
3787 cli_setatr(cli1, fname, 0, 0);
3788 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3790 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3791 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3792 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3793 if (!NT_STATUS_IS_OK(status)) {
3794 printf("[2] open of %s failed (%s)\n", fname, nt_errstr(status));
3799 status = cli_nt_delete_on_close(cli1, fnum1, true);
3800 if (!NT_STATUS_IS_OK(status)) {
3801 printf("[2] setting delete_on_close failed (%s)\n", nt_errstr(status));
3806 status = cli_close(cli1, fnum1);
3807 if (!NT_STATUS_IS_OK(status)) {
3808 printf("[2] close failed (%s)\n", nt_errstr(status));
3813 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3814 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3815 status = cli_close(cli1, fnum1);
3816 if (!NT_STATUS_IS_OK(status)) {
3817 printf("[2] close failed (%s)\n", nt_errstr(status));
3821 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3823 printf("second delete on close test succeeded.\n");
3826 cli_setatr(cli1, fname, 0, 0);
3827 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3829 status = cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3830 FILE_ATTRIBUTE_NORMAL,
3831 FILE_SHARE_READ|FILE_SHARE_WRITE,
3832 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3833 if (!NT_STATUS_IS_OK(status)) {
3834 printf("[3] open - 1 of %s failed (%s)\n", fname, nt_errstr(status));
3839 /* This should fail with a sharing violation - open for delete is only compatible
3840 with SHARE_DELETE. */
3842 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3843 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3844 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3849 /* This should succeed. */
3850 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3851 FILE_ATTRIBUTE_NORMAL,
3852 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3853 FILE_OPEN, 0, 0, &fnum2);
3854 if (!NT_STATUS_IS_OK(status)) {
3855 printf("[3] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3860 status = cli_nt_delete_on_close(cli1, fnum1, true);
3861 if (!NT_STATUS_IS_OK(status)) {
3862 printf("[3] setting delete_on_close failed (%s)\n", nt_errstr(status));
3867 status = cli_close(cli1, fnum1);
3868 if (!NT_STATUS_IS_OK(status)) {
3869 printf("[3] close 1 failed (%s)\n", nt_errstr(status));
3874 status = cli_close(cli1, fnum2);
3875 if (!NT_STATUS_IS_OK(status)) {
3876 printf("[3] close 2 failed (%s)\n", nt_errstr(status));
3881 /* This should fail - file should no longer be there. */
3883 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3884 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3885 status = cli_close(cli1, fnum1);
3886 if (!NT_STATUS_IS_OK(status)) {
3887 printf("[3] close failed (%s)\n", nt_errstr(status));
3889 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3893 printf("third delete on close test succeeded.\n");
3896 cli_setatr(cli1, fname, 0, 0);
3897 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3899 status = cli_ntcreate(cli1, fname, 0,
3900 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3901 FILE_ATTRIBUTE_NORMAL,
3902 FILE_SHARE_READ|FILE_SHARE_WRITE,
3903 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3904 if (!NT_STATUS_IS_OK(status)) {
3905 printf("[4] open of %s failed (%s)\n", fname, nt_errstr(status));
3910 /* This should succeed. */
3911 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3912 FILE_ATTRIBUTE_NORMAL,
3913 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3914 FILE_OPEN, 0, 0, &fnum2);
3915 if (!NT_STATUS_IS_OK(status)) {
3916 printf("[4] open - 2 of %s failed (%s)\n", fname, nt_errstr(status));
3921 status = cli_close(cli1, fnum2);
3922 if (!NT_STATUS_IS_OK(status)) {
3923 printf("[4] close - 1 failed (%s)\n", nt_errstr(status));
3928 status = cli_nt_delete_on_close(cli1, fnum1, true);
3929 if (!NT_STATUS_IS_OK(status)) {
3930 printf("[4] setting delete_on_close failed (%s)\n", nt_errstr(status));
3935 /* This should fail - no more opens once delete on close set. */
3936 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3937 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3938 FILE_OPEN, 0, 0, &fnum2))) {
3939 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3943 printf("fourth delete on close test succeeded.\n");
3945 status = cli_close(cli1, fnum1);
3946 if (!NT_STATUS_IS_OK(status)) {
3947 printf("[4] close - 2 failed (%s)\n", nt_errstr(status));
3953 cli_setatr(cli1, fname, 0, 0);
3954 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3956 status = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1);
3957 if (!NT_STATUS_IS_OK(status)) {
3958 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
3963 /* This should fail - only allowed on NT opens with DELETE access. */
3965 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3966 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3971 status = cli_close(cli1, fnum1);
3972 if (!NT_STATUS_IS_OK(status)) {
3973 printf("[5] close - 2 failed (%s)\n", nt_errstr(status));
3978 printf("fifth delete on close test succeeded.\n");
3981 cli_setatr(cli1, fname, 0, 0);
3982 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
3984 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3985 FILE_ATTRIBUTE_NORMAL,
3986 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3987 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3988 if (!NT_STATUS_IS_OK(status)) {
3989 printf("[6] open of %s failed (%s)\n", fname,
3995 /* This should fail - only allowed on NT opens with DELETE access. */
3997 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3998 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
4003 status = cli_close(cli1, fnum1);
4004 if (!NT_STATUS_IS_OK(status)) {
4005 printf("[6] close - 2 failed (%s)\n", nt_errstr(status));
4010 printf("sixth delete on close test succeeded.\n");
4013 cli_setatr(cli1, fname, 0, 0);
4014 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4016 status = cli_ntcreate(cli1, fname, 0,
4017 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4018 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
4020 if (!NT_STATUS_IS_OK(status)) {
4021 printf("[7] open of %s failed (%s)\n", fname, nt_errstr(status));
4026 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4027 printf("[7] setting delete_on_close on file failed !\n");
4032 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
4033 printf("[7] unsetting delete_on_close on file failed !\n");
4038 status = cli_close(cli1, fnum1);
4039 if (!NT_STATUS_IS_OK(status)) {
4040 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4045 /* This next open should succeed - we reset the flag. */
4046 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4047 if (!NT_STATUS_IS_OK(status)) {
4048 printf("[5] open of %s failed (%s)\n", fname, nt_errstr(status));
4053 status = cli_close(cli1, fnum1);
4054 if (!NT_STATUS_IS_OK(status)) {
4055 printf("[7] close - 2 failed (%s)\n", nt_errstr(status));
4060 printf("seventh delete on close test succeeded.\n");
4063 cli_setatr(cli1, fname, 0, 0);
4064 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4066 if (!torture_open_connection(&cli2, 1)) {
4067 printf("[8] failed to open second connection.\n");
4072 cli_sockopt(cli1, sockops);
4074 status = cli_ntcreate(cli1, fname, 0,
4075 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4076 FILE_ATTRIBUTE_NORMAL,
4077 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4078 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4079 if (!NT_STATUS_IS_OK(status)) {
4080 printf("[8] open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4085 status = cli_ntcreate(cli2, fname, 0,
4086 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4087 FILE_ATTRIBUTE_NORMAL,
4088 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4089 FILE_OPEN, 0, 0, &fnum2);
4090 if (!NT_STATUS_IS_OK(status)) {
4091 printf("[8] open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4096 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
4097 printf("[8] setting delete_on_close on file failed !\n");
4102 status = cli_close(cli1, fnum1);
4103 if (!NT_STATUS_IS_OK(status)) {
4104 printf("[8] close - 1 failed (%s)\n", nt_errstr(status));
4109 status = cli_close(cli2, fnum2);
4110 if (!NT_STATUS_IS_OK(status)) {
4111 printf("[8] close - 2 failed (%s)\n", nt_errstr(status));
4116 /* This should fail.. */
4117 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1);
4118 if (NT_STATUS_IS_OK(status)) {
4119 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
4123 printf("eighth delete on close test succeeded.\n");
4125 /* This should fail - we need to set DELETE_ACCESS. */
4126 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
4127 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
4128 printf("[9] open of %s succeeded should have failed!\n", fname);
4133 printf("ninth delete on close test succeeded.\n");
4135 status = cli_ntcreate(cli1, fname, 0,
4136 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
4137 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4138 FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE,
4140 if (!NT_STATUS_IS_OK(status)) {
4141 printf("[10] open of %s failed (%s)\n", fname, nt_errstr(status));
4146 /* This should delete the file. */
4147 status = cli_close(cli1, fnum1);
4148 if (!NT_STATUS_IS_OK(status)) {
4149 printf("[10] close failed (%s)\n", nt_errstr(status));
4154 /* This should fail.. */
4155 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
4156 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
4160 printf("tenth delete on close test succeeded.\n");
4162 cli_setatr(cli1, fname, 0, 0);
4163 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4165 /* What error do we get when attempting to open a read-only file with
4168 /* Create a readonly file. */
4169 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
4170 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE,
4171 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4172 if (!NT_STATUS_IS_OK(status)) {
4173 printf("[11] open of %s failed (%s)\n", fname, nt_errstr(status));
4178 status = cli_close(cli1, fnum1);
4179 if (!NT_STATUS_IS_OK(status)) {
4180 printf("[11] close failed (%s)\n", nt_errstr(status));
4185 /* Now try open for delete access. */
4186 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
4187 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4188 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4189 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
4190 cli_close(cli1, fnum1);
4194 NTSTATUS nterr = cli_nt_error(cli1);
4195 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4196 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4200 printf("eleventh delete on close test succeeded.\n");
4204 printf("finished delete test\n");
4207 /* FIXME: This will crash if we aborted before cli2 got
4208 * intialized, because these functions don't handle
4209 * uninitialized connections. */
4211 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4212 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4213 cli_setatr(cli1, fname, 0, 0);
4214 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4216 if (cli1 && !torture_close_connection(cli1)) {
4219 if (cli2 && !torture_close_connection(cli2)) {
4225 static bool run_deletetest_ln(int dummy)
4227 struct cli_state *cli;
4228 const char *fname = "\\delete1";
4229 const char *fname_ln = "\\delete1_ln";
4233 bool correct = true;
4236 printf("starting deletetest-ln\n");
4238 if (!torture_open_connection(&cli, 0)) {
4242 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4243 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4245 cli_sockopt(cli, sockops);
4247 /* Create the file. */
4248 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
4249 if (!NT_STATUS_IS_OK(status)) {
4250 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4254 status = cli_close(cli, fnum);
4255 if (!NT_STATUS_IS_OK(status)) {
4256 printf("close1 failed (%s)\n", nt_errstr(status));
4260 /* Now create a hardlink. */
4261 status = cli_nt_hardlink(cli, fname, fname_ln);
4262 if (!NT_STATUS_IS_OK(status)) {
4263 printf("nt hardlink failed (%s)\n", nt_errstr(status));
4267 /* Open the original file. */
4268 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4269 FILE_ATTRIBUTE_NORMAL,
4270 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4271 FILE_OPEN_IF, 0, 0, &fnum);
4272 if (!NT_STATUS_IS_OK(status)) {
4273 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4277 /* Unlink the hard link path. */
4278 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4279 FILE_ATTRIBUTE_NORMAL,
4280 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4281 FILE_OPEN_IF, 0, 0, &fnum1);
4282 if (!NT_STATUS_IS_OK(status)) {
4283 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4286 status = cli_nt_delete_on_close(cli, fnum1, true);
4287 if (!NT_STATUS_IS_OK(status)) {
4288 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4289 __location__, fname_ln, nt_errstr(status));
4293 status = cli_close(cli, fnum1);
4294 if (!NT_STATUS_IS_OK(status)) {
4295 printf("close %s failed (%s)\n",
4296 fname_ln, nt_errstr(status));
4300 status = cli_close(cli, fnum);
4301 if (!NT_STATUS_IS_OK(status)) {
4302 printf("close %s failed (%s)\n",
4303 fname, nt_errstr(status));
4307 /* Ensure the original file is still there. */
4308 status = cli_getatr(cli, fname, NULL, NULL, &t);
4309 if (!NT_STATUS_IS_OK(status)) {
4310 printf("%s getatr on file %s failed (%s)\n",
4317 /* Ensure the link path is gone. */
4318 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4319 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4320 printf("%s, getatr for file %s returned wrong error code %s "
4321 "- should have been deleted\n",
4323 fname_ln, nt_errstr(status));
4327 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4328 cli_unlink(cli, fname_ln, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4330 if (!torture_close_connection(cli)) {
4334 printf("finished deletetest-ln\n");
4340 print out server properties
4342 static bool run_properties(int dummy)
4344 struct cli_state *cli;
4345 bool correct = True;
4347 printf("starting properties test\n");
4351 if (!torture_open_connection(&cli, 0)) {
4355 cli_sockopt(cli, sockops);
4357 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4359 if (!torture_close_connection(cli)) {
4368 /* FIRST_DESIRED_ACCESS 0xf019f */
4369 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4370 FILE_READ_EA| /* 0xf */ \
4371 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4372 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4373 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4374 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4375 /* SECOND_DESIRED_ACCESS 0xe0080 */
4376 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4377 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4378 WRITE_OWNER_ACCESS /* 0xe0000 */
4381 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4382 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4384 WRITE_OWNER_ACCESS /* */
4388 Test ntcreate calls made by xcopy
4390 static bool run_xcopy(int dummy)
4392 static struct cli_state *cli1;
4393 const char *fname = "\\test.txt";
4394 bool correct = True;
4395 uint16_t fnum1, fnum2;
4398 printf("starting xcopy test\n");
4400 if (!torture_open_connection(&cli1, 0)) {
4404 status = cli_ntcreate(cli1, fname, 0, FIRST_DESIRED_ACCESS,
4405 FILE_ATTRIBUTE_ARCHIVE, FILE_SHARE_NONE,
4406 FILE_OVERWRITE_IF, 0x4044, 0, &fnum1);
4407 if (!NT_STATUS_IS_OK(status)) {
4408 printf("First open failed - %s\n", nt_errstr(status));
4412 status = cli_ntcreate(cli1, fname, 0, SECOND_DESIRED_ACCESS, 0,
4413 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4414 FILE_OPEN, 0x200000, 0, &fnum2);
4415 if (!NT_STATUS_IS_OK(status)) {
4416 printf("second open failed - %s\n", nt_errstr(status));
4420 if (!torture_close_connection(cli1)) {
4428 Test rename on files open with share delete and no share delete.
4430 static bool run_rename(int dummy)
4432 static struct cli_state *cli1;
4433 const char *fname = "\\test.txt";
4434 const char *fname1 = "\\test1.txt";
4435 bool correct = True;
4440 printf("starting rename test\n");
4442 if (!torture_open_connection(&cli1, 0)) {
4446 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4447 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4449 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4450 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
4451 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4452 if (!NT_STATUS_IS_OK(status)) {
4453 printf("First open failed - %s\n", nt_errstr(status));
4457 status = cli_rename(cli1, fname, fname1);
4458 if (!NT_STATUS_IS_OK(status)) {
4459 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", nt_errstr(status));
4461 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4465 status = cli_close(cli1, fnum1);
4466 if (!NT_STATUS_IS_OK(status)) {
4467 printf("close - 1 failed (%s)\n", nt_errstr(status));
4471 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4472 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4473 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4475 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4477 FILE_SHARE_DELETE|FILE_SHARE_READ,
4479 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4480 if (!NT_STATUS_IS_OK(status)) {
4481 printf("Second open failed - %s\n", nt_errstr(status));
4485 status = cli_rename(cli1, fname, fname1);
4486 if (!NT_STATUS_IS_OK(status)) {
4487 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", nt_errstr(status));
4490 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4493 status = cli_close(cli1, fnum1);
4494 if (!NT_STATUS_IS_OK(status)) {
4495 printf("close - 2 failed (%s)\n", nt_errstr(status));
4499 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4500 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4502 status = cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS,
4503 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4504 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4505 if (!NT_STATUS_IS_OK(status)) {
4506 printf("Third open failed - %s\n", nt_errstr(status));
4515 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4516 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4517 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4520 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4521 printf("[8] setting delete_on_close on file failed !\n");
4525 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4526 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4532 status = cli_rename(cli1, fname, fname1);
4533 if (!NT_STATUS_IS_OK(status)) {
4534 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", nt_errstr(status));
4537 printf("Third rename succeeded (SHARE_NONE)\n");
4540 status = cli_close(cli1, fnum1);
4541 if (!NT_STATUS_IS_OK(status)) {
4542 printf("close - 3 failed (%s)\n", nt_errstr(status));
4546 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4547 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4551 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4552 FILE_ATTRIBUTE_NORMAL,
4553 FILE_SHARE_READ | FILE_SHARE_WRITE,
4554 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4555 if (!NT_STATUS_IS_OK(status)) {
4556 printf("Fourth open failed - %s\n", nt_errstr(status));
4560 status = cli_rename(cli1, fname, fname1);
4561 if (!NT_STATUS_IS_OK(status)) {
4562 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", nt_errstr(status));
4564 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4568 status = cli_close(cli1, fnum1);
4569 if (!NT_STATUS_IS_OK(status)) {
4570 printf("close - 4 failed (%s)\n", nt_errstr(status));
4574 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4575 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4579 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
4580 FILE_ATTRIBUTE_NORMAL,
4581 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
4582 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4583 if (!NT_STATUS_IS_OK(status)) {
4584 printf("Fifth open failed - %s\n", nt_errstr(status));
4588 status = cli_rename(cli1, fname, fname1);
4589 if (!NT_STATUS_IS_OK(status)) {
4590 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n", nt_errstr(status));
4593 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", nt_errstr(status));
4597 * Now check if the first name still exists ...
4600 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4601 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4602 printf("Opening original file after rename of open file fails: %s\n",
4606 printf("Opening original file after rename of open file works ...\n");
4607 (void)cli_close(cli1, fnum2);
4611 status = cli_close(cli1, fnum1);
4612 if (!NT_STATUS_IS_OK(status)) {
4613 printf("close - 5 failed (%s)\n", nt_errstr(status));
4617 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4618 status = cli_getatr(cli1, fname1, &attr, NULL, NULL);
4619 if (!NT_STATUS_IS_OK(status)) {
4620 printf("getatr on file %s failed - %s ! \n",
4621 fname1, nt_errstr(status));
4624 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4625 printf("Renamed file %s has wrong attr 0x%x "
4626 "(should be 0x%x)\n",
4629 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4632 printf("Renamed file %s has archive bit set\n", fname1);
4636 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4637 cli_unlink(cli1, fname1, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4639 if (!torture_close_connection(cli1)) {
4646 static bool run_pipe_number(int dummy)
4648 struct cli_state *cli1;
4649 const char *pipe_name = "\\SPOOLSS";
4654 printf("starting pipenumber test\n");
4655 if (!torture_open_connection(&cli1, 0)) {
4659 cli_sockopt(cli1, sockops);
4661 status = cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA,
4662 FILE_ATTRIBUTE_NORMAL,
4663 FILE_SHARE_READ|FILE_SHARE_WRITE,
4664 FILE_OPEN_IF, 0, 0, &fnum);
4665 if (!NT_STATUS_IS_OK(status)) {
4666 printf("Open of pipe %s failed with error (%s)\n", pipe_name, nt_errstr(status));
4670 printf("\r%6d", num_pipes);
4673 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4674 torture_close_connection(cli1);
4679 Test open mode returns on read-only files.
4681 static bool run_opentest(int dummy)
4683 static struct cli_state *cli1;
4684 static struct cli_state *cli2;
4685 const char *fname = "\\readonly.file";
4686 uint16_t fnum1, fnum2;
4689 bool correct = True;
4693 printf("starting open test\n");
4695 if (!torture_open_connection(&cli1, 0)) {
4699 cli_setatr(cli1, fname, 0, 0);
4700 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4702 cli_sockopt(cli1, sockops);
4704 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4705 if (!NT_STATUS_IS_OK(status)) {
4706 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4710 status = cli_close(cli1, fnum1);
4711 if (!NT_STATUS_IS_OK(status)) {
4712 printf("close2 failed (%s)\n", nt_errstr(status));
4716 status = cli_setatr(cli1, fname, FILE_ATTRIBUTE_READONLY, 0);
4717 if (!NT_STATUS_IS_OK(status)) {
4718 printf("cli_setatr failed (%s)\n", nt_errstr(status));
4722 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4723 if (!NT_STATUS_IS_OK(status)) {
4724 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4728 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4729 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4731 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4732 NT_STATUS_ACCESS_DENIED)) {
4733 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4736 printf("finished open test 1\n");
4738 cli_close(cli1, fnum1);
4740 /* Now try not readonly and ensure ERRbadshare is returned. */
4742 cli_setatr(cli1, fname, 0, 0);
4744 status = cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1);
4745 if (!NT_STATUS_IS_OK(status)) {
4746 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
4750 /* This will fail - but the error should be ERRshare. */
4751 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4753 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4754 NT_STATUS_SHARING_VIOLATION)) {
4755 printf("correct error code ERRDOS/ERRbadshare returned\n");
4758 status = cli_close(cli1, fnum1);
4759 if (!NT_STATUS_IS_OK(status)) {
4760 printf("close2 failed (%s)\n", nt_errstr(status));
4764 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4766 printf("finished open test 2\n");
4768 /* Test truncate open disposition on file opened for read. */
4769 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
4770 if (!NT_STATUS_IS_OK(status)) {
4771 printf("(3) open (1) of %s failed (%s)\n", fname, nt_errstr(status));
4775 /* write 20 bytes. */
4777 memset(buf, '\0', 20);
4779 status = cli_writeall(cli1, fnum1, 0, (uint8_t *)buf, 0, 20, NULL);
4780 if (!NT_STATUS_IS_OK(status)) {
4781 printf("write failed (%s)\n", nt_errstr(status));
4785 status = cli_close(cli1, fnum1);
4786 if (!NT_STATUS_IS_OK(status)) {
4787 printf("(3) close1 failed (%s)\n", nt_errstr(status));
4791 /* Ensure size == 20. */
4792 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4793 if (!NT_STATUS_IS_OK(status)) {
4794 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4799 printf("(3) file size != 20\n");
4803 /* Now test if we can truncate a file opened for readonly. */
4804 status = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1);
4805 if (!NT_STATUS_IS_OK(status)) {
4806 printf("(3) open (2) of %s failed (%s)\n", fname, nt_errstr(status));
4810 status = cli_close(cli1, fnum1);
4811 if (!NT_STATUS_IS_OK(status)) {
4812 printf("close2 failed (%s)\n", nt_errstr(status));
4816 /* Ensure size == 0. */
4817 status = cli_getatr(cli1, fname, NULL, &fsize, NULL);
4818 if (!NT_STATUS_IS_OK(status)) {
4819 printf("(3) getatr failed (%s)\n", nt_errstr(status));
4824 printf("(3) file size != 0\n");
4827 printf("finished open test 3\n");
4829 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4831 printf("Do ctemp tests\n");
4832 status = cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path);
4833 if (!NT_STATUS_IS_OK(status)) {
4834 printf("ctemp failed (%s)\n", nt_errstr(status));
4838 printf("ctemp gave path %s\n", tmp_path);
4839 status = cli_close(cli1, fnum1);
4840 if (!NT_STATUS_IS_OK(status)) {
4841 printf("close of temp failed (%s)\n", nt_errstr(status));
4844 status = cli_unlink(cli1, tmp_path, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4845 if (!NT_STATUS_IS_OK(status)) {
4846 printf("unlink of temp failed (%s)\n", nt_errstr(status));
4849 /* Test the non-io opens... */
4851 if (!torture_open_connection(&cli2, 1)) {
4855 cli_setatr(cli2, fname, 0, 0);
4856 cli_unlink(cli2, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4858 cli_sockopt(cli2, sockops);
4860 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4861 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4862 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4863 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4864 if (!NT_STATUS_IS_OK(status)) {
4865 printf("TEST #1 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4869 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4870 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4871 FILE_OPEN_IF, 0, 0, &fnum2);
4872 if (!NT_STATUS_IS_OK(status)) {
4873 printf("TEST #1 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4877 status = cli_close(cli1, fnum1);
4878 if (!NT_STATUS_IS_OK(status)) {
4879 printf("TEST #1 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4883 status = cli_close(cli2, fnum2);
4884 if (!NT_STATUS_IS_OK(status)) {
4885 printf("TEST #1 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4889 printf("non-io open test #1 passed.\n");
4891 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4893 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4895 status = cli_ntcreate(cli1, fname, 0,
4896 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4897 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4898 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4899 if (!NT_STATUS_IS_OK(status)) {
4900 printf("TEST #2 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4904 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
4905 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4906 FILE_OPEN_IF, 0, 0, &fnum2);
4907 if (!NT_STATUS_IS_OK(status)) {
4908 printf("TEST #2 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4912 status = cli_close(cli1, fnum1);
4913 if (!NT_STATUS_IS_OK(status)) {
4914 printf("TEST #2 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4918 status = cli_close(cli2, fnum2);
4919 if (!NT_STATUS_IS_OK(status)) {
4920 printf("TEST #2 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4924 printf("non-io open test #2 passed.\n");
4926 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4928 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4930 status = cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES,
4931 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4932 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4933 if (!NT_STATUS_IS_OK(status)) {
4934 printf("TEST #3 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4938 status = cli_ntcreate(cli2, fname, 0,
4939 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4940 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4941 FILE_OPEN_IF, 0, 0, &fnum2);
4942 if (!NT_STATUS_IS_OK(status)) {
4943 printf("TEST #3 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
4947 status = cli_close(cli1, fnum1);
4948 if (!NT_STATUS_IS_OK(status)) {
4949 printf("TEST #3 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4953 status = cli_close(cli2, fnum2);
4954 if (!NT_STATUS_IS_OK(status)) {
4955 printf("TEST #3 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
4959 printf("non-io open test #3 passed.\n");
4961 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4963 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4965 status = cli_ntcreate(cli1, fname, 0,
4966 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4967 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4968 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4969 if (!NT_STATUS_IS_OK(status)) {
4970 printf("TEST #4 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
4974 status = cli_ntcreate(cli2, fname, 0,
4975 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4976 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
4977 FILE_OPEN_IF, 0, 0, &fnum2);
4978 if (NT_STATUS_IS_OK(status)) {
4979 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
4983 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
4985 status = cli_close(cli1, fnum1);
4986 if (!NT_STATUS_IS_OK(status)) {
4987 printf("TEST #4 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
4991 printf("non-io open test #4 passed.\n");
4993 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
4995 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4997 status = cli_ntcreate(cli1, fname, 0,
4998 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
4999 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5000 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5001 if (!NT_STATUS_IS_OK(status)) {
5002 printf("TEST #5 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5006 status = cli_ntcreate(cli2, fname, 0,
5007 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5008 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_DELETE,
5009 FILE_OPEN_IF, 0, 0, &fnum2);
5010 if (!NT_STATUS_IS_OK(status)) {
5011 printf("TEST #5 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5015 status = cli_close(cli1, fnum1);
5016 if (!NT_STATUS_IS_OK(status)) {
5017 printf("TEST #5 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5021 status = cli_close(cli2, fnum2);
5022 if (!NT_STATUS_IS_OK(status)) {
5023 printf("TEST #5 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5027 printf("non-io open test #5 passed.\n");
5029 printf("TEST #6 testing 1 non-io open, one io open\n");
5031 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5033 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5034 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5035 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5036 if (!NT_STATUS_IS_OK(status)) {
5037 printf("TEST #6 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5041 status = cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES,
5042 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
5043 FILE_OPEN_IF, 0, 0, &fnum2);
5044 if (!NT_STATUS_IS_OK(status)) {
5045 printf("TEST #6 open 2 of %s failed (%s)\n", fname, nt_errstr(status));
5049 status = cli_close(cli1, fnum1);
5050 if (!NT_STATUS_IS_OK(status)) {
5051 printf("TEST #6 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5055 status = cli_close(cli2, fnum2);
5056 if (!NT_STATUS_IS_OK(status)) {
5057 printf("TEST #6 close 2 of %s failed (%s)\n", fname, nt_errstr(status));
5061 printf("non-io open test #6 passed.\n");
5063 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
5065 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5067 status = cli_ntcreate(cli1, fname, 0, FILE_READ_DATA,
5068 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
5069 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5070 if (!NT_STATUS_IS_OK(status)) {
5071 printf("TEST #7 open 1 of %s failed (%s)\n", fname, nt_errstr(status));
5075 status = cli_ntcreate(cli2, fname, 0,
5076 DELETE_ACCESS|FILE_READ_ATTRIBUTES,
5077 FILE_ATTRIBUTE_NORMAL,
5078 FILE_SHARE_READ|FILE_SHARE_DELETE,
5079 FILE_OPEN_IF, 0, 0, &fnum2);
5080 if (NT_STATUS_IS_OK(status)) {
5081 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, nt_errstr(status));
5085 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, nt_errstr(status), "sharing violation");
5087 status = cli_close(cli1, fnum1);
5088 if (!NT_STATUS_IS_OK(status)) {
5089 printf("TEST #7 close 1 of %s failed (%s)\n", fname, nt_errstr(status));
5093 printf("non-io open test #7 passed.\n");
5095 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5097 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
5098 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
5099 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5100 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5101 if (!NT_STATUS_IS_OK(status)) {
5102 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
5107 /* Write to ensure we have to update the file time. */
5108 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5110 if (!NT_STATUS_IS_OK(status)) {
5111 printf("TEST #8 cli_write failed: %s\n", nt_errstr(status));
5116 status = cli_close(cli1, fnum1);
5117 if (!NT_STATUS_IS_OK(status)) {
5118 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
5124 if (!torture_close_connection(cli1)) {
5127 if (!torture_close_connection(cli2)) {
5134 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
5136 uint16 major, minor;
5137 uint32 caplow, caphigh;
5140 if (!SERVER_HAS_UNIX_CIFS(cli)) {
5141 printf("Server doesn't support UNIX CIFS extensions.\n");
5142 return NT_STATUS_NOT_SUPPORTED;
5145 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
5147 if (!NT_STATUS_IS_OK(status)) {
5148 printf("Server didn't return UNIX CIFS extensions: %s\n",
5153 status = cli_set_unix_extensions_capabilities(cli, major, minor,
5155 if (!NT_STATUS_IS_OK(status)) {
5156 printf("Server doesn't support setting UNIX CIFS extensions: "
5157 "%s.\n", nt_errstr(status));
5161 return NT_STATUS_OK;
5165 Test POSIX open /mkdir calls.
5167 static bool run_simple_posix_open_test(int dummy)
5169 static struct cli_state *cli1;
5170 const char *fname = "posix:file";
5171 const char *hname = "posix:hlink";
5172 const char *sname = "posix:symlink";
5173 const char *dname = "posix:dir";
5176 uint16_t fnum1 = (uint16_t)-1;
5177 SMB_STRUCT_STAT sbuf;
5178 bool correct = false;
5181 printf("Starting simple POSIX open test\n");
5183 if (!torture_open_connection(&cli1, 0)) {
5187 cli_sockopt(cli1, sockops);
5189 status = torture_setup_unix_extensions(cli1);
5190 if (!NT_STATUS_IS_OK(status)) {
5194 cli_setatr(cli1, fname, 0, 0);
5195 cli_posix_unlink(cli1, fname);
5196 cli_setatr(cli1, dname, 0, 0);
5197 cli_posix_rmdir(cli1, dname);
5198 cli_setatr(cli1, hname, 0, 0);
5199 cli_posix_unlink(cli1, hname);
5200 cli_setatr(cli1, sname, 0, 0);
5201 cli_posix_unlink(cli1, sname);
5203 /* Create a directory. */
5204 status = cli_posix_mkdir(cli1, dname, 0777);
5205 if (!NT_STATUS_IS_OK(status)) {
5206 printf("POSIX mkdir of %s failed (%s)\n", dname, nt_errstr(status));
5210 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5212 if (!NT_STATUS_IS_OK(status)) {
5213 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5217 /* Test ftruncate - set file size. */
5218 status = cli_ftruncate(cli1, fnum1, 1000);
5219 if (!NT_STATUS_IS_OK(status)) {
5220 printf("ftruncate failed (%s)\n", nt_errstr(status));
5224 /* Ensure st_size == 1000 */
5225 status = cli_posix_stat(cli1, fname, &sbuf);
5226 if (!NT_STATUS_IS_OK(status)) {
5227 printf("stat failed (%s)\n", nt_errstr(status));
5231 if (sbuf.st_ex_size != 1000) {
5232 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5236 /* Test ftruncate - set file size back to zero. */
5237 status = cli_ftruncate(cli1, fnum1, 0);
5238 if (!NT_STATUS_IS_OK(status)) {
5239 printf("ftruncate failed (%s)\n", nt_errstr(status));
5243 status = cli_close(cli1, fnum1);
5244 if (!NT_STATUS_IS_OK(status)) {
5245 printf("close failed (%s)\n", nt_errstr(status));
5249 /* Now open the file again for read only. */
5250 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5251 if (!NT_STATUS_IS_OK(status)) {
5252 printf("POSIX open of %s failed (%s)\n", fname, nt_errstr(status));
5256 /* Now unlink while open. */
5257 status = cli_posix_unlink(cli1, fname);
5258 if (!NT_STATUS_IS_OK(status)) {
5259 printf("POSIX unlink of %s failed (%s)\n", fname, nt_errstr(status));
5263 status = cli_close(cli1, fnum1);
5264 if (!NT_STATUS_IS_OK(status)) {
5265 printf("close(2) failed (%s)\n", nt_errstr(status));
5269 /* Ensure the file has gone. */
5270 status = cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1);
5271 if (NT_STATUS_IS_OK(status)) {
5272 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
5276 /* Create again to test open with O_TRUNC. */
5277 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
5278 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5282 /* Test ftruncate - set file size. */
5283 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
5284 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
5288 /* Ensure st_size == 1000 */
5289 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5290 printf("stat failed (%s)\n", cli_errstr(cli1));
5294 if (sbuf.st_ex_size != 1000) {
5295 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
5299 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5300 printf("close(2) failed (%s)\n", cli_errstr(cli1));
5304 /* Re-open with O_TRUNC. */
5305 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_WRONLY|O_TRUNC, 0600, &fnum1))) {
5306 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
5310 /* Ensure st_size == 0 */
5311 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
5312 printf("stat failed (%s)\n", cli_errstr(cli1));
5316 if (sbuf.st_ex_size != 0) {
5317 printf("O_TRUNC - stat size (%u) != 0\n", (unsigned int)sbuf.st_ex_size);
5321 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5322 printf("close failed (%s)\n", cli_errstr(cli1));
5326 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
5327 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
5331 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
5332 printf("POSIX open directory O_RDONLY of %s failed (%s)\n",
5333 dname, cli_errstr(cli1));
5337 cli_close(cli1, fnum1);
5339 /* What happens when we try and POSIX open a directory for write ? */
5340 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDWR, 0, &fnum1))) {
5341 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
5344 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
5345 NT_STATUS_FILE_IS_A_DIRECTORY)) {
5350 /* Create the file. */
5351 status = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL,
5353 if (!NT_STATUS_IS_OK(status)) {
5354 printf("POSIX create of %s failed (%s)\n", fname, nt_errstr(status));
5358 /* Write some data into it. */
5359 status = cli_writeall(cli1, fnum1, 0, (const uint8_t *)"TEST DATA\n", 0, 10,
5361 if (!NT_STATUS_IS_OK(status)) {
5362 printf("cli_write failed: %s\n", nt_errstr(status));
5366 cli_close(cli1, fnum1);
5368 /* Now create a hardlink. */
5369 status = cli_posix_hardlink(cli1, fname, hname);
5370 if (!NT_STATUS_IS_OK(status)) {
5371 printf("POSIX hardlink of %s failed (%s)\n", hname, nt_errstr(status));
5375 /* Now create a symlink. */
5376 status = cli_posix_symlink(cli1, fname, sname);
5377 if (!NT_STATUS_IS_OK(status)) {
5378 printf("POSIX symlink of %s failed (%s)\n", sname, nt_errstr(status));
5382 /* Open the hardlink for read. */
5383 status = cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1);
5384 if (!NT_STATUS_IS_OK(status)) {
5385 printf("POSIX open of %s failed (%s)\n", hname, nt_errstr(status));
5389 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5390 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5394 if (memcmp(buf, "TEST DATA\n", 10)) {
5395 printf("invalid data read from hardlink\n");
5399 /* Do a POSIX lock/unlock. */
5400 status = cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK);
5401 if (!NT_STATUS_IS_OK(status)) {
5402 printf("POSIX lock failed %s\n", nt_errstr(status));
5406 /* Punch a hole in the locked area. */
5407 status = cli_posix_unlock(cli1, fnum1, 10, 80);
5408 if (!NT_STATUS_IS_OK(status)) {
5409 printf("POSIX unlock failed %s\n", nt_errstr(status));
5413 cli_close(cli1, fnum1);
5415 /* Open the symlink for read - this should fail. A POSIX
5416 client should not be doing opens on a symlink. */
5417 status = cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1);
5418 if (NT_STATUS_IS_OK(status)) {
5419 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5422 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5423 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5424 printf("POSIX open of %s should have failed "
5425 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5426 "failed with %s instead.\n",
5427 sname, nt_errstr(status));
5432 status = cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf));
5433 if (!NT_STATUS_IS_OK(status)) {
5434 printf("POSIX readlink on %s failed (%s)\n", sname, nt_errstr(status));
5438 if (strcmp(namebuf, fname) != 0) {
5439 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5440 sname, fname, namebuf);
5444 status = cli_posix_rmdir(cli1, dname);
5445 if (!NT_STATUS_IS_OK(status)) {
5446 printf("POSIX rmdir failed (%s)\n", nt_errstr(status));
5450 printf("Simple POSIX open test passed\n");
5455 if (fnum1 != (uint16_t)-1) {
5456 cli_close(cli1, fnum1);
5457 fnum1 = (uint16_t)-1;
5460 cli_setatr(cli1, sname, 0, 0);
5461 cli_posix_unlink(cli1, sname);
5462 cli_setatr(cli1, hname, 0, 0);
5463 cli_posix_unlink(cli1, hname);
5464 cli_setatr(cli1, fname, 0, 0);
5465 cli_posix_unlink(cli1, fname);
5466 cli_setatr(cli1, dname, 0, 0);
5467 cli_posix_rmdir(cli1, dname);
5469 if (!torture_close_connection(cli1)) {
5477 static uint32 open_attrs_table[] = {
5478 FILE_ATTRIBUTE_NORMAL,
5479 FILE_ATTRIBUTE_ARCHIVE,
5480 FILE_ATTRIBUTE_READONLY,
5481 FILE_ATTRIBUTE_HIDDEN,
5482 FILE_ATTRIBUTE_SYSTEM,
5484 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5485 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5486 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5487 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5488 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5489 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5491 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5492 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5493 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5494 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5497 struct trunc_open_results {
5504 static struct trunc_open_results attr_results[] = {
5505 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5506 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5507 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5508 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5509 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5510 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5511 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5512 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5513 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5514 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5515 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5516 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5517 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5518 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5519 { 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 },
5520 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5521 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5522 { 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 },
5523 { 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 },
5524 { 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 },
5525 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5526 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5527 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5528 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5529 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5530 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5533 static bool run_openattrtest(int dummy)
5535 static struct cli_state *cli1;
5536 const char *fname = "\\openattr.file";
5538 bool correct = True;
5540 unsigned int i, j, k, l;
5543 printf("starting open attr test\n");
5545 if (!torture_open_connection(&cli1, 0)) {
5549 cli_sockopt(cli1, sockops);
5551 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5552 cli_setatr(cli1, fname, 0, 0);
5553 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5555 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA,
5556 open_attrs_table[i], FILE_SHARE_NONE,
5557 FILE_OVERWRITE_IF, 0, 0, &fnum1);
5558 if (!NT_STATUS_IS_OK(status)) {
5559 printf("open %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5563 status = cli_close(cli1, fnum1);
5564 if (!NT_STATUS_IS_OK(status)) {
5565 printf("close %d (1) of %s failed (%s)\n", i, fname, nt_errstr(status));
5569 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5570 status = cli_ntcreate(cli1, fname, 0,
5571 FILE_READ_DATA|FILE_WRITE_DATA,
5572 open_attrs_table[j],
5573 FILE_SHARE_NONE, FILE_OVERWRITE,
5575 if (!NT_STATUS_IS_OK(status)) {
5576 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5577 if (attr_results[l].num == k) {
5578 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5579 k, open_attrs_table[i],
5580 open_attrs_table[j],
5581 fname, NT_STATUS_V(status), nt_errstr(status));
5586 if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
5587 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5588 k, open_attrs_table[i], open_attrs_table[j],
5593 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5599 status = cli_close(cli1, fnum1);
5600 if (!NT_STATUS_IS_OK(status)) {
5601 printf("close %d (2) of %s failed (%s)\n", j, fname, nt_errstr(status));
5605 status = cli_getatr(cli1, fname, &attr, NULL, NULL);
5606 if (!NT_STATUS_IS_OK(status)) {
5607 printf("getatr(2) failed (%s)\n", nt_errstr(status));
5612 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5613 k, open_attrs_table[i], open_attrs_table[j], attr );
5616 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5617 if (attr_results[l].num == k) {
5618 if (attr != attr_results[l].result_attr ||
5619 open_attrs_table[i] != attr_results[l].init_attr ||
5620 open_attrs_table[j] != attr_results[l].trunc_attr) {
5621 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5622 open_attrs_table[i],
5623 open_attrs_table[j],
5625 attr_results[l].result_attr);
5635 cli_setatr(cli1, fname, 0, 0);
5636 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5638 printf("open attr test %s.\n", correct ? "passed" : "failed");
5640 if (!torture_close_connection(cli1)) {
5646 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5647 const char *name, void *state)
5649 int *matched = (int *)state;
5650 if (matched != NULL) {
5653 return NT_STATUS_OK;
5657 test directory listing speed
5659 static bool run_dirtest(int dummy)
5662 static struct cli_state *cli;
5664 struct timeval core_start;
5665 bool correct = True;
5668 printf("starting directory test\n");
5670 if (!torture_open_connection(&cli, 0)) {
5674 cli_sockopt(cli, sockops);
5677 for (i=0;i<torture_numops;i++) {
5679 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5680 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5681 fprintf(stderr,"Failed to open %s\n", fname);
5684 cli_close(cli, fnum);
5687 core_start = timeval_current();
5690 cli_list(cli, "a*.*", 0, list_fn, &matched);
5691 printf("Matched %d\n", matched);
5694 cli_list(cli, "b*.*", 0, list_fn, &matched);
5695 printf("Matched %d\n", matched);
5698 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5699 printf("Matched %d\n", matched);
5701 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5704 for (i=0;i<torture_numops;i++) {
5706 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5707 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5710 if (!torture_close_connection(cli)) {
5714 printf("finished dirtest\n");
5719 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5722 struct cli_state *pcli = (struct cli_state *)state;
5724 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5726 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5727 return NT_STATUS_OK;
5729 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
5730 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5731 printf("del_fn: failed to rmdir %s\n,", fname );
5733 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN)))
5734 printf("del_fn: failed to unlink %s\n,", fname );
5736 return NT_STATUS_OK;
5741 sees what IOCTLs are supported
5743 bool torture_ioctl_test(int dummy)
5745 static struct cli_state *cli;
5746 uint16_t device, function;
5748 const char *fname = "\\ioctl.dat";
5752 if (!torture_open_connection(&cli, 0)) {
5756 printf("starting ioctl test\n");
5758 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5760 status = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
5761 if (!NT_STATUS_IS_OK(status)) {
5762 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
5766 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5767 printf("ioctl device info: %s\n", nt_errstr(status));
5769 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5770 printf("ioctl job info: %s\n", nt_errstr(status));
5772 for (device=0;device<0x100;device++) {
5773 printf("ioctl test with device = 0x%x\n", device);
5774 for (function=0;function<0x100;function++) {
5775 uint32 code = (device<<16) | function;
5777 status = cli_raw_ioctl(cli, fnum, code, &blob);
5779 if (NT_STATUS_IS_OK(status)) {
5780 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5782 data_blob_free(&blob);
5787 if (!torture_close_connection(cli)) {
5796 tries varients of chkpath
5798 bool torture_chkpath_test(int dummy)
5800 static struct cli_state *cli;
5805 if (!torture_open_connection(&cli, 0)) {
5809 printf("starting chkpath test\n");
5811 /* cleanup from an old run */
5812 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5813 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5814 cli_rmdir(cli, "\\chkpath.dir");
5816 status = cli_mkdir(cli, "\\chkpath.dir");
5817 if (!NT_STATUS_IS_OK(status)) {
5818 printf("mkdir1 failed : %s\n", nt_errstr(status));
5822 status = cli_mkdir(cli, "\\chkpath.dir\\dir2");
5823 if (!NT_STATUS_IS_OK(status)) {
5824 printf("mkdir2 failed : %s\n", nt_errstr(status));
5828 status = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL,
5830 if (!NT_STATUS_IS_OK(status)) {
5831 printf("open1 failed (%s)\n", nt_errstr(status));
5834 cli_close(cli, fnum);
5836 status = cli_chkpath(cli, "\\chkpath.dir");
5837 if (!NT_STATUS_IS_OK(status)) {
5838 printf("chkpath1 failed: %s\n", nt_errstr(status));
5842 status = cli_chkpath(cli, "\\chkpath.dir\\dir2");
5843 if (!NT_STATUS_IS_OK(status)) {
5844 printf("chkpath2 failed: %s\n", nt_errstr(status));
5848 status = cli_chkpath(cli, "\\chkpath.dir\\foo.txt");
5849 if (!NT_STATUS_IS_OK(status)) {
5850 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5851 NT_STATUS_NOT_A_DIRECTORY);
5853 printf("* chkpath on a file should fail\n");
5857 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5858 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5859 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5861 printf("* chkpath on a non existant file should fail\n");
5865 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5866 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5867 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5869 printf("* chkpath on a non existent component should fail\n");
5873 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5874 cli_unlink(cli, "\\chkpath.dir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5875 cli_rmdir(cli, "\\chkpath.dir");
5877 if (!torture_close_connection(cli)) {
5884 static bool run_eatest(int dummy)
5886 static struct cli_state *cli;
5887 const char *fname = "\\eatest.txt";
5888 bool correct = True;
5892 struct ea_struct *ea_list = NULL;
5893 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5896 printf("starting eatest\n");
5898 if (!torture_open_connection(&cli, 0)) {
5899 talloc_destroy(mem_ctx);
5903 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
5905 status = cli_ntcreate(cli, fname, 0,
5906 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5907 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5909 if (!NT_STATUS_IS_OK(status)) {
5910 printf("open failed - %s\n", nt_errstr(status));
5911 talloc_destroy(mem_ctx);
5915 for (i = 0; i < 10; i++) {
5916 fstring ea_name, ea_val;
5918 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5919 memset(ea_val, (char)i+1, i+1);
5920 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5921 if (!NT_STATUS_IS_OK(status)) {
5922 printf("ea_set of name %s failed - %s\n", ea_name,
5924 talloc_destroy(mem_ctx);
5929 cli_close(cli, fnum);
5930 for (i = 0; i < 10; i++) {
5931 fstring ea_name, ea_val;
5933 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5934 memset(ea_val, (char)i+1, i+1);
5935 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5936 if (!NT_STATUS_IS_OK(status)) {
5937 printf("ea_set of name %s failed - %s\n", ea_name,
5939 talloc_destroy(mem_ctx);
5944 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5945 if (!NT_STATUS_IS_OK(status)) {
5946 printf("ea_get list failed - %s\n", nt_errstr(status));
5950 printf("num_eas = %d\n", (int)num_eas);
5952 if (num_eas != 20) {
5953 printf("Should be 20 EA's stored... failing.\n");
5957 for (i = 0; i < num_eas; i++) {
5958 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5959 dump_data(0, ea_list[i].value.data,
5960 ea_list[i].value.length);
5963 /* Setting EA's to zero length deletes them. Test this */
5964 printf("Now deleting all EA's - case indepenent....\n");
5967 cli_set_ea_path(cli, fname, "", "", 0);
5969 for (i = 0; i < 20; i++) {
5971 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5972 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5973 if (!NT_STATUS_IS_OK(status)) {
5974 printf("ea_set of name %s failed - %s\n", ea_name,
5976 talloc_destroy(mem_ctx);
5982 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5983 if (!NT_STATUS_IS_OK(status)) {
5984 printf("ea_get list failed - %s\n", nt_errstr(status));
5988 printf("num_eas = %d\n", (int)num_eas);
5989 for (i = 0; i < num_eas; i++) {
5990 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5991 dump_data(0, ea_list[i].value.data,
5992 ea_list[i].value.length);
5996 printf("deleting EA's failed.\n");
6000 /* Try and delete a non existant EA. */
6001 status = cli_set_ea_path(cli, fname, "foo", "", 0);
6002 if (!NT_STATUS_IS_OK(status)) {
6003 printf("deleting non-existant EA 'foo' should succeed. %s\n",
6008 talloc_destroy(mem_ctx);
6009 if (!torture_close_connection(cli)) {
6016 static bool run_dirtest1(int dummy)
6019 static struct cli_state *cli;
6022 bool correct = True;
6024 printf("starting directory test\n");
6026 if (!torture_open_connection(&cli, 0)) {
6030 cli_sockopt(cli, sockops);
6032 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6033 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6034 cli_rmdir(cli, "\\LISTDIR");
6035 cli_mkdir(cli, "\\LISTDIR");
6037 /* Create 1000 files and 1000 directories. */
6038 for (i=0;i<1000;i++) {
6040 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
6041 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
6042 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6043 fprintf(stderr,"Failed to open %s\n", fname);
6046 cli_close(cli, fnum);
6048 for (i=0;i<1000;i++) {
6050 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
6051 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
6052 fprintf(stderr,"Failed to open %s\n", fname);
6057 /* Now ensure that doing an old list sees both files and directories. */
6059 cli_list_old(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6060 printf("num_seen = %d\n", num_seen );
6061 /* We should see 100 files + 1000 directories + . and .. */
6062 if (num_seen != 2002)
6065 /* Ensure if we have the "must have" bits we only see the
6069 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_DIRECTORY<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6070 printf("num_seen = %d\n", num_seen );
6071 if (num_seen != 1002)
6075 cli_list_old(cli, "\\LISTDIR\\*", (FILE_ATTRIBUTE_ARCHIVE<<8)|FILE_ATTRIBUTE_DIRECTORY, list_fn, &num_seen);
6076 printf("num_seen = %d\n", num_seen );
6077 if (num_seen != 1000)
6080 /* Delete everything. */
6081 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
6082 cli_list(cli, "\\LISTDIR\\*", FILE_ATTRIBUTE_DIRECTORY, del_fn, cli);
6083 cli_rmdir(cli, "\\LISTDIR");
6086 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
6087 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
6088 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
6091 if (!torture_close_connection(cli)) {
6095 printf("finished dirtest1\n");
6100 static bool run_error_map_extract(int dummy) {
6102 static struct cli_state *c_dos;
6103 static struct cli_state *c_nt;
6108 uint32 flgs2, errnum;
6115 /* NT-Error connection */
6117 if (!(c_nt = open_nbt_connection())) {
6121 c_nt->use_spnego = False;
6123 status = cli_negprot(c_nt);
6125 if (!NT_STATUS_IS_OK(status)) {
6126 printf("%s rejected the NT-error negprot (%s)\n", host,
6132 status = cli_session_setup(c_nt, "", "", 0, "", 0, workgroup);
6133 if (!NT_STATUS_IS_OK(status)) {
6134 printf("%s rejected the NT-error initial session setup (%s)\n",host, nt_errstr(status));
6138 /* DOS-Error connection */
6140 if (!(c_dos = open_nbt_connection())) {
6144 c_dos->use_spnego = False;
6145 c_dos->force_dos_errors = True;
6147 status = cli_negprot(c_dos);
6148 if (!NT_STATUS_IS_OK(status)) {
6149 printf("%s rejected the DOS-error negprot (%s)\n", host,
6151 cli_shutdown(c_dos);
6155 status = cli_session_setup(c_dos, "", "", 0, "", 0, workgroup);
6156 if (!NT_STATUS_IS_OK(status)) {
6157 printf("%s rejected the DOS-error initial session setup (%s)\n",
6158 host, nt_errstr(status));
6162 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
6163 fstr_sprintf(user, "%X", error);
6165 status = cli_session_setup(c_nt, user,
6166 password, strlen(password),
6167 password, strlen(password),
6169 if (NT_STATUS_IS_OK(status)) {
6170 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6173 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
6175 /* Case #1: 32-bit NT errors */
6176 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6177 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
6179 printf("/** Dos error on NT connection! (%s) */\n",
6181 nt_status = NT_STATUS(0xc0000000);
6184 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
6185 password, strlen(password),
6186 password, strlen(password),
6188 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
6190 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
6192 /* Case #1: 32-bit NT errors */
6193 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
6194 printf("/** NT error on DOS connection! (%s) */\n",
6196 errnum = errclass = 0;
6198 cli_dos_error(c_dos, &errclass, &errnum);
6201 if (NT_STATUS_V(nt_status) != error) {
6202 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
6203 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)),
6204 get_nt_error_c_code(talloc_tos(), nt_status));
6207 printf("\t{%s,\t%s,\t%s},\n",
6208 smb_dos_err_class(errclass),
6209 smb_dos_err_name(errclass, errnum),
6210 get_nt_error_c_code(talloc_tos(), NT_STATUS(error)));
6215 static bool run_sesssetup_bench(int dummy)
6217 static struct cli_state *c;
6218 const char *fname = "\\file.dat";
6223 if (!torture_open_connection(&c, 0)) {
6227 status = cli_ntcreate(c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6228 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6229 FILE_DELETE_ON_CLOSE, 0, &fnum);
6230 if (!NT_STATUS_IS_OK(status)) {
6231 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6235 for (i=0; i<torture_numops; i++) {
6236 status = cli_session_setup(
6238 password, strlen(password),
6239 password, strlen(password),
6241 if (!NT_STATUS_IS_OK(status)) {
6242 d_printf("(%s) cli_session_setup failed: %s\n",
6243 __location__, nt_errstr(status));
6247 d_printf("\r%d ", (int)c->vuid);
6249 status = cli_ulogoff(c);
6250 if (!NT_STATUS_IS_OK(status)) {
6251 d_printf("(%s) cli_ulogoff failed: %s\n",
6252 __location__, nt_errstr(status));
6261 static bool subst_test(const char *str, const char *user, const char *domain,
6262 uid_t uid, gid_t gid, const char *expected)
6267 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
6269 if (strcmp(subst, expected) != 0) {
6270 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
6271 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
6280 static void chain1_open_completion(struct tevent_req *req)
6284 status = cli_open_recv(req, &fnum);
6287 d_printf("cli_open_recv returned %s: %d\n",
6289 NT_STATUS_IS_OK(status) ? fnum : -1);
6292 static void chain1_write_completion(struct tevent_req *req)
6296 status = cli_write_andx_recv(req, &written);
6299 d_printf("cli_write_andx_recv returned %s: %d\n",
6301 NT_STATUS_IS_OK(status) ? (int)written : -1);
6304 static void chain1_close_completion(struct tevent_req *req)
6307 bool *done = (bool *)tevent_req_callback_data_void(req);
6309 status = cli_close_recv(req);
6314 d_printf("cli_close returned %s\n", nt_errstr(status));
6317 static bool run_chain1(int dummy)
6319 struct cli_state *cli1;
6320 struct event_context *evt = event_context_init(NULL);
6321 struct tevent_req *reqs[3], *smbreqs[3];
6323 const char *str = "foobar";
6326 printf("starting chain1 test\n");
6327 if (!torture_open_connection(&cli1, 0)) {
6331 cli_sockopt(cli1, sockops);
6333 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
6334 O_CREAT|O_RDWR, 0, &smbreqs[0]);
6335 if (reqs[0] == NULL) return false;
6336 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
6339 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
6340 (const uint8_t *)str, 0, strlen(str)+1,
6341 smbreqs, 1, &smbreqs[1]);
6342 if (reqs[1] == NULL) return false;
6343 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
6345 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
6346 if (reqs[2] == NULL) return false;
6347 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
6349 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6350 if (!NT_STATUS_IS_OK(status)) {
6355 event_loop_once(evt);
6358 torture_close_connection(cli1);
6362 static void chain2_sesssetup_completion(struct tevent_req *req)
6365 status = cli_session_setup_guest_recv(req);
6366 d_printf("sesssetup returned %s\n", nt_errstr(status));
6369 static void chain2_tcon_completion(struct tevent_req *req)
6371 bool *done = (bool *)tevent_req_callback_data_void(req);
6373 status = cli_tcon_andx_recv(req);
6374 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
6378 static bool run_chain2(int dummy)
6380 struct cli_state *cli1;
6381 struct event_context *evt = event_context_init(NULL);
6382 struct tevent_req *reqs[2], *smbreqs[2];
6386 printf("starting chain2 test\n");
6387 status = cli_start_connection(&cli1, global_myname(), host, NULL,
6388 port_to_use, Undefined, 0);
6389 if (!NT_STATUS_IS_OK(status)) {
6393 cli_sockopt(cli1, sockops);
6395 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
6397 if (reqs[0] == NULL) return false;
6398 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
6400 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
6401 "?????", NULL, 0, &smbreqs[1]);
6402 if (reqs[1] == NULL) return false;
6403 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6405 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6406 if (!NT_STATUS_IS_OK(status)) {
6411 event_loop_once(evt);
6414 torture_close_connection(cli1);
6419 struct torture_createdel_state {
6420 struct tevent_context *ev;
6421 struct cli_state *cli;
6424 static void torture_createdel_created(struct tevent_req *subreq);
6425 static void torture_createdel_closed(struct tevent_req *subreq);
6427 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6428 struct tevent_context *ev,
6429 struct cli_state *cli,
6432 struct tevent_req *req, *subreq;
6433 struct torture_createdel_state *state;
6435 req = tevent_req_create(mem_ctx, &state,
6436 struct torture_createdel_state);
6443 subreq = cli_ntcreate_send(
6444 state, ev, cli, name, 0,
6445 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6446 FILE_ATTRIBUTE_NORMAL,
6447 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6448 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6450 if (tevent_req_nomem(subreq, req)) {
6451 return tevent_req_post(req, ev);
6453 tevent_req_set_callback(subreq, torture_createdel_created, req);
6457 static void torture_createdel_created(struct tevent_req *subreq)
6459 struct tevent_req *req = tevent_req_callback_data(
6460 subreq, struct tevent_req);
6461 struct torture_createdel_state *state = tevent_req_data(
6462 req, struct torture_createdel_state);
6466 status = cli_ntcreate_recv(subreq, &fnum);
6467 TALLOC_FREE(subreq);
6468 if (!NT_STATUS_IS_OK(status)) {
6469 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6470 nt_errstr(status)));
6471 tevent_req_nterror(req, status);
6475 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6476 if (tevent_req_nomem(subreq, req)) {
6479 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6482 static void torture_createdel_closed(struct tevent_req *subreq)
6484 struct tevent_req *req = tevent_req_callback_data(
6485 subreq, struct tevent_req);
6488 status = cli_close_recv(subreq);
6489 if (!NT_STATUS_IS_OK(status)) {
6490 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6491 tevent_req_nterror(req, status);
6494 tevent_req_done(req);
6497 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6499 return tevent_req_simple_recv_ntstatus(req);
6502 struct torture_createdels_state {
6503 struct tevent_context *ev;
6504 struct cli_state *cli;
6505 const char *base_name;
6509 struct tevent_req **reqs;
6512 static void torture_createdels_done(struct tevent_req *subreq);
6514 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6515 struct tevent_context *ev,
6516 struct cli_state *cli,
6517 const char *base_name,
6521 struct tevent_req *req;
6522 struct torture_createdels_state *state;
6525 req = tevent_req_create(mem_ctx, &state,
6526 struct torture_createdels_state);
6532 state->base_name = talloc_strdup(state, base_name);
6533 if (tevent_req_nomem(state->base_name, req)) {
6534 return tevent_req_post(req, ev);
6536 state->num_files = MAX(num_parallel, num_files);
6538 state->received = 0;
6540 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6541 if (tevent_req_nomem(state->reqs, req)) {
6542 return tevent_req_post(req, ev);
6545 for (i=0; i<num_parallel; i++) {
6548 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6550 if (tevent_req_nomem(name, req)) {
6551 return tevent_req_post(req, ev);
6553 state->reqs[i] = torture_createdel_send(
6554 state->reqs, state->ev, state->cli, name);
6555 if (tevent_req_nomem(state->reqs[i], req)) {
6556 return tevent_req_post(req, ev);
6558 name = talloc_move(state->reqs[i], &name);
6559 tevent_req_set_callback(state->reqs[i],
6560 torture_createdels_done, req);
6566 static void torture_createdels_done(struct tevent_req *subreq)
6568 struct tevent_req *req = tevent_req_callback_data(
6569 subreq, struct tevent_req);
6570 struct torture_createdels_state *state = tevent_req_data(
6571 req, struct torture_createdels_state);
6572 size_t num_parallel = talloc_array_length(state->reqs);
6577 status = torture_createdel_recv(subreq);
6578 if (!NT_STATUS_IS_OK(status)){
6579 DEBUG(10, ("torture_createdel_recv returned %s\n",
6580 nt_errstr(status)));
6581 TALLOC_FREE(subreq);
6582 tevent_req_nterror(req, status);
6586 for (i=0; i<num_parallel; i++) {
6587 if (subreq == state->reqs[i]) {
6591 if (i == num_parallel) {
6592 DEBUG(10, ("received something we did not send\n"));
6593 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6596 TALLOC_FREE(state->reqs[i]);
6598 if (state->sent >= state->num_files) {
6599 tevent_req_done(req);
6603 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6605 if (tevent_req_nomem(name, req)) {
6608 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6610 if (tevent_req_nomem(state->reqs[i], req)) {
6613 name = talloc_move(state->reqs[i], &name);
6614 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6618 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6620 return tevent_req_simple_recv_ntstatus(req);
6623 struct swallow_notify_state {
6624 struct tevent_context *ev;
6625 struct cli_state *cli;
6627 uint32_t completion_filter;
6629 bool (*fn)(uint32_t action, const char *name, void *priv);
6633 static void swallow_notify_done(struct tevent_req *subreq);
6635 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6636 struct tevent_context *ev,
6637 struct cli_state *cli,
6639 uint32_t completion_filter,
6641 bool (*fn)(uint32_t action,
6646 struct tevent_req *req, *subreq;
6647 struct swallow_notify_state *state;
6649 req = tevent_req_create(mem_ctx, &state,
6650 struct swallow_notify_state);
6657 state->completion_filter = completion_filter;
6658 state->recursive = recursive;
6662 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6663 0xffff, state->completion_filter,
6665 if (tevent_req_nomem(subreq, req)) {
6666 return tevent_req_post(req, ev);
6668 tevent_req_set_callback(subreq, swallow_notify_done, req);
6672 static void swallow_notify_done(struct tevent_req *subreq)
6674 struct tevent_req *req = tevent_req_callback_data(
6675 subreq, struct tevent_req);
6676 struct swallow_notify_state *state = tevent_req_data(
6677 req, struct swallow_notify_state);
6679 uint32_t i, num_changes;
6680 struct notify_change *changes;
6682 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6683 TALLOC_FREE(subreq);
6684 if (!NT_STATUS_IS_OK(status)) {
6685 DEBUG(10, ("cli_notify_recv returned %s\n",
6686 nt_errstr(status)));
6687 tevent_req_nterror(req, status);
6691 for (i=0; i<num_changes; i++) {
6692 state->fn(changes[i].action, changes[i].name, state->priv);
6694 TALLOC_FREE(changes);
6696 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6697 0xffff, state->completion_filter,
6699 if (tevent_req_nomem(subreq, req)) {
6702 tevent_req_set_callback(subreq, swallow_notify_done, req);
6705 static bool print_notifies(uint32_t action, const char *name, void *priv)
6707 if (DEBUGLEVEL > 5) {
6708 d_printf("%d %s\n", (int)action, name);
6713 static void notify_bench_done(struct tevent_req *req)
6715 int *num_finished = (int *)tevent_req_callback_data_void(req);
6719 static bool run_notify_bench(int dummy)
6721 const char *dname = "\\notify-bench";
6722 struct tevent_context *ev;
6725 struct tevent_req *req1;
6726 struct tevent_req *req2 = NULL;
6727 int i, num_unc_names;
6728 int num_finished = 0;
6730 printf("starting notify-bench test\n");
6732 if (use_multishare_conn) {
6734 unc_list = file_lines_load(multishare_conn_fname,
6735 &num_unc_names, 0, NULL);
6736 if (!unc_list || num_unc_names <= 0) {
6737 d_printf("Failed to load unc names list from '%s'\n",
6738 multishare_conn_fname);
6741 TALLOC_FREE(unc_list);
6746 ev = tevent_context_init(talloc_tos());
6748 d_printf("tevent_context_init failed\n");
6752 for (i=0; i<num_unc_names; i++) {
6753 struct cli_state *cli;
6756 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6758 if (base_fname == NULL) {
6762 if (!torture_open_connection(&cli, i)) {
6766 status = cli_ntcreate(cli, dname, 0,
6767 MAXIMUM_ALLOWED_ACCESS,
6768 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6770 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6773 if (!NT_STATUS_IS_OK(status)) {
6774 d_printf("Could not create %s: %s\n", dname,
6779 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6780 FILE_NOTIFY_CHANGE_FILE_NAME |
6781 FILE_NOTIFY_CHANGE_DIR_NAME |
6782 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6783 FILE_NOTIFY_CHANGE_LAST_WRITE,
6784 false, print_notifies, NULL);
6786 d_printf("Could not create notify request\n");
6790 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6791 base_fname, 10, torture_numops);
6793 d_printf("Could not create createdels request\n");
6796 TALLOC_FREE(base_fname);
6798 tevent_req_set_callback(req2, notify_bench_done,
6802 while (num_finished < num_unc_names) {
6804 ret = tevent_loop_once(ev);
6806 d_printf("tevent_loop_once failed\n");
6811 if (!tevent_req_poll(req2, ev)) {
6812 d_printf("tevent_req_poll failed\n");
6815 status = torture_createdels_recv(req2);
6816 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6821 static bool run_mangle1(int dummy)
6823 struct cli_state *cli;
6824 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6828 time_t change_time, access_time, write_time;
6832 printf("starting mangle1 test\n");
6833 if (!torture_open_connection(&cli, 0)) {
6837 cli_sockopt(cli, sockops);
6839 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6840 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
6842 if (!NT_STATUS_IS_OK(status)) {
6843 d_printf("open %s failed: %s\n", fname, nt_errstr(status));
6846 cli_close(cli, fnum);
6848 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6849 if (!NT_STATUS_IS_OK(status)) {
6850 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6854 d_printf("alt_name: %s\n", alt_name);
6856 status = cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum);
6857 if (!NT_STATUS_IS_OK(status)) {
6858 d_printf("cli_open(%s) failed: %s\n", alt_name,
6862 cli_close(cli, fnum);
6864 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6865 &write_time, &size, &mode);
6866 if (!NT_STATUS_IS_OK(status)) {
6867 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6875 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6877 size_t *to_pull = (size_t *)priv;
6878 size_t thistime = *to_pull;
6880 thistime = MIN(thistime, n);
6881 if (thistime == 0) {
6885 memset(buf, 0, thistime);
6886 *to_pull -= thistime;
6890 static bool run_windows_write(int dummy)
6892 struct cli_state *cli1;
6896 const char *fname = "\\writetest.txt";
6897 struct timeval start_time;
6902 printf("starting windows_write test\n");
6903 if (!torture_open_connection(&cli1, 0)) {
6907 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
6908 if (!NT_STATUS_IS_OK(status)) {
6909 printf("open failed (%s)\n", nt_errstr(status));
6913 cli_sockopt(cli1, sockops);
6915 start_time = timeval_current();
6917 for (i=0; i<torture_numops; i++) {
6919 off_t start = i * torture_blocksize;
6920 size_t to_pull = torture_blocksize - 1;
6922 status = cli_writeall(cli1, fnum, 0, &c,
6923 start + torture_blocksize - 1, 1, NULL);
6924 if (!NT_STATUS_IS_OK(status)) {
6925 printf("cli_write failed: %s\n", nt_errstr(status));
6929 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6930 null_source, &to_pull);
6931 if (!NT_STATUS_IS_OK(status)) {
6932 printf("cli_push returned: %s\n", nt_errstr(status));
6937 seconds = timeval_elapsed(&start_time);
6938 kbytes = (double)torture_blocksize * torture_numops;
6941 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6942 (double)seconds, (int)(kbytes/seconds));
6946 cli_close(cli1, fnum);
6947 cli_unlink(cli1, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
6948 torture_close_connection(cli1);
6952 static bool run_cli_echo(int dummy)
6954 struct cli_state *cli;
6957 printf("starting cli_echo test\n");
6958 if (!torture_open_connection(&cli, 0)) {
6961 cli_sockopt(cli, sockops);
6963 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6965 d_printf("cli_echo returned %s\n", nt_errstr(status));
6967 torture_close_connection(cli);
6968 return NT_STATUS_IS_OK(status);
6971 static bool run_uid_regression_test(int dummy)
6973 static struct cli_state *cli;
6976 bool correct = True;
6979 printf("starting uid regression test\n");
6981 if (!torture_open_connection(&cli, 0)) {
6985 cli_sockopt(cli, sockops);
6987 /* Ok - now save then logoff our current user. */
6988 old_vuid = cli->vuid;
6990 status = cli_ulogoff(cli);
6991 if (!NT_STATUS_IS_OK(status)) {
6992 d_printf("(%s) cli_ulogoff failed: %s\n",
6993 __location__, nt_errstr(status));
6998 cli->vuid = old_vuid;
7000 /* Try an operation. */
7001 status = cli_mkdir(cli, "\\uid_reg_test");
7002 if (NT_STATUS_IS_OK(status)) {
7003 d_printf("(%s) cli_mkdir succeeded\n",
7008 /* Should be bad uid. */
7009 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
7010 NT_STATUS_USER_SESSION_DELETED)) {
7016 old_cnum = cli->cnum;
7018 /* Now try a SMBtdis with the invald vuid set to zero. */
7021 /* This should succeed. */
7022 status = cli_tdis(cli);
7024 if (NT_STATUS_IS_OK(status)) {
7025 d_printf("First tdis with invalid vuid should succeed.\n");
7027 d_printf("First tdis failed (%s)\n", nt_errstr(status));
7032 cli->vuid = old_vuid;
7033 cli->cnum = old_cnum;
7035 /* This should fail. */
7036 status = cli_tdis(cli);
7037 if (NT_STATUS_IS_OK(status)) {
7038 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
7042 /* Should be bad tid. */
7043 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
7044 NT_STATUS_NETWORK_NAME_DELETED)) {
7050 cli_rmdir(cli, "\\uid_reg_test");
7059 static const char *illegal_chars = "*\\/?<>|\":";
7060 static char force_shortname_chars[] = " +,.[];=\177";
7062 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
7063 const char *mask, void *state)
7065 struct cli_state *pcli = (struct cli_state *)state;
7067 NTSTATUS status = NT_STATUS_OK;
7069 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
7071 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
7072 return NT_STATUS_OK;
7074 if (finfo->mode & FILE_ATTRIBUTE_DIRECTORY) {
7075 status = cli_rmdir(pcli, fname);
7076 if (!NT_STATUS_IS_OK(status)) {
7077 printf("del_fn: failed to rmdir %s\n,", fname );
7080 status = cli_unlink(pcli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7081 if (!NT_STATUS_IS_OK(status)) {
7082 printf("del_fn: failed to unlink %s\n,", fname );
7094 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
7095 const char *name, void *state)
7097 struct sn_state *s = (struct sn_state *)state;
7101 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
7102 i, finfo->name, finfo->short_name);
7105 if (strchr(force_shortname_chars, i)) {
7106 if (!finfo->short_name[0]) {
7107 /* Shortname not created when it should be. */
7108 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
7109 __location__, finfo->name, i);
7112 } else if (finfo->short_name[0]){
7113 /* Shortname created when it should not be. */
7114 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
7115 __location__, finfo->short_name, finfo->name);
7119 return NT_STATUS_OK;
7122 static bool run_shortname_test(int dummy)
7124 static struct cli_state *cli;
7125 bool correct = True;
7131 printf("starting shortname test\n");
7133 if (!torture_open_connection(&cli, 0)) {
7137 cli_sockopt(cli, sockops);
7139 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7140 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7141 cli_rmdir(cli, "\\shortname");
7143 status = cli_mkdir(cli, "\\shortname");
7144 if (!NT_STATUS_IS_OK(status)) {
7145 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
7146 __location__, nt_errstr(status));
7151 strlcpy(fname, "\\shortname\\", sizeof(fname));
7152 strlcat(fname, "test .txt", sizeof(fname));
7156 for (i = 32; i < 128; i++) {
7157 uint16_t fnum = (uint16_t)-1;
7161 if (strchr(illegal_chars, i)) {
7166 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
7167 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
7168 if (!NT_STATUS_IS_OK(status)) {
7169 d_printf("(%s) cli_nt_create of %s failed: %s\n",
7170 __location__, fname, nt_errstr(status));
7174 cli_close(cli, fnum);
7177 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
7179 if (s.matched != 1) {
7180 d_printf("(%s) failed to list %s: %s\n",
7181 __location__, fname, cli_errstr(cli));
7186 status = cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7187 if (!NT_STATUS_IS_OK(status)) {
7188 d_printf("(%s) failed to delete %s: %s\n",
7189 __location__, fname, nt_errstr(status));
7202 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
7203 cli_list(cli, "\\shortname\\*", FILE_ATTRIBUTE_DIRECTORY, shortname_del_fn, cli);
7204 cli_rmdir(cli, "\\shortname");
7205 torture_close_connection(cli);
7209 static void pagedsearch_cb(struct tevent_req *req)
7212 struct tldap_message *msg;
7215 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
7216 if (rc != TLDAP_SUCCESS) {
7217 d_printf("tldap_search_paged_recv failed: %s\n",
7218 tldap_err2string(rc));
7221 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
7225 if (!tldap_entry_dn(msg, &dn)) {
7226 d_printf("tldap_entry_dn failed\n");
7229 d_printf("%s\n", dn);
7233 static bool run_tldap(int dummy)
7235 struct tldap_context *ld;
7238 struct sockaddr_storage addr;
7239 struct tevent_context *ev;
7240 struct tevent_req *req;
7244 if (!resolve_name(host, &addr, 0, false)) {
7245 d_printf("could not find host %s\n", host);
7248 status = open_socket_out(&addr, 389, 9999, &fd);
7249 if (!NT_STATUS_IS_OK(status)) {
7250 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
7254 ld = tldap_context_create(talloc_tos(), fd);
7257 d_printf("tldap_context_create failed\n");
7261 rc = tldap_fetch_rootdse(ld);
7262 if (rc != TLDAP_SUCCESS) {
7263 d_printf("tldap_fetch_rootdse failed: %s\n",
7264 tldap_errstr(talloc_tos(), ld, rc));
7268 basedn = tldap_talloc_single_attribute(
7269 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
7270 if (basedn == NULL) {
7271 d_printf("no defaultNamingContext\n");
7274 d_printf("defaultNamingContext: %s\n", basedn);
7276 ev = tevent_context_init(talloc_tos());
7278 d_printf("tevent_context_init failed\n");
7282 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
7283 TLDAP_SCOPE_SUB, "(objectclass=*)",
7285 NULL, 0, NULL, 0, 0, 0, 0, 5);
7287 d_printf("tldap_search_paged_send failed\n");
7290 tevent_req_set_callback(req, pagedsearch_cb, NULL);
7292 tevent_req_poll(req, ev);
7296 /* test search filters against rootDSE */
7297 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
7298 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
7300 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
7301 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
7302 talloc_tos(), NULL, NULL);
7303 if (rc != TLDAP_SUCCESS) {
7304 d_printf("tldap_search with complex filter failed: %s\n",
7305 tldap_errstr(talloc_tos(), ld, rc));
7313 /* Torture test to ensure no regression of :
7314 https://bugzilla.samba.org/show_bug.cgi?id=7084
7317 static bool run_dir_createtime(int dummy)
7319 struct cli_state *cli;
7320 const char *dname = "\\testdir";
7321 const char *fname = "\\testdir\\testfile";
7323 struct timespec create_time;
7324 struct timespec create_time1;
7328 if (!torture_open_connection(&cli, 0)) {
7332 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7333 cli_rmdir(cli, dname);
7335 status = cli_mkdir(cli, dname);
7336 if (!NT_STATUS_IS_OK(status)) {
7337 printf("mkdir failed: %s\n", nt_errstr(status));
7341 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
7343 if (!NT_STATUS_IS_OK(status)) {
7344 printf("cli_qpathinfo2 returned %s\n",
7349 /* Sleep 3 seconds, then create a file. */
7352 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
7354 if (!NT_STATUS_IS_OK(status)) {
7355 printf("cli_open failed: %s\n", nt_errstr(status));
7359 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
7361 if (!NT_STATUS_IS_OK(status)) {
7362 printf("cli_qpathinfo2 (2) returned %s\n",
7367 if (timespec_compare(&create_time1, &create_time)) {
7368 printf("run_dir_createtime: create time was updated (error)\n");
7370 printf("run_dir_createtime: create time was not updated (correct)\n");
7376 cli_unlink(cli, fname, FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7377 cli_rmdir(cli, dname);
7378 if (!torture_close_connection(cli)) {
7385 static bool run_streamerror(int dummy)
7387 struct cli_state *cli;
7388 const char *dname = "\\testdir";
7389 const char *streamname =
7390 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
7392 time_t change_time, access_time, write_time;
7394 uint16_t mode, fnum;
7397 if (!torture_open_connection(&cli, 0)) {
7401 cli_unlink(cli, "\\testdir\\*", FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN);
7402 cli_rmdir(cli, dname);
7404 status = cli_mkdir(cli, dname);
7405 if (!NT_STATUS_IS_OK(status)) {
7406 printf("mkdir failed: %s\n", nt_errstr(status));
7410 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7412 status = cli_nt_error(cli);
7414 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7415 printf("pathinfo returned %s, expected "
7416 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7421 status = cli_ntcreate(cli, streamname, 0x16,
7422 FILE_READ_DATA|FILE_READ_EA|
7423 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7424 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7425 FILE_OPEN, 0, 0, &fnum);
7427 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7428 printf("ntcreate returned %s, expected "
7429 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7435 cli_rmdir(cli, dname);
7439 static bool run_local_substitute(int dummy)
7443 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7444 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7445 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7446 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7447 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7448 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7449 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7450 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7452 /* Different captialization rules in sub_basic... */
7454 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7460 static bool run_local_base64(int dummy)
7465 for (i=1; i<2000; i++) {
7466 DATA_BLOB blob1, blob2;
7469 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7471 generate_random_buffer(blob1.data, blob1.length);
7473 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7475 d_fprintf(stderr, "base64_encode_data_blob failed "
7476 "for %d bytes\n", i);
7479 blob2 = base64_decode_data_blob(b64);
7482 if (data_blob_cmp(&blob1, &blob2)) {
7483 d_fprintf(stderr, "data_blob_cmp failed for %d "
7487 TALLOC_FREE(blob1.data);
7488 data_blob_free(&blob2);
7493 static bool run_local_gencache(int dummy)
7499 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7500 d_printf("%s: gencache_set() failed\n", __location__);
7504 if (!gencache_get("foo", NULL, NULL)) {
7505 d_printf("%s: gencache_get() failed\n", __location__);
7509 if (!gencache_get("foo", &val, &tm)) {
7510 d_printf("%s: gencache_get() failed\n", __location__);
7514 if (strcmp(val, "bar") != 0) {
7515 d_printf("%s: gencache_get() returned %s, expected %s\n",
7516 __location__, val, "bar");
7523 if (!gencache_del("foo")) {
7524 d_printf("%s: gencache_del() failed\n", __location__);
7527 if (gencache_del("foo")) {
7528 d_printf("%s: second gencache_del() succeeded\n",
7533 if (gencache_get("foo", &val, &tm)) {
7534 d_printf("%s: gencache_get() on deleted entry "
7535 "succeeded\n", __location__);
7539 blob = data_blob_string_const_null("bar");
7540 tm = time(NULL) + 60;
7542 if (!gencache_set_data_blob("foo", &blob, tm)) {
7543 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7547 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7548 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7552 if (strcmp((const char *)blob.data, "bar") != 0) {
7553 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7554 __location__, (const char *)blob.data, "bar");
7555 data_blob_free(&blob);
7559 data_blob_free(&blob);
7561 if (!gencache_del("foo")) {
7562 d_printf("%s: gencache_del() failed\n", __location__);
7565 if (gencache_del("foo")) {
7566 d_printf("%s: second gencache_del() succeeded\n",
7571 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7572 d_printf("%s: gencache_get_data_blob() on deleted entry "
7573 "succeeded\n", __location__);
7580 static bool rbt_testval(struct db_context *db, const char *key,
7583 struct db_record *rec;
7584 TDB_DATA data = string_tdb_data(value);
7588 rec = db->fetch_locked(db, db, string_tdb_data(key));
7590 d_fprintf(stderr, "fetch_locked failed\n");
7593 status = rec->store(rec, data, 0);
7594 if (!NT_STATUS_IS_OK(status)) {
7595 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7600 rec = db->fetch_locked(db, db, string_tdb_data(key));
7602 d_fprintf(stderr, "second fetch_locked failed\n");
7605 if ((rec->value.dsize != data.dsize)
7606 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7607 d_fprintf(stderr, "Got wrong data back\n");
7617 static bool run_local_rbtree(int dummy)
7619 struct db_context *db;
7623 db = db_open_rbt(NULL);
7626 d_fprintf(stderr, "db_open_rbt failed\n");
7630 for (i=0; i<1000; i++) {
7633 if (asprintf(&key, "key%ld", random()) == -1) {
7636 if (asprintf(&value, "value%ld", random()) == -1) {
7641 if (!rbt_testval(db, key, value)) {
7648 if (asprintf(&value, "value%ld", random()) == -1) {
7653 if (!rbt_testval(db, key, value)) {
7672 local test for character set functions
7674 This is a very simple test for the functionality in convert_string_error()
7676 static bool run_local_convert_string(int dummy)
7678 TALLOC_CTX *tmp_ctx = talloc_new(NULL);
7679 const char *test_strings[2] = { "March", "M\303\244rz" };
7683 for (i=0; i<2; i++) {
7684 const char *str = test_strings[i];
7685 int len = strlen(str);
7686 size_t converted_size;
7689 memset(dst, 'X', sizeof(dst));
7691 /* first try with real source length */
7692 ret = convert_string_error(CH_UNIX, CH_UTF8,
7697 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7701 if (converted_size != len) {
7702 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7703 str, len, (int)converted_size);
7707 if (strncmp(str, dst, converted_size) != 0) {
7708 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7712 if (strlen(str) != converted_size) {
7713 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7714 (int)strlen(str), (int)converted_size);
7718 if (dst[converted_size] != 'X') {
7719 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7723 /* now with srclen==-1, this causes the nul to be
7725 ret = convert_string_error(CH_UNIX, CH_UTF8,
7730 d_fprintf(stderr, "Failed to convert '%s' to CH_DISPLAY\n", str);
7734 if (converted_size != len+1) {
7735 d_fprintf(stderr, "Converted size of '%s' should be %d - got %d\n",
7736 str, len, (int)converted_size);
7740 if (strncmp(str, dst, converted_size) != 0) {
7741 d_fprintf(stderr, "Expected '%s' to match '%s'\n", str, dst);
7745 if (len+1 != converted_size) {
7746 d_fprintf(stderr, "Expected '%s' length %d - got %d\n", str,
7747 len+1, (int)converted_size);
7751 if (dst[converted_size] != 'X') {
7752 d_fprintf(stderr, "Expected no termination of '%s'\n", dst);
7759 TALLOC_FREE(tmp_ctx);
7762 TALLOC_FREE(tmp_ctx);
7767 struct talloc_dict_test {
7771 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7773 int *count = (int *)priv;
7778 static bool run_local_talloc_dict(int dummy)
7780 struct talloc_dict *dict;
7781 struct talloc_dict_test *t;
7784 dict = talloc_dict_init(talloc_tos());
7789 t = talloc(talloc_tos(), struct talloc_dict_test);
7796 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7801 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7814 static bool run_local_string_to_sid(int dummy) {
7817 if (string_to_sid(&sid, "S--1-5-32-545")) {
7818 printf("allowing S--1-5-32-545\n");
7821 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7822 printf("allowing S-1-5-32-+545\n");
7825 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")) {
7826 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7829 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7830 printf("allowing S-1-5-32-545-abc\n");
7833 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7834 printf("could not parse S-1-5-32-545\n");
7837 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7838 printf("mis-parsed S-1-5-32-545 as %s\n",
7839 sid_string_tos(&sid));
7845 static bool run_local_binary_to_sid(int dummy) {
7846 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7847 static const char good_binary_sid[] = {
7848 0x1, /* revision number */
7850 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7851 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7852 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7853 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7854 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7855 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7856 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7857 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7858 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7859 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7860 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7861 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7862 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7863 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7864 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7865 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7868 static const char long_binary_sid[] = {
7869 0x1, /* revision number */
7871 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7872 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7873 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7874 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7875 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7876 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7877 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7878 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7879 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7880 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7881 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7882 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7883 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7884 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7885 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7886 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7887 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7888 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7889 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7892 static const char long_binary_sid2[] = {
7893 0x1, /* revision number */
7895 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7896 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7897 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7898 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7899 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7900 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7901 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7902 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7903 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7904 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7905 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7906 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7907 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7908 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7909 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7910 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7911 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7912 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7913 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7914 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7915 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7916 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7917 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7918 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7919 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7920 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7921 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7922 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7923 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7924 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7925 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7926 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7927 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7930 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7933 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7936 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7942 /* Split a path name into filename and stream name components. Canonicalise
7943 * such that an implicit $DATA token is always explicit.
7945 * The "specification" of this function can be found in the
7946 * run_local_stream_name() function in torture.c, I've tried those
7947 * combinations against a W2k3 server.
7950 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7951 char **pbase, char **pstream)
7954 char *stream = NULL;
7955 char *sname; /* stream name */
7956 const char *stype; /* stream type */
7958 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7960 sname = strchr_m(fname, ':');
7962 if (lp_posix_pathnames() || (sname == NULL)) {
7963 if (pbase != NULL) {
7964 base = talloc_strdup(mem_ctx, fname);
7965 NT_STATUS_HAVE_NO_MEMORY(base);
7970 if (pbase != NULL) {
7971 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7972 NT_STATUS_HAVE_NO_MEMORY(base);
7977 stype = strchr_m(sname, ':');
7979 if (stype == NULL) {
7980 sname = talloc_strdup(mem_ctx, sname);
7984 if (StrCaseCmp(stype, ":$DATA") != 0) {
7986 * If there is an explicit stream type, so far we only
7987 * allow $DATA. Is there anything else allowed? -- vl
7989 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7991 return NT_STATUS_OBJECT_NAME_INVALID;
7993 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7997 if (sname == NULL) {
7999 return NT_STATUS_NO_MEMORY;
8002 if (sname[0] == '\0') {
8004 * no stream name, so no stream
8009 if (pstream != NULL) {
8010 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
8011 if (stream == NULL) {
8014 return NT_STATUS_NO_MEMORY;
8017 * upper-case the type field
8019 strupper_m(strchr_m(stream, ':')+1);
8023 if (pbase != NULL) {
8026 if (pstream != NULL) {
8029 return NT_STATUS_OK;
8032 static bool test_stream_name(const char *fname, const char *expected_base,
8033 const char *expected_stream,
8034 NTSTATUS expected_status)
8038 char *stream = NULL;
8040 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
8041 if (!NT_STATUS_EQUAL(status, expected_status)) {
8045 if (!NT_STATUS_IS_OK(status)) {
8049 if (base == NULL) goto error;
8051 if (strcmp(expected_base, base) != 0) goto error;
8053 if ((expected_stream != NULL) && (stream == NULL)) goto error;
8054 if ((expected_stream == NULL) && (stream != NULL)) goto error;
8056 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
8060 TALLOC_FREE(stream);
8064 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
8065 fname, expected_base ? expected_base : "<NULL>",
8066 expected_stream ? expected_stream : "<NULL>",
8067 nt_errstr(expected_status));
8068 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
8069 base ? base : "<NULL>", stream ? stream : "<NULL>",
8072 TALLOC_FREE(stream);
8076 static bool run_local_stream_name(int dummy)
8080 ret &= test_stream_name(
8081 "bla", "bla", NULL, NT_STATUS_OK);
8082 ret &= test_stream_name(
8083 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
8084 ret &= test_stream_name(
8085 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8086 ret &= test_stream_name(
8087 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
8088 ret &= test_stream_name(
8089 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
8090 ret &= test_stream_name(
8091 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
8092 ret &= test_stream_name(
8093 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
8094 ret &= test_stream_name(
8095 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
8100 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
8102 if (a.length != b.length) {
8103 printf("a.length=%d != b.length=%d\n",
8104 (int)a.length, (int)b.length);
8107 if (memcmp(a.data, b.data, a.length) != 0) {
8108 printf("a.data and b.data differ\n");
8114 static bool run_local_memcache(int dummy)
8116 struct memcache *cache;
8118 DATA_BLOB d1, d2, d3;
8119 DATA_BLOB v1, v2, v3;
8121 TALLOC_CTX *mem_ctx;
8123 size_t size1, size2;
8126 cache = memcache_init(NULL, 100);
8128 if (cache == NULL) {
8129 printf("memcache_init failed\n");
8133 d1 = data_blob_const("d1", 2);
8134 d2 = data_blob_const("d2", 2);
8135 d3 = data_blob_const("d3", 2);
8137 k1 = data_blob_const("d1", 2);
8138 k2 = data_blob_const("d2", 2);
8140 memcache_add(cache, STAT_CACHE, k1, d1);
8141 memcache_add(cache, GETWD_CACHE, k2, d2);
8143 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
8144 printf("could not find k1\n");
8147 if (!data_blob_equal(d1, v1)) {
8151 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8152 printf("could not find k2\n");
8155 if (!data_blob_equal(d2, v2)) {
8159 memcache_add(cache, STAT_CACHE, k1, d3);
8161 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
8162 printf("could not find replaced k1\n");
8165 if (!data_blob_equal(d3, v3)) {
8169 memcache_add(cache, GETWD_CACHE, k1, d1);
8171 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
8172 printf("Did find k2, should have been purged\n");
8178 cache = memcache_init(NULL, 0);
8180 mem_ctx = talloc_init("foo");
8182 str1 = talloc_strdup(mem_ctx, "string1");
8183 str2 = talloc_strdup(mem_ctx, "string2");
8185 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8186 data_blob_string_const("torture"), &str1);
8187 size1 = talloc_total_size(cache);
8189 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
8190 data_blob_string_const("torture"), &str2);
8191 size2 = talloc_total_size(cache);
8193 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
8195 if (size2 > size1) {
8196 printf("memcache leaks memory!\n");
8206 static void wbclient_done(struct tevent_req *req)
8209 struct winbindd_response *wb_resp;
8210 int *i = (int *)tevent_req_callback_data_void(req);
8212 wbc_err = wb_trans_recv(req, req, &wb_resp);
8215 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
8218 static bool run_local_wbclient(int dummy)
8220 struct event_context *ev;
8221 struct wb_context **wb_ctx;
8222 struct winbindd_request wb_req;
8223 bool result = false;
8226 BlockSignals(True, SIGPIPE);
8228 ev = tevent_context_init_byname(talloc_tos(), "epoll");
8233 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
8234 if (wb_ctx == NULL) {
8238 ZERO_STRUCT(wb_req);
8239 wb_req.cmd = WINBINDD_PING;
8241 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
8243 for (i=0; i<nprocs; i++) {
8244 wb_ctx[i] = wb_context_init(ev, NULL);
8245 if (wb_ctx[i] == NULL) {
8248 for (j=0; j<torture_numops; j++) {
8249 struct tevent_req *req;
8250 req = wb_trans_send(ev, ev, wb_ctx[i],
8251 (j % 2) == 0, &wb_req);
8255 tevent_req_set_callback(req, wbclient_done, &i);
8261 while (i < nprocs * torture_numops) {
8262 event_loop_once(ev);
8271 static void getaddrinfo_finished(struct tevent_req *req)
8273 char *name = (char *)tevent_req_callback_data_void(req);
8274 struct addrinfo *ainfo;
8277 res = getaddrinfo_recv(req, &ainfo);
8279 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
8282 d_printf("gai(%s) succeeded\n", name);
8283 freeaddrinfo(ainfo);
8286 static bool run_getaddrinfo_send(int dummy)
8288 TALLOC_CTX *frame = talloc_stackframe();
8289 struct fncall_context *ctx;
8290 struct tevent_context *ev;
8291 bool result = false;
8292 const char *names[4] = { "www.samba.org", "notfound.samba.org",
8293 "www.slashdot.org", "heise.de" };
8294 struct tevent_req *reqs[4];
8297 ev = event_context_init(frame);
8302 ctx = fncall_context_init(frame, 4);
8304 for (i=0; i<ARRAY_SIZE(names); i++) {
8305 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
8307 if (reqs[i] == NULL) {
8310 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
8311 discard_const_p(void, names[i]));
8314 for (i=0; i<ARRAY_SIZE(reqs); i++) {
8315 tevent_loop_once(ev);
8324 static bool dbtrans_inc(struct db_context *db)
8326 struct db_record *rec;
8331 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8333 printf(__location__ "fetch_lock failed\n");
8337 if (rec->value.dsize != sizeof(uint32_t)) {
8338 printf(__location__ "value.dsize = %d\n",
8339 (int)rec->value.dsize);
8343 val = (uint32_t *)rec->value.dptr;
8346 status = rec->store(rec, make_tdb_data((uint8_t *)val,
8349 if (!NT_STATUS_IS_OK(status)) {
8350 printf(__location__ "store failed: %s\n",
8361 static bool run_local_dbtrans(int dummy)
8363 struct db_context *db;
8364 struct db_record *rec;
8369 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
8370 O_RDWR|O_CREAT, 0600);
8372 printf("Could not open transtest.db\n");
8376 res = db->transaction_start(db);
8378 printf(__location__ "transaction_start failed\n");
8382 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
8384 printf(__location__ "fetch_lock failed\n");
8388 if (rec->value.dptr == NULL) {
8390 status = rec->store(
8391 rec, make_tdb_data((uint8_t *)&initial,
8394 if (!NT_STATUS_IS_OK(status)) {
8395 printf(__location__ "store returned %s\n",
8403 res = db->transaction_commit(db);
8405 printf(__location__ "transaction_commit failed\n");
8413 res = db->transaction_start(db);
8415 printf(__location__ "transaction_start failed\n");
8419 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
8420 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8424 for (i=0; i<10; i++) {
8425 if (!dbtrans_inc(db)) {
8430 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
8431 printf(__location__ "dbwrap_fetch_uint32 failed\n");
8435 if (val2 != val + 10) {
8436 printf(__location__ "val=%d, val2=%d\n",
8437 (int)val, (int)val2);
8441 printf("val2=%d\r", val2);
8443 res = db->transaction_commit(db);
8445 printf(__location__ "transaction_commit failed\n");
8455 * Just a dummy test to be run under a debugger. There's no real way
8456 * to inspect the tevent_select specific function from outside of
8460 static bool run_local_tevent_select(int dummy)
8462 struct tevent_context *ev;
8463 struct tevent_fd *fd1, *fd2;
8464 bool result = false;
8466 ev = tevent_context_init_byname(NULL, "select");
8468 d_fprintf(stderr, "tevent_context_init_byname failed\n");
8472 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
8474 d_fprintf(stderr, "tevent_add_fd failed\n");
8477 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
8479 d_fprintf(stderr, "tevent_add_fd failed\n");
8484 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
8486 d_fprintf(stderr, "tevent_add_fd failed\n");
8496 static double create_procs(bool (*fn)(int), bool *result)
8499 volatile pid_t *child_status;
8500 volatile bool *child_status_out;
8503 struct timeval start;
8507 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8508 if (!child_status) {
8509 printf("Failed to setup shared memory\n");
8513 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8514 if (!child_status_out) {
8515 printf("Failed to setup result status shared memory\n");
8519 for (i = 0; i < nprocs; i++) {
8520 child_status[i] = 0;
8521 child_status_out[i] = True;
8524 start = timeval_current();
8526 for (i=0;i<nprocs;i++) {
8529 pid_t mypid = getpid();
8530 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8532 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8535 if (torture_open_connection(¤t_cli, i)) break;
8537 printf("pid %d failed to start\n", (int)getpid());
8543 child_status[i] = getpid();
8545 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8547 child_status_out[i] = fn(i);
8554 for (i=0;i<nprocs;i++) {
8555 if (child_status[i]) synccount++;
8557 if (synccount == nprocs) break;
8559 } while (timeval_elapsed(&start) < 30);
8561 if (synccount != nprocs) {
8562 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8564 return timeval_elapsed(&start);
8567 /* start the client load */
8568 start = timeval_current();
8570 for (i=0;i<nprocs;i++) {
8571 child_status[i] = 0;
8574 printf("%d clients started\n", nprocs);
8576 for (i=0;i<nprocs;i++) {
8577 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8582 for (i=0;i<nprocs;i++) {
8583 if (!child_status_out[i]) {
8587 return timeval_elapsed(&start);
8590 #define FLAG_MULTIPROC 1
8597 {"FDPASS", run_fdpasstest, 0},
8598 {"LOCK1", run_locktest1, 0},
8599 {"LOCK2", run_locktest2, 0},
8600 {"LOCK3", run_locktest3, 0},
8601 {"LOCK4", run_locktest4, 0},
8602 {"LOCK5", run_locktest5, 0},
8603 {"LOCK6", run_locktest6, 0},
8604 {"LOCK7", run_locktest7, 0},
8605 {"LOCK8", run_locktest8, 0},
8606 {"LOCK9", run_locktest9, 0},
8607 {"UNLINK", run_unlinktest, 0},
8608 {"BROWSE", run_browsetest, 0},
8609 {"ATTR", run_attrtest, 0},
8610 {"TRANS2", run_trans2test, 0},
8611 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8612 {"TORTURE",run_torture, FLAG_MULTIPROC},
8613 {"RANDOMIPC", run_randomipc, 0},
8614 {"NEGNOWAIT", run_negprot_nowait, 0},
8615 {"NBENCH", run_nbench, 0},
8616 {"NBENCH2", run_nbench2, 0},
8617 {"OPLOCK1", run_oplock1, 0},
8618 {"OPLOCK2", run_oplock2, 0},
8619 {"OPLOCK3", run_oplock3, 0},
8620 {"OPLOCK4", run_oplock4, 0},
8621 {"DIR", run_dirtest, 0},
8622 {"DIR1", run_dirtest1, 0},
8623 {"DIR-CREATETIME", run_dir_createtime, 0},
8624 {"DENY1", torture_denytest1, 0},
8625 {"DENY2", torture_denytest2, 0},
8626 {"TCON", run_tcon_test, 0},
8627 {"TCONDEV", run_tcon_devtype_test, 0},
8628 {"RW1", run_readwritetest, 0},
8629 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8630 {"RW3", run_readwritelarge, 0},
8631 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8632 {"OPEN", run_opentest, 0},
8633 {"POSIX", run_simple_posix_open_test, 0},
8634 {"POSIX-APPEND", run_posix_append, 0},
8635 {"CASE-INSENSITIVE-CREATE", run_case_insensitive_create, 0},
8636 {"ASYNC-ECHO", run_async_echo, 0},
8637 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8638 { "SHORTNAME-TEST", run_shortname_test, 0},
8639 { "ADDRCHANGE", run_addrchange, 0},
8641 {"OPENATTR", run_openattrtest, 0},
8643 {"XCOPY", run_xcopy, 0},
8644 {"RENAME", run_rename, 0},
8645 {"DELETE", run_deletetest, 0},
8646 {"DELETE-LN", run_deletetest_ln, 0},
8647 {"PROPERTIES", run_properties, 0},
8648 {"MANGLE", torture_mangle, 0},
8649 {"MANGLE1", run_mangle1, 0},
8650 {"W2K", run_w2ktest, 0},
8651 {"TRANS2SCAN", torture_trans2_scan, 0},
8652 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8653 {"UTABLE", torture_utable, 0},
8654 {"CASETABLE", torture_casetable, 0},
8655 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8656 {"PIPE_NUMBER", run_pipe_number, 0},
8657 {"TCON2", run_tcon2_test, 0},
8658 {"IOCTL", torture_ioctl_test, 0},
8659 {"CHKPATH", torture_chkpath_test, 0},
8660 {"FDSESS", run_fdsesstest, 0},
8661 { "EATEST", run_eatest, 0},
8662 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8663 { "CHAIN1", run_chain1, 0},
8664 { "CHAIN2", run_chain2, 0},
8665 { "WINDOWS-WRITE", run_windows_write, 0},
8666 { "CLI_ECHO", run_cli_echo, 0},
8667 { "GETADDRINFO", run_getaddrinfo_send, 0},
8668 { "TLDAP", run_tldap },
8669 { "STREAMERROR", run_streamerror },
8670 { "NOTIFY-BENCH", run_notify_bench },
8671 { "BAD-NBT-SESSION", run_bad_nbt_session },
8672 { "SMB-ANY-CONNECT", run_smb_any_connect },
8673 { "NOTIFY-ONLINE", run_notify_online },
8674 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8675 { "LOCAL-GENCACHE", run_local_gencache, 0},
8676 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8677 { "LOCAL-BASE64", run_local_base64, 0},
8678 { "LOCAL-RBTREE", run_local_rbtree, 0},
8679 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8680 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8681 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8682 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8683 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8684 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8685 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8686 { "LOCAL-CONVERT-STRING", run_local_convert_string, 0},
8691 /****************************************************************************
8692 run a specified test or "ALL"
8693 ****************************************************************************/
8694 static bool run_test(const char *name)
8701 if (strequal(name,"ALL")) {
8702 for (i=0;torture_ops[i].name;i++) {
8703 run_test(torture_ops[i].name);
8708 for (i=0;torture_ops[i].name;i++) {
8709 fstr_sprintf(randomfname, "\\XX%x",
8710 (unsigned)random());
8712 if (strequal(name, torture_ops[i].name)) {
8714 printf("Running %s\n", name);
8715 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8716 t = create_procs(torture_ops[i].fn, &result);
8719 printf("TEST %s FAILED!\n", name);
8722 struct timeval start;
8723 start = timeval_current();
8724 if (!torture_ops[i].fn(0)) {
8726 printf("TEST %s FAILED!\n", name);
8728 t = timeval_elapsed(&start);
8730 printf("%s took %g secs\n\n", name, t);
8735 printf("Did not find a test named %s\n", name);
8743 static void usage(void)
8747 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8748 printf("Please use samba4 torture.\n\n");
8750 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8752 printf("\t-d debuglevel\n");
8753 printf("\t-U user%%pass\n");
8754 printf("\t-k use kerberos\n");
8755 printf("\t-N numprocs\n");
8756 printf("\t-n my_netbios_name\n");
8757 printf("\t-W workgroup\n");
8758 printf("\t-o num_operations\n");
8759 printf("\t-O socket_options\n");
8760 printf("\t-m maximum protocol\n");
8761 printf("\t-L use oplocks\n");
8762 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8763 printf("\t-A showall\n");
8764 printf("\t-p port\n");
8765 printf("\t-s seed\n");
8766 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8767 printf("\t-f filename filename to test\n");
8770 printf("tests are:");
8771 for (i=0;torture_ops[i].name;i++) {
8772 printf(" %s", torture_ops[i].name);
8776 printf("default test is ALL\n");
8781 /****************************************************************************
8783 ****************************************************************************/
8784 int main(int argc,char *argv[])
8790 bool correct = True;
8791 TALLOC_CTX *frame = talloc_stackframe();
8792 int seed = time(NULL);
8794 #ifdef HAVE_SETBUFFER
8795 setbuffer(stdout, NULL, 0);
8798 setup_logging("smbtorture", DEBUG_STDOUT);
8802 if (is_default_dyn_CONFIGFILE()) {
8803 if(getenv("SMB_CONF_PATH")) {
8804 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8807 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8814 for(p = argv[1]; *p; p++)
8818 if (strncmp(argv[1], "//", 2)) {
8822 fstrcpy(host, &argv[1][2]);
8823 p = strchr_m(&host[2],'/');
8828 fstrcpy(share, p+1);
8830 fstrcpy(myname, get_myname(talloc_tos()));
8832 fprintf(stderr, "Failed to get my hostname.\n");
8836 if (*username == 0 && getenv("LOGNAME")) {
8837 fstrcpy(username,getenv("LOGNAME"));
8843 fstrcpy(workgroup, lp_workgroup());
8845 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:f:"))
8849 port_to_use = atoi(optarg);
8852 seed = atoi(optarg);
8855 fstrcpy(workgroup,optarg);
8858 max_protocol = interpret_protocol(optarg, max_protocol);
8861 nprocs = atoi(optarg);
8864 torture_numops = atoi(optarg);
8867 lp_set_cmdline("log level", optarg);
8876 local_path = optarg;
8879 torture_showall = True;
8882 fstrcpy(myname, optarg);
8885 client_txt = optarg;
8892 use_kerberos = True;
8894 d_printf("No kerberos support compiled in\n");
8900 fstrcpy(username,optarg);
8901 p = strchr_m(username,'%');
8904 fstrcpy(password, p+1);
8909 fstrcpy(multishare_conn_fname, optarg);
8910 use_multishare_conn = True;
8913 torture_blocksize = atoi(optarg);
8916 test_filename = SMB_STRDUP(optarg);
8919 printf("Unknown option %c (%d)\n", (char)opt, opt);
8924 d_printf("using seed %d\n", seed);
8928 if(use_kerberos && !gotuser) gotpass = True;
8931 p = getpass("Password:");
8933 fstrcpy(password, p);
8938 printf("host=%s share=%s user=%s myname=%s\n",
8939 host, share, username, myname);
8941 if (argc == optind) {
8942 correct = run_test("ALL");
8944 for (i=optind;i<argc;i++) {
8945 if (!run_test(argv[i])) {