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;
670 NTSTATUS status = NT_STATUS_OK;
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)) {
4001 static bool run_deletetest_ln(int dummy)
4003 struct cli_state *cli;
4004 const char *fname = "\\delete1";
4005 const char *fname_ln = "\\delete1_ln";
4009 bool correct = true;
4012 printf("starting deletetest-ln\n");
4014 if (!torture_open_connection(&cli, 0)) {
4018 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4019 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4021 cli_sockopt(cli, sockops);
4023 /* Create the file. */
4024 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4025 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4029 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4030 printf("close1 failed (%s)\n", cli_errstr(cli));
4034 /* Now create a hardlink. */
4035 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4036 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4040 /* Open the original file. */
4041 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4042 FILE_ATTRIBUTE_NORMAL,
4043 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4044 FILE_OPEN_IF, 0, 0, &fnum);
4045 if (!NT_STATUS_IS_OK(status)) {
4046 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4050 /* Unlink the hard link path. */
4051 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4052 FILE_ATTRIBUTE_NORMAL,
4053 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4054 FILE_OPEN_IF, 0, 0, &fnum1);
4055 if (!NT_STATUS_IS_OK(status)) {
4056 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4059 status = cli_nt_delete_on_close(cli, fnum1, true);
4060 if (!NT_STATUS_IS_OK(status)) {
4061 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4062 __location__, fname_ln, nt_errstr(status));
4066 status = cli_close(cli, fnum1);
4067 if (!NT_STATUS_IS_OK(status)) {
4068 printf("close %s failed (%s)\n",
4069 fname_ln, nt_errstr(status));
4073 status = cli_close(cli, fnum);
4074 if (!NT_STATUS_IS_OK(status)) {
4075 printf("close %s failed (%s)\n",
4076 fname, nt_errstr(status));
4080 /* Ensure the original file is still there. */
4081 status = cli_getatr(cli, fname, NULL, NULL, &t);
4082 if (!NT_STATUS_IS_OK(status)) {
4083 printf("%s getatr on file %s failed (%s)\n",
4090 /* Ensure the link path is gone. */
4091 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4092 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4093 printf("%s, getatr for file %s returned wrong error code %s "
4094 "- should have been deleted\n",
4096 fname_ln, nt_errstr(status));
4100 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4101 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4103 if (!torture_close_connection(cli)) {
4107 printf("finished deletetest-ln\n");
4113 print out server properties
4115 static bool run_properties(int dummy)
4117 struct cli_state *cli;
4118 bool correct = True;
4120 printf("starting properties test\n");
4124 if (!torture_open_connection(&cli, 0)) {
4128 cli_sockopt(cli, sockops);
4130 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4132 if (!torture_close_connection(cli)) {
4141 /* FIRST_DESIRED_ACCESS 0xf019f */
4142 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4143 FILE_READ_EA| /* 0xf */ \
4144 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4145 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4146 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4147 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4148 /* SECOND_DESIRED_ACCESS 0xe0080 */
4149 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4150 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4151 WRITE_OWNER_ACCESS /* 0xe0000 */
4154 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4155 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4157 WRITE_OWNER_ACCESS /* */
4161 Test ntcreate calls made by xcopy
4163 static bool run_xcopy(int dummy)
4165 static struct cli_state *cli1;
4166 const char *fname = "\\test.txt";
4167 bool correct = True;
4168 uint16_t fnum1, fnum2;
4170 printf("starting xcopy test\n");
4172 if (!torture_open_connection(&cli1, 0)) {
4176 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4177 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4178 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4179 0x4044, 0, &fnum1))) {
4180 printf("First open failed - %s\n", cli_errstr(cli1));
4184 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4185 SECOND_DESIRED_ACCESS, 0,
4186 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4187 0x200000, 0, &fnum2))) {
4188 printf("second open failed - %s\n", cli_errstr(cli1));
4192 if (!torture_close_connection(cli1)) {
4200 Test rename on files open with share delete and no share delete.
4202 static bool run_rename(int dummy)
4204 static struct cli_state *cli1;
4205 const char *fname = "\\test.txt";
4206 const char *fname1 = "\\test1.txt";
4207 bool correct = True;
4212 printf("starting rename test\n");
4214 if (!torture_open_connection(&cli1, 0)) {
4218 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4219 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4220 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4221 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4222 printf("First open failed - %s\n", cli_errstr(cli1));
4226 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4227 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4229 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4233 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4234 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4238 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4239 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4240 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4242 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4244 FILE_SHARE_DELETE|FILE_SHARE_READ,
4246 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4247 if (!NT_STATUS_IS_OK(status)) {
4248 printf("Second open failed - %s\n", cli_errstr(cli1));
4252 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4253 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4256 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4259 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4260 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4264 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4265 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4267 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4268 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4269 printf("Third open failed - %s\n", cli_errstr(cli1));
4278 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4279 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4280 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4283 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4284 printf("[8] setting delete_on_close on file failed !\n");
4288 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4289 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4295 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4296 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4299 printf("Third rename succeeded (SHARE_NONE)\n");
4302 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4303 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4307 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4308 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4312 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4313 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4314 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4318 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4319 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4321 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4325 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4326 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4330 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4331 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4335 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4336 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4337 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4341 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4342 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4346 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4350 * Now check if the first name still exists ...
4353 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4354 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4355 printf("Opening original file after rename of open file fails: %s\n",
4359 printf("Opening original file after rename of open file works ...\n");
4360 (void)cli_close(cli1, fnum2);
4364 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4365 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4369 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4370 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4371 printf("getatr on file %s failed - %s ! \n",
4376 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4377 printf("Renamed file %s has wrong attr 0x%x "
4378 "(should be 0x%x)\n",
4381 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4384 printf("Renamed file %s has archive bit set\n", fname1);
4388 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4389 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4391 if (!torture_close_connection(cli1)) {
4398 static bool run_pipe_number(int dummy)
4400 struct cli_state *cli1;
4401 const char *pipe_name = "\\SPOOLSS";
4405 printf("starting pipenumber test\n");
4406 if (!torture_open_connection(&cli1, 0)) {
4410 cli_sockopt(cli1, sockops);
4412 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4413 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4414 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4418 printf("\r%6d", num_pipes);
4421 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4422 torture_close_connection(cli1);
4427 Test open mode returns on read-only files.
4429 static bool run_opentest(int dummy)
4431 static struct cli_state *cli1;
4432 static struct cli_state *cli2;
4433 const char *fname = "\\readonly.file";
4434 uint16_t fnum1, fnum2;
4437 bool correct = True;
4441 printf("starting open test\n");
4443 if (!torture_open_connection(&cli1, 0)) {
4447 cli_setatr(cli1, fname, 0, 0);
4448 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4450 cli_sockopt(cli1, sockops);
4452 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4453 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4457 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4458 printf("close2 failed (%s)\n", cli_errstr(cli1));
4462 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4463 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4467 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4468 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4472 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4473 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4475 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4476 NT_STATUS_ACCESS_DENIED)) {
4477 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4480 printf("finished open test 1\n");
4482 cli_close(cli1, fnum1);
4484 /* Now try not readonly and ensure ERRbadshare is returned. */
4486 cli_setatr(cli1, fname, 0, 0);
4488 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4489 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4493 /* This will fail - but the error should be ERRshare. */
4494 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4496 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4497 NT_STATUS_SHARING_VIOLATION)) {
4498 printf("correct error code ERRDOS/ERRbadshare returned\n");
4501 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4502 printf("close2 failed (%s)\n", cli_errstr(cli1));
4506 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4508 printf("finished open test 2\n");
4510 /* Test truncate open disposition on file opened for read. */
4512 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4513 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4517 /* write 20 bytes. */
4519 memset(buf, '\0', 20);
4521 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4522 printf("write failed (%s)\n", cli_errstr(cli1));
4526 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4527 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4531 /* Ensure size == 20. */
4532 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4533 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4538 printf("(3) file size != 20\n");
4542 /* Now test if we can truncate a file opened for readonly. */
4544 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4545 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4549 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4550 printf("close2 failed (%s)\n", cli_errstr(cli1));
4554 /* Ensure size == 0. */
4555 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4556 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4561 printf("(3) file size != 0\n");
4564 printf("finished open test 3\n");
4566 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4568 printf("Do ctemp tests\n");
4569 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4570 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4573 printf("ctemp gave path %s\n", tmp_path);
4574 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4575 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4577 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4578 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4581 /* Test the non-io opens... */
4583 if (!torture_open_connection(&cli2, 1)) {
4587 cli_setatr(cli2, fname, 0, 0);
4588 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4590 cli_sockopt(cli2, sockops);
4592 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4594 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4595 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4596 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4600 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4601 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4602 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4606 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4607 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4610 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4611 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4615 printf("non-io open test #1 passed.\n");
4617 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4619 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4621 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4622 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4623 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4627 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4628 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4629 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4633 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4634 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4637 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4638 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4642 printf("non-io open test #2 passed.\n");
4644 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4646 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4648 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4649 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4650 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4654 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4655 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4656 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4660 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4661 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4664 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4665 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4669 printf("non-io open test #3 passed.\n");
4671 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4673 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4675 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4676 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4677 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4681 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4682 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4683 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4687 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4689 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4690 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4694 printf("non-io open test #4 passed.\n");
4696 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4698 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4700 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4701 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4702 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4706 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4707 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4708 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4712 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4713 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4717 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4718 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4722 printf("non-io open test #5 passed.\n");
4724 printf("TEST #6 testing 1 non-io open, one io open\n");
4726 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4728 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4729 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4730 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4734 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4735 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4736 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4740 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4741 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4745 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4746 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4750 printf("non-io open test #6 passed.\n");
4752 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4754 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4756 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4757 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4758 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4762 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4763 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4764 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4768 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4770 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4771 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4775 printf("non-io open test #7 passed.\n");
4777 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4779 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4780 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4781 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4782 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4783 if (!NT_STATUS_IS_OK(status)) {
4784 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4789 /* Write to ensure we have to update the file time. */
4790 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4791 printf("TEST #8 cli_write failed: %s\n", cli_errstr(cli1));
4796 status = cli_close(cli1, fnum1);
4797 if (!NT_STATUS_IS_OK(status)) {
4798 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4804 if (!torture_close_connection(cli1)) {
4807 if (!torture_close_connection(cli2)) {
4814 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4816 uint16 major, minor;
4817 uint32 caplow, caphigh;
4820 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4821 printf("Server doesn't support UNIX CIFS extensions.\n");
4822 return NT_STATUS_NOT_SUPPORTED;
4825 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4827 if (!NT_STATUS_IS_OK(status)) {
4828 printf("Server didn't return UNIX CIFS extensions: %s\n",
4833 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4835 if (!NT_STATUS_IS_OK(status)) {
4836 printf("Server doesn't support setting UNIX CIFS extensions: "
4837 "%s.\n", nt_errstr(status));
4841 return NT_STATUS_OK;
4845 Test POSIX open /mkdir calls.
4847 static bool run_simple_posix_open_test(int dummy)
4849 static struct cli_state *cli1;
4850 const char *fname = "posix:file";
4851 const char *hname = "posix:hlink";
4852 const char *sname = "posix:symlink";
4853 const char *dname = "posix:dir";
4856 uint16_t fnum1 = (uint16_t)-1;
4857 SMB_STRUCT_STAT sbuf;
4858 bool correct = false;
4861 printf("Starting simple POSIX open test\n");
4863 if (!torture_open_connection(&cli1, 0)) {
4867 cli_sockopt(cli1, sockops);
4869 status = torture_setup_unix_extensions(cli1);
4870 if (!NT_STATUS_IS_OK(status)) {
4874 cli_setatr(cli1, fname, 0, 0);
4875 cli_posix_unlink(cli1, fname);
4876 cli_setatr(cli1, dname, 0, 0);
4877 cli_posix_rmdir(cli1, dname);
4878 cli_setatr(cli1, hname, 0, 0);
4879 cli_posix_unlink(cli1, hname);
4880 cli_setatr(cli1, sname, 0, 0);
4881 cli_posix_unlink(cli1, sname);
4883 /* Create a directory. */
4884 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4885 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4889 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4890 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4894 /* Test ftruncate - set file size. */
4895 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4896 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4900 /* Ensure st_size == 1000 */
4901 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4902 printf("stat failed (%s)\n", cli_errstr(cli1));
4906 if (sbuf.st_ex_size != 1000) {
4907 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4911 /* Test ftruncate - set file size back to zero. */
4912 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4913 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4917 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4918 printf("close failed (%s)\n", cli_errstr(cli1));
4922 /* Now open the file again for read only. */
4923 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4924 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4928 /* Now unlink while open. */
4929 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4930 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4934 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4935 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4939 /* Ensure the file has gone. */
4940 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4941 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4945 /* What happens when we try and POSIX open a directory ? */
4946 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4947 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4950 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4951 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4956 /* Create the file. */
4957 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4958 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4962 /* Write some data into it. */
4963 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4964 printf("cli_write failed: %s\n", cli_errstr(cli1));
4968 cli_close(cli1, fnum1);
4970 /* Now create a hardlink. */
4971 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4972 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4976 /* Now create a symlink. */
4977 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4978 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4982 /* Open the hardlink for read. */
4983 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4984 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4988 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4989 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4993 if (memcmp(buf, "TEST DATA\n", 10)) {
4994 printf("invalid data read from hardlink\n");
4998 /* Do a POSIX lock/unlock. */
4999 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5000 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5004 /* Punch a hole in the locked area. */
5005 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5006 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5010 cli_close(cli1, fnum1);
5012 /* Open the symlink for read - this should fail. A POSIX
5013 client should not be doing opens on a symlink. */
5014 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5015 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5018 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5019 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5020 printf("POSIX open of %s should have failed "
5021 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5022 "failed with %s instead.\n",
5023 sname, cli_errstr(cli1));
5028 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5029 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5033 if (strcmp(namebuf, fname) != 0) {
5034 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5035 sname, fname, namebuf);
5039 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5040 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5044 printf("Simple POSIX open test passed\n");
5049 if (fnum1 != (uint16_t)-1) {
5050 cli_close(cli1, fnum1);
5051 fnum1 = (uint16_t)-1;
5054 cli_setatr(cli1, sname, 0, 0);
5055 cli_posix_unlink(cli1, sname);
5056 cli_setatr(cli1, hname, 0, 0);
5057 cli_posix_unlink(cli1, hname);
5058 cli_setatr(cli1, fname, 0, 0);
5059 cli_posix_unlink(cli1, fname);
5060 cli_setatr(cli1, dname, 0, 0);
5061 cli_posix_rmdir(cli1, dname);
5063 if (!torture_close_connection(cli1)) {
5071 static uint32 open_attrs_table[] = {
5072 FILE_ATTRIBUTE_NORMAL,
5073 FILE_ATTRIBUTE_ARCHIVE,
5074 FILE_ATTRIBUTE_READONLY,
5075 FILE_ATTRIBUTE_HIDDEN,
5076 FILE_ATTRIBUTE_SYSTEM,
5078 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5079 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5080 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5081 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5082 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5083 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5085 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5086 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5087 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5088 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5091 struct trunc_open_results {
5098 static struct trunc_open_results attr_results[] = {
5099 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5100 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5101 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5102 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5103 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5104 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5105 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5106 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5107 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5108 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5109 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5110 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5111 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5112 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5113 { 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 },
5114 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5115 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5116 { 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 },
5117 { 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 },
5118 { 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 },
5119 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5120 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5121 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5122 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5123 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5124 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5127 static bool run_openattrtest(int dummy)
5129 static struct cli_state *cli1;
5130 const char *fname = "\\openattr.file";
5132 bool correct = True;
5134 unsigned int i, j, k, l;
5136 printf("starting open attr test\n");
5138 if (!torture_open_connection(&cli1, 0)) {
5142 cli_sockopt(cli1, sockops);
5144 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5145 cli_setatr(cli1, fname, 0, 0);
5146 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5147 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5148 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5149 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5153 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5154 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5158 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5159 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5160 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5161 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5162 if (attr_results[l].num == k) {
5163 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5164 k, open_attrs_table[i],
5165 open_attrs_table[j],
5166 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5170 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5171 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5172 k, open_attrs_table[i], open_attrs_table[j],
5177 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5183 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5184 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5188 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5189 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5194 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5195 k, open_attrs_table[i], open_attrs_table[j], attr );
5198 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5199 if (attr_results[l].num == k) {
5200 if (attr != attr_results[l].result_attr ||
5201 open_attrs_table[i] != attr_results[l].init_attr ||
5202 open_attrs_table[j] != attr_results[l].trunc_attr) {
5203 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5204 open_attrs_table[i],
5205 open_attrs_table[j],
5207 attr_results[l].result_attr);
5217 cli_setatr(cli1, fname, 0, 0);
5218 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5220 printf("open attr test %s.\n", correct ? "passed" : "failed");
5222 if (!torture_close_connection(cli1)) {
5228 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5229 const char *name, void *state)
5231 int *matched = (int *)state;
5232 if (matched != NULL) {
5235 return NT_STATUS_OK;
5239 test directory listing speed
5241 static bool run_dirtest(int dummy)
5244 static struct cli_state *cli;
5246 struct timeval core_start;
5247 bool correct = True;
5250 printf("starting directory test\n");
5252 if (!torture_open_connection(&cli, 0)) {
5256 cli_sockopt(cli, sockops);
5259 for (i=0;i<torture_numops;i++) {
5261 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5262 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5263 fprintf(stderr,"Failed to open %s\n", fname);
5266 cli_close(cli, fnum);
5269 core_start = timeval_current();
5272 cli_list(cli, "a*.*", 0, list_fn, &matched);
5273 printf("Matched %d\n", matched);
5276 cli_list(cli, "b*.*", 0, list_fn, &matched);
5277 printf("Matched %d\n", matched);
5280 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5281 printf("Matched %d\n", matched);
5283 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5286 for (i=0;i<torture_numops;i++) {
5288 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5289 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5292 if (!torture_close_connection(cli)) {
5296 printf("finished dirtest\n");
5301 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5304 struct cli_state *pcli = (struct cli_state *)state;
5306 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5308 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5309 return NT_STATUS_OK;
5311 if (finfo->mode & aDIR) {
5312 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5313 printf("del_fn: failed to rmdir %s\n,", fname );
5315 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5316 printf("del_fn: failed to unlink %s\n,", fname );
5318 return NT_STATUS_OK;
5323 sees what IOCTLs are supported
5325 bool torture_ioctl_test(int dummy)
5327 static struct cli_state *cli;
5328 uint16_t device, function;
5330 const char *fname = "\\ioctl.dat";
5334 if (!torture_open_connection(&cli, 0)) {
5338 printf("starting ioctl test\n");
5340 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5342 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5343 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5347 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5348 printf("ioctl device info: %s\n", nt_errstr(status));
5350 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5351 printf("ioctl job info: %s\n", nt_errstr(status));
5353 for (device=0;device<0x100;device++) {
5354 printf("ioctl test with device = 0x%x\n", device);
5355 for (function=0;function<0x100;function++) {
5356 uint32 code = (device<<16) | function;
5358 status = cli_raw_ioctl(cli, fnum, code, &blob);
5360 if (NT_STATUS_IS_OK(status)) {
5361 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5363 data_blob_free(&blob);
5368 if (!torture_close_connection(cli)) {
5377 tries varients of chkpath
5379 bool torture_chkpath_test(int dummy)
5381 static struct cli_state *cli;
5385 if (!torture_open_connection(&cli, 0)) {
5389 printf("starting chkpath test\n");
5391 /* cleanup from an old run */
5392 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5393 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5394 cli_rmdir(cli, "\\chkpath.dir");
5396 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5397 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5401 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5402 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5406 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5407 printf("open1 failed (%s)\n", cli_errstr(cli));
5410 cli_close(cli, fnum);
5412 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5413 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5417 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5418 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5422 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5423 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5424 NT_STATUS_NOT_A_DIRECTORY);
5426 printf("* chkpath on a file should fail\n");
5430 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5431 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5432 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5434 printf("* chkpath on a non existant file should fail\n");
5438 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5439 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5440 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5442 printf("* chkpath on a non existent component should fail\n");
5446 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5447 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5448 cli_rmdir(cli, "\\chkpath.dir");
5450 if (!torture_close_connection(cli)) {
5457 static bool run_eatest(int dummy)
5459 static struct cli_state *cli;
5460 const char *fname = "\\eatest.txt";
5461 bool correct = True;
5465 struct ea_struct *ea_list = NULL;
5466 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5469 printf("starting eatest\n");
5471 if (!torture_open_connection(&cli, 0)) {
5472 talloc_destroy(mem_ctx);
5476 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5477 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5478 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5479 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5480 0x4044, 0, &fnum))) {
5481 printf("open failed - %s\n", cli_errstr(cli));
5482 talloc_destroy(mem_ctx);
5486 for (i = 0; i < 10; i++) {
5487 fstring ea_name, ea_val;
5489 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5490 memset(ea_val, (char)i+1, i+1);
5491 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5492 if (!NT_STATUS_IS_OK(status)) {
5493 printf("ea_set of name %s failed - %s\n", ea_name,
5495 talloc_destroy(mem_ctx);
5500 cli_close(cli, fnum);
5501 for (i = 0; i < 10; i++) {
5502 fstring ea_name, ea_val;
5504 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5505 memset(ea_val, (char)i+1, i+1);
5506 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5507 if (!NT_STATUS_IS_OK(status)) {
5508 printf("ea_set of name %s failed - %s\n", ea_name,
5510 talloc_destroy(mem_ctx);
5515 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5516 if (!NT_STATUS_IS_OK(status)) {
5517 printf("ea_get list failed - %s\n", nt_errstr(status));
5521 printf("num_eas = %d\n", (int)num_eas);
5523 if (num_eas != 20) {
5524 printf("Should be 20 EA's stored... failing.\n");
5528 for (i = 0; i < num_eas; i++) {
5529 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5530 dump_data(0, ea_list[i].value.data,
5531 ea_list[i].value.length);
5534 /* Setting EA's to zero length deletes them. Test this */
5535 printf("Now deleting all EA's - case indepenent....\n");
5538 cli_set_ea_path(cli, fname, "", "", 0);
5540 for (i = 0; i < 20; i++) {
5542 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5543 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5544 if (!NT_STATUS_IS_OK(status)) {
5545 printf("ea_set of name %s failed - %s\n", ea_name,
5547 talloc_destroy(mem_ctx);
5553 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5554 if (!NT_STATUS_IS_OK(status)) {
5555 printf("ea_get list failed - %s\n", nt_errstr(status));
5559 printf("num_eas = %d\n", (int)num_eas);
5560 for (i = 0; i < num_eas; i++) {
5561 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5562 dump_data(0, ea_list[i].value.data,
5563 ea_list[i].value.length);
5567 printf("deleting EA's failed.\n");
5571 /* Try and delete a non existant EA. */
5572 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5573 if (!NT_STATUS_IS_OK(status)) {
5574 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5579 talloc_destroy(mem_ctx);
5580 if (!torture_close_connection(cli)) {
5587 static bool run_dirtest1(int dummy)
5590 static struct cli_state *cli;
5593 bool correct = True;
5595 printf("starting directory test\n");
5597 if (!torture_open_connection(&cli, 0)) {
5601 cli_sockopt(cli, sockops);
5603 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5604 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5605 cli_rmdir(cli, "\\LISTDIR");
5606 cli_mkdir(cli, "\\LISTDIR");
5608 /* Create 1000 files and 1000 directories. */
5609 for (i=0;i<1000;i++) {
5611 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5612 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5613 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5614 fprintf(stderr,"Failed to open %s\n", fname);
5617 cli_close(cli, fnum);
5619 for (i=0;i<1000;i++) {
5621 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5622 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5623 fprintf(stderr,"Failed to open %s\n", fname);
5628 /* Now ensure that doing an old list sees both files and directories. */
5630 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5631 printf("num_seen = %d\n", num_seen );
5632 /* We should see 100 files + 1000 directories + . and .. */
5633 if (num_seen != 2002)
5636 /* Ensure if we have the "must have" bits we only see the
5640 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5641 printf("num_seen = %d\n", num_seen );
5642 if (num_seen != 1002)
5646 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5647 printf("num_seen = %d\n", num_seen );
5648 if (num_seen != 1000)
5651 /* Delete everything. */
5652 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5653 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5654 cli_rmdir(cli, "\\LISTDIR");
5657 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5658 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5659 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5662 if (!torture_close_connection(cli)) {
5666 printf("finished dirtest1\n");
5671 static bool run_error_map_extract(int dummy) {
5673 static struct cli_state *c_dos;
5674 static struct cli_state *c_nt;
5679 uint32 flgs2, errnum;
5686 /* NT-Error connection */
5688 if (!(c_nt = open_nbt_connection())) {
5692 c_nt->use_spnego = False;
5694 status = cli_negprot(c_nt);
5696 if (!NT_STATUS_IS_OK(status)) {
5697 printf("%s rejected the NT-error negprot (%s)\n", host,
5703 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5705 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5709 /* DOS-Error connection */
5711 if (!(c_dos = open_nbt_connection())) {
5715 c_dos->use_spnego = False;
5716 c_dos->force_dos_errors = True;
5718 status = cli_negprot(c_dos);
5719 if (!NT_STATUS_IS_OK(status)) {
5720 printf("%s rejected the DOS-error negprot (%s)\n", host,
5722 cli_shutdown(c_dos);
5726 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5728 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5732 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5733 fstr_sprintf(user, "%X", error);
5735 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5736 password, strlen(password),
5737 password, strlen(password),
5739 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5742 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5744 /* Case #1: 32-bit NT errors */
5745 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5746 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5748 printf("/** Dos error on NT connection! (%s) */\n",
5750 nt_status = NT_STATUS(0xc0000000);
5753 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5754 password, strlen(password),
5755 password, strlen(password),
5757 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5759 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5761 /* Case #1: 32-bit NT errors */
5762 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5763 printf("/** NT error on DOS connection! (%s) */\n",
5765 errnum = errclass = 0;
5767 cli_dos_error(c_dos, &errclass, &errnum);
5770 if (NT_STATUS_V(nt_status) != error) {
5771 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5772 get_nt_error_c_code(NT_STATUS(error)),
5773 get_nt_error_c_code(nt_status));
5776 printf("\t{%s,\t%s,\t%s},\n",
5777 smb_dos_err_class(errclass),
5778 smb_dos_err_name(errclass, errnum),
5779 get_nt_error_c_code(NT_STATUS(error)));
5784 static bool run_sesssetup_bench(int dummy)
5786 static struct cli_state *c;
5787 const char *fname = "\\file.dat";
5792 if (!torture_open_connection(&c, 0)) {
5796 if (!NT_STATUS_IS_OK(cli_ntcreate(
5797 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5798 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5799 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5800 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5804 for (i=0; i<torture_numops; i++) {
5805 status = cli_session_setup(
5807 password, strlen(password),
5808 password, strlen(password),
5810 if (!NT_STATUS_IS_OK(status)) {
5811 d_printf("(%s) cli_session_setup failed: %s\n",
5812 __location__, nt_errstr(status));
5816 d_printf("\r%d ", (int)c->vuid);
5818 status = cli_ulogoff(c);
5819 if (!NT_STATUS_IS_OK(status)) {
5820 d_printf("(%s) cli_ulogoff failed: %s\n",
5821 __location__, nt_errstr(status));
5830 static bool subst_test(const char *str, const char *user, const char *domain,
5831 uid_t uid, gid_t gid, const char *expected)
5836 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5838 if (strcmp(subst, expected) != 0) {
5839 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5840 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5849 static void chain1_open_completion(struct tevent_req *req)
5853 status = cli_open_recv(req, &fnum);
5856 d_printf("cli_open_recv returned %s: %d\n",
5858 NT_STATUS_IS_OK(status) ? fnum : -1);
5861 static void chain1_write_completion(struct tevent_req *req)
5865 status = cli_write_andx_recv(req, &written);
5868 d_printf("cli_write_andx_recv returned %s: %d\n",
5870 NT_STATUS_IS_OK(status) ? (int)written : -1);
5873 static void chain1_close_completion(struct tevent_req *req)
5876 bool *done = (bool *)tevent_req_callback_data_void(req);
5878 status = cli_close_recv(req);
5883 d_printf("cli_close returned %s\n", nt_errstr(status));
5886 static bool run_chain1(int dummy)
5888 struct cli_state *cli1;
5889 struct event_context *evt = event_context_init(NULL);
5890 struct tevent_req *reqs[3], *smbreqs[3];
5892 const char *str = "foobar";
5895 printf("starting chain1 test\n");
5896 if (!torture_open_connection(&cli1, 0)) {
5900 cli_sockopt(cli1, sockops);
5902 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5903 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5904 if (reqs[0] == NULL) return false;
5905 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5908 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5909 (uint8_t *)str, 0, strlen(str)+1,
5910 smbreqs, 1, &smbreqs[1]);
5911 if (reqs[1] == NULL) return false;
5912 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5914 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5915 if (reqs[2] == NULL) return false;
5916 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5918 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5919 if (!NT_STATUS_IS_OK(status)) {
5924 event_loop_once(evt);
5927 torture_close_connection(cli1);
5931 static void chain2_sesssetup_completion(struct tevent_req *req)
5934 status = cli_session_setup_guest_recv(req);
5935 d_printf("sesssetup returned %s\n", nt_errstr(status));
5938 static void chain2_tcon_completion(struct tevent_req *req)
5940 bool *done = (bool *)tevent_req_callback_data_void(req);
5942 status = cli_tcon_andx_recv(req);
5943 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5947 static bool run_chain2(int dummy)
5949 struct cli_state *cli1;
5950 struct event_context *evt = event_context_init(NULL);
5951 struct tevent_req *reqs[2], *smbreqs[2];
5955 printf("starting chain2 test\n");
5956 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5957 port_to_use, Undefined, 0);
5958 if (!NT_STATUS_IS_OK(status)) {
5962 cli_sockopt(cli1, sockops);
5964 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5966 if (reqs[0] == NULL) return false;
5967 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5969 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5970 "?????", NULL, 0, &smbreqs[1]);
5971 if (reqs[1] == NULL) return false;
5972 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5974 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5975 if (!NT_STATUS_IS_OK(status)) {
5980 event_loop_once(evt);
5983 torture_close_connection(cli1);
5988 struct torture_createdel_state {
5989 struct tevent_context *ev;
5990 struct cli_state *cli;
5993 static void torture_createdel_created(struct tevent_req *subreq);
5994 static void torture_createdel_closed(struct tevent_req *subreq);
5996 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5997 struct tevent_context *ev,
5998 struct cli_state *cli,
6001 struct tevent_req *req, *subreq;
6002 struct torture_createdel_state *state;
6004 req = tevent_req_create(mem_ctx, &state,
6005 struct torture_createdel_state);
6012 subreq = cli_ntcreate_send(
6013 state, ev, cli, name, 0,
6014 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6015 FILE_ATTRIBUTE_NORMAL,
6016 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6017 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6019 if (tevent_req_nomem(subreq, req)) {
6020 return tevent_req_post(req, ev);
6022 tevent_req_set_callback(subreq, torture_createdel_created, req);
6026 static void torture_createdel_created(struct tevent_req *subreq)
6028 struct tevent_req *req = tevent_req_callback_data(
6029 subreq, struct tevent_req);
6030 struct torture_createdel_state *state = tevent_req_data(
6031 req, struct torture_createdel_state);
6035 status = cli_ntcreate_recv(subreq, &fnum);
6036 TALLOC_FREE(subreq);
6037 if (!NT_STATUS_IS_OK(status)) {
6038 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6039 nt_errstr(status)));
6040 tevent_req_nterror(req, status);
6044 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6045 if (tevent_req_nomem(subreq, req)) {
6048 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6051 static void torture_createdel_closed(struct tevent_req *subreq)
6053 struct tevent_req *req = tevent_req_callback_data(
6054 subreq, struct tevent_req);
6057 status = cli_close_recv(subreq);
6058 if (!NT_STATUS_IS_OK(status)) {
6059 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6060 tevent_req_nterror(req, status);
6063 tevent_req_done(req);
6066 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6068 return tevent_req_simple_recv_ntstatus(req);
6071 struct torture_createdels_state {
6072 struct tevent_context *ev;
6073 struct cli_state *cli;
6074 const char *base_name;
6078 struct tevent_req **reqs;
6081 static void torture_createdels_done(struct tevent_req *subreq);
6083 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6084 struct tevent_context *ev,
6085 struct cli_state *cli,
6086 const char *base_name,
6090 struct tevent_req *req;
6091 struct torture_createdels_state *state;
6094 req = tevent_req_create(mem_ctx, &state,
6095 struct torture_createdels_state);
6101 state->base_name = talloc_strdup(state, base_name);
6102 if (tevent_req_nomem(state->base_name, req)) {
6103 return tevent_req_post(req, ev);
6105 state->num_files = MAX(num_parallel, num_files);
6107 state->received = 0;
6109 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6110 if (tevent_req_nomem(state->reqs, req)) {
6111 return tevent_req_post(req, ev);
6114 for (i=0; i<num_parallel; i++) {
6117 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6119 if (tevent_req_nomem(name, req)) {
6120 return tevent_req_post(req, ev);
6122 state->reqs[i] = torture_createdel_send(
6123 state->reqs, state->ev, state->cli, name);
6124 if (tevent_req_nomem(state->reqs[i], req)) {
6125 return tevent_req_post(req, ev);
6127 name = talloc_move(state->reqs[i], &name);
6128 tevent_req_set_callback(state->reqs[i],
6129 torture_createdels_done, req);
6135 static void torture_createdels_done(struct tevent_req *subreq)
6137 struct tevent_req *req = tevent_req_callback_data(
6138 subreq, struct tevent_req);
6139 struct torture_createdels_state *state = tevent_req_data(
6140 req, struct torture_createdels_state);
6141 size_t num_parallel = talloc_array_length(state->reqs);
6146 status = torture_createdel_recv(subreq);
6147 if (!NT_STATUS_IS_OK(status)){
6148 DEBUG(10, ("torture_createdel_recv returned %s\n",
6149 nt_errstr(status)));
6150 TALLOC_FREE(subreq);
6151 tevent_req_nterror(req, status);
6155 for (i=0; i<num_parallel; i++) {
6156 if (subreq == state->reqs[i]) {
6160 if (i == num_parallel) {
6161 DEBUG(10, ("received something we did not send\n"));
6162 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6165 TALLOC_FREE(state->reqs[i]);
6167 if (state->sent >= state->num_files) {
6168 tevent_req_done(req);
6172 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6174 if (tevent_req_nomem(name, req)) {
6177 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6179 if (tevent_req_nomem(state->reqs[i], req)) {
6182 name = talloc_move(state->reqs[i], &name);
6183 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6187 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6189 return tevent_req_simple_recv_ntstatus(req);
6192 struct swallow_notify_state {
6193 struct tevent_context *ev;
6194 struct cli_state *cli;
6196 uint32_t completion_filter;
6198 bool (*fn)(uint32_t action, const char *name, void *priv);
6202 static void swallow_notify_done(struct tevent_req *subreq);
6204 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6205 struct tevent_context *ev,
6206 struct cli_state *cli,
6208 uint32_t completion_filter,
6210 bool (*fn)(uint32_t action,
6215 struct tevent_req *req, *subreq;
6216 struct swallow_notify_state *state;
6218 req = tevent_req_create(mem_ctx, &state,
6219 struct swallow_notify_state);
6226 state->completion_filter = completion_filter;
6227 state->recursive = recursive;
6231 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6232 0xffff, state->completion_filter,
6234 if (tevent_req_nomem(subreq, req)) {
6235 return tevent_req_post(req, ev);
6237 tevent_req_set_callback(subreq, swallow_notify_done, req);
6241 static void swallow_notify_done(struct tevent_req *subreq)
6243 struct tevent_req *req = tevent_req_callback_data(
6244 subreq, struct tevent_req);
6245 struct swallow_notify_state *state = tevent_req_data(
6246 req, struct swallow_notify_state);
6248 uint32_t i, num_changes;
6249 struct notify_change *changes;
6251 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6252 TALLOC_FREE(subreq);
6253 if (!NT_STATUS_IS_OK(status)) {
6254 DEBUG(10, ("cli_notify_recv returned %s\n",
6255 nt_errstr(status)));
6256 tevent_req_nterror(req, status);
6260 for (i=0; i<num_changes; i++) {
6261 state->fn(changes[i].action, changes[i].name, state->priv);
6263 TALLOC_FREE(changes);
6265 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6266 0xffff, state->completion_filter,
6268 if (tevent_req_nomem(subreq, req)) {
6271 tevent_req_set_callback(subreq, swallow_notify_done, req);
6274 static bool print_notifies(uint32_t action, const char *name, void *priv)
6276 if (DEBUGLEVEL > 5) {
6277 d_printf("%d %s\n", (int)action, name);
6282 static void notify_bench_done(struct tevent_req *req)
6284 int *num_finished = (int *)tevent_req_callback_data_void(req);
6288 static bool run_notify_bench(int dummy)
6290 const char *dname = "\\notify-bench";
6291 struct tevent_context *ev;
6294 struct tevent_req *req1;
6295 struct tevent_req *req2 = NULL;
6296 int i, num_unc_names;
6297 int num_finished = 0;
6299 printf("starting notify-bench test\n");
6301 if (use_multishare_conn) {
6303 unc_list = file_lines_load(multishare_conn_fname,
6304 &num_unc_names, 0, NULL);
6305 if (!unc_list || num_unc_names <= 0) {
6306 d_printf("Failed to load unc names list from '%s'\n",
6307 multishare_conn_fname);
6310 TALLOC_FREE(unc_list);
6315 ev = tevent_context_init(talloc_tos());
6317 d_printf("tevent_context_init failed\n");
6321 for (i=0; i<num_unc_names; i++) {
6322 struct cli_state *cli;
6325 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6327 if (base_fname == NULL) {
6331 if (!torture_open_connection(&cli, i)) {
6335 status = cli_ntcreate(cli, dname, 0,
6336 MAXIMUM_ALLOWED_ACCESS,
6337 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6339 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6342 if (!NT_STATUS_IS_OK(status)) {
6343 d_printf("Could not create %s: %s\n", dname,
6348 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6349 FILE_NOTIFY_CHANGE_FILE_NAME |
6350 FILE_NOTIFY_CHANGE_DIR_NAME |
6351 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6352 FILE_NOTIFY_CHANGE_LAST_WRITE,
6353 false, print_notifies, NULL);
6355 d_printf("Could not create notify request\n");
6359 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6360 base_fname, 10, torture_numops);
6362 d_printf("Could not create createdels request\n");
6365 TALLOC_FREE(base_fname);
6367 tevent_req_set_callback(req2, notify_bench_done,
6371 while (num_finished < num_unc_names) {
6373 ret = tevent_loop_once(ev);
6375 d_printf("tevent_loop_once failed\n");
6380 if (!tevent_req_poll(req2, ev)) {
6381 d_printf("tevent_req_poll failed\n");
6384 status = torture_createdels_recv(req2);
6385 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6390 static bool run_mangle1(int dummy)
6392 struct cli_state *cli;
6393 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6397 time_t change_time, access_time, write_time;
6401 printf("starting mangle1 test\n");
6402 if (!torture_open_connection(&cli, 0)) {
6406 cli_sockopt(cli, sockops);
6408 if (!NT_STATUS_IS_OK(cli_ntcreate(
6409 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6410 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6411 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6414 cli_close(cli, fnum);
6416 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6417 if (!NT_STATUS_IS_OK(status)) {
6418 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6422 d_printf("alt_name: %s\n", alt_name);
6424 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6425 d_printf("cli_open(%s) failed: %s\n", alt_name,
6429 cli_close(cli, fnum);
6431 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6432 &write_time, &size, &mode);
6433 if (!NT_STATUS_IS_OK(status)) {
6434 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6442 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6444 size_t *to_pull = (size_t *)priv;
6445 size_t thistime = *to_pull;
6447 thistime = MIN(thistime, n);
6448 if (thistime == 0) {
6452 memset(buf, 0, thistime);
6453 *to_pull -= thistime;
6457 static bool run_windows_write(int dummy)
6459 struct cli_state *cli1;
6463 const char *fname = "\\writetest.txt";
6464 struct timeval start_time;
6468 printf("starting windows_write test\n");
6469 if (!torture_open_connection(&cli1, 0)) {
6473 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6474 printf("open failed (%s)\n", cli_errstr(cli1));
6478 cli_sockopt(cli1, sockops);
6480 start_time = timeval_current();
6482 for (i=0; i<torture_numops; i++) {
6484 off_t start = i * torture_blocksize;
6486 size_t to_pull = torture_blocksize - 1;
6488 if (cli_write(cli1, fnum, 0, &c,
6489 start + torture_blocksize - 1, 1) != 1) {
6490 printf("cli_write failed: %s\n", cli_errstr(cli1));
6494 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6495 null_source, &to_pull);
6496 if (!NT_STATUS_IS_OK(status)) {
6497 printf("cli_push returned: %s\n", nt_errstr(status));
6502 seconds = timeval_elapsed(&start_time);
6503 kbytes = (double)torture_blocksize * torture_numops;
6506 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6507 (double)seconds, (int)(kbytes/seconds));
6511 cli_close(cli1, fnum);
6512 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6513 torture_close_connection(cli1);
6517 static bool run_cli_echo(int dummy)
6519 struct cli_state *cli;
6522 printf("starting cli_echo test\n");
6523 if (!torture_open_connection(&cli, 0)) {
6526 cli_sockopt(cli, sockops);
6528 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6530 d_printf("cli_echo returned %s\n", nt_errstr(status));
6532 torture_close_connection(cli);
6533 return NT_STATUS_IS_OK(status);
6536 static bool run_uid_regression_test(int dummy)
6538 static struct cli_state *cli;
6541 bool correct = True;
6544 printf("starting uid regression test\n");
6546 if (!torture_open_connection(&cli, 0)) {
6550 cli_sockopt(cli, sockops);
6552 /* Ok - now save then logoff our current user. */
6553 old_vuid = cli->vuid;
6555 status = cli_ulogoff(cli);
6556 if (!NT_STATUS_IS_OK(status)) {
6557 d_printf("(%s) cli_ulogoff failed: %s\n",
6558 __location__, nt_errstr(status));
6563 cli->vuid = old_vuid;
6565 /* Try an operation. */
6566 status = cli_mkdir(cli, "\\uid_reg_test");
6567 if (NT_STATUS_IS_OK(status)) {
6568 d_printf("(%s) cli_mkdir succeeded\n",
6573 /* Should be bad uid. */
6574 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6575 NT_STATUS_USER_SESSION_DELETED)) {
6581 old_cnum = cli->cnum;
6583 /* Now try a SMBtdis with the invald vuid set to zero. */
6586 /* This should succeed. */
6587 status = cli_tdis(cli);
6589 if (NT_STATUS_IS_OK(status)) {
6590 d_printf("First tdis with invalid vuid should succeed.\n");
6592 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6597 cli->vuid = old_vuid;
6598 cli->cnum = old_cnum;
6600 /* This should fail. */
6601 status = cli_tdis(cli);
6602 if (NT_STATUS_IS_OK(status)) {
6603 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6607 /* Should be bad tid. */
6608 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6609 NT_STATUS_NETWORK_NAME_DELETED)) {
6615 cli_rmdir(cli, "\\uid_reg_test");
6624 static const char *illegal_chars = "*\\/?<>|\":";
6625 static char force_shortname_chars[] = " +,.[];=\177";
6627 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6628 const char *mask, void *state)
6630 struct cli_state *pcli = (struct cli_state *)state;
6632 NTSTATUS status = NT_STATUS_OK;
6634 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6636 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6637 return NT_STATUS_OK;
6639 if (finfo->mode & aDIR) {
6640 status = cli_rmdir(pcli, fname);
6641 if (!NT_STATUS_IS_OK(status)) {
6642 printf("del_fn: failed to rmdir %s\n,", fname );
6645 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6646 if (!NT_STATUS_IS_OK(status)) {
6647 printf("del_fn: failed to unlink %s\n,", fname );
6659 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6660 const char *name, void *state)
6662 struct sn_state *s = (struct sn_state *)state;
6666 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6667 i, finfo->name, finfo->short_name);
6670 if (strchr(force_shortname_chars, i)) {
6671 if (!finfo->short_name[0]) {
6672 /* Shortname not created when it should be. */
6673 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6674 __location__, finfo->name, i);
6677 } else if (finfo->short_name[0]){
6678 /* Shortname created when it should not be. */
6679 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6680 __location__, finfo->short_name, finfo->name);
6684 return NT_STATUS_OK;
6687 static bool run_shortname_test(int dummy)
6689 static struct cli_state *cli;
6690 bool correct = True;
6695 printf("starting shortname test\n");
6697 if (!torture_open_connection(&cli, 0)) {
6701 cli_sockopt(cli, sockops);
6703 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6704 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6705 cli_rmdir(cli, "\\shortname");
6707 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6708 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6709 __location__, cli_errstr(cli));
6714 strlcpy(fname, "\\shortname\\", sizeof(fname));
6715 strlcat(fname, "test .txt", sizeof(fname));
6719 for (i = 32; i < 128; i++) {
6721 uint16_t fnum = (uint16_t)-1;
6725 if (strchr(illegal_chars, i)) {
6730 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6731 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6732 if (!NT_STATUS_IS_OK(status)) {
6733 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6734 __location__, fname, cli_errstr(cli));
6738 cli_close(cli, fnum);
6741 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6743 if (s.matched != 1) {
6744 d_printf("(%s) failed to list %s: %s\n",
6745 __location__, fname, cli_errstr(cli));
6749 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6750 d_printf("(%s) failed to delete %s: %s\n",
6751 __location__, fname, cli_errstr(cli));
6764 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6765 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6766 cli_rmdir(cli, "\\shortname");
6767 torture_close_connection(cli);
6771 static void pagedsearch_cb(struct tevent_req *req)
6774 struct tldap_message *msg;
6777 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6778 if (rc != TLDAP_SUCCESS) {
6779 d_printf("tldap_search_paged_recv failed: %s\n",
6780 tldap_err2string(rc));
6783 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6787 if (!tldap_entry_dn(msg, &dn)) {
6788 d_printf("tldap_entry_dn failed\n");
6791 d_printf("%s\n", dn);
6795 static bool run_tldap(int dummy)
6797 struct tldap_context *ld;
6800 struct sockaddr_storage addr;
6801 struct tevent_context *ev;
6802 struct tevent_req *req;
6806 if (!resolve_name(host, &addr, 0, false)) {
6807 d_printf("could not find host %s\n", host);
6810 status = open_socket_out(&addr, 389, 9999, &fd);
6811 if (!NT_STATUS_IS_OK(status)) {
6812 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6816 ld = tldap_context_create(talloc_tos(), fd);
6819 d_printf("tldap_context_create failed\n");
6823 rc = tldap_fetch_rootdse(ld);
6824 if (rc != TLDAP_SUCCESS) {
6825 d_printf("tldap_fetch_rootdse failed: %s\n",
6826 tldap_errstr(talloc_tos(), ld, rc));
6830 basedn = tldap_talloc_single_attribute(
6831 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6832 if (basedn == NULL) {
6833 d_printf("no defaultNamingContext\n");
6836 d_printf("defaultNamingContext: %s\n", basedn);
6838 ev = tevent_context_init(talloc_tos());
6840 d_printf("tevent_context_init failed\n");
6844 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6845 TLDAP_SCOPE_SUB, "(objectclass=*)",
6847 NULL, 0, NULL, 0, 0, 0, 0, 5);
6849 d_printf("tldap_search_paged_send failed\n");
6852 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6854 tevent_req_poll(req, ev);
6858 /* test search filters against rootDSE */
6859 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6860 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6862 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6863 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6864 talloc_tos(), NULL, NULL);
6865 if (rc != TLDAP_SUCCESS) {
6866 d_printf("tldap_search with complex filter failed: %s\n",
6867 tldap_errstr(talloc_tos(), ld, rc));
6875 /* Torture test to ensure no regression of :
6876 https://bugzilla.samba.org/show_bug.cgi?id=7084
6879 static bool run_dir_createtime(int dummy)
6881 struct cli_state *cli;
6882 const char *dname = "\\testdir";
6883 const char *fname = "\\testdir\\testfile";
6885 struct timespec create_time;
6886 struct timespec create_time1;
6890 if (!torture_open_connection(&cli, 0)) {
6894 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6895 cli_rmdir(cli, dname);
6897 status = cli_mkdir(cli, dname);
6898 if (!NT_STATUS_IS_OK(status)) {
6899 printf("mkdir failed: %s\n", nt_errstr(status));
6903 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6905 if (!NT_STATUS_IS_OK(status)) {
6906 printf("cli_qpathinfo2 returned %s\n",
6911 /* Sleep 3 seconds, then create a file. */
6914 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6916 if (!NT_STATUS_IS_OK(status)) {
6917 printf("cli_open failed: %s\n", nt_errstr(status));
6921 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6923 if (!NT_STATUS_IS_OK(status)) {
6924 printf("cli_qpathinfo2 (2) returned %s\n",
6929 if (timespec_compare(&create_time1, &create_time)) {
6930 printf("run_dir_createtime: create time was updated (error)\n");
6932 printf("run_dir_createtime: create time was not updated (correct)\n");
6938 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6939 cli_rmdir(cli, dname);
6940 if (!torture_close_connection(cli)) {
6947 static bool run_streamerror(int dummy)
6949 struct cli_state *cli;
6950 const char *dname = "\\testdir";
6951 const char *streamname =
6952 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6954 time_t change_time, access_time, write_time;
6956 uint16_t mode, fnum;
6959 if (!torture_open_connection(&cli, 0)) {
6963 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6964 cli_rmdir(cli, dname);
6966 status = cli_mkdir(cli, dname);
6967 if (!NT_STATUS_IS_OK(status)) {
6968 printf("mkdir failed: %s\n", nt_errstr(status));
6972 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6974 status = cli_nt_error(cli);
6976 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6977 printf("pathinfo returned %s, expected "
6978 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6983 status = cli_ntcreate(cli, streamname, 0x16,
6984 FILE_READ_DATA|FILE_READ_EA|
6985 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6986 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6987 FILE_OPEN, 0, 0, &fnum);
6989 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6990 printf("ntcreate returned %s, expected "
6991 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6997 cli_rmdir(cli, dname);
7001 static bool run_local_substitute(int dummy)
7005 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7006 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7007 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7008 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7009 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7010 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7011 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7012 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7014 /* Different captialization rules in sub_basic... */
7016 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7022 static bool run_local_base64(int dummy)
7027 for (i=1; i<2000; i++) {
7028 DATA_BLOB blob1, blob2;
7031 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7033 generate_random_buffer(blob1.data, blob1.length);
7035 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7037 d_fprintf(stderr, "base64_encode_data_blob failed "
7038 "for %d bytes\n", i);
7041 blob2 = base64_decode_data_blob(b64);
7044 if (data_blob_cmp(&blob1, &blob2)) {
7045 d_fprintf(stderr, "data_blob_cmp failed for %d "
7049 TALLOC_FREE(blob1.data);
7050 data_blob_free(&blob2);
7055 static bool run_local_gencache(int dummy)
7061 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7062 d_printf("%s: gencache_set() failed\n", __location__);
7066 if (!gencache_get("foo", NULL, NULL)) {
7067 d_printf("%s: gencache_get() failed\n", __location__);
7071 if (!gencache_get("foo", &val, &tm)) {
7072 d_printf("%s: gencache_get() failed\n", __location__);
7076 if (strcmp(val, "bar") != 0) {
7077 d_printf("%s: gencache_get() returned %s, expected %s\n",
7078 __location__, val, "bar");
7085 if (!gencache_del("foo")) {
7086 d_printf("%s: gencache_del() failed\n", __location__);
7089 if (gencache_del("foo")) {
7090 d_printf("%s: second gencache_del() succeeded\n",
7095 if (gencache_get("foo", &val, &tm)) {
7096 d_printf("%s: gencache_get() on deleted entry "
7097 "succeeded\n", __location__);
7101 blob = data_blob_string_const_null("bar");
7102 tm = time(NULL) + 60;
7104 if (!gencache_set_data_blob("foo", &blob, tm)) {
7105 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7109 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7110 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7114 if (strcmp((const char *)blob.data, "bar") != 0) {
7115 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7116 __location__, (const char *)blob.data, "bar");
7117 data_blob_free(&blob);
7121 data_blob_free(&blob);
7123 if (!gencache_del("foo")) {
7124 d_printf("%s: gencache_del() failed\n", __location__);
7127 if (gencache_del("foo")) {
7128 d_printf("%s: second gencache_del() succeeded\n",
7133 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7134 d_printf("%s: gencache_get_data_blob() on deleted entry "
7135 "succeeded\n", __location__);
7142 static bool rbt_testval(struct db_context *db, const char *key,
7145 struct db_record *rec;
7146 TDB_DATA data = string_tdb_data(value);
7150 rec = db->fetch_locked(db, db, string_tdb_data(key));
7152 d_fprintf(stderr, "fetch_locked failed\n");
7155 status = rec->store(rec, data, 0);
7156 if (!NT_STATUS_IS_OK(status)) {
7157 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7162 rec = db->fetch_locked(db, db, string_tdb_data(key));
7164 d_fprintf(stderr, "second fetch_locked failed\n");
7167 if ((rec->value.dsize != data.dsize)
7168 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7169 d_fprintf(stderr, "Got wrong data back\n");
7179 static bool run_local_rbtree(int dummy)
7181 struct db_context *db;
7185 db = db_open_rbt(NULL);
7188 d_fprintf(stderr, "db_open_rbt failed\n");
7192 for (i=0; i<1000; i++) {
7195 if (asprintf(&key, "key%ld", random()) == -1) {
7198 if (asprintf(&value, "value%ld", random()) == -1) {
7203 if (!rbt_testval(db, key, value)) {
7210 if (asprintf(&value, "value%ld", random()) == -1) {
7215 if (!rbt_testval(db, key, value)) {
7232 struct talloc_dict_test {
7236 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7238 int *count = (int *)priv;
7243 static bool run_local_talloc_dict(int dummy)
7245 struct talloc_dict *dict;
7246 struct talloc_dict_test *t;
7249 dict = talloc_dict_init(talloc_tos());
7254 t = talloc(talloc_tos(), struct talloc_dict_test);
7261 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7266 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7279 static bool run_local_string_to_sid(int dummy) {
7282 if (string_to_sid(&sid, "S--1-5-32-545")) {
7283 printf("allowing S--1-5-32-545\n");
7286 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7287 printf("allowing S-1-5-32-+545\n");
7290 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")) {
7291 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7294 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7295 printf("allowing S-1-5-32-545-abc\n");
7298 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7299 printf("could not parse S-1-5-32-545\n");
7302 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7303 printf("mis-parsed S-1-5-32-545 as %s\n",
7304 sid_string_tos(&sid));
7310 static bool run_local_binary_to_sid(int dummy) {
7311 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7312 static const char good_binary_sid[] = {
7313 0x1, /* revision number */
7315 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7316 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7317 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7318 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7319 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7320 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7321 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7322 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7323 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7324 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7325 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7326 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7327 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7328 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7329 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7330 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7333 static const char long_binary_sid[] = {
7334 0x1, /* revision number */
7336 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7337 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7338 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7339 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7340 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7341 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7342 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7343 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7344 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7345 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7346 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7347 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7348 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7349 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7350 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7351 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7352 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7353 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7354 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7357 static const char long_binary_sid2[] = {
7358 0x1, /* revision number */
7360 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7361 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7362 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7363 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7364 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7365 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7366 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7367 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7368 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7369 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7370 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7371 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7372 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7373 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7374 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7375 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7376 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7377 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7378 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7379 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7380 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7381 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7382 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7383 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7384 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7385 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7386 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7387 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7388 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7389 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7390 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7391 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7392 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7395 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7398 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7401 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7407 /* Split a path name into filename and stream name components. Canonicalise
7408 * such that an implicit $DATA token is always explicit.
7410 * The "specification" of this function can be found in the
7411 * run_local_stream_name() function in torture.c, I've tried those
7412 * combinations against a W2k3 server.
7415 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7416 char **pbase, char **pstream)
7419 char *stream = NULL;
7420 char *sname; /* stream name */
7421 const char *stype; /* stream type */
7423 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7425 sname = strchr_m(fname, ':');
7427 if (lp_posix_pathnames() || (sname == NULL)) {
7428 if (pbase != NULL) {
7429 base = talloc_strdup(mem_ctx, fname);
7430 NT_STATUS_HAVE_NO_MEMORY(base);
7435 if (pbase != NULL) {
7436 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7437 NT_STATUS_HAVE_NO_MEMORY(base);
7442 stype = strchr_m(sname, ':');
7444 if (stype == NULL) {
7445 sname = talloc_strdup(mem_ctx, sname);
7449 if (StrCaseCmp(stype, ":$DATA") != 0) {
7451 * If there is an explicit stream type, so far we only
7452 * allow $DATA. Is there anything else allowed? -- vl
7454 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7456 return NT_STATUS_OBJECT_NAME_INVALID;
7458 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7462 if (sname == NULL) {
7464 return NT_STATUS_NO_MEMORY;
7467 if (sname[0] == '\0') {
7469 * no stream name, so no stream
7474 if (pstream != NULL) {
7475 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7476 if (stream == NULL) {
7479 return NT_STATUS_NO_MEMORY;
7482 * upper-case the type field
7484 strupper_m(strchr_m(stream, ':')+1);
7488 if (pbase != NULL) {
7491 if (pstream != NULL) {
7494 return NT_STATUS_OK;
7497 static bool test_stream_name(const char *fname, const char *expected_base,
7498 const char *expected_stream,
7499 NTSTATUS expected_status)
7503 char *stream = NULL;
7505 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7506 if (!NT_STATUS_EQUAL(status, expected_status)) {
7510 if (!NT_STATUS_IS_OK(status)) {
7514 if (base == NULL) goto error;
7516 if (strcmp(expected_base, base) != 0) goto error;
7518 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7519 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7521 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7525 TALLOC_FREE(stream);
7529 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7530 fname, expected_base ? expected_base : "<NULL>",
7531 expected_stream ? expected_stream : "<NULL>",
7532 nt_errstr(expected_status));
7533 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7534 base ? base : "<NULL>", stream ? stream : "<NULL>",
7537 TALLOC_FREE(stream);
7541 static bool run_local_stream_name(int dummy)
7545 ret &= test_stream_name(
7546 "bla", "bla", NULL, NT_STATUS_OK);
7547 ret &= test_stream_name(
7548 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7549 ret &= test_stream_name(
7550 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7551 ret &= test_stream_name(
7552 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7553 ret &= test_stream_name(
7554 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7555 ret &= test_stream_name(
7556 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7557 ret &= test_stream_name(
7558 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7559 ret &= test_stream_name(
7560 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7565 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7567 if (a.length != b.length) {
7568 printf("a.length=%d != b.length=%d\n",
7569 (int)a.length, (int)b.length);
7572 if (memcmp(a.data, b.data, a.length) != 0) {
7573 printf("a.data and b.data differ\n");
7579 static bool run_local_memcache(int dummy)
7581 struct memcache *cache;
7583 DATA_BLOB d1, d2, d3;
7584 DATA_BLOB v1, v2, v3;
7586 TALLOC_CTX *mem_ctx;
7588 size_t size1, size2;
7591 cache = memcache_init(NULL, 100);
7593 if (cache == NULL) {
7594 printf("memcache_init failed\n");
7598 d1 = data_blob_const("d1", 2);
7599 d2 = data_blob_const("d2", 2);
7600 d3 = data_blob_const("d3", 2);
7602 k1 = data_blob_const("d1", 2);
7603 k2 = data_blob_const("d2", 2);
7605 memcache_add(cache, STAT_CACHE, k1, d1);
7606 memcache_add(cache, GETWD_CACHE, k2, d2);
7608 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7609 printf("could not find k1\n");
7612 if (!data_blob_equal(d1, v1)) {
7616 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7617 printf("could not find k2\n");
7620 if (!data_blob_equal(d2, v2)) {
7624 memcache_add(cache, STAT_CACHE, k1, d3);
7626 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7627 printf("could not find replaced k1\n");
7630 if (!data_blob_equal(d3, v3)) {
7634 memcache_add(cache, GETWD_CACHE, k1, d1);
7636 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7637 printf("Did find k2, should have been purged\n");
7643 cache = memcache_init(NULL, 0);
7645 mem_ctx = talloc_init("foo");
7647 str1 = talloc_strdup(mem_ctx, "string1");
7648 str2 = talloc_strdup(mem_ctx, "string2");
7650 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7651 data_blob_string_const("torture"), &str1);
7652 size1 = talloc_total_size(cache);
7654 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7655 data_blob_string_const("torture"), &str2);
7656 size2 = talloc_total_size(cache);
7658 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7660 if (size2 > size1) {
7661 printf("memcache leaks memory!\n");
7671 static void wbclient_done(struct tevent_req *req)
7674 struct winbindd_response *wb_resp;
7675 int *i = (int *)tevent_req_callback_data_void(req);
7677 wbc_err = wb_trans_recv(req, req, &wb_resp);
7680 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7683 static bool run_local_wbclient(int dummy)
7685 struct event_context *ev;
7686 struct wb_context **wb_ctx;
7687 struct winbindd_request wb_req;
7688 bool result = false;
7691 BlockSignals(True, SIGPIPE);
7693 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7698 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7699 if (wb_ctx == NULL) {
7703 ZERO_STRUCT(wb_req);
7704 wb_req.cmd = WINBINDD_PING;
7706 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7708 for (i=0; i<nprocs; i++) {
7709 wb_ctx[i] = wb_context_init(ev, NULL);
7710 if (wb_ctx[i] == NULL) {
7713 for (j=0; j<torture_numops; j++) {
7714 struct tevent_req *req;
7715 req = wb_trans_send(ev, ev, wb_ctx[i],
7716 (j % 2) == 0, &wb_req);
7720 tevent_req_set_callback(req, wbclient_done, &i);
7726 while (i < nprocs * torture_numops) {
7727 event_loop_once(ev);
7736 static void getaddrinfo_finished(struct tevent_req *req)
7738 char *name = (char *)tevent_req_callback_data_void(req);
7739 struct addrinfo *ainfo;
7742 res = getaddrinfo_recv(req, &ainfo);
7744 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7747 d_printf("gai(%s) succeeded\n", name);
7748 freeaddrinfo(ainfo);
7751 static bool run_getaddrinfo_send(int dummy)
7753 TALLOC_CTX *frame = talloc_stackframe();
7754 struct fncall_context *ctx;
7755 struct tevent_context *ev;
7756 bool result = false;
7757 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7758 "www.slashdot.org", "heise.de" };
7759 struct tevent_req *reqs[4];
7762 ev = event_context_init(frame);
7767 ctx = fncall_context_init(frame, 4);
7769 for (i=0; i<ARRAY_SIZE(names); i++) {
7770 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7772 if (reqs[i] == NULL) {
7775 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7779 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7780 tevent_loop_once(ev);
7789 static bool dbtrans_inc(struct db_context *db)
7791 struct db_record *rec;
7796 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7798 printf(__location__ "fetch_lock failed\n");
7802 if (rec->value.dsize != sizeof(uint32_t)) {
7803 printf(__location__ "value.dsize = %d\n",
7804 (int)rec->value.dsize);
7808 val = (uint32_t *)rec->value.dptr;
7811 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7814 if (!NT_STATUS_IS_OK(status)) {
7815 printf(__location__ "store failed: %s\n",
7826 static bool run_local_dbtrans(int dummy)
7828 struct db_context *db;
7829 struct db_record *rec;
7834 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7835 O_RDWR|O_CREAT, 0600);
7837 printf("Could not open transtest.db\n");
7841 res = db->transaction_start(db);
7843 printf(__location__ "transaction_start failed\n");
7847 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7849 printf(__location__ "fetch_lock failed\n");
7853 if (rec->value.dptr == NULL) {
7855 status = rec->store(
7856 rec, make_tdb_data((uint8_t *)&initial,
7859 if (!NT_STATUS_IS_OK(status)) {
7860 printf(__location__ "store returned %s\n",
7868 res = db->transaction_commit(db);
7870 printf(__location__ "transaction_commit failed\n");
7878 res = db->transaction_start(db);
7880 printf(__location__ "transaction_start failed\n");
7884 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7885 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7889 for (i=0; i<10; i++) {
7890 if (!dbtrans_inc(db)) {
7895 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7896 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7900 if (val2 != val + 10) {
7901 printf(__location__ "val=%d, val2=%d\n",
7902 (int)val, (int)val2);
7906 printf("val2=%d\r", val2);
7908 res = db->transaction_commit(db);
7910 printf(__location__ "transaction_commit failed\n");
7920 * Just a dummy test to be run under a debugger. There's no real way
7921 * to inspect the tevent_select specific function from outside of
7925 static bool run_local_tevent_select(int dummy)
7927 struct tevent_context *ev;
7928 struct tevent_fd *fd1, *fd2;
7929 bool result = false;
7931 ev = tevent_context_init_byname(NULL, "select");
7933 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7937 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7939 d_fprintf(stderr, "tevent_add_fd failed\n");
7942 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7944 d_fprintf(stderr, "tevent_add_fd failed\n");
7949 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7951 d_fprintf(stderr, "tevent_add_fd failed\n");
7961 static double create_procs(bool (*fn)(int), bool *result)
7964 volatile pid_t *child_status;
7965 volatile bool *child_status_out;
7968 struct timeval start;
7972 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7973 if (!child_status) {
7974 printf("Failed to setup shared memory\n");
7978 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7979 if (!child_status_out) {
7980 printf("Failed to setup result status shared memory\n");
7984 for (i = 0; i < nprocs; i++) {
7985 child_status[i] = 0;
7986 child_status_out[i] = True;
7989 start = timeval_current();
7991 for (i=0;i<nprocs;i++) {
7994 pid_t mypid = getpid();
7995 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7997 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8000 if (torture_open_connection(¤t_cli, i)) break;
8002 printf("pid %d failed to start\n", (int)getpid());
8008 child_status[i] = getpid();
8010 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8012 child_status_out[i] = fn(i);
8019 for (i=0;i<nprocs;i++) {
8020 if (child_status[i]) synccount++;
8022 if (synccount == nprocs) break;
8024 } while (timeval_elapsed(&start) < 30);
8026 if (synccount != nprocs) {
8027 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8029 return timeval_elapsed(&start);
8032 /* start the client load */
8033 start = timeval_current();
8035 for (i=0;i<nprocs;i++) {
8036 child_status[i] = 0;
8039 printf("%d clients started\n", nprocs);
8041 for (i=0;i<nprocs;i++) {
8042 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8047 for (i=0;i<nprocs;i++) {
8048 if (!child_status_out[i]) {
8052 return timeval_elapsed(&start);
8055 #define FLAG_MULTIPROC 1
8062 {"FDPASS", run_fdpasstest, 0},
8063 {"LOCK1", run_locktest1, 0},
8064 {"LOCK2", run_locktest2, 0},
8065 {"LOCK3", run_locktest3, 0},
8066 {"LOCK4", run_locktest4, 0},
8067 {"LOCK5", run_locktest5, 0},
8068 {"LOCK6", run_locktest6, 0},
8069 {"LOCK7", run_locktest7, 0},
8070 {"LOCK8", run_locktest8, 0},
8071 {"LOCK9", run_locktest9, 0},
8072 {"UNLINK", run_unlinktest, 0},
8073 {"BROWSE", run_browsetest, 0},
8074 {"ATTR", run_attrtest, 0},
8075 {"TRANS2", run_trans2test, 0},
8076 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8077 {"TORTURE",run_torture, FLAG_MULTIPROC},
8078 {"RANDOMIPC", run_randomipc, 0},
8079 {"NEGNOWAIT", run_negprot_nowait, 0},
8080 {"NBENCH", run_nbench, 0},
8081 {"NBENCH2", run_nbench2, 0},
8082 {"OPLOCK1", run_oplock1, 0},
8083 {"OPLOCK2", run_oplock2, 0},
8084 {"OPLOCK3", run_oplock3, 0},
8085 {"OPLOCK4", run_oplock4, 0},
8086 {"DIR", run_dirtest, 0},
8087 {"DIR1", run_dirtest1, 0},
8088 {"DIR-CREATETIME", run_dir_createtime, 0},
8089 {"DENY1", torture_denytest1, 0},
8090 {"DENY2", torture_denytest2, 0},
8091 {"TCON", run_tcon_test, 0},
8092 {"TCONDEV", run_tcon_devtype_test, 0},
8093 {"RW1", run_readwritetest, 0},
8094 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8095 {"RW3", run_readwritelarge, 0},
8096 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8097 {"OPEN", run_opentest, 0},
8098 {"POSIX", run_simple_posix_open_test, 0},
8099 {"POSIX-APPEND", run_posix_append, 0},
8100 {"ASYNC-ECHO", run_async_echo, 0},
8101 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8102 { "SHORTNAME-TEST", run_shortname_test, 0},
8103 { "ADDRCHANGE", run_addrchange, 0},
8105 {"OPENATTR", run_openattrtest, 0},
8107 {"XCOPY", run_xcopy, 0},
8108 {"RENAME", run_rename, 0},
8109 {"DELETE", run_deletetest, 0},
8110 {"DELETE-LN", run_deletetest_ln, 0},
8111 {"PROPERTIES", run_properties, 0},
8112 {"MANGLE", torture_mangle, 0},
8113 {"MANGLE1", run_mangle1, 0},
8114 {"W2K", run_w2ktest, 0},
8115 {"TRANS2SCAN", torture_trans2_scan, 0},
8116 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8117 {"UTABLE", torture_utable, 0},
8118 {"CASETABLE", torture_casetable, 0},
8119 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8120 {"PIPE_NUMBER", run_pipe_number, 0},
8121 {"TCON2", run_tcon2_test, 0},
8122 {"IOCTL", torture_ioctl_test, 0},
8123 {"CHKPATH", torture_chkpath_test, 0},
8124 {"FDSESS", run_fdsesstest, 0},
8125 { "EATEST", run_eatest, 0},
8126 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8127 { "CHAIN1", run_chain1, 0},
8128 { "CHAIN2", run_chain2, 0},
8129 { "WINDOWS-WRITE", run_windows_write, 0},
8130 { "CLI_ECHO", run_cli_echo, 0},
8131 { "GETADDRINFO", run_getaddrinfo_send, 0},
8132 { "TLDAP", run_tldap },
8133 { "STREAMERROR", run_streamerror },
8134 { "NOTIFY-BENCH", run_notify_bench },
8135 { "BAD-NBT-SESSION", run_bad_nbt_session },
8136 { "SMB-ANY-CONNECT", run_smb_any_connect },
8137 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8138 { "LOCAL-GENCACHE", run_local_gencache, 0},
8139 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8140 { "LOCAL-BASE64", run_local_base64, 0},
8141 { "LOCAL-RBTREE", run_local_rbtree, 0},
8142 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8143 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8144 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8145 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8146 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8147 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8148 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8153 /****************************************************************************
8154 run a specified test or "ALL"
8155 ****************************************************************************/
8156 static bool run_test(const char *name)
8163 if (strequal(name,"ALL")) {
8164 for (i=0;torture_ops[i].name;i++) {
8165 run_test(torture_ops[i].name);
8170 for (i=0;torture_ops[i].name;i++) {
8171 fstr_sprintf(randomfname, "\\XX%x",
8172 (unsigned)random());
8174 if (strequal(name, torture_ops[i].name)) {
8176 printf("Running %s\n", name);
8177 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8178 t = create_procs(torture_ops[i].fn, &result);
8181 printf("TEST %s FAILED!\n", name);
8184 struct timeval start;
8185 start = timeval_current();
8186 if (!torture_ops[i].fn(0)) {
8188 printf("TEST %s FAILED!\n", name);
8190 t = timeval_elapsed(&start);
8192 printf("%s took %g secs\n\n", name, t);
8197 printf("Did not find a test named %s\n", name);
8205 static void usage(void)
8209 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8210 printf("Please use samba4 torture.\n\n");
8212 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8214 printf("\t-d debuglevel\n");
8215 printf("\t-U user%%pass\n");
8216 printf("\t-k use kerberos\n");
8217 printf("\t-N numprocs\n");
8218 printf("\t-n my_netbios_name\n");
8219 printf("\t-W workgroup\n");
8220 printf("\t-o num_operations\n");
8221 printf("\t-O socket_options\n");
8222 printf("\t-m maximum protocol\n");
8223 printf("\t-L use oplocks\n");
8224 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8225 printf("\t-A showall\n");
8226 printf("\t-p port\n");
8227 printf("\t-s seed\n");
8228 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8231 printf("tests are:");
8232 for (i=0;torture_ops[i].name;i++) {
8233 printf(" %s", torture_ops[i].name);
8237 printf("default test is ALL\n");
8242 /****************************************************************************
8244 ****************************************************************************/
8245 int main(int argc,char *argv[])
8251 bool correct = True;
8252 TALLOC_CTX *frame = talloc_stackframe();
8253 int seed = time(NULL);
8255 #ifdef HAVE_SETBUFFER
8256 setbuffer(stdout, NULL, 0);
8259 setup_logging("smbtorture", DEBUG_STDOUT);
8263 if (is_default_dyn_CONFIGFILE()) {
8264 if(getenv("SMB_CONF_PATH")) {
8265 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8268 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8275 for(p = argv[1]; *p; p++)
8279 if (strncmp(argv[1], "//", 2)) {
8283 fstrcpy(host, &argv[1][2]);
8284 p = strchr_m(&host[2],'/');
8289 fstrcpy(share, p+1);
8291 fstrcpy(myname, get_myname(talloc_tos()));
8293 fprintf(stderr, "Failed to get my hostname.\n");
8297 if (*username == 0 && getenv("LOGNAME")) {
8298 fstrcpy(username,getenv("LOGNAME"));
8304 fstrcpy(workgroup, lp_workgroup());
8306 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8309 port_to_use = atoi(optarg);
8312 seed = atoi(optarg);
8315 fstrcpy(workgroup,optarg);
8318 max_protocol = interpret_protocol(optarg, max_protocol);
8321 nprocs = atoi(optarg);
8324 torture_numops = atoi(optarg);
8327 lp_set_cmdline("log level", optarg);
8336 local_path = optarg;
8339 torture_showall = True;
8342 fstrcpy(myname, optarg);
8345 client_txt = optarg;
8352 use_kerberos = True;
8354 d_printf("No kerberos support compiled in\n");
8360 fstrcpy(username,optarg);
8361 p = strchr_m(username,'%');
8364 fstrcpy(password, p+1);
8369 fstrcpy(multishare_conn_fname, optarg);
8370 use_multishare_conn = True;
8373 torture_blocksize = atoi(optarg);
8376 printf("Unknown option %c (%d)\n", (char)opt, opt);
8381 d_printf("using seed %d\n", seed);
8385 if(use_kerberos && !gotuser) gotpass = True;
8388 p = getpass("Password:");
8390 fstrcpy(password, p);
8395 printf("host=%s share=%s user=%s myname=%s\n",
8396 host, share, username, myname);
8398 if (argc == optind) {
8399 correct = run_test("ALL");
8401 for (i=optind;i<argc;i++) {
8402 if (!run_test(argv[i])) {