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 "wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/security.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
29 #include "nsswitch/winbind_client.h"
31 #include "talloc_dict.h"
32 #include "async_smb.h"
37 static fstring host, workgroup, share, password, username, myname;
38 static int max_protocol = PROTOCOL_NT1;
39 static const char *sockops="TCP_NODELAY";
41 static int port_to_use=0;
42 int torture_numops=100;
43 int torture_blocksize=1024*1024;
44 static int procnum; /* records process count number when forking */
45 static struct cli_state *current_cli;
46 static fstring randomfname;
47 static bool use_oplocks;
48 static bool use_level_II_oplocks;
49 static const char *client_txt = "client_oplocks.txt";
50 static bool use_kerberos;
51 static fstring multishare_conn_fname;
52 static bool use_multishare_conn = False;
53 static bool do_encrypt;
54 static const char *local_path = NULL;
55 static int signing_state = Undefined;
57 bool torture_showall = False;
59 static double create_procs(bool (*fn)(int), bool *result);
62 /* return a pointer to a anonymous shared memory segment of size "size"
63 which will persist across fork() but will disappear when all processes
66 The memory is not zeroed
68 This function uses system5 shared memory. It takes advantage of a property
69 that the memory is not destroyed if it is attached when the id is removed
71 void *shm_setup(int size)
77 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
79 printf("can't get shared memory\n");
82 shm_unlink("private");
83 if (ftruncate(shmid, size) == -1) {
84 printf("can't set shared memory size\n");
87 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
88 if (ret == MAP_FAILED) {
89 printf("can't map shared memory\n");
93 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
95 printf("can't get shared memory\n");
98 ret = (void *)shmat(shmid, 0, 0);
99 if (!ret || ret == (void *)-1) {
100 printf("can't attach to shared memory\n");
103 /* the following releases the ipc, but note that this process
104 and all its children will still have access to the memory, its
105 just that the shmid is no longer valid for other shm calls. This
106 means we don't leave behind lots of shm segments after we exit
108 See Stevens "advanced programming in unix env" for details
110 shmctl(shmid, IPC_RMID, 0);
116 /********************************************************************
117 Ensure a connection is encrypted.
118 ********************************************************************/
120 static bool force_cli_encryption(struct cli_state *c,
121 const char *sharename)
124 uint32 caplow, caphigh;
127 if (!SERVER_HAS_UNIX_CIFS(c)) {
128 d_printf("Encryption required and "
129 "server that doesn't support "
130 "UNIX extensions - failing connect\n");
134 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
136 if (!NT_STATUS_IS_OK(status)) {
137 d_printf("Encryption required and "
138 "can't get UNIX CIFS extensions "
139 "version from server: %s\n", nt_errstr(status));
143 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
144 d_printf("Encryption required and "
145 "share %s doesn't support "
146 "encryption.\n", sharename);
150 if (c->use_kerberos) {
151 status = cli_gss_smb_encryption_start(c);
153 status = cli_raw_ntlm_smb_encryption_start(c,
159 if (!NT_STATUS_IS_OK(status)) {
160 d_printf("Encryption required and "
161 "setup failed with error %s.\n",
170 static struct cli_state *open_nbt_connection(void)
172 struct nmb_name called, calling;
173 struct sockaddr_storage ss;
177 make_nmb_name(&calling, myname, 0x0);
178 make_nmb_name(&called , host, 0x20);
182 if (!(c = cli_initialise_ex(signing_state))) {
183 printf("Failed initialize cli_struct to connect with %s\n", host);
187 c->port = port_to_use;
189 status = cli_connect(c, host, &ss);
190 if (!NT_STATUS_IS_OK(status)) {
191 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
195 c->use_kerberos = use_kerberos;
197 c->timeout = 120000; /* set a really long timeout (2 minutes) */
198 if (use_oplocks) c->use_oplocks = True;
199 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
201 if (!cli_session_request(c, &calling, &called)) {
203 * Well, that failed, try *SMBSERVER ...
204 * However, we must reconnect as well ...
206 status = cli_connect(c, host, &ss);
207 if (!NT_STATUS_IS_OK(status)) {
208 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
212 make_nmb_name(&called, "*SMBSERVER", 0x20);
213 if (!cli_session_request(c, &calling, &called)) {
214 printf("%s rejected the session\n",host);
215 printf("We tried with a called name of %s & %s\n",
225 /****************************************************************************
226 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
227 ****************************************************************************/
229 static bool cli_bad_session_request(struct cli_state *cli,
230 struct nmb_name *calling, struct nmb_name *called)
237 memcpy(&(cli->calling), calling, sizeof(*calling));
238 memcpy(&(cli->called ), called , sizeof(*called ));
240 /* put in the destination name */
242 tmp = name_mangle(talloc_tos(), cli->called.name,
243 cli->called.name_type);
249 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
251 memcpy(p, tmp, namelen);
256 /* Deliberately corrupt the name len (first byte) */
261 tmp = name_mangle(talloc_tos(), cli->calling.name,
262 cli->calling.name_type);
268 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
270 memcpy(p, tmp, namelen);
274 /* Deliberately corrupt the name len (first byte) */
277 /* send a session request (RFC 1002) */
278 /* setup the packet length
279 * Remove four bytes from the length count, since the length
280 * field in the NBT Session Service header counts the number
281 * of bytes which follow. The cli_send_smb() function knows
282 * about this and accounts for those four bytes.
286 _smb_setlen(cli->outbuf,len);
287 SCVAL(cli->outbuf,0,0x81);
290 DEBUG(5,("Sent session request\n"));
292 if (!cli_receive_smb(cli))
295 if (CVAL(cli->inbuf,0) != 0x82) {
296 /* This is the wrong place to put the error... JRA. */
297 cli->rap_error = CVAL(cli->inbuf,4);
303 static struct cli_state *open_bad_nbt_connection(void)
305 struct nmb_name called, calling;
306 struct sockaddr_storage ss;
310 make_nmb_name(&calling, myname, 0x0);
311 make_nmb_name(&called , host, 0x20);
315 if (!(c = cli_initialise_ex(signing_state))) {
316 printf("Failed initialize cli_struct to connect with %s\n", host);
322 status = cli_connect(c, host, &ss);
323 if (!NT_STATUS_IS_OK(status)) {
324 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
328 c->timeout = 4000; /* set a short timeout (4 seconds) */
330 if (!cli_bad_session_request(c, &calling, &called)) {
331 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
339 /* Insert a NULL at the first separator of the given path and return a pointer
340 * to the remainder of the string.
343 terminate_path_at_separator(char * path)
351 if ((p = strchr_m(path, '/'))) {
356 if ((p = strchr_m(path, '\\'))) {
366 parse a //server/share type UNC name
368 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
369 char **hostname, char **sharename)
373 *hostname = *sharename = NULL;
375 if (strncmp(unc_name, "\\\\", 2) &&
376 strncmp(unc_name, "//", 2)) {
380 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
381 p = terminate_path_at_separator(*hostname);
384 *sharename = talloc_strdup(mem_ctx, p);
385 terminate_path_at_separator(*sharename);
388 if (*hostname && *sharename) {
392 TALLOC_FREE(*hostname);
393 TALLOC_FREE(*sharename);
397 static bool torture_open_connection_share(struct cli_state **c,
398 const char *hostname,
399 const char *sharename)
405 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
407 flags |= CLI_FULL_CONNECTION_OPLOCKS;
408 if (use_level_II_oplocks)
409 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
411 status = cli_full_connection(c, myname,
412 hostname, NULL, port_to_use,
415 password, flags, signing_state);
416 if (!NT_STATUS_IS_OK(status)) {
417 printf("failed to open share connection: //%s/%s port:%d - %s\n",
418 hostname, sharename, port_to_use, nt_errstr(status));
422 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
425 return force_cli_encryption(*c,
431 bool torture_open_connection(struct cli_state **c, int conn_index)
433 char **unc_list = NULL;
434 int num_unc_names = 0;
437 if (use_multishare_conn==True) {
439 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
440 if (!unc_list || num_unc_names <= 0) {
441 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
445 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
447 printf("Failed to parse UNC name %s\n",
448 unc_list[conn_index % num_unc_names]);
449 TALLOC_FREE(unc_list);
453 result = torture_open_connection_share(c, h, s);
455 /* h, s were copied earlier */
456 TALLOC_FREE(unc_list);
460 return torture_open_connection_share(c, host, share);
463 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
465 uint16 old_vuid = cli->vuid;
466 fstring old_user_name;
467 size_t passlen = strlen(password);
471 fstrcpy(old_user_name, cli->user_name);
473 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
477 *new_vuid = cli->vuid;
478 cli->vuid = old_vuid;
479 status = cli_set_username(cli, old_user_name);
480 if (!NT_STATUS_IS_OK(status)) {
487 bool torture_close_connection(struct cli_state *c)
492 status = cli_tdis(c);
493 if (!NT_STATUS_IS_OK(status)) {
494 printf("tdis failed (%s)\n", nt_errstr(status));
504 /* check if the server produced the expected error code */
505 static bool check_error(int line, struct cli_state *c,
506 uint8 eclass, uint32 ecode, NTSTATUS nterr)
508 if (cli_is_dos_error(c)) {
512 /* Check DOS error */
514 cli_dos_error(c, &cclass, &num);
516 if (eclass != cclass || ecode != num) {
517 printf("unexpected error code class=%d code=%d\n",
518 (int)cclass, (int)num);
519 printf(" expected %d/%d %s (line=%d)\n",
520 (int)eclass, (int)ecode, nt_errstr(nterr), line);
529 status = cli_nt_error(c);
531 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
532 printf("unexpected error code %s\n", nt_errstr(status));
533 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
542 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
544 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
545 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
551 static bool rw_torture(struct cli_state *c)
553 const char *lockfname = "\\torture.lck";
557 pid_t pid2, pid = getpid();
563 memset(buf, '\0', sizeof(buf));
565 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
567 if (!NT_STATUS_IS_OK(status)) {
568 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
570 if (!NT_STATUS_IS_OK(status)) {
571 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
575 for (i=0;i<torture_numops;i++) {
576 unsigned n = (unsigned)sys_random()%10;
578 printf("%d\r", i); fflush(stdout);
580 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
582 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
586 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
587 printf("open failed (%s)\n", cli_errstr(c));
592 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
593 printf("write failed (%s)\n", cli_errstr(c));
598 if (cli_write(c, fnum, 0, (char *)buf,
599 sizeof(pid)+(j*sizeof(buf)),
600 sizeof(buf)) != sizeof(buf)) {
601 printf("write failed (%s)\n", cli_errstr(c));
608 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
609 printf("read failed (%s)\n", cli_errstr(c));
614 printf("data corruption!\n");
618 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
619 printf("close failed (%s)\n", cli_errstr(c));
623 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
624 printf("unlink failed (%s)\n", cli_errstr(c));
628 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
629 printf("unlock failed (%s)\n", cli_errstr(c));
635 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
642 static bool run_torture(int dummy)
644 struct cli_state *cli;
649 cli_sockopt(cli, sockops);
651 ret = rw_torture(cli);
653 if (!torture_close_connection(cli)) {
660 static bool rw_torture3(struct cli_state *c, char *lockfname)
662 uint16_t fnum = (uint16_t)-1;
667 unsigned countprev = 0;
673 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
675 SIVAL(buf, i, sys_random());
680 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
681 DENY_NONE, &fnum))) {
682 printf("first open read/write of %s failed (%s)\n",
683 lockfname, cli_errstr(c));
689 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
691 status = cli_open(c, lockfname, O_RDONLY,
693 if (!NT_STATUS_IS_OK(status)) {
698 if (!NT_STATUS_IS_OK(status)) {
699 printf("second open read-only of %s failed (%s)\n",
700 lockfname, cli_errstr(c));
706 for (count = 0; count < sizeof(buf); count += sent)
708 if (count >= countprev) {
709 printf("%d %8d\r", i, count);
712 countprev += (sizeof(buf) / 20);
717 sent = ((unsigned)sys_random()%(20))+ 1;
718 if (sent > sizeof(buf) - count)
720 sent = sizeof(buf) - count;
723 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
724 printf("write failed (%s)\n", cli_errstr(c));
730 sent = cli_read(c, fnum, buf_rd+count, count,
734 printf("read failed offset:%d size:%ld (%s)\n",
735 count, (unsigned long)sizeof(buf)-count,
742 if (memcmp(buf_rd+count, buf+count, sent) != 0)
744 printf("read/write compare failed\n");
745 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
754 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
755 printf("close failed (%s)\n", cli_errstr(c));
762 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
764 const char *lockfname = "\\torture2.lck";
773 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
774 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
777 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
778 DENY_NONE, &fnum1))) {
779 printf("first open read/write of %s failed (%s)\n",
780 lockfname, cli_errstr(c1));
783 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
784 DENY_NONE, &fnum2))) {
785 printf("second open read-only of %s failed (%s)\n",
786 lockfname, cli_errstr(c2));
787 cli_close(c1, fnum1);
791 for (i=0;i<torture_numops;i++)
793 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
795 printf("%d\r", i); fflush(stdout);
798 generate_random_buffer((unsigned char *)buf, buf_size);
800 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
801 printf("write failed (%s)\n", cli_errstr(c1));
806 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
807 printf("read failed (%s)\n", cli_errstr(c2));
808 printf("read %d, expected %ld\n", (int)bytes_read,
809 (unsigned long)buf_size);
814 if (memcmp(buf_rd, buf, buf_size) != 0)
816 printf("read/write compare failed\n");
822 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
823 printf("close failed (%s)\n", cli_errstr(c2));
826 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
827 printf("close failed (%s)\n", cli_errstr(c1));
831 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
832 printf("unlink failed (%s)\n", cli_errstr(c1));
839 static bool run_readwritetest(int dummy)
841 struct cli_state *cli1, *cli2;
842 bool test1, test2 = False;
844 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
847 cli_sockopt(cli1, sockops);
848 cli_sockopt(cli2, sockops);
850 printf("starting readwritetest\n");
852 test1 = rw_torture2(cli1, cli2);
853 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
856 test2 = rw_torture2(cli1, cli1);
857 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
860 if (!torture_close_connection(cli1)) {
864 if (!torture_close_connection(cli2)) {
868 return (test1 && test2);
871 static bool run_readwritemulti(int dummy)
873 struct cli_state *cli;
878 cli_sockopt(cli, sockops);
880 printf("run_readwritemulti: fname %s\n", randomfname);
881 test = rw_torture3(cli, randomfname);
883 if (!torture_close_connection(cli)) {
890 static bool run_readwritelarge_internal(int max_xmit_k)
892 static struct cli_state *cli1;
894 const char *lockfname = "\\large.dat";
899 if (!torture_open_connection(&cli1, 0)) {
902 cli_sockopt(cli1, sockops);
903 memset(buf,'\0',sizeof(buf));
905 cli1->max_xmit = max_xmit_k*1024;
907 if (signing_state == Required) {
908 /* Horrible cheat to force
909 multiple signed outstanding
910 packets against a Samba server.
912 cli1->is_samba = false;
915 printf("starting readwritelarge_internal\n");
917 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
919 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
920 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
924 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
926 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
927 cli1, fnum1, NULL, &fsize, NULL, NULL,
928 NULL, NULL, NULL))) {
929 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
933 if (fsize == sizeof(buf))
934 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
935 (unsigned long)fsize);
937 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
938 (unsigned long)fsize);
942 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
943 printf("close failed (%s)\n", cli_errstr(cli1));
947 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
948 printf("unlink failed (%s)\n", cli_errstr(cli1));
952 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
953 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
957 cli1->max_xmit = 4*1024;
959 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
961 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
962 cli1, fnum1, NULL, &fsize, NULL, NULL,
963 NULL, NULL, NULL))) {
964 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
968 if (fsize == sizeof(buf))
969 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
970 (unsigned long)fsize);
972 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
973 (unsigned long)fsize);
978 /* ToDo - set allocation. JRA */
979 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
980 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
983 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
985 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
989 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
992 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
993 printf("close failed (%s)\n", cli_errstr(cli1));
997 if (!torture_close_connection(cli1)) {
1003 static bool run_readwritelarge(int dummy)
1005 return run_readwritelarge_internal(128);
1008 static bool run_readwritelarge_signtest(int dummy)
1011 signing_state = Required;
1012 ret = run_readwritelarge_internal(2);
1013 signing_state = Undefined;
1020 #define ival(s) strtol(s, NULL, 0)
1022 /* run a test that simulates an approximate netbench client load */
1023 static bool run_netbench(int client)
1025 struct cli_state *cli;
1030 const char *params[20];
1031 bool correct = True;
1037 cli_sockopt(cli, sockops);
1041 slprintf(cname,sizeof(cname)-1, "client%d", client);
1043 f = fopen(client_txt, "r");
1050 while (fgets(line, sizeof(line)-1, f)) {
1054 line[strlen(line)-1] = 0;
1056 /* printf("[%d] %s\n", line_count, line); */
1058 all_string_sub(line,"client1", cname, sizeof(line));
1060 /* parse the command parameters */
1061 params[0] = strtok_r(line, " ", &saveptr);
1063 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1067 if (i < 2) continue;
1069 if (!strncmp(params[0],"SMB", 3)) {
1070 printf("ERROR: You are using a dbench 1 load file\n");
1074 if (!strcmp(params[0],"NTCreateX")) {
1075 nb_createx(params[1], ival(params[2]), ival(params[3]),
1077 } else if (!strcmp(params[0],"Close")) {
1078 nb_close(ival(params[1]));
1079 } else if (!strcmp(params[0],"Rename")) {
1080 nb_rename(params[1], params[2]);
1081 } else if (!strcmp(params[0],"Unlink")) {
1082 nb_unlink(params[1]);
1083 } else if (!strcmp(params[0],"Deltree")) {
1084 nb_deltree(params[1]);
1085 } else if (!strcmp(params[0],"Rmdir")) {
1086 nb_rmdir(params[1]);
1087 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1088 nb_qpathinfo(params[1]);
1089 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1090 nb_qfileinfo(ival(params[1]));
1091 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1092 nb_qfsinfo(ival(params[1]));
1093 } else if (!strcmp(params[0],"FIND_FIRST")) {
1094 nb_findfirst(params[1]);
1095 } else if (!strcmp(params[0],"WriteX")) {
1096 nb_writex(ival(params[1]),
1097 ival(params[2]), ival(params[3]), ival(params[4]));
1098 } else if (!strcmp(params[0],"ReadX")) {
1099 nb_readx(ival(params[1]),
1100 ival(params[2]), ival(params[3]), ival(params[4]));
1101 } else if (!strcmp(params[0],"Flush")) {
1102 nb_flush(ival(params[1]));
1104 printf("Unknown operation %s\n", params[0]);
1112 if (!torture_close_connection(cli)) {
1120 /* run a test that simulates an approximate netbench client load */
1121 static bool run_nbench(int dummy)
1124 bool correct = True;
1130 signal(SIGALRM, nb_alarm);
1132 t = create_procs(run_netbench, &correct);
1135 printf("\nThroughput %g MB/sec\n",
1136 1.0e-6 * nbio_total() / t);
1142 This test checks for two things:
1144 1) correct support for retaining locks over a close (ie. the server
1145 must not use posix semantics)
1146 2) support for lock timeouts
1148 static bool run_locktest1(int dummy)
1150 struct cli_state *cli1, *cli2;
1151 const char *fname = "\\lockt1.lck";
1152 uint16_t fnum1, fnum2, fnum3;
1154 unsigned lock_timeout;
1156 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1159 cli_sockopt(cli1, sockops);
1160 cli_sockopt(cli2, sockops);
1162 printf("starting locktest1\n");
1164 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1166 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1167 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1170 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1171 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1174 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1175 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1179 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1180 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1185 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1186 printf("lock2 succeeded! This is a locking bug\n");
1189 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1190 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1194 lock_timeout = (1 + (random() % 20));
1195 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1197 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1198 printf("lock3 succeeded! This is a locking bug\n");
1201 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1202 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1206 if (ABS(t2 - t1) < lock_timeout-1) {
1207 printf("error: This server appears not to support timed lock requests\n");
1210 printf("server slept for %u seconds for a %u second timeout\n",
1211 (unsigned int)(t2-t1), lock_timeout);
1213 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1214 printf("close1 failed (%s)\n", cli_errstr(cli1));
1218 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1219 printf("lock4 succeeded! This is a locking bug\n");
1222 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1223 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1226 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1227 printf("close2 failed (%s)\n", cli_errstr(cli1));
1231 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1232 printf("close3 failed (%s)\n", cli_errstr(cli2));
1236 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1237 printf("unlink failed (%s)\n", cli_errstr(cli1));
1242 if (!torture_close_connection(cli1)) {
1246 if (!torture_close_connection(cli2)) {
1250 printf("Passed locktest1\n");
1255 this checks to see if a secondary tconx can use open files from an
1258 static bool run_tcon_test(int dummy)
1260 static struct cli_state *cli;
1261 const char *fname = "\\tcontest.tmp";
1263 uint16 cnum1, cnum2, cnum3;
1264 uint16 vuid1, vuid2;
1269 memset(buf, '\0', sizeof(buf));
1271 if (!torture_open_connection(&cli, 0)) {
1274 cli_sockopt(cli, sockops);
1276 printf("starting tcontest\n");
1278 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1280 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1281 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1288 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1289 printf("initial write failed (%s)", cli_errstr(cli));
1293 status = cli_tcon_andx(cli, share, "?????",
1294 password, strlen(password)+1);
1295 if (!NT_STATUS_IS_OK(status)) {
1296 printf("%s refused 2nd tree connect (%s)\n", host,
1303 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1304 vuid2 = cli->vuid + 1;
1306 /* try a write with the wrong tid */
1309 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1310 printf("* server allows write with wrong TID\n");
1313 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1317 /* try a write with an invalid tid */
1320 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1321 printf("* server allows write with invalid TID\n");
1324 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1327 /* try a write with an invalid vuid */
1331 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1332 printf("* server allows write with invalid VUID\n");
1335 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1341 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1342 printf("close failed (%s)\n", cli_errstr(cli));
1348 status = cli_tdis(cli);
1349 if (!NT_STATUS_IS_OK(status)) {
1350 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1356 if (!torture_close_connection(cli)) {
1365 checks for old style tcon support
1367 static bool run_tcon2_test(int dummy)
1369 static struct cli_state *cli;
1370 uint16 cnum, max_xmit;
1374 if (!torture_open_connection(&cli, 0)) {
1377 cli_sockopt(cli, sockops);
1379 printf("starting tcon2 test\n");
1381 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1385 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 printf("tcon2 failed : %s\n", cli_errstr(cli));
1390 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1391 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1394 if (!torture_close_connection(cli)) {
1398 printf("Passed tcon2 test\n");
1402 static bool tcon_devtest(struct cli_state *cli,
1403 const char *myshare, const char *devtype,
1404 const char *return_devtype,
1405 NTSTATUS expected_error)
1410 status = cli_tcon_andx(cli, myshare, devtype,
1411 password, strlen(password)+1);
1413 if (NT_STATUS_IS_OK(expected_error)) {
1414 if (NT_STATUS_IS_OK(status)) {
1415 if (strcmp(cli->dev, return_devtype) == 0) {
1418 printf("tconX to share %s with type %s "
1419 "succeeded but returned the wrong "
1420 "device type (got [%s] but should have got [%s])\n",
1421 myshare, devtype, cli->dev, return_devtype);
1425 printf("tconX to share %s with type %s "
1426 "should have succeeded but failed\n",
1432 if (NT_STATUS_IS_OK(status)) {
1433 printf("tconx to share %s with type %s "
1434 "should have failed but succeeded\n",
1438 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1442 printf("Returned unexpected error\n");
1451 checks for correct tconX support
1453 static bool run_tcon_devtype_test(int dummy)
1455 static struct cli_state *cli1 = NULL;
1460 status = cli_full_connection(&cli1, myname,
1461 host, NULL, port_to_use,
1463 username, workgroup,
1464 password, flags, signing_state);
1466 if (!NT_STATUS_IS_OK(status)) {
1467 printf("could not open connection\n");
1471 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1474 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1477 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1480 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1483 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1486 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1489 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1492 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1495 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1498 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1504 printf("Passed tcondevtest\n");
1511 This test checks that
1513 1) the server supports multiple locking contexts on the one SMB
1514 connection, distinguished by PID.
1516 2) the server correctly fails overlapping locks made by the same PID (this
1517 goes against POSIX behaviour, which is why it is tricky to implement)
1519 3) the server denies unlock requests by an incorrect client PID
1521 static bool run_locktest2(int dummy)
1523 static struct cli_state *cli;
1524 const char *fname = "\\lockt2.lck";
1525 uint16_t fnum1, fnum2, fnum3;
1526 bool correct = True;
1528 if (!torture_open_connection(&cli, 0)) {
1532 cli_sockopt(cli, sockops);
1534 printf("starting locktest2\n");
1536 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1540 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1541 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1545 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1546 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1552 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1553 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1559 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1560 printf("lock1 failed (%s)\n", cli_errstr(cli));
1564 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1565 printf("WRITE lock1 succeeded! This is a locking bug\n");
1568 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1569 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1572 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1573 printf("WRITE lock2 succeeded! This is a locking bug\n");
1576 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1577 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1580 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1581 printf("READ lock2 succeeded! This is a locking bug\n");
1584 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1585 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1588 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1589 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1592 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1593 printf("unlock at 100 succeeded! This is a locking bug\n");
1597 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1598 printf("unlock1 succeeded! This is a locking bug\n");
1601 if (!check_error(__LINE__, cli,
1603 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1606 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1607 printf("unlock2 succeeded! This is a locking bug\n");
1610 if (!check_error(__LINE__, cli,
1612 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1615 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1616 printf("lock3 succeeded! This is a locking bug\n");
1619 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1624 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1625 printf("close1 failed (%s)\n", cli_errstr(cli));
1629 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1630 printf("close2 failed (%s)\n", cli_errstr(cli));
1634 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1635 printf("close3 failed (%s)\n", cli_errstr(cli));
1639 if (!torture_close_connection(cli)) {
1643 printf("locktest2 finished\n");
1650 This test checks that
1652 1) the server supports the full offset range in lock requests
1654 static bool run_locktest3(int dummy)
1656 static struct cli_state *cli1, *cli2;
1657 const char *fname = "\\lockt3.lck";
1658 uint16_t fnum1, fnum2;
1661 bool correct = True;
1663 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1665 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1668 cli_sockopt(cli1, sockops);
1669 cli_sockopt(cli2, sockops);
1671 printf("starting locktest3\n");
1673 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1675 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1676 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1679 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1680 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1684 for (offset=i=0;i<torture_numops;i++) {
1686 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1687 printf("lock1 %d failed (%s)\n",
1693 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1694 printf("lock2 %d failed (%s)\n",
1701 for (offset=i=0;i<torture_numops;i++) {
1704 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1705 printf("error: lock1 %d succeeded!\n", i);
1709 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1710 printf("error: lock2 %d succeeded!\n", i);
1714 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1715 printf("error: lock3 %d succeeded!\n", i);
1719 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1720 printf("error: lock4 %d succeeded!\n", i);
1725 for (offset=i=0;i<torture_numops;i++) {
1728 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1729 printf("unlock1 %d failed (%s)\n",
1735 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1736 printf("unlock2 %d failed (%s)\n",
1743 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1744 printf("close1 failed (%s)\n", cli_errstr(cli1));
1748 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1749 printf("close2 failed (%s)\n", cli_errstr(cli2));
1753 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1754 printf("unlink failed (%s)\n", cli_errstr(cli1));
1758 if (!torture_close_connection(cli1)) {
1762 if (!torture_close_connection(cli2)) {
1766 printf("finished locktest3\n");
1771 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1772 printf("** "); correct = False; \
1776 looks at overlapping locks
1778 static bool run_locktest4(int dummy)
1780 static struct cli_state *cli1, *cli2;
1781 const char *fname = "\\lockt4.lck";
1782 uint16_t fnum1, fnum2, f;
1785 bool correct = True;
1787 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1791 cli_sockopt(cli1, sockops);
1792 cli_sockopt(cli2, sockops);
1794 printf("starting locktest4\n");
1796 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1798 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1799 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1801 memset(buf, 0, sizeof(buf));
1803 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1804 printf("Failed to create file\n");
1809 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1810 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1811 EXPECTED(ret, False);
1812 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1814 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1815 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1816 EXPECTED(ret, True);
1817 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1819 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1820 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1821 EXPECTED(ret, False);
1822 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1824 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1825 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1826 EXPECTED(ret, True);
1827 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1829 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1830 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1831 EXPECTED(ret, False);
1832 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1834 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1835 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1836 EXPECTED(ret, True);
1837 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1839 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1840 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1841 EXPECTED(ret, True);
1842 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1844 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1845 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1846 EXPECTED(ret, False);
1847 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1849 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1850 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1851 EXPECTED(ret, False);
1852 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1854 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1855 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1856 EXPECTED(ret, True);
1857 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1859 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1860 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1861 EXPECTED(ret, False);
1862 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1864 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1865 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1866 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1867 EXPECTED(ret, False);
1868 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1871 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1872 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1873 EXPECTED(ret, False);
1874 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1876 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1877 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1878 EXPECTED(ret, False);
1879 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1882 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1883 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1884 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1885 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1886 EXPECTED(ret, True);
1887 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1890 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1891 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1892 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1893 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1894 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1895 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1896 EXPECTED(ret, True);
1897 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1899 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1900 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1901 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1902 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1903 EXPECTED(ret, True);
1904 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1906 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1907 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1908 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1909 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1910 EXPECTED(ret, True);
1911 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1913 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1914 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1915 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1916 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1917 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1918 EXPECTED(ret, True);
1919 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1921 cli_close(cli1, fnum1);
1922 cli_close(cli2, fnum2);
1923 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1924 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1925 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1926 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1927 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1928 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1929 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1931 cli_close(cli1, fnum1);
1932 EXPECTED(ret, True);
1933 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1936 cli_close(cli1, fnum1);
1937 cli_close(cli2, fnum2);
1938 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1939 torture_close_connection(cli1);
1940 torture_close_connection(cli2);
1942 printf("finished locktest4\n");
1947 looks at lock upgrade/downgrade.
1949 static bool run_locktest5(int dummy)
1951 static struct cli_state *cli1, *cli2;
1952 const char *fname = "\\lockt5.lck";
1953 uint16_t fnum1, fnum2, fnum3;
1956 bool correct = True;
1958 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1962 cli_sockopt(cli1, sockops);
1963 cli_sockopt(cli2, sockops);
1965 printf("starting locktest5\n");
1967 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1969 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1970 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1971 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1973 memset(buf, 0, sizeof(buf));
1975 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1976 printf("Failed to create file\n");
1981 /* Check for NT bug... */
1982 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1983 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1984 cli_close(cli1, fnum1);
1985 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1986 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1987 EXPECTED(ret, True);
1988 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1989 cli_close(cli1, fnum1);
1990 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1991 cli_unlock(cli1, fnum3, 0, 1);
1993 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1994 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1995 EXPECTED(ret, True);
1996 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1998 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1999 EXPECTED(ret, False);
2001 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2003 /* Unlock the process 2 lock. */
2004 cli_unlock(cli2, fnum2, 0, 4);
2006 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2007 EXPECTED(ret, False);
2009 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2011 /* Unlock the process 1 fnum3 lock. */
2012 cli_unlock(cli1, fnum3, 0, 4);
2014 /* Stack 2 more locks here. */
2015 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2016 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2018 EXPECTED(ret, True);
2019 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2021 /* Unlock the first process lock, then check this was the WRITE lock that was
2024 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2025 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2027 EXPECTED(ret, True);
2028 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2030 /* Unlock the process 2 lock. */
2031 cli_unlock(cli2, fnum2, 0, 4);
2033 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2035 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2036 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2037 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2039 EXPECTED(ret, True);
2040 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2042 /* Ensure the next unlock fails. */
2043 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2044 EXPECTED(ret, False);
2045 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2047 /* Ensure connection 2 can get a write lock. */
2048 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2049 EXPECTED(ret, True);
2051 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2055 cli_close(cli1, fnum1);
2056 cli_close(cli2, fnum2);
2057 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2058 if (!torture_close_connection(cli1)) {
2061 if (!torture_close_connection(cli2)) {
2065 printf("finished locktest5\n");
2071 tries the unusual lockingX locktype bits
2073 static bool run_locktest6(int dummy)
2075 static struct cli_state *cli;
2076 const char *fname[1] = { "\\lock6.txt" };
2081 if (!torture_open_connection(&cli, 0)) {
2085 cli_sockopt(cli, sockops);
2087 printf("starting locktest6\n");
2090 printf("Testing %s\n", fname[i]);
2092 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2094 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2095 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2096 cli_close(cli, fnum);
2097 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2099 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2100 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2101 cli_close(cli, fnum);
2102 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2104 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2107 torture_close_connection(cli);
2109 printf("finished locktest6\n");
2113 static bool run_locktest7(int dummy)
2115 struct cli_state *cli1;
2116 const char *fname = "\\lockt7.lck";
2119 bool correct = False;
2121 if (!torture_open_connection(&cli1, 0)) {
2125 cli_sockopt(cli1, sockops);
2127 printf("starting locktest7\n");
2129 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2131 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2133 memset(buf, 0, sizeof(buf));
2135 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2136 printf("Failed to create file\n");
2140 cli_setpid(cli1, 1);
2142 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2143 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2146 printf("pid1 successfully locked range 130:4 for READ\n");
2149 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2150 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2153 printf("pid1 successfully read the range 130:4\n");
2156 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2157 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2158 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2159 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2163 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2167 cli_setpid(cli1, 2);
2169 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2170 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2172 printf("pid2 successfully read the range 130:4\n");
2175 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2176 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2177 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2178 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2182 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2186 cli_setpid(cli1, 1);
2187 cli_unlock(cli1, fnum1, 130, 4);
2189 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2190 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2193 printf("pid1 successfully locked range 130:4 for WRITE\n");
2196 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2197 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2200 printf("pid1 successfully read the range 130:4\n");
2203 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2204 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2207 printf("pid1 successfully wrote to the range 130:4\n");
2210 cli_setpid(cli1, 2);
2212 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2213 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2214 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2215 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2219 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2223 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2224 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2225 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2226 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2230 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2234 cli_unlock(cli1, fnum1, 130, 0);
2238 cli_close(cli1, fnum1);
2239 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2240 torture_close_connection(cli1);
2242 printf("finished locktest7\n");
2247 * This demonstrates a problem with our use of GPFS share modes: A file
2248 * descriptor sitting in the pending close queue holding a GPFS share mode
2249 * blocks opening a file another time. Happens with Word 2007 temp files.
2250 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2251 * open is denied with NT_STATUS_SHARING_VIOLATION.
2254 static bool run_locktest8(int dummy)
2256 struct cli_state *cli1;
2257 const char *fname = "\\lockt8.lck";
2258 uint16_t fnum1, fnum2;
2260 bool correct = False;
2263 if (!torture_open_connection(&cli1, 0)) {
2267 cli_sockopt(cli1, sockops);
2269 printf("starting locktest8\n");
2271 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2273 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2275 if (!NT_STATUS_IS_OK(status)) {
2276 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2280 memset(buf, 0, sizeof(buf));
2282 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2283 if (!NT_STATUS_IS_OK(status)) {
2284 d_fprintf(stderr, "cli_open second time returned %s\n",
2289 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2290 printf("Unable to apply read lock on range 1:1, error was "
2291 "%s\n", cli_errstr(cli1));
2295 status = cli_close(cli1, fnum1);
2296 if (!NT_STATUS_IS_OK(status)) {
2297 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2301 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2302 if (!NT_STATUS_IS_OK(status)) {
2303 d_fprintf(stderr, "cli_open third time returned %s\n",
2311 cli_close(cli1, fnum1);
2312 cli_close(cli1, fnum2);
2313 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2314 torture_close_connection(cli1);
2316 printf("finished locktest8\n");
2321 * This test is designed to be run in conjunction with
2322 * external NFS or POSIX locks taken in the filesystem.
2323 * It checks that the smbd server will block until the
2324 * lock is released and then acquire it. JRA.
2327 static bool got_alarm;
2328 static int alarm_fd;
2330 static void alarm_handler(int dummy)
2335 static void alarm_handler_parent(int dummy)
2340 static void do_local_lock(int read_fd, int write_fd)
2345 const char *local_pathname = NULL;
2348 local_pathname = talloc_asprintf(talloc_tos(),
2349 "%s/lockt9.lck", local_path);
2350 if (!local_pathname) {
2351 printf("child: alloc fail\n");
2355 unlink(local_pathname);
2356 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2358 printf("child: open of %s failed %s.\n",
2359 local_pathname, strerror(errno));
2363 /* Now take a fcntl lock. */
2364 lock.l_type = F_WRLCK;
2365 lock.l_whence = SEEK_SET;
2368 lock.l_pid = getpid();
2370 ret = fcntl(fd,F_SETLK,&lock);
2372 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2373 local_pathname, strerror(errno));
2376 printf("child: got lock 0:4 on file %s.\n",
2381 CatchSignal(SIGALRM, alarm_handler);
2383 /* Signal the parent. */
2384 if (write(write_fd, &c, 1) != 1) {
2385 printf("child: start signal fail %s.\n",
2392 /* Wait for the parent to be ready. */
2393 if (read(read_fd, &c, 1) != 1) {
2394 printf("child: reply signal fail %s.\n",
2402 printf("child: released lock 0:4 on file %s.\n",
2408 static bool run_locktest9(int dummy)
2410 struct cli_state *cli1;
2411 const char *fname = "\\lockt9.lck";
2413 bool correct = False;
2414 int pipe_in[2], pipe_out[2];
2418 struct timeval start;
2422 printf("starting locktest9\n");
2424 if (local_path == NULL) {
2425 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2429 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2434 if (child_pid == -1) {
2438 if (child_pid == 0) {
2440 do_local_lock(pipe_out[0], pipe_in[1]);
2450 ret = read(pipe_in[0], &c, 1);
2452 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2457 if (!torture_open_connection(&cli1, 0)) {
2461 cli_sockopt(cli1, sockops);
2463 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2465 if (!NT_STATUS_IS_OK(status)) {
2466 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2470 /* Ensure the child has the lock. */
2471 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2472 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2475 d_printf("Child has the lock.\n");
2478 /* Tell the child to wait 5 seconds then exit. */
2479 ret = write(pipe_out[1], &c, 1);
2481 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2486 /* Wait 20 seconds for the lock. */
2487 alarm_fd = cli1->fd;
2488 CatchSignal(SIGALRM, alarm_handler_parent);
2491 start = timeval_current();
2493 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2494 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2495 "%s\n", cli_errstr(cli1));
2500 seconds = timeval_elapsed(&start);
2502 printf("Parent got the lock after %.2f seconds.\n",
2505 status = cli_close(cli1, fnum);
2506 if (!NT_STATUS_IS_OK(status)) {
2507 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2514 cli_close(cli1, fnum);
2515 torture_close_connection(cli1);
2519 printf("finished locktest9\n");
2524 test whether fnums and tids open on one VC are available on another (a major
2527 static bool run_fdpasstest(int dummy)
2529 struct cli_state *cli1, *cli2;
2530 const char *fname = "\\fdpass.tst";
2534 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2537 cli_sockopt(cli1, sockops);
2538 cli_sockopt(cli2, sockops);
2540 printf("starting fdpasstest\n");
2542 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2544 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2545 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2549 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2550 printf("write failed (%s)\n", cli_errstr(cli1));
2554 cli2->vuid = cli1->vuid;
2555 cli2->cnum = cli1->cnum;
2556 cli2->pid = cli1->pid;
2558 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2559 printf("read succeeded! nasty security hole [%s]\n",
2564 cli_close(cli1, fnum1);
2565 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2567 torture_close_connection(cli1);
2568 torture_close_connection(cli2);
2570 printf("finished fdpasstest\n");
2574 static bool run_fdsesstest(int dummy)
2576 struct cli_state *cli;
2581 const char *fname = "\\fdsess.tst";
2582 const char *fname1 = "\\fdsess1.tst";
2588 if (!torture_open_connection(&cli, 0))
2590 cli_sockopt(cli, sockops);
2592 if (!torture_cli_session_setup2(cli, &new_vuid))
2595 saved_cnum = cli->cnum;
2596 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2598 new_cnum = cli->cnum;
2599 cli->cnum = saved_cnum;
2601 printf("starting fdsesstest\n");
2603 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2604 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2606 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2607 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2611 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2612 printf("write failed (%s)\n", cli_errstr(cli));
2616 saved_vuid = cli->vuid;
2617 cli->vuid = new_vuid;
2619 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2620 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2624 /* Try to open a file with different vuid, samba cnum. */
2625 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2626 printf("create with different vuid, same cnum succeeded.\n");
2627 cli_close(cli, fnum2);
2628 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2630 printf("create with different vuid, same cnum failed.\n");
2631 printf("This will cause problems with service clients.\n");
2635 cli->vuid = saved_vuid;
2637 /* Try with same vuid, different cnum. */
2638 cli->cnum = new_cnum;
2640 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2641 printf("read succeeded with different cnum![%s]\n",
2646 cli->cnum = saved_cnum;
2647 cli_close(cli, fnum1);
2648 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2650 torture_close_connection(cli);
2652 printf("finished fdsesstest\n");
2657 This test checks that
2659 1) the server does not allow an unlink on a file that is open
2661 static bool run_unlinktest(int dummy)
2663 struct cli_state *cli;
2664 const char *fname = "\\unlink.tst";
2666 bool correct = True;
2668 if (!torture_open_connection(&cli, 0)) {
2672 cli_sockopt(cli, sockops);
2674 printf("starting unlink test\n");
2676 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2680 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2681 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2685 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2686 printf("error: server allowed unlink on an open file\n");
2689 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2690 NT_STATUS_SHARING_VIOLATION);
2693 cli_close(cli, fnum);
2694 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2696 if (!torture_close_connection(cli)) {
2700 printf("unlink test finished\n");
2707 test how many open files this server supports on the one socket
2709 static bool run_maxfidtest(int dummy)
2711 struct cli_state *cli;
2712 const char *ftemplate = "\\maxfid.%d.%d";
2714 uint16_t fnums[0x11000];
2717 bool correct = True;
2722 printf("failed to connect\n");
2726 cli_sockopt(cli, sockops);
2728 for (i=0; i<0x11000; i++) {
2729 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2730 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2731 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2732 printf("open of %s failed (%s)\n",
2733 fname, cli_errstr(cli));
2734 printf("maximum fnum is %d\n", i);
2742 printf("cleaning up\n");
2744 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2745 cli_close(cli, fnums[i]);
2746 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2747 printf("unlink of %s failed (%s)\n",
2748 fname, cli_errstr(cli));
2755 printf("maxfid test finished\n");
2756 if (!torture_close_connection(cli)) {
2762 /* generate a random buffer */
2763 static void rand_buf(char *buf, int len)
2766 *buf = (char)sys_random();
2771 /* send smb negprot commands, not reading the response */
2772 static bool run_negprot_nowait(int dummy)
2775 static struct cli_state *cli;
2776 bool correct = True;
2778 printf("starting negprot nowait test\n");
2780 if (!(cli = open_nbt_connection())) {
2784 for (i=0;i<50000;i++) {
2785 cli_negprot_sendsync(cli);
2788 if (!torture_close_connection(cli)) {
2792 printf("finished negprot nowait test\n");
2797 /* send smb negprot commands, not reading the response */
2798 static bool run_bad_nbt_session(int dummy)
2800 static struct cli_state *cli;
2802 printf("starting bad nbt session test\n");
2804 if (!(cli = open_bad_nbt_connection())) {
2809 printf("finished bad nbt session test\n");
2813 /* send random IPC commands */
2814 static bool run_randomipc(int dummy)
2816 char *rparam = NULL;
2818 unsigned int rdrcnt,rprcnt;
2820 int api, param_len, i;
2821 struct cli_state *cli;
2822 bool correct = True;
2825 printf("starting random ipc test\n");
2827 if (!torture_open_connection(&cli, 0)) {
2831 for (i=0;i<count;i++) {
2832 api = sys_random() % 500;
2833 param_len = (sys_random() % 64);
2835 rand_buf(param, param_len);
2840 param, param_len, 8,
2841 NULL, 0, BUFFER_SIZE,
2845 printf("%d/%d\r", i,count);
2848 printf("%d/%d\n", i, count);
2850 if (!torture_close_connection(cli)) {
2854 printf("finished random ipc test\n");
2861 static void browse_callback(const char *sname, uint32 stype,
2862 const char *comment, void *state)
2864 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2870 This test checks the browse list code
2873 static bool run_browsetest(int dummy)
2875 static struct cli_state *cli;
2876 bool correct = True;
2878 printf("starting browse test\n");
2880 if (!torture_open_connection(&cli, 0)) {
2884 printf("domain list:\n");
2885 cli_NetServerEnum(cli, cli->server_domain,
2886 SV_TYPE_DOMAIN_ENUM,
2887 browse_callback, NULL);
2889 printf("machine list:\n");
2890 cli_NetServerEnum(cli, cli->server_domain,
2892 browse_callback, NULL);
2894 if (!torture_close_connection(cli)) {
2898 printf("browse test finished\n");
2906 This checks how the getatr calls works
2908 static bool run_attrtest(int dummy)
2910 struct cli_state *cli;
2913 const char *fname = "\\attrib123456789.tst";
2914 bool correct = True;
2916 printf("starting attrib test\n");
2918 if (!torture_open_connection(&cli, 0)) {
2922 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2923 cli_open(cli, fname,
2924 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2925 cli_close(cli, fnum);
2926 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2927 printf("getatr failed (%s)\n", cli_errstr(cli));
2931 if (abs(t - time(NULL)) > 60*60*24*10) {
2932 printf("ERROR: SMBgetatr bug. time is %s",
2938 t2 = t-60*60*24; /* 1 day ago */
2940 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2941 printf("setatr failed (%s)\n", cli_errstr(cli));
2945 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2946 printf("getatr failed (%s)\n", cli_errstr(cli));
2951 printf("ERROR: getatr/setatr bug. times are\n%s",
2953 printf("%s", ctime(&t2));
2957 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2959 if (!torture_close_connection(cli)) {
2963 printf("attrib test finished\n");
2970 This checks a couple of trans2 calls
2972 static bool run_trans2test(int dummy)
2974 struct cli_state *cli;
2977 time_t c_time, a_time, m_time;
2978 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2979 const char *fname = "\\trans2.tst";
2980 const char *dname = "\\trans2";
2981 const char *fname2 = "\\trans2\\trans2.tst";
2983 bool correct = True;
2987 printf("starting trans2 test\n");
2989 if (!torture_open_connection(&cli, 0)) {
2993 status = cli_get_fs_attr_info(cli, &fs_attr);
2994 if (!NT_STATUS_IS_OK(status)) {
2995 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3000 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3001 cli_open(cli, fname,
3002 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3003 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3004 cli, fnum, NULL, &size, &c_time_ts,
3005 &a_time_ts, &w_time_ts,
3006 &m_time_ts, NULL))) {
3007 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3011 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3012 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3016 if (strcmp(pname, fname)) {
3017 printf("qfilename gave different name? [%s] [%s]\n",
3022 cli_close(cli, fnum);
3026 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3027 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3028 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3029 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3032 cli_close(cli, fnum);
3034 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3036 if (!NT_STATUS_IS_OK(status)) {
3037 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3040 if (c_time != m_time) {
3041 printf("create time=%s", ctime(&c_time));
3042 printf("modify time=%s", ctime(&m_time));
3043 printf("This system appears to have sticky create times\n");
3045 if (a_time % (60*60) == 0) {
3046 printf("access time=%s", ctime(&a_time));
3047 printf("This system appears to set a midnight access time\n");
3051 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3052 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3058 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3059 cli_open(cli, fname,
3060 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3061 cli_close(cli, fnum);
3062 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3063 &m_time_ts, &size, NULL, NULL);
3064 if (!NT_STATUS_IS_OK(status)) {
3065 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3068 if (w_time_ts.tv_sec < 60*60*24*2) {
3069 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3070 printf("This system appears to set a initial 0 write time\n");
3075 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3078 /* check if the server updates the directory modification time
3079 when creating a new file */
3080 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3081 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3085 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3086 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3087 if (!NT_STATUS_IS_OK(status)) {
3088 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3092 cli_open(cli, fname2,
3093 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3094 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
3095 cli_close(cli, fnum);
3096 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3097 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3098 if (!NT_STATUS_IS_OK(status)) {
3099 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3102 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3104 printf("This system does not update directory modification times\n");
3108 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3109 cli_rmdir(cli, dname);
3111 if (!torture_close_connection(cli)) {
3115 printf("trans2 test finished\n");
3121 This checks new W2K calls.
3124 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3126 uint8_t *buf = NULL;
3130 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3131 pcli->max_xmit, &buf, &len);
3132 if (!NT_STATUS_IS_OK(status)) {
3133 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3136 printf("qfileinfo: level %d, len = %u\n", level, len);
3137 dump_data(0, (uint8 *)buf, len);
3144 static bool run_w2ktest(int dummy)
3146 struct cli_state *cli;
3148 const char *fname = "\\w2ktest\\w2k.tst";
3150 bool correct = True;
3152 printf("starting w2k test\n");
3154 if (!torture_open_connection(&cli, 0)) {
3158 cli_open(cli, fname,
3159 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3161 for (level = 1004; level < 1040; level++) {
3162 new_trans(cli, fnum, level);
3165 cli_close(cli, fnum);
3167 if (!torture_close_connection(cli)) {
3171 printf("w2k test finished\n");
3178 this is a harness for some oplock tests
3180 static bool run_oplock1(int dummy)
3182 struct cli_state *cli1;
3183 const char *fname = "\\lockt1.lck";
3185 bool correct = True;
3187 printf("starting oplock test 1\n");
3189 if (!torture_open_connection(&cli1, 0)) {
3193 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3195 cli_sockopt(cli1, sockops);
3197 cli1->use_oplocks = True;
3199 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3200 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3204 cli1->use_oplocks = False;
3206 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3207 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3209 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3210 printf("close2 failed (%s)\n", cli_errstr(cli1));
3214 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3215 printf("unlink failed (%s)\n", cli_errstr(cli1));
3219 if (!torture_close_connection(cli1)) {
3223 printf("finished oplock test 1\n");
3228 static bool run_oplock2(int dummy)
3230 struct cli_state *cli1, *cli2;
3231 const char *fname = "\\lockt2.lck";
3232 uint16_t fnum1, fnum2;
3233 int saved_use_oplocks = use_oplocks;
3235 bool correct = True;
3236 volatile bool *shared_correct;
3238 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3239 *shared_correct = True;
3241 use_level_II_oplocks = True;
3244 printf("starting oplock test 2\n");
3246 if (!torture_open_connection(&cli1, 0)) {
3247 use_level_II_oplocks = False;
3248 use_oplocks = saved_use_oplocks;
3252 cli1->use_oplocks = True;
3253 cli1->use_level_II_oplocks = True;
3255 if (!torture_open_connection(&cli2, 1)) {
3256 use_level_II_oplocks = False;
3257 use_oplocks = saved_use_oplocks;
3261 cli2->use_oplocks = True;
3262 cli2->use_level_II_oplocks = True;
3264 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3266 cli_sockopt(cli1, sockops);
3267 cli_sockopt(cli2, sockops);
3269 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3270 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3274 /* Don't need the globals any more. */
3275 use_level_II_oplocks = False;
3276 use_oplocks = saved_use_oplocks;
3280 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3281 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3282 *shared_correct = False;
3288 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3289 printf("close2 failed (%s)\n", cli_errstr(cli1));
3290 *shared_correct = False;
3298 /* Ensure cli1 processes the break. Empty file should always return 0
3301 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3302 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3306 /* Should now be at level II. */
3307 /* Test if sending a write locks causes a break to none. */
3309 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3310 printf("lock failed (%s)\n", cli_errstr(cli1));
3314 cli_unlock(cli1, fnum1, 0, 4);
3318 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3319 printf("lock failed (%s)\n", cli_errstr(cli1));
3323 cli_unlock(cli1, fnum1, 0, 4);
3327 cli_read(cli1, fnum1, buf, 0, 4);
3330 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3331 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3336 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3337 printf("close1 failed (%s)\n", cli_errstr(cli1));
3343 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3344 printf("unlink failed (%s)\n", cli_errstr(cli1));
3348 if (!torture_close_connection(cli1)) {
3352 if (!*shared_correct) {
3356 printf("finished oplock test 2\n");
3361 /* handler for oplock 3 tests */
3362 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3364 printf("got oplock break fnum=%d level=%d\n",
3366 return cli_oplock_ack(cli, fnum, level);
3369 static bool run_oplock3(int dummy)
3371 struct cli_state *cli;
3372 const char *fname = "\\oplockt3.dat";
3374 char buf[4] = "abcd";
3375 bool correct = True;
3376 volatile bool *shared_correct;
3378 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3379 *shared_correct = True;
3381 printf("starting oplock test 3\n");
3386 use_level_II_oplocks = True;
3387 if (!torture_open_connection(&cli, 0)) {
3388 *shared_correct = False;
3392 /* try to trigger a oplock break in parent */
3393 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3394 cli_write(cli, fnum, 0, buf, 0, 4);
3400 use_level_II_oplocks = True;
3401 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3404 cli_oplock_handler(cli, oplock3_handler);
3405 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3406 cli_write(cli, fnum, 0, buf, 0, 4);
3407 cli_close(cli, fnum);
3408 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3409 cli->timeout = 20000;
3410 cli_receive_smb(cli);
3411 printf("finished oplock test 3\n");
3413 return (correct && *shared_correct);
3415 /* What are we looking for here? What's sucess and what's FAILURE? */
3418 /* handler for oplock 4 tests */
3419 bool *oplock4_shared_correct;
3421 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3423 printf("got oplock break fnum=%d level=%d\n",
3425 *oplock4_shared_correct = true;
3426 cli_oplock_ack(cli, fnum, level);
3427 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3430 static bool run_oplock4(int dummy)
3432 struct cli_state *cli1, *cli2;
3433 const char *fname = "\\lockt4.lck";
3434 const char *fname_ln = "\\lockt4_ln.lck";
3435 uint16_t fnum1, fnum2;
3436 int saved_use_oplocks = use_oplocks;
3438 bool correct = true;
3440 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3441 *oplock4_shared_correct = false;
3443 printf("starting oplock test 4\n");
3445 if (!torture_open_connection(&cli1, 0)) {
3446 use_level_II_oplocks = false;
3447 use_oplocks = saved_use_oplocks;
3451 if (!torture_open_connection(&cli2, 1)) {
3452 use_level_II_oplocks = false;
3453 use_oplocks = saved_use_oplocks;
3457 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3458 cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN);
3460 cli_sockopt(cli1, sockops);
3461 cli_sockopt(cli2, sockops);
3463 /* Create the file. */
3464 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3465 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3469 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3470 printf("close1 failed (%s)\n", cli_errstr(cli1));
3474 /* Now create a hardlink. */
3475 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3476 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3480 /* Prove that opening hardlinks cause deny modes to conflict. */
3481 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3482 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3486 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3487 if (NT_STATUS_IS_OK(status)) {
3488 printf("open of %s succeeded - should fail with sharing violation.\n",
3493 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3494 printf("open of %s should fail with sharing violation. Got %s\n",
3495 fname_ln, nt_errstr(status));
3499 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3500 printf("close1 failed (%s)\n", cli_errstr(cli1));
3504 cli1->use_oplocks = true;
3505 cli1->use_level_II_oplocks = true;
3507 cli2->use_oplocks = true;
3508 cli2->use_level_II_oplocks = true;
3510 cli_oplock_handler(cli1, oplock4_handler);
3511 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3512 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3518 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3519 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3520 *oplock4_shared_correct = false;
3524 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3525 printf("close2 failed (%s)\n", cli_errstr(cli1));
3526 *oplock4_shared_correct = false;
3534 /* Process the oplock break. */
3535 cli_receive_smb(cli1);
3537 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3538 printf("close1 failed (%s)\n", cli_errstr(cli1));
3542 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3543 printf("unlink failed (%s)\n", cli_errstr(cli1));
3546 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN))) {
3547 printf("unlink failed (%s)\n", cli_errstr(cli1));
3551 if (!torture_close_connection(cli1)) {
3555 if (!*oplock4_shared_correct) {
3559 printf("finished oplock test 4\n");
3566 Test delete on close semantics.
3568 static bool run_deletetest(int dummy)
3570 struct cli_state *cli1 = NULL;
3571 struct cli_state *cli2 = NULL;
3572 const char *fname = "\\delete.file";
3573 uint16_t fnum1 = (uint16_t)-1;
3574 uint16_t fnum2 = (uint16_t)-1;
3575 bool correct = True;
3577 printf("starting delete test\n");
3579 if (!torture_open_connection(&cli1, 0)) {
3583 cli_sockopt(cli1, sockops);
3585 /* Test 1 - this should delete the file on close. */
3587 cli_setatr(cli1, fname, 0, 0);
3588 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3590 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3591 0, FILE_OVERWRITE_IF,
3592 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3593 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3598 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3599 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3604 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3605 printf("[1] open of %s succeeded (should fail)\n", fname);
3610 printf("first delete on close test succeeded.\n");
3612 /* Test 2 - this should delete the file on close. */
3614 cli_setatr(cli1, fname, 0, 0);
3615 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3617 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3618 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3619 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3620 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3625 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3626 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3631 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3632 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3637 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3638 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3639 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3640 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3644 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3646 printf("second delete on close test succeeded.\n");
3649 cli_setatr(cli1, fname, 0, 0);
3650 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3652 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3653 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3654 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3659 /* This should fail with a sharing violation - open for delete is only compatible
3660 with SHARE_DELETE. */
3662 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3663 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3664 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3669 /* This should succeed. */
3671 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3672 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3673 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3678 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3679 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3684 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3685 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3690 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3691 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3696 /* This should fail - file should no longer be there. */
3698 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3699 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3700 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3701 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3703 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3707 printf("third delete on close test succeeded.\n");
3710 cli_setatr(cli1, fname, 0, 0);
3711 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3713 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3714 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3715 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3720 /* This should succeed. */
3721 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3722 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3723 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3728 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3729 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3734 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3735 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3740 /* This should fail - no more opens once delete on close set. */
3741 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3742 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3743 FILE_OPEN, 0, 0, &fnum2))) {
3744 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3748 printf("fourth delete on close test succeeded.\n");
3750 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3751 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3757 cli_setatr(cli1, fname, 0, 0);
3758 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3760 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3761 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3766 /* This should fail - only allowed on NT opens with DELETE access. */
3768 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3769 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3774 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3775 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3780 printf("fifth delete on close test succeeded.\n");
3783 cli_setatr(cli1, fname, 0, 0);
3784 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3786 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3787 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3788 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3789 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3794 /* This should fail - only allowed on NT opens with DELETE access. */
3796 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3797 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3802 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3803 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3808 printf("sixth delete on close test succeeded.\n");
3811 cli_setatr(cli1, fname, 0, 0);
3812 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3814 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3815 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3816 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3821 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3822 printf("[7] setting delete_on_close on file failed !\n");
3827 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3828 printf("[7] unsetting delete_on_close on file failed !\n");
3833 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3834 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3839 /* This next open should succeed - we reset the flag. */
3841 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3842 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3847 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3848 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3853 printf("seventh delete on close test succeeded.\n");
3856 cli_setatr(cli1, fname, 0, 0);
3857 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3859 if (!torture_open_connection(&cli2, 1)) {
3860 printf("[8] failed to open second connection.\n");
3865 cli_sockopt(cli1, sockops);
3867 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3868 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3869 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3870 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3875 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3876 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3877 FILE_OPEN, 0, 0, &fnum2))) {
3878 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3883 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3884 printf("[8] setting delete_on_close on file failed !\n");
3889 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3890 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3895 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3896 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3901 /* This should fail.. */
3902 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3903 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3907 printf("eighth delete on close test succeeded.\n");
3909 /* This should fail - we need to set DELETE_ACCESS. */
3910 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3911 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3912 printf("[9] open of %s succeeded should have failed!\n", fname);
3917 printf("ninth delete on close test succeeded.\n");
3919 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3920 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3921 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3926 /* This should delete the file. */
3927 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3928 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3933 /* This should fail.. */
3934 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3935 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3939 printf("tenth delete on close test succeeded.\n");
3941 cli_setatr(cli1, fname, 0, 0);
3942 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3944 /* What error do we get when attempting to open a read-only file with
3947 /* Create a readonly file. */
3948 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3949 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3950 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3955 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3956 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3961 /* Now try open for delete access. */
3962 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3963 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3964 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3965 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3966 cli_close(cli1, fnum1);
3970 NTSTATUS nterr = cli_nt_error(cli1);
3971 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3972 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3976 printf("eleventh delete on close test succeeded.\n");
3980 printf("finished delete test\n");
3983 /* FIXME: This will crash if we aborted before cli2 got
3984 * intialized, because these functions don't handle
3985 * uninitialized connections. */
3987 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3988 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3989 cli_setatr(cli1, fname, 0, 0);
3990 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3992 if (cli1 && !torture_close_connection(cli1)) {
3995 if (cli2 && !torture_close_connection(cli2)) {
4003 print out server properties
4005 static bool run_properties(int dummy)
4007 struct cli_state *cli;
4008 bool correct = True;
4010 printf("starting properties test\n");
4014 if (!torture_open_connection(&cli, 0)) {
4018 cli_sockopt(cli, sockops);
4020 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4022 if (!torture_close_connection(cli)) {
4031 /* FIRST_DESIRED_ACCESS 0xf019f */
4032 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4033 FILE_READ_EA| /* 0xf */ \
4034 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4035 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4036 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4037 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4038 /* SECOND_DESIRED_ACCESS 0xe0080 */
4039 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4040 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4041 WRITE_OWNER_ACCESS /* 0xe0000 */
4044 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4045 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4047 WRITE_OWNER_ACCESS /* */
4051 Test ntcreate calls made by xcopy
4053 static bool run_xcopy(int dummy)
4055 static struct cli_state *cli1;
4056 const char *fname = "\\test.txt";
4057 bool correct = True;
4058 uint16_t fnum1, fnum2;
4060 printf("starting xcopy test\n");
4062 if (!torture_open_connection(&cli1, 0)) {
4066 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4067 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4068 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4069 0x4044, 0, &fnum1))) {
4070 printf("First open failed - %s\n", cli_errstr(cli1));
4074 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4075 SECOND_DESIRED_ACCESS, 0,
4076 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4077 0x200000, 0, &fnum2))) {
4078 printf("second open failed - %s\n", cli_errstr(cli1));
4082 if (!torture_close_connection(cli1)) {
4090 Test rename on files open with share delete and no share delete.
4092 static bool run_rename(int dummy)
4094 static struct cli_state *cli1;
4095 const char *fname = "\\test.txt";
4096 const char *fname1 = "\\test1.txt";
4097 bool correct = True;
4102 printf("starting rename test\n");
4104 if (!torture_open_connection(&cli1, 0)) {
4108 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4109 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4110 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4111 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4112 printf("First open failed - %s\n", cli_errstr(cli1));
4116 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4117 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4119 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4123 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4124 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4128 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4129 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4130 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4132 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4134 FILE_SHARE_DELETE|FILE_SHARE_READ,
4136 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4137 if (!NT_STATUS_IS_OK(status)) {
4138 printf("Second open failed - %s\n", cli_errstr(cli1));
4142 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4143 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4146 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4149 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4150 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4154 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4155 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4157 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4158 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4159 printf("Third open failed - %s\n", cli_errstr(cli1));
4168 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4169 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4170 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4173 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4174 printf("[8] setting delete_on_close on file failed !\n");
4178 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4179 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4185 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4186 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4189 printf("Third rename succeeded (SHARE_NONE)\n");
4192 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4193 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4197 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4198 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4202 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4203 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4204 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4208 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4209 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4211 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4215 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4216 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4220 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4221 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4225 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4226 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4227 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4231 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4232 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4236 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4240 * Now check if the first name still exists ...
4243 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4244 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4245 printf("Opening original file after rename of open file fails: %s\n",
4249 printf("Opening original file after rename of open file works ...\n");
4250 (void)cli_close(cli1, fnum2);
4254 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4255 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4259 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4260 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4261 printf("getatr on file %s failed - %s ! \n",
4266 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4267 printf("Renamed file %s has wrong attr 0x%x "
4268 "(should be 0x%x)\n",
4271 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4274 printf("Renamed file %s has archive bit set\n", fname1);
4278 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4279 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4281 if (!torture_close_connection(cli1)) {
4288 static bool run_pipe_number(int dummy)
4290 struct cli_state *cli1;
4291 const char *pipe_name = "\\SPOOLSS";
4295 printf("starting pipenumber test\n");
4296 if (!torture_open_connection(&cli1, 0)) {
4300 cli_sockopt(cli1, sockops);
4302 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4303 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4304 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4308 printf("\r%6d", num_pipes);
4311 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4312 torture_close_connection(cli1);
4317 Test open mode returns on read-only files.
4319 static bool run_opentest(int dummy)
4321 static struct cli_state *cli1;
4322 static struct cli_state *cli2;
4323 const char *fname = "\\readonly.file";
4324 uint16_t fnum1, fnum2;
4327 bool correct = True;
4330 printf("starting open test\n");
4332 if (!torture_open_connection(&cli1, 0)) {
4336 cli_setatr(cli1, fname, 0, 0);
4337 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4339 cli_sockopt(cli1, sockops);
4341 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4342 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4346 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4347 printf("close2 failed (%s)\n", cli_errstr(cli1));
4351 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4352 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4356 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4357 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4361 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4362 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4364 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4365 NT_STATUS_ACCESS_DENIED)) {
4366 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4369 printf("finished open test 1\n");
4371 cli_close(cli1, fnum1);
4373 /* Now try not readonly and ensure ERRbadshare is returned. */
4375 cli_setatr(cli1, fname, 0, 0);
4377 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4378 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4382 /* This will fail - but the error should be ERRshare. */
4383 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4385 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4386 NT_STATUS_SHARING_VIOLATION)) {
4387 printf("correct error code ERRDOS/ERRbadshare returned\n");
4390 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4391 printf("close2 failed (%s)\n", cli_errstr(cli1));
4395 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4397 printf("finished open test 2\n");
4399 /* Test truncate open disposition on file opened for read. */
4401 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4402 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4406 /* write 20 bytes. */
4408 memset(buf, '\0', 20);
4410 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4411 printf("write failed (%s)\n", cli_errstr(cli1));
4415 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4416 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4420 /* Ensure size == 20. */
4421 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4422 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4427 printf("(3) file size != 20\n");
4431 /* Now test if we can truncate a file opened for readonly. */
4433 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4434 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4438 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4439 printf("close2 failed (%s)\n", cli_errstr(cli1));
4443 /* Ensure size == 0. */
4444 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4445 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4450 printf("(3) file size != 0\n");
4453 printf("finished open test 3\n");
4455 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4457 printf("Do ctemp tests\n");
4458 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4459 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4462 printf("ctemp gave path %s\n", tmp_path);
4463 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4464 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4466 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4467 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4470 /* Test the non-io opens... */
4472 if (!torture_open_connection(&cli2, 1)) {
4476 cli_setatr(cli2, fname, 0, 0);
4477 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4479 cli_sockopt(cli2, sockops);
4481 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4483 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4484 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4485 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4489 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4490 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4491 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4495 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4496 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4499 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4500 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4504 printf("non-io open test #1 passed.\n");
4506 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4508 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4510 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4511 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4512 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4516 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4517 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4518 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4522 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4523 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4526 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4527 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4531 printf("non-io open test #2 passed.\n");
4533 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4535 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4537 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4538 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4539 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4543 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4544 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4545 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4549 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4550 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4553 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4554 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4558 printf("non-io open test #3 passed.\n");
4560 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4562 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4564 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4565 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4566 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4570 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4571 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4572 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4576 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4578 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4579 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4583 printf("non-io open test #4 passed.\n");
4585 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4587 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4589 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4590 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4591 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4595 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4596 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4597 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4601 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4602 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4606 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4607 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4611 printf("non-io open test #5 passed.\n");
4613 printf("TEST #6 testing 1 non-io open, one io open\n");
4615 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4617 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4618 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4619 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4623 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4624 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4625 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4629 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4630 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4634 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4635 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4639 printf("non-io open test #6 passed.\n");
4641 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4643 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4645 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4646 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4647 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4651 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4652 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4653 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4657 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4659 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4660 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4664 printf("non-io open test #7 passed.\n");
4666 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4668 if (!torture_close_connection(cli1)) {
4671 if (!torture_close_connection(cli2)) {
4678 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4680 uint16 major, minor;
4681 uint32 caplow, caphigh;
4684 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4685 printf("Server doesn't support UNIX CIFS extensions.\n");
4686 return NT_STATUS_NOT_SUPPORTED;
4689 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4691 if (!NT_STATUS_IS_OK(status)) {
4692 printf("Server didn't return UNIX CIFS extensions: %s\n",
4697 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4699 if (!NT_STATUS_IS_OK(status)) {
4700 printf("Server doesn't support setting UNIX CIFS extensions: "
4701 "%s.\n", nt_errstr(status));
4705 return NT_STATUS_OK;
4709 Test POSIX open /mkdir calls.
4711 static bool run_simple_posix_open_test(int dummy)
4713 static struct cli_state *cli1;
4714 const char *fname = "posix:file";
4715 const char *hname = "posix:hlink";
4716 const char *sname = "posix:symlink";
4717 const char *dname = "posix:dir";
4720 uint16_t fnum1 = (uint16_t)-1;
4721 SMB_STRUCT_STAT sbuf;
4722 bool correct = false;
4725 printf("Starting simple POSIX open test\n");
4727 if (!torture_open_connection(&cli1, 0)) {
4731 cli_sockopt(cli1, sockops);
4733 status = torture_setup_unix_extensions(cli1);
4734 if (!NT_STATUS_IS_OK(status)) {
4738 cli_setatr(cli1, fname, 0, 0);
4739 cli_posix_unlink(cli1, fname);
4740 cli_setatr(cli1, dname, 0, 0);
4741 cli_posix_rmdir(cli1, dname);
4742 cli_setatr(cli1, hname, 0, 0);
4743 cli_posix_unlink(cli1, hname);
4744 cli_setatr(cli1, sname, 0, 0);
4745 cli_posix_unlink(cli1, sname);
4747 /* Create a directory. */
4748 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4749 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4753 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4754 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4758 /* Test ftruncate - set file size. */
4759 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4760 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4764 /* Ensure st_size == 1000 */
4765 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4766 printf("stat failed (%s)\n", cli_errstr(cli1));
4770 if (sbuf.st_ex_size != 1000) {
4771 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4775 /* Test ftruncate - set file size back to zero. */
4776 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4777 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4781 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4782 printf("close failed (%s)\n", cli_errstr(cli1));
4786 /* Now open the file again for read only. */
4787 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4788 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4792 /* Now unlink while open. */
4793 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4794 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4798 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4799 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4803 /* Ensure the file has gone. */
4804 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4805 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4809 /* What happens when we try and POSIX open a directory ? */
4810 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4811 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4814 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4815 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4820 /* Create the file. */
4821 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4822 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4826 /* Write some data into it. */
4827 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4828 printf("cli_write failed: %s\n", cli_errstr(cli1));
4832 cli_close(cli1, fnum1);
4834 /* Now create a hardlink. */
4835 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4836 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4840 /* Now create a symlink. */
4841 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4842 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4846 /* Open the hardlink for read. */
4847 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4848 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4852 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4853 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4857 if (memcmp(buf, "TEST DATA\n", 10)) {
4858 printf("invalid data read from hardlink\n");
4862 /* Do a POSIX lock/unlock. */
4863 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4864 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4868 /* Punch a hole in the locked area. */
4869 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4870 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4874 cli_close(cli1, fnum1);
4876 /* Open the symlink for read - this should fail. A POSIX
4877 client should not be doing opens on a symlink. */
4878 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4879 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4882 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4883 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4884 printf("POSIX open of %s should have failed "
4885 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4886 "failed with %s instead.\n",
4887 sname, cli_errstr(cli1));
4892 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4893 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4897 if (strcmp(namebuf, fname) != 0) {
4898 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4899 sname, fname, namebuf);
4903 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4904 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4908 printf("Simple POSIX open test passed\n");
4913 if (fnum1 != (uint16_t)-1) {
4914 cli_close(cli1, fnum1);
4915 fnum1 = (uint16_t)-1;
4918 cli_setatr(cli1, sname, 0, 0);
4919 cli_posix_unlink(cli1, sname);
4920 cli_setatr(cli1, hname, 0, 0);
4921 cli_posix_unlink(cli1, hname);
4922 cli_setatr(cli1, fname, 0, 0);
4923 cli_posix_unlink(cli1, fname);
4924 cli_setatr(cli1, dname, 0, 0);
4925 cli_posix_rmdir(cli1, dname);
4927 if (!torture_close_connection(cli1)) {
4935 static uint32 open_attrs_table[] = {
4936 FILE_ATTRIBUTE_NORMAL,
4937 FILE_ATTRIBUTE_ARCHIVE,
4938 FILE_ATTRIBUTE_READONLY,
4939 FILE_ATTRIBUTE_HIDDEN,
4940 FILE_ATTRIBUTE_SYSTEM,
4942 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4943 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4944 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4945 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4946 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4947 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4949 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4950 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4951 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4952 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4955 struct trunc_open_results {
4962 static struct trunc_open_results attr_results[] = {
4963 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4964 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4965 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4966 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4967 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4968 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4969 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4970 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4971 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4972 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4973 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4974 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4975 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4976 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4977 { 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 },
4978 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4979 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4980 { 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 },
4981 { 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 },
4982 { 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 },
4983 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4984 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4985 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4986 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4987 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4988 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4991 static bool run_openattrtest(int dummy)
4993 static struct cli_state *cli1;
4994 const char *fname = "\\openattr.file";
4996 bool correct = True;
4998 unsigned int i, j, k, l;
5000 printf("starting open attr test\n");
5002 if (!torture_open_connection(&cli1, 0)) {
5006 cli_sockopt(cli1, sockops);
5008 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5009 cli_setatr(cli1, fname, 0, 0);
5010 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5011 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5012 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5013 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5017 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5018 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5022 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5023 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5024 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5025 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5026 if (attr_results[l].num == k) {
5027 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5028 k, open_attrs_table[i],
5029 open_attrs_table[j],
5030 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5034 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5035 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5036 k, open_attrs_table[i], open_attrs_table[j],
5041 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5047 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5048 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5052 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5053 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5058 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5059 k, open_attrs_table[i], open_attrs_table[j], attr );
5062 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5063 if (attr_results[l].num == k) {
5064 if (attr != attr_results[l].result_attr ||
5065 open_attrs_table[i] != attr_results[l].init_attr ||
5066 open_attrs_table[j] != attr_results[l].trunc_attr) {
5067 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5068 open_attrs_table[i],
5069 open_attrs_table[j],
5071 attr_results[l].result_attr);
5081 cli_setatr(cli1, fname, 0, 0);
5082 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5084 printf("open attr test %s.\n", correct ? "passed" : "failed");
5086 if (!torture_close_connection(cli1)) {
5092 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5093 const char *name, void *state)
5095 int *matched = (int *)state;
5096 if (matched != NULL) {
5099 return NT_STATUS_OK;
5103 test directory listing speed
5105 static bool run_dirtest(int dummy)
5108 static struct cli_state *cli;
5110 struct timeval core_start;
5111 bool correct = True;
5114 printf("starting directory test\n");
5116 if (!torture_open_connection(&cli, 0)) {
5120 cli_sockopt(cli, sockops);
5123 for (i=0;i<torture_numops;i++) {
5125 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5126 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5127 fprintf(stderr,"Failed to open %s\n", fname);
5130 cli_close(cli, fnum);
5133 core_start = timeval_current();
5136 cli_list(cli, "a*.*", 0, list_fn, &matched);
5137 printf("Matched %d\n", matched);
5140 cli_list(cli, "b*.*", 0, list_fn, &matched);
5141 printf("Matched %d\n", matched);
5144 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5145 printf("Matched %d\n", matched);
5147 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5150 for (i=0;i<torture_numops;i++) {
5152 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5153 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5156 if (!torture_close_connection(cli)) {
5160 printf("finished dirtest\n");
5165 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5168 struct cli_state *pcli = (struct cli_state *)state;
5170 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5172 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5173 return NT_STATUS_OK;
5175 if (finfo->mode & aDIR) {
5176 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5177 printf("del_fn: failed to rmdir %s\n,", fname );
5179 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5180 printf("del_fn: failed to unlink %s\n,", fname );
5182 return NT_STATUS_OK;
5187 sees what IOCTLs are supported
5189 bool torture_ioctl_test(int dummy)
5191 static struct cli_state *cli;
5192 uint16_t device, function;
5194 const char *fname = "\\ioctl.dat";
5198 if (!torture_open_connection(&cli, 0)) {
5202 printf("starting ioctl test\n");
5204 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5206 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5207 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5211 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5212 printf("ioctl device info: %s\n", nt_errstr(status));
5214 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5215 printf("ioctl job info: %s\n", nt_errstr(status));
5217 for (device=0;device<0x100;device++) {
5218 printf("ioctl test with device = 0x%x\n", device);
5219 for (function=0;function<0x100;function++) {
5220 uint32 code = (device<<16) | function;
5222 status = cli_raw_ioctl(cli, fnum, code, &blob);
5224 if (NT_STATUS_IS_OK(status)) {
5225 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5227 data_blob_free(&blob);
5232 if (!torture_close_connection(cli)) {
5241 tries varients of chkpath
5243 bool torture_chkpath_test(int dummy)
5245 static struct cli_state *cli;
5249 if (!torture_open_connection(&cli, 0)) {
5253 printf("starting chkpath test\n");
5255 /* cleanup from an old run */
5256 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5257 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5258 cli_rmdir(cli, "\\chkpath.dir");
5260 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5261 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5265 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5266 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5270 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5271 printf("open1 failed (%s)\n", cli_errstr(cli));
5274 cli_close(cli, fnum);
5276 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5277 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5281 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5282 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5286 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5287 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5288 NT_STATUS_NOT_A_DIRECTORY);
5290 printf("* chkpath on a file should fail\n");
5294 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5295 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5296 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5298 printf("* chkpath on a non existant file should fail\n");
5302 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5303 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5304 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5306 printf("* chkpath on a non existent component should fail\n");
5310 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5311 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5312 cli_rmdir(cli, "\\chkpath.dir");
5314 if (!torture_close_connection(cli)) {
5321 static bool run_eatest(int dummy)
5323 static struct cli_state *cli;
5324 const char *fname = "\\eatest.txt";
5325 bool correct = True;
5329 struct ea_struct *ea_list = NULL;
5330 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5333 printf("starting eatest\n");
5335 if (!torture_open_connection(&cli, 0)) {
5336 talloc_destroy(mem_ctx);
5340 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5341 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5342 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5343 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5344 0x4044, 0, &fnum))) {
5345 printf("open failed - %s\n", cli_errstr(cli));
5346 talloc_destroy(mem_ctx);
5350 for (i = 0; i < 10; i++) {
5351 fstring ea_name, ea_val;
5353 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5354 memset(ea_val, (char)i+1, i+1);
5355 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5356 if (!NT_STATUS_IS_OK(status)) {
5357 printf("ea_set of name %s failed - %s\n", ea_name,
5359 talloc_destroy(mem_ctx);
5364 cli_close(cli, fnum);
5365 for (i = 0; i < 10; i++) {
5366 fstring ea_name, ea_val;
5368 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5369 memset(ea_val, (char)i+1, i+1);
5370 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5371 if (!NT_STATUS_IS_OK(status)) {
5372 printf("ea_set of name %s failed - %s\n", ea_name,
5374 talloc_destroy(mem_ctx);
5379 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5380 if (!NT_STATUS_IS_OK(status)) {
5381 printf("ea_get list failed - %s\n", nt_errstr(status));
5385 printf("num_eas = %d\n", (int)num_eas);
5387 if (num_eas != 20) {
5388 printf("Should be 20 EA's stored... failing.\n");
5392 for (i = 0; i < num_eas; i++) {
5393 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5394 dump_data(0, ea_list[i].value.data,
5395 ea_list[i].value.length);
5398 /* Setting EA's to zero length deletes them. Test this */
5399 printf("Now deleting all EA's - case indepenent....\n");
5402 cli_set_ea_path(cli, fname, "", "", 0);
5404 for (i = 0; i < 20; i++) {
5406 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5407 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5408 if (!NT_STATUS_IS_OK(status)) {
5409 printf("ea_set of name %s failed - %s\n", ea_name,
5411 talloc_destroy(mem_ctx);
5417 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5418 if (!NT_STATUS_IS_OK(status)) {
5419 printf("ea_get list failed - %s\n", nt_errstr(status));
5423 printf("num_eas = %d\n", (int)num_eas);
5424 for (i = 0; i < num_eas; i++) {
5425 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5426 dump_data(0, ea_list[i].value.data,
5427 ea_list[i].value.length);
5431 printf("deleting EA's failed.\n");
5435 /* Try and delete a non existant EA. */
5436 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5437 if (!NT_STATUS_IS_OK(status)) {
5438 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5443 talloc_destroy(mem_ctx);
5444 if (!torture_close_connection(cli)) {
5451 static bool run_dirtest1(int dummy)
5454 static struct cli_state *cli;
5457 bool correct = True;
5459 printf("starting directory test\n");
5461 if (!torture_open_connection(&cli, 0)) {
5465 cli_sockopt(cli, sockops);
5467 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5468 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5469 cli_rmdir(cli, "\\LISTDIR");
5470 cli_mkdir(cli, "\\LISTDIR");
5472 /* Create 1000 files and 1000 directories. */
5473 for (i=0;i<1000;i++) {
5475 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5476 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5477 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5478 fprintf(stderr,"Failed to open %s\n", fname);
5481 cli_close(cli, fnum);
5483 for (i=0;i<1000;i++) {
5485 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5486 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5487 fprintf(stderr,"Failed to open %s\n", fname);
5492 /* Now ensure that doing an old list sees both files and directories. */
5494 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5495 printf("num_seen = %d\n", num_seen );
5496 /* We should see 100 files + 1000 directories + . and .. */
5497 if (num_seen != 2002)
5500 /* Ensure if we have the "must have" bits we only see the
5504 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5505 printf("num_seen = %d\n", num_seen );
5506 if (num_seen != 1002)
5510 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5511 printf("num_seen = %d\n", num_seen );
5512 if (num_seen != 1000)
5515 /* Delete everything. */
5516 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5517 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5518 cli_rmdir(cli, "\\LISTDIR");
5521 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5522 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5523 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5526 if (!torture_close_connection(cli)) {
5530 printf("finished dirtest1\n");
5535 static bool run_error_map_extract(int dummy) {
5537 static struct cli_state *c_dos;
5538 static struct cli_state *c_nt;
5543 uint32 flgs2, errnum;
5550 /* NT-Error connection */
5552 if (!(c_nt = open_nbt_connection())) {
5556 c_nt->use_spnego = False;
5558 status = cli_negprot(c_nt);
5560 if (!NT_STATUS_IS_OK(status)) {
5561 printf("%s rejected the NT-error negprot (%s)\n", host,
5567 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5569 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5573 /* DOS-Error connection */
5575 if (!(c_dos = open_nbt_connection())) {
5579 c_dos->use_spnego = False;
5580 c_dos->force_dos_errors = True;
5582 status = cli_negprot(c_dos);
5583 if (!NT_STATUS_IS_OK(status)) {
5584 printf("%s rejected the DOS-error negprot (%s)\n", host,
5586 cli_shutdown(c_dos);
5590 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5592 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5596 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5597 fstr_sprintf(user, "%X", error);
5599 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5600 password, strlen(password),
5601 password, strlen(password),
5603 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5606 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5608 /* Case #1: 32-bit NT errors */
5609 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5610 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5612 printf("/** Dos error on NT connection! (%s) */\n",
5614 nt_status = NT_STATUS(0xc0000000);
5617 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5618 password, strlen(password),
5619 password, strlen(password),
5621 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5623 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5625 /* Case #1: 32-bit NT errors */
5626 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5627 printf("/** NT error on DOS connection! (%s) */\n",
5629 errnum = errclass = 0;
5631 cli_dos_error(c_dos, &errclass, &errnum);
5634 if (NT_STATUS_V(nt_status) != error) {
5635 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5636 get_nt_error_c_code(NT_STATUS(error)),
5637 get_nt_error_c_code(nt_status));
5640 printf("\t{%s,\t%s,\t%s},\n",
5641 smb_dos_err_class(errclass),
5642 smb_dos_err_name(errclass, errnum),
5643 get_nt_error_c_code(NT_STATUS(error)));
5648 static bool run_sesssetup_bench(int dummy)
5650 static struct cli_state *c;
5651 const char *fname = "\\file.dat";
5656 if (!torture_open_connection(&c, 0)) {
5660 if (!NT_STATUS_IS_OK(cli_ntcreate(
5661 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5662 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5663 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5664 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5668 for (i=0; i<torture_numops; i++) {
5669 status = cli_session_setup(
5671 password, strlen(password),
5672 password, strlen(password),
5674 if (!NT_STATUS_IS_OK(status)) {
5675 d_printf("(%s) cli_session_setup failed: %s\n",
5676 __location__, nt_errstr(status));
5680 d_printf("\r%d ", (int)c->vuid);
5682 status = cli_ulogoff(c);
5683 if (!NT_STATUS_IS_OK(status)) {
5684 d_printf("(%s) cli_ulogoff failed: %s\n",
5685 __location__, nt_errstr(status));
5694 static bool subst_test(const char *str, const char *user, const char *domain,
5695 uid_t uid, gid_t gid, const char *expected)
5700 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5702 if (strcmp(subst, expected) != 0) {
5703 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5704 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5713 static void chain1_open_completion(struct tevent_req *req)
5717 status = cli_open_recv(req, &fnum);
5720 d_printf("cli_open_recv returned %s: %d\n",
5722 NT_STATUS_IS_OK(status) ? fnum : -1);
5725 static void chain1_write_completion(struct tevent_req *req)
5729 status = cli_write_andx_recv(req, &written);
5732 d_printf("cli_write_andx_recv returned %s: %d\n",
5734 NT_STATUS_IS_OK(status) ? (int)written : -1);
5737 static void chain1_close_completion(struct tevent_req *req)
5740 bool *done = (bool *)tevent_req_callback_data_void(req);
5742 status = cli_close_recv(req);
5747 d_printf("cli_close returned %s\n", nt_errstr(status));
5750 static bool run_chain1(int dummy)
5752 struct cli_state *cli1;
5753 struct event_context *evt = event_context_init(NULL);
5754 struct tevent_req *reqs[3], *smbreqs[3];
5756 const char *str = "foobar";
5759 printf("starting chain1 test\n");
5760 if (!torture_open_connection(&cli1, 0)) {
5764 cli_sockopt(cli1, sockops);
5766 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5767 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5768 if (reqs[0] == NULL) return false;
5769 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5772 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5773 (uint8_t *)str, 0, strlen(str)+1,
5774 smbreqs, 1, &smbreqs[1]);
5775 if (reqs[1] == NULL) return false;
5776 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5778 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5779 if (reqs[2] == NULL) return false;
5780 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5782 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5783 if (!NT_STATUS_IS_OK(status)) {
5788 event_loop_once(evt);
5791 torture_close_connection(cli1);
5795 static void chain2_sesssetup_completion(struct tevent_req *req)
5798 status = cli_session_setup_guest_recv(req);
5799 d_printf("sesssetup returned %s\n", nt_errstr(status));
5802 static void chain2_tcon_completion(struct tevent_req *req)
5804 bool *done = (bool *)tevent_req_callback_data_void(req);
5806 status = cli_tcon_andx_recv(req);
5807 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5811 static bool run_chain2(int dummy)
5813 struct cli_state *cli1;
5814 struct event_context *evt = event_context_init(NULL);
5815 struct tevent_req *reqs[2], *smbreqs[2];
5819 printf("starting chain2 test\n");
5820 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5821 port_to_use, Undefined, 0);
5822 if (!NT_STATUS_IS_OK(status)) {
5826 cli_sockopt(cli1, sockops);
5828 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5830 if (reqs[0] == NULL) return false;
5831 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5833 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5834 "?????", NULL, 0, &smbreqs[1]);
5835 if (reqs[1] == NULL) return false;
5836 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5838 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5839 if (!NT_STATUS_IS_OK(status)) {
5844 event_loop_once(evt);
5847 torture_close_connection(cli1);
5852 struct torture_createdel_state {
5853 struct tevent_context *ev;
5854 struct cli_state *cli;
5857 static void torture_createdel_created(struct tevent_req *subreq);
5858 static void torture_createdel_closed(struct tevent_req *subreq);
5860 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5861 struct tevent_context *ev,
5862 struct cli_state *cli,
5865 struct tevent_req *req, *subreq;
5866 struct torture_createdel_state *state;
5868 req = tevent_req_create(mem_ctx, &state,
5869 struct torture_createdel_state);
5876 subreq = cli_ntcreate_send(
5877 state, ev, cli, name, 0,
5878 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5879 FILE_ATTRIBUTE_NORMAL,
5880 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5881 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5883 if (tevent_req_nomem(subreq, req)) {
5884 return tevent_req_post(req, ev);
5886 tevent_req_set_callback(subreq, torture_createdel_created, req);
5890 static void torture_createdel_created(struct tevent_req *subreq)
5892 struct tevent_req *req = tevent_req_callback_data(
5893 subreq, struct tevent_req);
5894 struct torture_createdel_state *state = tevent_req_data(
5895 req, struct torture_createdel_state);
5899 status = cli_ntcreate_recv(subreq, &fnum);
5900 TALLOC_FREE(subreq);
5901 if (!NT_STATUS_IS_OK(status)) {
5902 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5903 nt_errstr(status)));
5904 tevent_req_nterror(req, status);
5908 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5909 if (tevent_req_nomem(subreq, req)) {
5912 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5915 static void torture_createdel_closed(struct tevent_req *subreq)
5917 struct tevent_req *req = tevent_req_callback_data(
5918 subreq, struct tevent_req);
5921 status = cli_close_recv(subreq);
5922 if (!NT_STATUS_IS_OK(status)) {
5923 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5924 tevent_req_nterror(req, status);
5927 tevent_req_done(req);
5930 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5932 return tevent_req_simple_recv_ntstatus(req);
5935 struct torture_createdels_state {
5936 struct tevent_context *ev;
5937 struct cli_state *cli;
5938 const char *base_name;
5942 struct tevent_req **reqs;
5945 static void torture_createdels_done(struct tevent_req *subreq);
5947 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5948 struct tevent_context *ev,
5949 struct cli_state *cli,
5950 const char *base_name,
5954 struct tevent_req *req;
5955 struct torture_createdels_state *state;
5958 req = tevent_req_create(mem_ctx, &state,
5959 struct torture_createdels_state);
5965 state->base_name = talloc_strdup(state, base_name);
5966 if (tevent_req_nomem(state->base_name, req)) {
5967 return tevent_req_post(req, ev);
5969 state->num_files = MAX(num_parallel, num_files);
5971 state->received = 0;
5973 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5974 if (tevent_req_nomem(state->reqs, req)) {
5975 return tevent_req_post(req, ev);
5978 for (i=0; i<num_parallel; i++) {
5981 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5983 if (tevent_req_nomem(name, req)) {
5984 return tevent_req_post(req, ev);
5986 state->reqs[i] = torture_createdel_send(
5987 state->reqs, state->ev, state->cli, name);
5988 if (tevent_req_nomem(state->reqs[i], req)) {
5989 return tevent_req_post(req, ev);
5991 name = talloc_move(state->reqs[i], &name);
5992 tevent_req_set_callback(state->reqs[i],
5993 torture_createdels_done, req);
5999 static void torture_createdels_done(struct tevent_req *subreq)
6001 struct tevent_req *req = tevent_req_callback_data(
6002 subreq, struct tevent_req);
6003 struct torture_createdels_state *state = tevent_req_data(
6004 req, struct torture_createdels_state);
6005 size_t num_parallel = talloc_array_length(state->reqs);
6010 status = torture_createdel_recv(subreq);
6011 if (!NT_STATUS_IS_OK(status)){
6012 DEBUG(10, ("torture_createdel_recv returned %s\n",
6013 nt_errstr(status)));
6014 TALLOC_FREE(subreq);
6015 tevent_req_nterror(req, status);
6019 for (i=0; i<num_parallel; i++) {
6020 if (subreq == state->reqs[i]) {
6024 if (i == num_parallel) {
6025 DEBUG(10, ("received something we did not send\n"));
6026 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6029 TALLOC_FREE(state->reqs[i]);
6031 if (state->sent >= state->num_files) {
6032 tevent_req_done(req);
6036 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6038 if (tevent_req_nomem(name, req)) {
6041 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6043 if (tevent_req_nomem(state->reqs[i], req)) {
6046 name = talloc_move(state->reqs[i], &name);
6047 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6051 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6053 return tevent_req_simple_recv_ntstatus(req);
6056 struct swallow_notify_state {
6057 struct tevent_context *ev;
6058 struct cli_state *cli;
6060 uint32_t completion_filter;
6062 bool (*fn)(uint32_t action, const char *name, void *priv);
6066 static void swallow_notify_done(struct tevent_req *subreq);
6068 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6069 struct tevent_context *ev,
6070 struct cli_state *cli,
6072 uint32_t completion_filter,
6074 bool (*fn)(uint32_t action,
6079 struct tevent_req *req, *subreq;
6080 struct swallow_notify_state *state;
6082 req = tevent_req_create(mem_ctx, &state,
6083 struct swallow_notify_state);
6090 state->completion_filter = completion_filter;
6091 state->recursive = recursive;
6095 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6096 0xffff, state->completion_filter,
6098 if (tevent_req_nomem(subreq, req)) {
6099 return tevent_req_post(req, ev);
6101 tevent_req_set_callback(subreq, swallow_notify_done, req);
6105 static void swallow_notify_done(struct tevent_req *subreq)
6107 struct tevent_req *req = tevent_req_callback_data(
6108 subreq, struct tevent_req);
6109 struct swallow_notify_state *state = tevent_req_data(
6110 req, struct swallow_notify_state);
6112 uint32_t i, num_changes;
6113 struct notify_change *changes;
6115 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6116 TALLOC_FREE(subreq);
6117 if (!NT_STATUS_IS_OK(status)) {
6118 DEBUG(10, ("cli_notify_recv returned %s\n",
6119 nt_errstr(status)));
6120 tevent_req_nterror(req, status);
6124 for (i=0; i<num_changes; i++) {
6125 state->fn(changes[i].action, changes[i].name, state->priv);
6127 TALLOC_FREE(changes);
6129 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6130 0xffff, state->completion_filter,
6132 if (tevent_req_nomem(subreq, req)) {
6135 tevent_req_set_callback(subreq, swallow_notify_done, req);
6138 static bool print_notifies(uint32_t action, const char *name, void *priv)
6140 if (DEBUGLEVEL > 5) {
6141 d_printf("%d %s\n", (int)action, name);
6146 static void notify_bench_done(struct tevent_req *req)
6148 int *num_finished = (int *)tevent_req_callback_data_void(req);
6152 static bool run_notify_bench(int dummy)
6154 const char *dname = "\\notify-bench";
6155 struct tevent_context *ev;
6158 struct tevent_req *req1;
6159 struct tevent_req *req2 = NULL;
6160 int i, num_unc_names;
6161 int num_finished = 0;
6163 printf("starting notify-bench test\n");
6165 if (use_multishare_conn) {
6167 unc_list = file_lines_load(multishare_conn_fname,
6168 &num_unc_names, 0, NULL);
6169 if (!unc_list || num_unc_names <= 0) {
6170 d_printf("Failed to load unc names list from '%s'\n",
6171 multishare_conn_fname);
6174 TALLOC_FREE(unc_list);
6179 ev = tevent_context_init(talloc_tos());
6181 d_printf("tevent_context_init failed\n");
6185 for (i=0; i<num_unc_names; i++) {
6186 struct cli_state *cli;
6189 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6191 if (base_fname == NULL) {
6195 if (!torture_open_connection(&cli, i)) {
6199 status = cli_ntcreate(cli, dname, 0,
6200 MAXIMUM_ALLOWED_ACCESS,
6201 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6203 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6206 if (!NT_STATUS_IS_OK(status)) {
6207 d_printf("Could not create %s: %s\n", dname,
6212 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6213 FILE_NOTIFY_CHANGE_FILE_NAME |
6214 FILE_NOTIFY_CHANGE_DIR_NAME |
6215 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6216 FILE_NOTIFY_CHANGE_LAST_WRITE,
6217 false, print_notifies, NULL);
6219 d_printf("Could not create notify request\n");
6223 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6224 base_fname, 10, torture_numops);
6226 d_printf("Could not create createdels request\n");
6229 TALLOC_FREE(base_fname);
6231 tevent_req_set_callback(req2, notify_bench_done,
6235 while (num_finished < num_unc_names) {
6237 ret = tevent_loop_once(ev);
6239 d_printf("tevent_loop_once failed\n");
6244 if (!tevent_req_poll(req2, ev)) {
6245 d_printf("tevent_req_poll failed\n");
6248 status = torture_createdels_recv(req2);
6249 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6254 static bool run_mangle1(int dummy)
6256 struct cli_state *cli;
6257 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6261 time_t change_time, access_time, write_time;
6265 printf("starting mangle1 test\n");
6266 if (!torture_open_connection(&cli, 0)) {
6270 cli_sockopt(cli, sockops);
6272 if (!NT_STATUS_IS_OK(cli_ntcreate(
6273 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6274 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6275 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6278 cli_close(cli, fnum);
6280 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6281 if (!NT_STATUS_IS_OK(status)) {
6282 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6286 d_printf("alt_name: %s\n", alt_name);
6288 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6289 d_printf("cli_open(%s) failed: %s\n", alt_name,
6293 cli_close(cli, fnum);
6295 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6296 &write_time, &size, &mode);
6297 if (!NT_STATUS_IS_OK(status)) {
6298 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6306 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6308 size_t *to_pull = (size_t *)priv;
6309 size_t thistime = *to_pull;
6311 thistime = MIN(thistime, n);
6312 if (thistime == 0) {
6316 memset(buf, 0, thistime);
6317 *to_pull -= thistime;
6321 static bool run_windows_write(int dummy)
6323 struct cli_state *cli1;
6327 const char *fname = "\\writetest.txt";
6328 struct timeval start_time;
6332 printf("starting windows_write test\n");
6333 if (!torture_open_connection(&cli1, 0)) {
6337 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6338 printf("open failed (%s)\n", cli_errstr(cli1));
6342 cli_sockopt(cli1, sockops);
6344 start_time = timeval_current();
6346 for (i=0; i<torture_numops; i++) {
6348 off_t start = i * torture_blocksize;
6350 size_t to_pull = torture_blocksize - 1;
6352 if (cli_write(cli1, fnum, 0, &c,
6353 start + torture_blocksize - 1, 1) != 1) {
6354 printf("cli_write failed: %s\n", cli_errstr(cli1));
6358 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6359 null_source, &to_pull);
6360 if (!NT_STATUS_IS_OK(status)) {
6361 printf("cli_push returned: %s\n", nt_errstr(status));
6366 seconds = timeval_elapsed(&start_time);
6367 kbytes = (double)torture_blocksize * torture_numops;
6370 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6371 (double)seconds, (int)(kbytes/seconds));
6375 cli_close(cli1, fnum);
6376 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6377 torture_close_connection(cli1);
6381 static bool run_cli_echo(int dummy)
6383 struct cli_state *cli;
6386 printf("starting cli_echo test\n");
6387 if (!torture_open_connection(&cli, 0)) {
6390 cli_sockopt(cli, sockops);
6392 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6394 d_printf("cli_echo returned %s\n", nt_errstr(status));
6396 torture_close_connection(cli);
6397 return NT_STATUS_IS_OK(status);
6400 static bool run_uid_regression_test(int dummy)
6402 static struct cli_state *cli;
6405 bool correct = True;
6408 printf("starting uid regression test\n");
6410 if (!torture_open_connection(&cli, 0)) {
6414 cli_sockopt(cli, sockops);
6416 /* Ok - now save then logoff our current user. */
6417 old_vuid = cli->vuid;
6419 status = cli_ulogoff(cli);
6420 if (!NT_STATUS_IS_OK(status)) {
6421 d_printf("(%s) cli_ulogoff failed: %s\n",
6422 __location__, nt_errstr(status));
6427 cli->vuid = old_vuid;
6429 /* Try an operation. */
6430 status = cli_mkdir(cli, "\\uid_reg_test");
6431 if (NT_STATUS_IS_OK(status)) {
6432 d_printf("(%s) cli_mkdir succeeded\n",
6437 /* Should be bad uid. */
6438 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6439 NT_STATUS_USER_SESSION_DELETED)) {
6445 old_cnum = cli->cnum;
6447 /* Now try a SMBtdis with the invald vuid set to zero. */
6450 /* This should succeed. */
6451 status = cli_tdis(cli);
6453 if (NT_STATUS_IS_OK(status)) {
6454 d_printf("First tdis with invalid vuid should succeed.\n");
6456 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6461 cli->vuid = old_vuid;
6462 cli->cnum = old_cnum;
6464 /* This should fail. */
6465 status = cli_tdis(cli);
6466 if (NT_STATUS_IS_OK(status)) {
6467 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6471 /* Should be bad tid. */
6472 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6473 NT_STATUS_NETWORK_NAME_DELETED)) {
6479 cli_rmdir(cli, "\\uid_reg_test");
6488 static const char *illegal_chars = "*\\/?<>|\":";
6489 static char force_shortname_chars[] = " +,.[];=\177";
6491 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6492 const char *mask, void *state)
6494 struct cli_state *pcli = (struct cli_state *)state;
6496 NTSTATUS status = NT_STATUS_OK;
6498 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6500 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6501 return NT_STATUS_OK;
6503 if (finfo->mode & aDIR) {
6504 status = cli_rmdir(pcli, fname);
6505 if (!NT_STATUS_IS_OK(status)) {
6506 printf("del_fn: failed to rmdir %s\n,", fname );
6509 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6510 if (!NT_STATUS_IS_OK(status)) {
6511 printf("del_fn: failed to unlink %s\n,", fname );
6523 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6524 const char *name, void *state)
6526 struct sn_state *s = (struct sn_state *)state;
6530 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6531 i, finfo->name, finfo->short_name);
6534 if (strchr(force_shortname_chars, i)) {
6535 if (!finfo->short_name[0]) {
6536 /* Shortname not created when it should be. */
6537 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6538 __location__, finfo->name, i);
6541 } else if (finfo->short_name[0]){
6542 /* Shortname created when it should not be. */
6543 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6544 __location__, finfo->short_name, finfo->name);
6548 return NT_STATUS_OK;
6551 static bool run_shortname_test(int dummy)
6553 static struct cli_state *cli;
6554 bool correct = True;
6559 printf("starting shortname test\n");
6561 if (!torture_open_connection(&cli, 0)) {
6565 cli_sockopt(cli, sockops);
6567 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6568 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6569 cli_rmdir(cli, "\\shortname");
6571 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6572 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6573 __location__, cli_errstr(cli));
6578 strlcpy(fname, "\\shortname\\", sizeof(fname));
6579 strlcat(fname, "test .txt", sizeof(fname));
6583 for (i = 32; i < 128; i++) {
6585 uint16_t fnum = (uint16_t)-1;
6589 if (strchr(illegal_chars, i)) {
6594 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6595 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6596 if (!NT_STATUS_IS_OK(status)) {
6597 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6598 __location__, fname, cli_errstr(cli));
6602 cli_close(cli, fnum);
6605 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6607 if (s.matched != 1) {
6608 d_printf("(%s) failed to list %s: %s\n",
6609 __location__, fname, cli_errstr(cli));
6613 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6614 d_printf("(%s) failed to delete %s: %s\n",
6615 __location__, fname, cli_errstr(cli));
6628 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6629 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6630 cli_rmdir(cli, "\\shortname");
6631 torture_close_connection(cli);
6635 static void pagedsearch_cb(struct tevent_req *req)
6638 struct tldap_message *msg;
6641 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6642 if (rc != TLDAP_SUCCESS) {
6643 d_printf("tldap_search_paged_recv failed: %s\n",
6644 tldap_err2string(rc));
6647 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6651 if (!tldap_entry_dn(msg, &dn)) {
6652 d_printf("tldap_entry_dn failed\n");
6655 d_printf("%s\n", dn);
6659 static bool run_tldap(int dummy)
6661 struct tldap_context *ld;
6664 struct sockaddr_storage addr;
6665 struct tevent_context *ev;
6666 struct tevent_req *req;
6670 if (!resolve_name(host, &addr, 0, false)) {
6671 d_printf("could not find host %s\n", host);
6674 status = open_socket_out(&addr, 389, 9999, &fd);
6675 if (!NT_STATUS_IS_OK(status)) {
6676 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6680 ld = tldap_context_create(talloc_tos(), fd);
6683 d_printf("tldap_context_create failed\n");
6687 rc = tldap_fetch_rootdse(ld);
6688 if (rc != TLDAP_SUCCESS) {
6689 d_printf("tldap_fetch_rootdse failed: %s\n",
6690 tldap_errstr(talloc_tos(), ld, rc));
6694 basedn = tldap_talloc_single_attribute(
6695 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6696 if (basedn == NULL) {
6697 d_printf("no defaultNamingContext\n");
6700 d_printf("defaultNamingContext: %s\n", basedn);
6702 ev = tevent_context_init(talloc_tos());
6704 d_printf("tevent_context_init failed\n");
6708 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6709 TLDAP_SCOPE_SUB, "(objectclass=*)",
6711 NULL, 0, NULL, 0, 0, 0, 0, 5);
6713 d_printf("tldap_search_paged_send failed\n");
6716 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6718 tevent_req_poll(req, ev);
6722 /* test search filters against rootDSE */
6723 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6724 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6726 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6727 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6728 talloc_tos(), NULL, NULL);
6729 if (rc != TLDAP_SUCCESS) {
6730 d_printf("tldap_search with complex filter failed: %s\n",
6731 tldap_errstr(talloc_tos(), ld, rc));
6739 /* Torture test to ensure no regression of :
6740 https://bugzilla.samba.org/show_bug.cgi?id=7084
6743 static bool run_dir_createtime(int dummy)
6745 struct cli_state *cli;
6746 const char *dname = "\\testdir";
6747 const char *fname = "\\testdir\\testfile";
6749 struct timespec create_time;
6750 struct timespec create_time1;
6754 if (!torture_open_connection(&cli, 0)) {
6758 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6759 cli_rmdir(cli, dname);
6761 status = cli_mkdir(cli, dname);
6762 if (!NT_STATUS_IS_OK(status)) {
6763 printf("mkdir failed: %s\n", nt_errstr(status));
6767 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6769 if (!NT_STATUS_IS_OK(status)) {
6770 printf("cli_qpathinfo2 returned %s\n",
6775 /* Sleep 3 seconds, then create a file. */
6778 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6780 if (!NT_STATUS_IS_OK(status)) {
6781 printf("cli_open failed: %s\n", nt_errstr(status));
6785 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6787 if (!NT_STATUS_IS_OK(status)) {
6788 printf("cli_qpathinfo2 (2) returned %s\n",
6793 if (timespec_compare(&create_time1, &create_time)) {
6794 printf("run_dir_createtime: create time was updated (error)\n");
6796 printf("run_dir_createtime: create time was not updated (correct)\n");
6802 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6803 cli_rmdir(cli, dname);
6804 if (!torture_close_connection(cli)) {
6811 static bool run_streamerror(int dummy)
6813 struct cli_state *cli;
6814 const char *dname = "\\testdir";
6815 const char *streamname =
6816 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6818 time_t change_time, access_time, write_time;
6820 uint16_t mode, fnum;
6823 if (!torture_open_connection(&cli, 0)) {
6827 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6828 cli_rmdir(cli, dname);
6830 status = cli_mkdir(cli, dname);
6831 if (!NT_STATUS_IS_OK(status)) {
6832 printf("mkdir failed: %s\n", nt_errstr(status));
6836 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6838 status = cli_nt_error(cli);
6840 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6841 printf("pathinfo returned %s, expected "
6842 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6847 status = cli_ntcreate(cli, streamname, 0x16,
6848 FILE_READ_DATA|FILE_READ_EA|
6849 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6850 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6851 FILE_OPEN, 0, 0, &fnum);
6853 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6854 printf("ntcreate returned %s, expected "
6855 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6861 cli_rmdir(cli, dname);
6865 static bool run_local_substitute(int dummy)
6869 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6870 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6871 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6872 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6873 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6874 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6875 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6876 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6878 /* Different captialization rules in sub_basic... */
6880 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6886 static bool run_local_base64(int dummy)
6891 for (i=1; i<2000; i++) {
6892 DATA_BLOB blob1, blob2;
6895 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6897 generate_random_buffer(blob1.data, blob1.length);
6899 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6901 d_fprintf(stderr, "base64_encode_data_blob failed "
6902 "for %d bytes\n", i);
6905 blob2 = base64_decode_data_blob(b64);
6908 if (data_blob_cmp(&blob1, &blob2)) {
6909 d_fprintf(stderr, "data_blob_cmp failed for %d "
6913 TALLOC_FREE(blob1.data);
6914 data_blob_free(&blob2);
6919 static bool run_local_gencache(int dummy)
6925 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6926 d_printf("%s: gencache_set() failed\n", __location__);
6930 if (!gencache_get("foo", NULL, NULL)) {
6931 d_printf("%s: gencache_get() failed\n", __location__);
6935 if (!gencache_get("foo", &val, &tm)) {
6936 d_printf("%s: gencache_get() failed\n", __location__);
6940 if (strcmp(val, "bar") != 0) {
6941 d_printf("%s: gencache_get() returned %s, expected %s\n",
6942 __location__, val, "bar");
6949 if (!gencache_del("foo")) {
6950 d_printf("%s: gencache_del() failed\n", __location__);
6953 if (gencache_del("foo")) {
6954 d_printf("%s: second gencache_del() succeeded\n",
6959 if (gencache_get("foo", &val, &tm)) {
6960 d_printf("%s: gencache_get() on deleted entry "
6961 "succeeded\n", __location__);
6965 blob = data_blob_string_const_null("bar");
6966 tm = time(NULL) + 60;
6968 if (!gencache_set_data_blob("foo", &blob, tm)) {
6969 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6973 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6974 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6978 if (strcmp((const char *)blob.data, "bar") != 0) {
6979 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6980 __location__, (const char *)blob.data, "bar");
6981 data_blob_free(&blob);
6985 data_blob_free(&blob);
6987 if (!gencache_del("foo")) {
6988 d_printf("%s: gencache_del() failed\n", __location__);
6991 if (gencache_del("foo")) {
6992 d_printf("%s: second gencache_del() succeeded\n",
6997 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6998 d_printf("%s: gencache_get_data_blob() on deleted entry "
6999 "succeeded\n", __location__);
7006 static bool rbt_testval(struct db_context *db, const char *key,
7009 struct db_record *rec;
7010 TDB_DATA data = string_tdb_data(value);
7014 rec = db->fetch_locked(db, db, string_tdb_data(key));
7016 d_fprintf(stderr, "fetch_locked failed\n");
7019 status = rec->store(rec, data, 0);
7020 if (!NT_STATUS_IS_OK(status)) {
7021 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7026 rec = db->fetch_locked(db, db, string_tdb_data(key));
7028 d_fprintf(stderr, "second fetch_locked failed\n");
7031 if ((rec->value.dsize != data.dsize)
7032 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7033 d_fprintf(stderr, "Got wrong data back\n");
7043 static bool run_local_rbtree(int dummy)
7045 struct db_context *db;
7049 db = db_open_rbt(NULL);
7052 d_fprintf(stderr, "db_open_rbt failed\n");
7056 for (i=0; i<1000; i++) {
7059 if (asprintf(&key, "key%ld", random()) == -1) {
7062 if (asprintf(&value, "value%ld", random()) == -1) {
7067 if (!rbt_testval(db, key, value)) {
7074 if (asprintf(&value, "value%ld", random()) == -1) {
7079 if (!rbt_testval(db, key, value)) {
7096 struct talloc_dict_test {
7100 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7102 int *count = (int *)priv;
7107 static bool run_local_talloc_dict(int dummy)
7109 struct talloc_dict *dict;
7110 struct talloc_dict_test *t;
7113 dict = talloc_dict_init(talloc_tos());
7118 t = talloc(talloc_tos(), struct talloc_dict_test);
7125 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7130 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7143 static bool run_local_string_to_sid(int dummy) {
7146 if (string_to_sid(&sid, "S--1-5-32-545")) {
7147 printf("allowing S--1-5-32-545\n");
7150 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7151 printf("allowing S-1-5-32-+545\n");
7154 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")) {
7155 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7158 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7159 printf("allowing S-1-5-32-545-abc\n");
7162 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7163 printf("could not parse S-1-5-32-545\n");
7166 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7167 printf("mis-parsed S-1-5-32-545 as %s\n",
7168 sid_string_tos(&sid));
7174 static bool run_local_binary_to_sid(int dummy) {
7175 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7176 static const char good_binary_sid[] = {
7177 0x1, /* revision number */
7179 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7180 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7181 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7182 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7183 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7184 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7185 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7186 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7187 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7188 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7189 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7190 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7191 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7192 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7193 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7194 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7197 static const char long_binary_sid[] = {
7198 0x1, /* revision number */
7200 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7201 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7202 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7203 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7204 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7205 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7206 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7207 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7208 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7209 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7210 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7211 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7212 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7213 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7214 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7215 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7216 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7217 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7218 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7221 static const char long_binary_sid2[] = {
7222 0x1, /* revision number */
7224 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7225 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7226 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7227 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7228 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7229 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7230 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7231 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7232 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7233 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7234 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7235 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7236 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7237 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7238 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7239 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7240 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7241 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7242 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7243 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7244 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7245 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7246 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7247 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7248 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7249 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7250 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7251 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7252 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7253 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7254 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7255 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7256 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7259 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7262 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7265 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7271 /* Split a path name into filename and stream name components. Canonicalise
7272 * such that an implicit $DATA token is always explicit.
7274 * The "specification" of this function can be found in the
7275 * run_local_stream_name() function in torture.c, I've tried those
7276 * combinations against a W2k3 server.
7279 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7280 char **pbase, char **pstream)
7283 char *stream = NULL;
7284 char *sname; /* stream name */
7285 const char *stype; /* stream type */
7287 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7289 sname = strchr_m(fname, ':');
7291 if (lp_posix_pathnames() || (sname == NULL)) {
7292 if (pbase != NULL) {
7293 base = talloc_strdup(mem_ctx, fname);
7294 NT_STATUS_HAVE_NO_MEMORY(base);
7299 if (pbase != NULL) {
7300 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7301 NT_STATUS_HAVE_NO_MEMORY(base);
7306 stype = strchr_m(sname, ':');
7308 if (stype == NULL) {
7309 sname = talloc_strdup(mem_ctx, sname);
7313 if (StrCaseCmp(stype, ":$DATA") != 0) {
7315 * If there is an explicit stream type, so far we only
7316 * allow $DATA. Is there anything else allowed? -- vl
7318 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7320 return NT_STATUS_OBJECT_NAME_INVALID;
7322 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7326 if (sname == NULL) {
7328 return NT_STATUS_NO_MEMORY;
7331 if (sname[0] == '\0') {
7333 * no stream name, so no stream
7338 if (pstream != NULL) {
7339 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7340 if (stream == NULL) {
7343 return NT_STATUS_NO_MEMORY;
7346 * upper-case the type field
7348 strupper_m(strchr_m(stream, ':')+1);
7352 if (pbase != NULL) {
7355 if (pstream != NULL) {
7358 return NT_STATUS_OK;
7361 static bool test_stream_name(const char *fname, const char *expected_base,
7362 const char *expected_stream,
7363 NTSTATUS expected_status)
7367 char *stream = NULL;
7369 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7370 if (!NT_STATUS_EQUAL(status, expected_status)) {
7374 if (!NT_STATUS_IS_OK(status)) {
7378 if (base == NULL) goto error;
7380 if (strcmp(expected_base, base) != 0) goto error;
7382 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7383 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7385 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7389 TALLOC_FREE(stream);
7393 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7394 fname, expected_base ? expected_base : "<NULL>",
7395 expected_stream ? expected_stream : "<NULL>",
7396 nt_errstr(expected_status));
7397 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7398 base ? base : "<NULL>", stream ? stream : "<NULL>",
7401 TALLOC_FREE(stream);
7405 static bool run_local_stream_name(int dummy)
7409 ret &= test_stream_name(
7410 "bla", "bla", NULL, NT_STATUS_OK);
7411 ret &= test_stream_name(
7412 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7413 ret &= test_stream_name(
7414 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7415 ret &= test_stream_name(
7416 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7417 ret &= test_stream_name(
7418 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7419 ret &= test_stream_name(
7420 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7421 ret &= test_stream_name(
7422 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7423 ret &= test_stream_name(
7424 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7429 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7431 if (a.length != b.length) {
7432 printf("a.length=%d != b.length=%d\n",
7433 (int)a.length, (int)b.length);
7436 if (memcmp(a.data, b.data, a.length) != 0) {
7437 printf("a.data and b.data differ\n");
7443 static bool run_local_memcache(int dummy)
7445 struct memcache *cache;
7447 DATA_BLOB d1, d2, d3;
7448 DATA_BLOB v1, v2, v3;
7450 TALLOC_CTX *mem_ctx;
7452 size_t size1, size2;
7455 cache = memcache_init(NULL, 100);
7457 if (cache == NULL) {
7458 printf("memcache_init failed\n");
7462 d1 = data_blob_const("d1", 2);
7463 d2 = data_blob_const("d2", 2);
7464 d3 = data_blob_const("d3", 2);
7466 k1 = data_blob_const("d1", 2);
7467 k2 = data_blob_const("d2", 2);
7469 memcache_add(cache, STAT_CACHE, k1, d1);
7470 memcache_add(cache, GETWD_CACHE, k2, d2);
7472 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7473 printf("could not find k1\n");
7476 if (!data_blob_equal(d1, v1)) {
7480 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7481 printf("could not find k2\n");
7484 if (!data_blob_equal(d2, v2)) {
7488 memcache_add(cache, STAT_CACHE, k1, d3);
7490 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7491 printf("could not find replaced k1\n");
7494 if (!data_blob_equal(d3, v3)) {
7498 memcache_add(cache, GETWD_CACHE, k1, d1);
7500 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7501 printf("Did find k2, should have been purged\n");
7507 cache = memcache_init(NULL, 0);
7509 mem_ctx = talloc_init("foo");
7511 str1 = talloc_strdup(mem_ctx, "string1");
7512 str2 = talloc_strdup(mem_ctx, "string2");
7514 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7515 data_blob_string_const("torture"), &str1);
7516 size1 = talloc_total_size(cache);
7518 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7519 data_blob_string_const("torture"), &str2);
7520 size2 = talloc_total_size(cache);
7522 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7524 if (size2 > size1) {
7525 printf("memcache leaks memory!\n");
7535 static void wbclient_done(struct tevent_req *req)
7538 struct winbindd_response *wb_resp;
7539 int *i = (int *)tevent_req_callback_data_void(req);
7541 wbc_err = wb_trans_recv(req, req, &wb_resp);
7544 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7547 static bool run_local_wbclient(int dummy)
7549 struct event_context *ev;
7550 struct wb_context **wb_ctx;
7551 struct winbindd_request wb_req;
7552 bool result = false;
7555 BlockSignals(True, SIGPIPE);
7557 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7562 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7563 if (wb_ctx == NULL) {
7567 ZERO_STRUCT(wb_req);
7568 wb_req.cmd = WINBINDD_PING;
7570 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7572 for (i=0; i<nprocs; i++) {
7573 wb_ctx[i] = wb_context_init(ev, NULL);
7574 if (wb_ctx[i] == NULL) {
7577 for (j=0; j<torture_numops; j++) {
7578 struct tevent_req *req;
7579 req = wb_trans_send(ev, ev, wb_ctx[i],
7580 (j % 2) == 0, &wb_req);
7584 tevent_req_set_callback(req, wbclient_done, &i);
7590 while (i < nprocs * torture_numops) {
7591 event_loop_once(ev);
7600 static void getaddrinfo_finished(struct tevent_req *req)
7602 char *name = (char *)tevent_req_callback_data_void(req);
7603 struct addrinfo *ainfo;
7606 res = getaddrinfo_recv(req, &ainfo);
7608 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7611 d_printf("gai(%s) succeeded\n", name);
7612 freeaddrinfo(ainfo);
7615 static bool run_getaddrinfo_send(int dummy)
7617 TALLOC_CTX *frame = talloc_stackframe();
7618 struct fncall_context *ctx;
7619 struct tevent_context *ev;
7620 bool result = false;
7621 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7622 "www.slashdot.org", "heise.de" };
7623 struct tevent_req *reqs[4];
7626 ev = event_context_init(frame);
7631 ctx = fncall_context_init(frame, 4);
7633 for (i=0; i<ARRAY_SIZE(names); i++) {
7634 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7636 if (reqs[i] == NULL) {
7639 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7643 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7644 tevent_loop_once(ev);
7653 static bool dbtrans_inc(struct db_context *db)
7655 struct db_record *rec;
7660 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7662 printf(__location__ "fetch_lock failed\n");
7666 if (rec->value.dsize != sizeof(uint32_t)) {
7667 printf(__location__ "value.dsize = %d\n",
7668 (int)rec->value.dsize);
7672 val = (uint32_t *)rec->value.dptr;
7675 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7678 if (!NT_STATUS_IS_OK(status)) {
7679 printf(__location__ "store failed: %s\n",
7690 static bool run_local_dbtrans(int dummy)
7692 struct db_context *db;
7693 struct db_record *rec;
7698 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7699 O_RDWR|O_CREAT, 0600);
7701 printf("Could not open transtest.db\n");
7705 res = db->transaction_start(db);
7707 printf(__location__ "transaction_start failed\n");
7711 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7713 printf(__location__ "fetch_lock failed\n");
7717 if (rec->value.dptr == NULL) {
7719 status = rec->store(
7720 rec, make_tdb_data((uint8_t *)&initial,
7723 if (!NT_STATUS_IS_OK(status)) {
7724 printf(__location__ "store returned %s\n",
7732 res = db->transaction_commit(db);
7734 printf(__location__ "transaction_commit failed\n");
7742 res = db->transaction_start(db);
7744 printf(__location__ "transaction_start failed\n");
7748 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7749 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7753 for (i=0; i<10; i++) {
7754 if (!dbtrans_inc(db)) {
7759 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7760 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7764 if (val2 != val + 10) {
7765 printf(__location__ "val=%d, val2=%d\n",
7766 (int)val, (int)val2);
7770 printf("val2=%d\r", val2);
7772 res = db->transaction_commit(db);
7774 printf(__location__ "transaction_commit failed\n");
7784 * Just a dummy test to be run under a debugger. There's no real way
7785 * to inspect the tevent_select specific function from outside of
7789 static bool run_local_tevent_select(int dummy)
7791 struct tevent_context *ev;
7792 struct tevent_fd *fd1, *fd2;
7793 bool result = false;
7795 ev = tevent_context_init_byname(NULL, "select");
7797 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7801 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7803 d_fprintf(stderr, "tevent_add_fd failed\n");
7806 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7808 d_fprintf(stderr, "tevent_add_fd failed\n");
7813 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7815 d_fprintf(stderr, "tevent_add_fd failed\n");
7825 static double create_procs(bool (*fn)(int), bool *result)
7828 volatile pid_t *child_status;
7829 volatile bool *child_status_out;
7832 struct timeval start;
7836 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7837 if (!child_status) {
7838 printf("Failed to setup shared memory\n");
7842 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7843 if (!child_status_out) {
7844 printf("Failed to setup result status shared memory\n");
7848 for (i = 0; i < nprocs; i++) {
7849 child_status[i] = 0;
7850 child_status_out[i] = True;
7853 start = timeval_current();
7855 for (i=0;i<nprocs;i++) {
7858 pid_t mypid = getpid();
7859 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7861 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7864 if (torture_open_connection(¤t_cli, i)) break;
7866 printf("pid %d failed to start\n", (int)getpid());
7872 child_status[i] = getpid();
7874 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7876 child_status_out[i] = fn(i);
7883 for (i=0;i<nprocs;i++) {
7884 if (child_status[i]) synccount++;
7886 if (synccount == nprocs) break;
7888 } while (timeval_elapsed(&start) < 30);
7890 if (synccount != nprocs) {
7891 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7893 return timeval_elapsed(&start);
7896 /* start the client load */
7897 start = timeval_current();
7899 for (i=0;i<nprocs;i++) {
7900 child_status[i] = 0;
7903 printf("%d clients started\n", nprocs);
7905 for (i=0;i<nprocs;i++) {
7906 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7911 for (i=0;i<nprocs;i++) {
7912 if (!child_status_out[i]) {
7916 return timeval_elapsed(&start);
7919 #define FLAG_MULTIPROC 1
7926 {"FDPASS", run_fdpasstest, 0},
7927 {"LOCK1", run_locktest1, 0},
7928 {"LOCK2", run_locktest2, 0},
7929 {"LOCK3", run_locktest3, 0},
7930 {"LOCK4", run_locktest4, 0},
7931 {"LOCK5", run_locktest5, 0},
7932 {"LOCK6", run_locktest6, 0},
7933 {"LOCK7", run_locktest7, 0},
7934 {"LOCK8", run_locktest8, 0},
7935 {"LOCK9", run_locktest9, 0},
7936 {"UNLINK", run_unlinktest, 0},
7937 {"BROWSE", run_browsetest, 0},
7938 {"ATTR", run_attrtest, 0},
7939 {"TRANS2", run_trans2test, 0},
7940 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7941 {"TORTURE",run_torture, FLAG_MULTIPROC},
7942 {"RANDOMIPC", run_randomipc, 0},
7943 {"NEGNOWAIT", run_negprot_nowait, 0},
7944 {"NBENCH", run_nbench, 0},
7945 {"NBENCH2", run_nbench2, 0},
7946 {"OPLOCK1", run_oplock1, 0},
7947 {"OPLOCK2", run_oplock2, 0},
7948 {"OPLOCK3", run_oplock3, 0},
7949 {"OPLOCK4", run_oplock4, 0},
7950 {"DIR", run_dirtest, 0},
7951 {"DIR1", run_dirtest1, 0},
7952 {"DIR-CREATETIME", run_dir_createtime, 0},
7953 {"DENY1", torture_denytest1, 0},
7954 {"DENY2", torture_denytest2, 0},
7955 {"TCON", run_tcon_test, 0},
7956 {"TCONDEV", run_tcon_devtype_test, 0},
7957 {"RW1", run_readwritetest, 0},
7958 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7959 {"RW3", run_readwritelarge, 0},
7960 {"RW-SIGNING", run_readwritelarge_signtest, 0},
7961 {"OPEN", run_opentest, 0},
7962 {"POSIX", run_simple_posix_open_test, 0},
7963 {"POSIX-APPEND", run_posix_append, 0},
7964 {"ASYNC-ECHO", run_async_echo, 0},
7965 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7966 { "SHORTNAME-TEST", run_shortname_test, 0},
7968 {"OPENATTR", run_openattrtest, 0},
7970 {"XCOPY", run_xcopy, 0},
7971 {"RENAME", run_rename, 0},
7972 {"DELETE", run_deletetest, 0},
7973 {"PROPERTIES", run_properties, 0},
7974 {"MANGLE", torture_mangle, 0},
7975 {"MANGLE1", run_mangle1, 0},
7976 {"W2K", run_w2ktest, 0},
7977 {"TRANS2SCAN", torture_trans2_scan, 0},
7978 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7979 {"UTABLE", torture_utable, 0},
7980 {"CASETABLE", torture_casetable, 0},
7981 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7982 {"PIPE_NUMBER", run_pipe_number, 0},
7983 {"TCON2", run_tcon2_test, 0},
7984 {"IOCTL", torture_ioctl_test, 0},
7985 {"CHKPATH", torture_chkpath_test, 0},
7986 {"FDSESS", run_fdsesstest, 0},
7987 { "EATEST", run_eatest, 0},
7988 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7989 { "CHAIN1", run_chain1, 0},
7990 { "CHAIN2", run_chain2, 0},
7991 { "WINDOWS-WRITE", run_windows_write, 0},
7992 { "CLI_ECHO", run_cli_echo, 0},
7993 { "GETADDRINFO", run_getaddrinfo_send, 0},
7994 { "TLDAP", run_tldap },
7995 { "STREAMERROR", run_streamerror },
7996 { "NOTIFY-BENCH", run_notify_bench },
7997 { "BAD-NBT-SESSION", run_bad_nbt_session },
7998 { "SMB-ANY-CONNECT", run_smb_any_connect },
7999 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8000 { "LOCAL-GENCACHE", run_local_gencache, 0},
8001 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8002 { "LOCAL-BASE64", run_local_base64, 0},
8003 { "LOCAL-RBTREE", run_local_rbtree, 0},
8004 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8005 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8006 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8007 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8008 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8009 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8010 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8015 /****************************************************************************
8016 run a specified test or "ALL"
8017 ****************************************************************************/
8018 static bool run_test(const char *name)
8025 if (strequal(name,"ALL")) {
8026 for (i=0;torture_ops[i].name;i++) {
8027 run_test(torture_ops[i].name);
8032 for (i=0;torture_ops[i].name;i++) {
8033 fstr_sprintf(randomfname, "\\XX%x",
8034 (unsigned)random());
8036 if (strequal(name, torture_ops[i].name)) {
8038 printf("Running %s\n", name);
8039 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8040 t = create_procs(torture_ops[i].fn, &result);
8043 printf("TEST %s FAILED!\n", name);
8046 struct timeval start;
8047 start = timeval_current();
8048 if (!torture_ops[i].fn(0)) {
8050 printf("TEST %s FAILED!\n", name);
8052 t = timeval_elapsed(&start);
8054 printf("%s took %g secs\n\n", name, t);
8059 printf("Did not find a test named %s\n", name);
8067 static void usage(void)
8071 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8072 printf("Please use samba4 torture.\n\n");
8074 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8076 printf("\t-d debuglevel\n");
8077 printf("\t-U user%%pass\n");
8078 printf("\t-k use kerberos\n");
8079 printf("\t-N numprocs\n");
8080 printf("\t-n my_netbios_name\n");
8081 printf("\t-W workgroup\n");
8082 printf("\t-o num_operations\n");
8083 printf("\t-O socket_options\n");
8084 printf("\t-m maximum protocol\n");
8085 printf("\t-L use oplocks\n");
8086 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8087 printf("\t-A showall\n");
8088 printf("\t-p port\n");
8089 printf("\t-s seed\n");
8090 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8093 printf("tests are:");
8094 for (i=0;torture_ops[i].name;i++) {
8095 printf(" %s", torture_ops[i].name);
8099 printf("default test is ALL\n");
8104 /****************************************************************************
8106 ****************************************************************************/
8107 int main(int argc,char *argv[])
8113 bool correct = True;
8114 TALLOC_CTX *frame = talloc_stackframe();
8115 int seed = time(NULL);
8117 #ifdef HAVE_SETBUFFER
8118 setbuffer(stdout, NULL, 0);
8121 setup_logging("smbtorture", DEBUG_STDOUT);
8125 if (is_default_dyn_CONFIGFILE()) {
8126 if(getenv("SMB_CONF_PATH")) {
8127 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8130 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8137 for(p = argv[1]; *p; p++)
8141 if (strncmp(argv[1], "//", 2)) {
8145 fstrcpy(host, &argv[1][2]);
8146 p = strchr_m(&host[2],'/');
8151 fstrcpy(share, p+1);
8153 fstrcpy(myname, get_myname(talloc_tos()));
8155 fprintf(stderr, "Failed to get my hostname.\n");
8159 if (*username == 0 && getenv("LOGNAME")) {
8160 fstrcpy(username,getenv("LOGNAME"));
8166 fstrcpy(workgroup, lp_workgroup());
8168 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8171 port_to_use = atoi(optarg);
8174 seed = atoi(optarg);
8177 fstrcpy(workgroup,optarg);
8180 max_protocol = interpret_protocol(optarg, max_protocol);
8183 nprocs = atoi(optarg);
8186 torture_numops = atoi(optarg);
8189 lp_set_cmdline("log level", optarg);
8198 local_path = optarg;
8201 torture_showall = True;
8204 fstrcpy(myname, optarg);
8207 client_txt = optarg;
8214 use_kerberos = True;
8216 d_printf("No kerberos support compiled in\n");
8222 fstrcpy(username,optarg);
8223 p = strchr_m(username,'%');
8226 fstrcpy(password, p+1);
8231 fstrcpy(multishare_conn_fname, optarg);
8232 use_multishare_conn = True;
8235 torture_blocksize = atoi(optarg);
8238 printf("Unknown option %c (%d)\n", (char)opt, opt);
8243 d_printf("using seed %d\n", seed);
8247 if(use_kerberos && !gotuser) gotpass = True;
8250 p = getpass("Password:");
8252 fstrcpy(password, p);
8257 printf("host=%s share=%s user=%s myname=%s\n",
8258 host, share, username, myname);
8260 if (argc == optind) {
8261 correct = run_test("ALL");
8263 for (i=optind;i<argc;i++) {
8264 if (!run_test(argv[i])) {