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"
33 #include "libsmb/clirap.h"
39 static fstring host, workgroup, share, password, username, myname;
40 static int max_protocol = PROTOCOL_NT1;
41 static const char *sockops="TCP_NODELAY";
43 static int port_to_use=0;
44 int torture_numops=100;
45 int torture_blocksize=1024*1024;
46 static int procnum; /* records process count number when forking */
47 static struct cli_state *current_cli;
48 static fstring randomfname;
49 static bool use_oplocks;
50 static bool use_level_II_oplocks;
51 static const char *client_txt = "client_oplocks.txt";
52 static bool use_kerberos;
53 static fstring multishare_conn_fname;
54 static bool use_multishare_conn = False;
55 static bool do_encrypt;
56 static const char *local_path = NULL;
57 static int signing_state = Undefined;
59 bool torture_showall = False;
61 static double create_procs(bool (*fn)(int), bool *result);
64 /* return a pointer to a anonymous shared memory segment of size "size"
65 which will persist across fork() but will disappear when all processes
68 The memory is not zeroed
70 This function uses system5 shared memory. It takes advantage of a property
71 that the memory is not destroyed if it is attached when the id is removed
73 void *shm_setup(int size)
79 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
81 printf("can't get shared memory\n");
84 shm_unlink("private");
85 if (ftruncate(shmid, size) == -1) {
86 printf("can't set shared memory size\n");
89 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
90 if (ret == MAP_FAILED) {
91 printf("can't map shared memory\n");
95 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
97 printf("can't get shared memory\n");
100 ret = (void *)shmat(shmid, 0, 0);
101 if (!ret || ret == (void *)-1) {
102 printf("can't attach to shared memory\n");
105 /* the following releases the ipc, but note that this process
106 and all its children will still have access to the memory, its
107 just that the shmid is no longer valid for other shm calls. This
108 means we don't leave behind lots of shm segments after we exit
110 See Stevens "advanced programming in unix env" for details
112 shmctl(shmid, IPC_RMID, 0);
118 /********************************************************************
119 Ensure a connection is encrypted.
120 ********************************************************************/
122 static bool force_cli_encryption(struct cli_state *c,
123 const char *sharename)
126 uint32 caplow, caphigh;
129 if (!SERVER_HAS_UNIX_CIFS(c)) {
130 d_printf("Encryption required and "
131 "server that doesn't support "
132 "UNIX extensions - failing connect\n");
136 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
138 if (!NT_STATUS_IS_OK(status)) {
139 d_printf("Encryption required and "
140 "can't get UNIX CIFS extensions "
141 "version from server: %s\n", nt_errstr(status));
145 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
146 d_printf("Encryption required and "
147 "share %s doesn't support "
148 "encryption.\n", sharename);
152 if (c->use_kerberos) {
153 status = cli_gss_smb_encryption_start(c);
155 status = cli_raw_ntlm_smb_encryption_start(c,
161 if (!NT_STATUS_IS_OK(status)) {
162 d_printf("Encryption required and "
163 "setup failed with error %s.\n",
172 static struct cli_state *open_nbt_connection(void)
174 struct nmb_name called, calling;
175 struct sockaddr_storage ss;
179 make_nmb_name(&calling, myname, 0x0);
180 make_nmb_name(&called , host, 0x20);
184 if (!(c = cli_initialise_ex(signing_state))) {
185 printf("Failed initialize cli_struct to connect with %s\n", host);
189 c->port = port_to_use;
191 status = cli_connect(c, host, &ss);
192 if (!NT_STATUS_IS_OK(status)) {
193 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
197 c->use_kerberos = use_kerberos;
199 c->timeout = 120000; /* set a really long timeout (2 minutes) */
200 if (use_oplocks) c->use_oplocks = True;
201 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
203 if (!cli_session_request(c, &calling, &called)) {
205 * Well, that failed, try *SMBSERVER ...
206 * However, we must reconnect as well ...
208 status = cli_connect(c, host, &ss);
209 if (!NT_STATUS_IS_OK(status)) {
210 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
214 make_nmb_name(&called, "*SMBSERVER", 0x20);
215 if (!cli_session_request(c, &calling, &called)) {
216 printf("%s rejected the session\n",host);
217 printf("We tried with a called name of %s & %s\n",
227 /****************************************************************************
228 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
229 ****************************************************************************/
231 static bool cli_bad_session_request(struct cli_state *cli,
232 struct nmb_name *calling, struct nmb_name *called)
239 memcpy(&(cli->calling), calling, sizeof(*calling));
240 memcpy(&(cli->called ), called , sizeof(*called ));
242 /* put in the destination name */
244 tmp = name_mangle(talloc_tos(), cli->called.name,
245 cli->called.name_type);
251 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
253 memcpy(p, tmp, namelen);
258 /* Deliberately corrupt the name len (first byte) */
263 tmp = name_mangle(talloc_tos(), cli->calling.name,
264 cli->calling.name_type);
270 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
272 memcpy(p, tmp, namelen);
276 /* Deliberately corrupt the name len (first byte) */
279 /* send a session request (RFC 1002) */
280 /* setup the packet length
281 * Remove four bytes from the length count, since the length
282 * field in the NBT Session Service header counts the number
283 * of bytes which follow. The cli_send_smb() function knows
284 * about this and accounts for those four bytes.
288 _smb_setlen(cli->outbuf,len);
289 SCVAL(cli->outbuf,0,0x81);
292 DEBUG(5,("Sent session request\n"));
294 if (!cli_receive_smb(cli))
297 if (CVAL(cli->inbuf,0) != 0x82) {
298 /* This is the wrong place to put the error... JRA. */
299 cli->rap_error = CVAL(cli->inbuf,4);
305 static struct cli_state *open_bad_nbt_connection(void)
307 struct nmb_name called, calling;
308 struct sockaddr_storage ss;
312 make_nmb_name(&calling, myname, 0x0);
313 make_nmb_name(&called , host, 0x20);
317 if (!(c = cli_initialise_ex(signing_state))) {
318 printf("Failed initialize cli_struct to connect with %s\n", host);
324 status = cli_connect(c, host, &ss);
325 if (!NT_STATUS_IS_OK(status)) {
326 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
330 c->timeout = 4000; /* set a short timeout (4 seconds) */
332 if (!cli_bad_session_request(c, &calling, &called)) {
333 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
341 /* Insert a NULL at the first separator of the given path and return a pointer
342 * to the remainder of the string.
345 terminate_path_at_separator(char * path)
353 if ((p = strchr_m(path, '/'))) {
358 if ((p = strchr_m(path, '\\'))) {
368 parse a //server/share type UNC name
370 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
371 char **hostname, char **sharename)
375 *hostname = *sharename = NULL;
377 if (strncmp(unc_name, "\\\\", 2) &&
378 strncmp(unc_name, "//", 2)) {
382 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
383 p = terminate_path_at_separator(*hostname);
386 *sharename = talloc_strdup(mem_ctx, p);
387 terminate_path_at_separator(*sharename);
390 if (*hostname && *sharename) {
394 TALLOC_FREE(*hostname);
395 TALLOC_FREE(*sharename);
399 static bool torture_open_connection_share(struct cli_state **c,
400 const char *hostname,
401 const char *sharename)
407 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
409 flags |= CLI_FULL_CONNECTION_OPLOCKS;
410 if (use_level_II_oplocks)
411 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
413 status = cli_full_connection(c, myname,
414 hostname, NULL, port_to_use,
417 password, flags, signing_state);
418 if (!NT_STATUS_IS_OK(status)) {
419 printf("failed to open share connection: //%s/%s port:%d - %s\n",
420 hostname, sharename, port_to_use, nt_errstr(status));
424 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
427 return force_cli_encryption(*c,
433 bool torture_open_connection(struct cli_state **c, int conn_index)
435 char **unc_list = NULL;
436 int num_unc_names = 0;
439 if (use_multishare_conn==True) {
441 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
442 if (!unc_list || num_unc_names <= 0) {
443 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
447 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
449 printf("Failed to parse UNC name %s\n",
450 unc_list[conn_index % num_unc_names]);
451 TALLOC_FREE(unc_list);
455 result = torture_open_connection_share(c, h, s);
457 /* h, s were copied earlier */
458 TALLOC_FREE(unc_list);
462 return torture_open_connection_share(c, host, share);
465 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
467 uint16 old_vuid = cli->vuid;
468 fstring old_user_name;
469 size_t passlen = strlen(password);
473 fstrcpy(old_user_name, cli->user_name);
475 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
479 *new_vuid = cli->vuid;
480 cli->vuid = old_vuid;
481 status = cli_set_username(cli, old_user_name);
482 if (!NT_STATUS_IS_OK(status)) {
489 bool torture_close_connection(struct cli_state *c)
494 status = cli_tdis(c);
495 if (!NT_STATUS_IS_OK(status)) {
496 printf("tdis failed (%s)\n", nt_errstr(status));
506 /* check if the server produced the expected error code */
507 static bool check_error(int line, struct cli_state *c,
508 uint8 eclass, uint32 ecode, NTSTATUS nterr)
510 if (cli_is_dos_error(c)) {
514 /* Check DOS error */
516 cli_dos_error(c, &cclass, &num);
518 if (eclass != cclass || ecode != num) {
519 printf("unexpected error code class=%d code=%d\n",
520 (int)cclass, (int)num);
521 printf(" expected %d/%d %s (line=%d)\n",
522 (int)eclass, (int)ecode, nt_errstr(nterr), line);
531 status = cli_nt_error(c);
533 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
534 printf("unexpected error code %s\n", nt_errstr(status));
535 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
544 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
546 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
547 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
553 static bool rw_torture(struct cli_state *c)
555 const char *lockfname = "\\torture.lck";
559 pid_t pid2, pid = getpid();
565 memset(buf, '\0', sizeof(buf));
567 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
569 if (!NT_STATUS_IS_OK(status)) {
570 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
572 if (!NT_STATUS_IS_OK(status)) {
573 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
577 for (i=0;i<torture_numops;i++) {
578 unsigned n = (unsigned)sys_random()%10;
580 printf("%d\r", i); fflush(stdout);
582 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
584 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
588 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
589 printf("open failed (%s)\n", cli_errstr(c));
594 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
595 printf("write failed (%s)\n", cli_errstr(c));
600 if (cli_write(c, fnum, 0, (char *)buf,
601 sizeof(pid)+(j*sizeof(buf)),
602 sizeof(buf)) != sizeof(buf)) {
603 printf("write failed (%s)\n", cli_errstr(c));
610 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
611 printf("read failed (%s)\n", cli_errstr(c));
616 printf("data corruption!\n");
620 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
621 printf("close failed (%s)\n", cli_errstr(c));
625 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
626 printf("unlink failed (%s)\n", cli_errstr(c));
630 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
631 printf("unlock failed (%s)\n", cli_errstr(c));
637 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
644 static bool run_torture(int dummy)
646 struct cli_state *cli;
651 cli_sockopt(cli, sockops);
653 ret = rw_torture(cli);
655 if (!torture_close_connection(cli)) {
662 static bool rw_torture3(struct cli_state *c, char *lockfname)
664 uint16_t fnum = (uint16_t)-1;
669 unsigned countprev = 0;
672 NTSTATUS status = NT_STATUS_OK;
675 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
677 SIVAL(buf, i, sys_random());
682 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, aSYSTEM | aHIDDEN))) {
683 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
686 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
687 DENY_NONE, &fnum))) {
688 printf("first open read/write of %s failed (%s)\n",
689 lockfname, cli_errstr(c));
695 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
697 status = cli_open(c, lockfname, O_RDONLY,
699 if (!NT_STATUS_IS_OK(status)) {
704 if (!NT_STATUS_IS_OK(status)) {
705 printf("second open read-only of %s failed (%s)\n",
706 lockfname, cli_errstr(c));
712 for (count = 0; count < sizeof(buf); count += sent)
714 if (count >= countprev) {
715 printf("%d %8d\r", i, count);
718 countprev += (sizeof(buf) / 20);
723 sent = ((unsigned)sys_random()%(20))+ 1;
724 if (sent > sizeof(buf) - count)
726 sent = sizeof(buf) - count;
729 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
730 printf("write failed (%s)\n", cli_errstr(c));
736 sent = cli_read(c, fnum, buf_rd+count, count,
740 printf("read failed offset:%d size:%ld (%s)\n",
741 count, (unsigned long)sizeof(buf)-count,
748 if (memcmp(buf_rd+count, buf+count, sent) != 0)
750 printf("read/write compare failed\n");
751 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
760 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
761 printf("close failed (%s)\n", cli_errstr(c));
768 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
770 const char *lockfname = "\\torture2.lck";
779 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
780 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
783 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
784 DENY_NONE, &fnum1))) {
785 printf("first open read/write of %s failed (%s)\n",
786 lockfname, cli_errstr(c1));
789 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
790 DENY_NONE, &fnum2))) {
791 printf("second open read-only of %s failed (%s)\n",
792 lockfname, cli_errstr(c2));
793 cli_close(c1, fnum1);
797 for (i=0;i<torture_numops;i++)
799 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
801 printf("%d\r", i); fflush(stdout);
804 generate_random_buffer((unsigned char *)buf, buf_size);
806 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
807 printf("write failed (%s)\n", cli_errstr(c1));
812 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
813 printf("read failed (%s)\n", cli_errstr(c2));
814 printf("read %d, expected %ld\n", (int)bytes_read,
815 (unsigned long)buf_size);
820 if (memcmp(buf_rd, buf, buf_size) != 0)
822 printf("read/write compare failed\n");
828 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
829 printf("close failed (%s)\n", cli_errstr(c2));
832 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
833 printf("close failed (%s)\n", cli_errstr(c1));
837 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
838 printf("unlink failed (%s)\n", cli_errstr(c1));
845 static bool run_readwritetest(int dummy)
847 struct cli_state *cli1, *cli2;
848 bool test1, test2 = False;
850 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
853 cli_sockopt(cli1, sockops);
854 cli_sockopt(cli2, sockops);
856 printf("starting readwritetest\n");
858 test1 = rw_torture2(cli1, cli2);
859 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
862 test2 = rw_torture2(cli1, cli1);
863 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
866 if (!torture_close_connection(cli1)) {
870 if (!torture_close_connection(cli2)) {
874 return (test1 && test2);
877 static bool run_readwritemulti(int dummy)
879 struct cli_state *cli;
884 cli_sockopt(cli, sockops);
886 printf("run_readwritemulti: fname %s\n", randomfname);
887 test = rw_torture3(cli, randomfname);
889 if (!torture_close_connection(cli)) {
896 static bool run_readwritelarge_internal(int max_xmit_k)
898 static struct cli_state *cli1;
900 const char *lockfname = "\\large.dat";
905 if (!torture_open_connection(&cli1, 0)) {
908 cli_sockopt(cli1, sockops);
909 memset(buf,'\0',sizeof(buf));
911 cli1->max_xmit = max_xmit_k*1024;
913 if (signing_state == Required) {
914 /* Horrible cheat to force
915 multiple signed outstanding
916 packets against a Samba server.
918 cli1->is_samba = false;
921 printf("starting readwritelarge_internal\n");
923 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
925 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
926 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
930 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
932 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
933 cli1, fnum1, NULL, &fsize, NULL, NULL,
934 NULL, NULL, NULL))) {
935 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
939 if (fsize == sizeof(buf))
940 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
941 (unsigned long)fsize);
943 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
944 (unsigned long)fsize);
948 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
949 printf("close failed (%s)\n", cli_errstr(cli1));
953 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
954 printf("unlink failed (%s)\n", cli_errstr(cli1));
958 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
959 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
963 cli1->max_xmit = 4*1024;
965 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
967 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
968 cli1, fnum1, NULL, &fsize, NULL, NULL,
969 NULL, NULL, NULL))) {
970 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
974 if (fsize == sizeof(buf))
975 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
976 (unsigned long)fsize);
978 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
979 (unsigned long)fsize);
984 /* ToDo - set allocation. JRA */
985 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
986 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
989 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
991 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
995 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
998 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
999 printf("close failed (%s)\n", cli_errstr(cli1));
1003 if (!torture_close_connection(cli1)) {
1009 static bool run_readwritelarge(int dummy)
1011 return run_readwritelarge_internal(128);
1014 static bool run_readwritelarge_signtest(int dummy)
1017 signing_state = Required;
1018 ret = run_readwritelarge_internal(2);
1019 signing_state = Undefined;
1026 #define ival(s) strtol(s, NULL, 0)
1028 /* run a test that simulates an approximate netbench client load */
1029 static bool run_netbench(int client)
1031 struct cli_state *cli;
1036 const char *params[20];
1037 bool correct = True;
1043 cli_sockopt(cli, sockops);
1047 slprintf(cname,sizeof(cname)-1, "client%d", client);
1049 f = fopen(client_txt, "r");
1056 while (fgets(line, sizeof(line)-1, f)) {
1060 line[strlen(line)-1] = 0;
1062 /* printf("[%d] %s\n", line_count, line); */
1064 all_string_sub(line,"client1", cname, sizeof(line));
1066 /* parse the command parameters */
1067 params[0] = strtok_r(line, " ", &saveptr);
1069 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1073 if (i < 2) continue;
1075 if (!strncmp(params[0],"SMB", 3)) {
1076 printf("ERROR: You are using a dbench 1 load file\n");
1080 if (!strcmp(params[0],"NTCreateX")) {
1081 nb_createx(params[1], ival(params[2]), ival(params[3]),
1083 } else if (!strcmp(params[0],"Close")) {
1084 nb_close(ival(params[1]));
1085 } else if (!strcmp(params[0],"Rename")) {
1086 nb_rename(params[1], params[2]);
1087 } else if (!strcmp(params[0],"Unlink")) {
1088 nb_unlink(params[1]);
1089 } else if (!strcmp(params[0],"Deltree")) {
1090 nb_deltree(params[1]);
1091 } else if (!strcmp(params[0],"Rmdir")) {
1092 nb_rmdir(params[1]);
1093 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1094 nb_qpathinfo(params[1]);
1095 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1096 nb_qfileinfo(ival(params[1]));
1097 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1098 nb_qfsinfo(ival(params[1]));
1099 } else if (!strcmp(params[0],"FIND_FIRST")) {
1100 nb_findfirst(params[1]);
1101 } else if (!strcmp(params[0],"WriteX")) {
1102 nb_writex(ival(params[1]),
1103 ival(params[2]), ival(params[3]), ival(params[4]));
1104 } else if (!strcmp(params[0],"ReadX")) {
1105 nb_readx(ival(params[1]),
1106 ival(params[2]), ival(params[3]), ival(params[4]));
1107 } else if (!strcmp(params[0],"Flush")) {
1108 nb_flush(ival(params[1]));
1110 printf("Unknown operation %s\n", params[0]);
1118 if (!torture_close_connection(cli)) {
1126 /* run a test that simulates an approximate netbench client load */
1127 static bool run_nbench(int dummy)
1130 bool correct = True;
1136 signal(SIGALRM, nb_alarm);
1138 t = create_procs(run_netbench, &correct);
1141 printf("\nThroughput %g MB/sec\n",
1142 1.0e-6 * nbio_total() / t);
1148 This test checks for two things:
1150 1) correct support for retaining locks over a close (ie. the server
1151 must not use posix semantics)
1152 2) support for lock timeouts
1154 static bool run_locktest1(int dummy)
1156 struct cli_state *cli1, *cli2;
1157 const char *fname = "\\lockt1.lck";
1158 uint16_t fnum1, fnum2, fnum3;
1160 unsigned lock_timeout;
1162 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1165 cli_sockopt(cli1, sockops);
1166 cli_sockopt(cli2, sockops);
1168 printf("starting locktest1\n");
1170 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1172 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1173 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1176 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1177 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1180 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1181 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1185 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1186 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1191 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1192 printf("lock2 succeeded! This is a locking bug\n");
1195 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1196 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1200 lock_timeout = (1 + (random() % 20));
1201 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1203 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1204 printf("lock3 succeeded! This is a locking bug\n");
1207 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1208 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1212 if (ABS(t2 - t1) < lock_timeout-1) {
1213 printf("error: This server appears not to support timed lock requests\n");
1216 printf("server slept for %u seconds for a %u second timeout\n",
1217 (unsigned int)(t2-t1), lock_timeout);
1219 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1220 printf("close1 failed (%s)\n", cli_errstr(cli1));
1224 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1225 printf("lock4 succeeded! This is a locking bug\n");
1228 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1229 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1232 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1233 printf("close2 failed (%s)\n", cli_errstr(cli1));
1237 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1238 printf("close3 failed (%s)\n", cli_errstr(cli2));
1242 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1243 printf("unlink failed (%s)\n", cli_errstr(cli1));
1248 if (!torture_close_connection(cli1)) {
1252 if (!torture_close_connection(cli2)) {
1256 printf("Passed locktest1\n");
1261 this checks to see if a secondary tconx can use open files from an
1264 static bool run_tcon_test(int dummy)
1266 static struct cli_state *cli;
1267 const char *fname = "\\tcontest.tmp";
1269 uint16 cnum1, cnum2, cnum3;
1270 uint16 vuid1, vuid2;
1275 memset(buf, '\0', sizeof(buf));
1277 if (!torture_open_connection(&cli, 0)) {
1280 cli_sockopt(cli, sockops);
1282 printf("starting tcontest\n");
1284 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1286 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1287 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1294 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1295 printf("initial write failed (%s)", cli_errstr(cli));
1299 status = cli_tcon_andx(cli, share, "?????",
1300 password, strlen(password)+1);
1301 if (!NT_STATUS_IS_OK(status)) {
1302 printf("%s refused 2nd tree connect (%s)\n", host,
1309 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1310 vuid2 = cli->vuid + 1;
1312 /* try a write with the wrong tid */
1315 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1316 printf("* server allows write with wrong TID\n");
1319 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1323 /* try a write with an invalid tid */
1326 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1327 printf("* server allows write with invalid TID\n");
1330 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1333 /* try a write with an invalid vuid */
1337 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1338 printf("* server allows write with invalid VUID\n");
1341 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1347 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1348 printf("close failed (%s)\n", cli_errstr(cli));
1354 status = cli_tdis(cli);
1355 if (!NT_STATUS_IS_OK(status)) {
1356 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1362 if (!torture_close_connection(cli)) {
1371 checks for old style tcon support
1373 static bool run_tcon2_test(int dummy)
1375 static struct cli_state *cli;
1376 uint16 cnum, max_xmit;
1380 if (!torture_open_connection(&cli, 0)) {
1383 cli_sockopt(cli, sockops);
1385 printf("starting tcon2 test\n");
1387 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1391 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1395 if (!NT_STATUS_IS_OK(status)) {
1396 printf("tcon2 failed : %s\n", nt_errstr(status));
1398 printf("tcon OK : max_xmit=%d cnum=%d\n",
1399 (int)max_xmit, (int)cnum);
1402 if (!torture_close_connection(cli)) {
1406 printf("Passed tcon2 test\n");
1410 static bool tcon_devtest(struct cli_state *cli,
1411 const char *myshare, const char *devtype,
1412 const char *return_devtype,
1413 NTSTATUS expected_error)
1418 status = cli_tcon_andx(cli, myshare, devtype,
1419 password, strlen(password)+1);
1421 if (NT_STATUS_IS_OK(expected_error)) {
1422 if (NT_STATUS_IS_OK(status)) {
1423 if (strcmp(cli->dev, return_devtype) == 0) {
1426 printf("tconX to share %s with type %s "
1427 "succeeded but returned the wrong "
1428 "device type (got [%s] but should have got [%s])\n",
1429 myshare, devtype, cli->dev, return_devtype);
1433 printf("tconX to share %s with type %s "
1434 "should have succeeded but failed\n",
1440 if (NT_STATUS_IS_OK(status)) {
1441 printf("tconx to share %s with type %s "
1442 "should have failed but succeeded\n",
1446 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1450 printf("Returned unexpected error\n");
1459 checks for correct tconX support
1461 static bool run_tcon_devtype_test(int dummy)
1463 static struct cli_state *cli1 = NULL;
1468 status = cli_full_connection(&cli1, myname,
1469 host, NULL, port_to_use,
1471 username, workgroup,
1472 password, flags, signing_state);
1474 if (!NT_STATUS_IS_OK(status)) {
1475 printf("could not open connection\n");
1479 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1482 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1485 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1488 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1491 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1494 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1497 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1500 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1503 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1506 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1512 printf("Passed tcondevtest\n");
1519 This test checks that
1521 1) the server supports multiple locking contexts on the one SMB
1522 connection, distinguished by PID.
1524 2) the server correctly fails overlapping locks made by the same PID (this
1525 goes against POSIX behaviour, which is why it is tricky to implement)
1527 3) the server denies unlock requests by an incorrect client PID
1529 static bool run_locktest2(int dummy)
1531 static struct cli_state *cli;
1532 const char *fname = "\\lockt2.lck";
1533 uint16_t fnum1, fnum2, fnum3;
1534 bool correct = True;
1536 if (!torture_open_connection(&cli, 0)) {
1540 cli_sockopt(cli, sockops);
1542 printf("starting locktest2\n");
1544 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1548 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1549 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1553 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1554 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1560 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1561 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1567 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1568 printf("lock1 failed (%s)\n", cli_errstr(cli));
1572 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1573 printf("WRITE lock1 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, WRITE_LOCK)) {
1581 printf("WRITE lock2 succeeded! This is a locking bug\n");
1584 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1585 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1588 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1589 printf("READ lock2 succeeded! This is a locking bug\n");
1592 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1593 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1596 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1597 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1600 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1601 printf("unlock at 100 succeeded! This is a locking bug\n");
1605 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1606 printf("unlock1 succeeded! This is a locking bug\n");
1609 if (!check_error(__LINE__, cli,
1611 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1614 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1615 printf("unlock2 succeeded! This is a locking bug\n");
1618 if (!check_error(__LINE__, cli,
1620 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1623 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1624 printf("lock3 succeeded! This is a locking bug\n");
1627 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1632 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1633 printf("close1 failed (%s)\n", cli_errstr(cli));
1637 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1638 printf("close2 failed (%s)\n", cli_errstr(cli));
1642 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1643 printf("close3 failed (%s)\n", cli_errstr(cli));
1647 if (!torture_close_connection(cli)) {
1651 printf("locktest2 finished\n");
1658 This test checks that
1660 1) the server supports the full offset range in lock requests
1662 static bool run_locktest3(int dummy)
1664 static struct cli_state *cli1, *cli2;
1665 const char *fname = "\\lockt3.lck";
1666 uint16_t fnum1, fnum2;
1669 bool correct = True;
1671 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1673 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1676 cli_sockopt(cli1, sockops);
1677 cli_sockopt(cli2, sockops);
1679 printf("starting locktest3\n");
1681 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1683 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1684 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1687 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1688 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1692 for (offset=i=0;i<torture_numops;i++) {
1694 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1695 printf("lock1 %d failed (%s)\n",
1701 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1702 printf("lock2 %d failed (%s)\n",
1709 for (offset=i=0;i<torture_numops;i++) {
1712 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1713 printf("error: lock1 %d succeeded!\n", i);
1717 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1718 printf("error: lock2 %d succeeded!\n", i);
1722 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1723 printf("error: lock3 %d succeeded!\n", i);
1727 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1728 printf("error: lock4 %d succeeded!\n", i);
1733 for (offset=i=0;i<torture_numops;i++) {
1736 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1737 printf("unlock1 %d failed (%s)\n",
1743 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1744 printf("unlock2 %d failed (%s)\n",
1751 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1752 printf("close1 failed (%s)\n", cli_errstr(cli1));
1756 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1757 printf("close2 failed (%s)\n", cli_errstr(cli2));
1761 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1762 printf("unlink failed (%s)\n", cli_errstr(cli1));
1766 if (!torture_close_connection(cli1)) {
1770 if (!torture_close_connection(cli2)) {
1774 printf("finished locktest3\n");
1779 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1780 printf("** "); correct = False; \
1784 looks at overlapping locks
1786 static bool run_locktest4(int dummy)
1788 static struct cli_state *cli1, *cli2;
1789 const char *fname = "\\lockt4.lck";
1790 uint16_t fnum1, fnum2, f;
1793 bool correct = True;
1795 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1799 cli_sockopt(cli1, sockops);
1800 cli_sockopt(cli2, sockops);
1802 printf("starting locktest4\n");
1804 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1806 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1807 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1809 memset(buf, 0, sizeof(buf));
1811 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1812 printf("Failed to create file\n");
1817 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1818 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1819 EXPECTED(ret, False);
1820 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1822 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1823 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1824 EXPECTED(ret, True);
1825 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1827 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1828 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1829 EXPECTED(ret, False);
1830 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1832 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1833 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1834 EXPECTED(ret, True);
1835 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1837 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1838 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1839 EXPECTED(ret, False);
1840 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1842 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1843 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1844 EXPECTED(ret, True);
1845 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1847 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1848 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1849 EXPECTED(ret, True);
1850 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1852 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1853 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1854 EXPECTED(ret, False);
1855 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1857 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1858 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1859 EXPECTED(ret, False);
1860 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1862 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1863 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1864 EXPECTED(ret, True);
1865 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1867 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1868 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1869 EXPECTED(ret, False);
1870 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1872 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1873 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1874 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1875 EXPECTED(ret, False);
1876 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1879 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1880 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1881 EXPECTED(ret, False);
1882 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1884 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1885 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1886 EXPECTED(ret, False);
1887 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1890 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1891 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1892 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1893 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1894 EXPECTED(ret, True);
1895 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1898 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1899 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1900 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1901 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1902 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1903 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1904 EXPECTED(ret, True);
1905 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1907 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1908 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1909 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1910 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1911 EXPECTED(ret, True);
1912 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1914 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1915 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1916 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1917 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1918 EXPECTED(ret, True);
1919 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1921 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1922 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1923 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1924 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1925 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1926 EXPECTED(ret, True);
1927 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1929 cli_close(cli1, fnum1);
1930 cli_close(cli2, fnum2);
1931 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1932 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1933 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1934 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1935 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1936 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1937 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1939 cli_close(cli1, fnum1);
1940 EXPECTED(ret, True);
1941 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1944 cli_close(cli1, fnum1);
1945 cli_close(cli2, fnum2);
1946 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1947 torture_close_connection(cli1);
1948 torture_close_connection(cli2);
1950 printf("finished locktest4\n");
1955 looks at lock upgrade/downgrade.
1957 static bool run_locktest5(int dummy)
1959 static struct cli_state *cli1, *cli2;
1960 const char *fname = "\\lockt5.lck";
1961 uint16_t fnum1, fnum2, fnum3;
1964 bool correct = True;
1966 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1970 cli_sockopt(cli1, sockops);
1971 cli_sockopt(cli2, sockops);
1973 printf("starting locktest5\n");
1975 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1977 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1978 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1979 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1981 memset(buf, 0, sizeof(buf));
1983 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1984 printf("Failed to create file\n");
1989 /* Check for NT bug... */
1990 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1991 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1992 cli_close(cli1, fnum1);
1993 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1994 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1995 EXPECTED(ret, True);
1996 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1997 cli_close(cli1, fnum1);
1998 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1999 cli_unlock(cli1, fnum3, 0, 1);
2001 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2002 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2003 EXPECTED(ret, True);
2004 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2006 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2007 EXPECTED(ret, False);
2009 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2011 /* Unlock the process 2 lock. */
2012 cli_unlock(cli2, fnum2, 0, 4);
2014 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2015 EXPECTED(ret, False);
2017 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2019 /* Unlock the process 1 fnum3 lock. */
2020 cli_unlock(cli1, fnum3, 0, 4);
2022 /* Stack 2 more locks here. */
2023 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2024 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2026 EXPECTED(ret, True);
2027 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2029 /* Unlock the first process lock, then check this was the WRITE lock that was
2032 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2033 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2035 EXPECTED(ret, True);
2036 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2038 /* Unlock the process 2 lock. */
2039 cli_unlock(cli2, fnum2, 0, 4);
2041 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2043 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2044 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2045 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2047 EXPECTED(ret, True);
2048 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2050 /* Ensure the next unlock fails. */
2051 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2052 EXPECTED(ret, False);
2053 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2055 /* Ensure connection 2 can get a write lock. */
2056 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2057 EXPECTED(ret, True);
2059 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2063 cli_close(cli1, fnum1);
2064 cli_close(cli2, fnum2);
2065 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2066 if (!torture_close_connection(cli1)) {
2069 if (!torture_close_connection(cli2)) {
2073 printf("finished locktest5\n");
2079 tries the unusual lockingX locktype bits
2081 static bool run_locktest6(int dummy)
2083 static struct cli_state *cli;
2084 const char *fname[1] = { "\\lock6.txt" };
2089 if (!torture_open_connection(&cli, 0)) {
2093 cli_sockopt(cli, sockops);
2095 printf("starting locktest6\n");
2098 printf("Testing %s\n", fname[i]);
2100 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2102 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2103 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2104 cli_close(cli, fnum);
2105 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2107 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2108 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2109 cli_close(cli, fnum);
2110 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2112 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2115 torture_close_connection(cli);
2117 printf("finished locktest6\n");
2121 static bool run_locktest7(int dummy)
2123 struct cli_state *cli1;
2124 const char *fname = "\\lockt7.lck";
2127 bool correct = False;
2129 if (!torture_open_connection(&cli1, 0)) {
2133 cli_sockopt(cli1, sockops);
2135 printf("starting locktest7\n");
2137 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2139 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2141 memset(buf, 0, sizeof(buf));
2143 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2144 printf("Failed to create file\n");
2148 cli_setpid(cli1, 1);
2150 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2151 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2154 printf("pid1 successfully locked range 130:4 for READ\n");
2157 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2158 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2161 printf("pid1 successfully read the range 130:4\n");
2164 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2165 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2166 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2167 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2171 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2175 cli_setpid(cli1, 2);
2177 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2178 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2180 printf("pid2 successfully read the range 130:4\n");
2183 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2184 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2185 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2186 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2190 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2194 cli_setpid(cli1, 1);
2195 cli_unlock(cli1, fnum1, 130, 4);
2197 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2198 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2201 printf("pid1 successfully locked range 130:4 for WRITE\n");
2204 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2205 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2208 printf("pid1 successfully read the range 130:4\n");
2211 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2212 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2215 printf("pid1 successfully wrote to the range 130:4\n");
2218 cli_setpid(cli1, 2);
2220 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2221 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2222 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2223 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2227 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2231 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2232 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2233 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2234 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2238 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2242 cli_unlock(cli1, fnum1, 130, 0);
2246 cli_close(cli1, fnum1);
2247 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2248 torture_close_connection(cli1);
2250 printf("finished locktest7\n");
2255 * This demonstrates a problem with our use of GPFS share modes: A file
2256 * descriptor sitting in the pending close queue holding a GPFS share mode
2257 * blocks opening a file another time. Happens with Word 2007 temp files.
2258 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2259 * open is denied with NT_STATUS_SHARING_VIOLATION.
2262 static bool run_locktest8(int dummy)
2264 struct cli_state *cli1;
2265 const char *fname = "\\lockt8.lck";
2266 uint16_t fnum1, fnum2;
2268 bool correct = False;
2271 if (!torture_open_connection(&cli1, 0)) {
2275 cli_sockopt(cli1, sockops);
2277 printf("starting locktest8\n");
2279 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2281 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2283 if (!NT_STATUS_IS_OK(status)) {
2284 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2288 memset(buf, 0, sizeof(buf));
2290 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2291 if (!NT_STATUS_IS_OK(status)) {
2292 d_fprintf(stderr, "cli_open second time returned %s\n",
2297 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2298 printf("Unable to apply read lock on range 1:1, error was "
2299 "%s\n", cli_errstr(cli1));
2303 status = cli_close(cli1, fnum1);
2304 if (!NT_STATUS_IS_OK(status)) {
2305 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2309 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2310 if (!NT_STATUS_IS_OK(status)) {
2311 d_fprintf(stderr, "cli_open third time returned %s\n",
2319 cli_close(cli1, fnum1);
2320 cli_close(cli1, fnum2);
2321 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2322 torture_close_connection(cli1);
2324 printf("finished locktest8\n");
2329 * This test is designed to be run in conjunction with
2330 * external NFS or POSIX locks taken in the filesystem.
2331 * It checks that the smbd server will block until the
2332 * lock is released and then acquire it. JRA.
2335 static bool got_alarm;
2336 static int alarm_fd;
2338 static void alarm_handler(int dummy)
2343 static void alarm_handler_parent(int dummy)
2348 static void do_local_lock(int read_fd, int write_fd)
2353 const char *local_pathname = NULL;
2356 local_pathname = talloc_asprintf(talloc_tos(),
2357 "%s/lockt9.lck", local_path);
2358 if (!local_pathname) {
2359 printf("child: alloc fail\n");
2363 unlink(local_pathname);
2364 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2366 printf("child: open of %s failed %s.\n",
2367 local_pathname, strerror(errno));
2371 /* Now take a fcntl lock. */
2372 lock.l_type = F_WRLCK;
2373 lock.l_whence = SEEK_SET;
2376 lock.l_pid = getpid();
2378 ret = fcntl(fd,F_SETLK,&lock);
2380 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2381 local_pathname, strerror(errno));
2384 printf("child: got lock 0:4 on file %s.\n",
2389 CatchSignal(SIGALRM, alarm_handler);
2391 /* Signal the parent. */
2392 if (write(write_fd, &c, 1) != 1) {
2393 printf("child: start signal fail %s.\n",
2400 /* Wait for the parent to be ready. */
2401 if (read(read_fd, &c, 1) != 1) {
2402 printf("child: reply signal fail %s.\n",
2410 printf("child: released lock 0:4 on file %s.\n",
2416 static bool run_locktest9(int dummy)
2418 struct cli_state *cli1;
2419 const char *fname = "\\lockt9.lck";
2421 bool correct = False;
2422 int pipe_in[2], pipe_out[2];
2426 struct timeval start;
2430 printf("starting locktest9\n");
2432 if (local_path == NULL) {
2433 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2437 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2442 if (child_pid == -1) {
2446 if (child_pid == 0) {
2448 do_local_lock(pipe_out[0], pipe_in[1]);
2458 ret = read(pipe_in[0], &c, 1);
2460 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2465 if (!torture_open_connection(&cli1, 0)) {
2469 cli_sockopt(cli1, sockops);
2471 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2473 if (!NT_STATUS_IS_OK(status)) {
2474 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2478 /* Ensure the child has the lock. */
2479 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2480 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2483 d_printf("Child has the lock.\n");
2486 /* Tell the child to wait 5 seconds then exit. */
2487 ret = write(pipe_out[1], &c, 1);
2489 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2494 /* Wait 20 seconds for the lock. */
2495 alarm_fd = cli1->fd;
2496 CatchSignal(SIGALRM, alarm_handler_parent);
2499 start = timeval_current();
2501 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2502 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2503 "%s\n", cli_errstr(cli1));
2508 seconds = timeval_elapsed(&start);
2510 printf("Parent got the lock after %.2f seconds.\n",
2513 status = cli_close(cli1, fnum);
2514 if (!NT_STATUS_IS_OK(status)) {
2515 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2522 cli_close(cli1, fnum);
2523 torture_close_connection(cli1);
2527 printf("finished locktest9\n");
2532 test whether fnums and tids open on one VC are available on another (a major
2535 static bool run_fdpasstest(int dummy)
2537 struct cli_state *cli1, *cli2;
2538 const char *fname = "\\fdpass.tst";
2542 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2545 cli_sockopt(cli1, sockops);
2546 cli_sockopt(cli2, sockops);
2548 printf("starting fdpasstest\n");
2550 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2552 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2553 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2557 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2558 printf("write failed (%s)\n", cli_errstr(cli1));
2562 cli2->vuid = cli1->vuid;
2563 cli2->cnum = cli1->cnum;
2564 cli2->pid = cli1->pid;
2566 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2567 printf("read succeeded! nasty security hole [%s]\n",
2572 cli_close(cli1, fnum1);
2573 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2575 torture_close_connection(cli1);
2576 torture_close_connection(cli2);
2578 printf("finished fdpasstest\n");
2582 static bool run_fdsesstest(int dummy)
2584 struct cli_state *cli;
2589 const char *fname = "\\fdsess.tst";
2590 const char *fname1 = "\\fdsess1.tst";
2596 if (!torture_open_connection(&cli, 0))
2598 cli_sockopt(cli, sockops);
2600 if (!torture_cli_session_setup2(cli, &new_vuid))
2603 saved_cnum = cli->cnum;
2604 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2606 new_cnum = cli->cnum;
2607 cli->cnum = saved_cnum;
2609 printf("starting fdsesstest\n");
2611 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2612 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2614 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2615 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2619 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2620 printf("write failed (%s)\n", cli_errstr(cli));
2624 saved_vuid = cli->vuid;
2625 cli->vuid = new_vuid;
2627 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2628 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2632 /* Try to open a file with different vuid, samba cnum. */
2633 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2634 printf("create with different vuid, same cnum succeeded.\n");
2635 cli_close(cli, fnum2);
2636 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2638 printf("create with different vuid, same cnum failed.\n");
2639 printf("This will cause problems with service clients.\n");
2643 cli->vuid = saved_vuid;
2645 /* Try with same vuid, different cnum. */
2646 cli->cnum = new_cnum;
2648 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2649 printf("read succeeded with different cnum![%s]\n",
2654 cli->cnum = saved_cnum;
2655 cli_close(cli, fnum1);
2656 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2658 torture_close_connection(cli);
2660 printf("finished fdsesstest\n");
2665 This test checks that
2667 1) the server does not allow an unlink on a file that is open
2669 static bool run_unlinktest(int dummy)
2671 struct cli_state *cli;
2672 const char *fname = "\\unlink.tst";
2674 bool correct = True;
2676 if (!torture_open_connection(&cli, 0)) {
2680 cli_sockopt(cli, sockops);
2682 printf("starting unlink test\n");
2684 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2688 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2689 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2693 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2694 printf("error: server allowed unlink on an open file\n");
2697 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2698 NT_STATUS_SHARING_VIOLATION);
2701 cli_close(cli, fnum);
2702 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2704 if (!torture_close_connection(cli)) {
2708 printf("unlink test finished\n");
2715 test how many open files this server supports on the one socket
2717 static bool run_maxfidtest(int dummy)
2719 struct cli_state *cli;
2720 const char *ftemplate = "\\maxfid.%d.%d";
2722 uint16_t fnums[0x11000];
2725 bool correct = True;
2730 printf("failed to connect\n");
2734 cli_sockopt(cli, sockops);
2736 for (i=0; i<0x11000; i++) {
2737 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2738 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2739 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2740 printf("open of %s failed (%s)\n",
2741 fname, cli_errstr(cli));
2742 printf("maximum fnum is %d\n", i);
2750 printf("cleaning up\n");
2752 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2753 cli_close(cli, fnums[i]);
2754 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2755 printf("unlink of %s failed (%s)\n",
2756 fname, cli_errstr(cli));
2763 printf("maxfid test finished\n");
2764 if (!torture_close_connection(cli)) {
2770 /* generate a random buffer */
2771 static void rand_buf(char *buf, int len)
2774 *buf = (char)sys_random();
2779 /* send smb negprot commands, not reading the response */
2780 static bool run_negprot_nowait(int dummy)
2782 struct tevent_context *ev;
2784 struct cli_state *cli;
2785 bool correct = True;
2787 printf("starting negprot nowait test\n");
2789 ev = tevent_context_init(talloc_tos());
2794 if (!(cli = open_nbt_connection())) {
2799 for (i=0;i<50000;i++) {
2800 struct tevent_req *req;
2802 req = cli_negprot_send(ev, ev, cli);
2807 if (!tevent_req_poll(req, ev)) {
2808 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2816 if (torture_close_connection(cli)) {
2820 printf("finished negprot nowait test\n");
2825 /* send smb negprot commands, not reading the response */
2826 static bool run_bad_nbt_session(int dummy)
2828 static struct cli_state *cli;
2830 printf("starting bad nbt session test\n");
2832 if (!(cli = open_bad_nbt_connection())) {
2837 printf("finished bad nbt session test\n");
2841 /* send random IPC commands */
2842 static bool run_randomipc(int dummy)
2844 char *rparam = NULL;
2846 unsigned int rdrcnt,rprcnt;
2848 int api, param_len, i;
2849 struct cli_state *cli;
2850 bool correct = True;
2853 printf("starting random ipc test\n");
2855 if (!torture_open_connection(&cli, 0)) {
2859 for (i=0;i<count;i++) {
2860 api = sys_random() % 500;
2861 param_len = (sys_random() % 64);
2863 rand_buf(param, param_len);
2868 param, param_len, 8,
2869 NULL, 0, BUFFER_SIZE,
2873 printf("%d/%d\r", i,count);
2876 printf("%d/%d\n", i, count);
2878 if (!torture_close_connection(cli)) {
2882 printf("finished random ipc test\n");
2889 static void browse_callback(const char *sname, uint32 stype,
2890 const char *comment, void *state)
2892 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2898 This test checks the browse list code
2901 static bool run_browsetest(int dummy)
2903 static struct cli_state *cli;
2904 bool correct = True;
2906 printf("starting browse test\n");
2908 if (!torture_open_connection(&cli, 0)) {
2912 printf("domain list:\n");
2913 cli_NetServerEnum(cli, cli->server_domain,
2914 SV_TYPE_DOMAIN_ENUM,
2915 browse_callback, NULL);
2917 printf("machine list:\n");
2918 cli_NetServerEnum(cli, cli->server_domain,
2920 browse_callback, NULL);
2922 if (!torture_close_connection(cli)) {
2926 printf("browse test finished\n");
2934 This checks how the getatr calls works
2936 static bool run_attrtest(int dummy)
2938 struct cli_state *cli;
2941 const char *fname = "\\attrib123456789.tst";
2942 bool correct = True;
2944 printf("starting attrib test\n");
2946 if (!torture_open_connection(&cli, 0)) {
2950 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2951 cli_open(cli, fname,
2952 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2953 cli_close(cli, fnum);
2954 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2955 printf("getatr failed (%s)\n", cli_errstr(cli));
2959 if (abs(t - time(NULL)) > 60*60*24*10) {
2960 printf("ERROR: SMBgetatr bug. time is %s",
2966 t2 = t-60*60*24; /* 1 day ago */
2968 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2969 printf("setatr failed (%s)\n", cli_errstr(cli));
2973 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2974 printf("getatr failed (%s)\n", cli_errstr(cli));
2979 printf("ERROR: getatr/setatr bug. times are\n%s",
2981 printf("%s", ctime(&t2));
2985 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2987 if (!torture_close_connection(cli)) {
2991 printf("attrib test finished\n");
2998 This checks a couple of trans2 calls
3000 static bool run_trans2test(int dummy)
3002 struct cli_state *cli;
3005 time_t c_time, a_time, m_time;
3006 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3007 const char *fname = "\\trans2.tst";
3008 const char *dname = "\\trans2";
3009 const char *fname2 = "\\trans2\\trans2.tst";
3011 bool correct = True;
3015 printf("starting trans2 test\n");
3017 if (!torture_open_connection(&cli, 0)) {
3021 status = cli_get_fs_attr_info(cli, &fs_attr);
3022 if (!NT_STATUS_IS_OK(status)) {
3023 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3028 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3029 cli_open(cli, fname,
3030 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3031 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3032 cli, fnum, NULL, &size, &c_time_ts,
3033 &a_time_ts, &w_time_ts,
3034 &m_time_ts, NULL))) {
3035 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3039 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3040 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3044 if (strcmp(pname, fname)) {
3045 printf("qfilename gave different name? [%s] [%s]\n",
3050 cli_close(cli, fnum);
3054 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3055 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3056 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3057 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3060 cli_close(cli, fnum);
3062 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3064 if (!NT_STATUS_IS_OK(status)) {
3065 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3068 if (c_time != m_time) {
3069 printf("create time=%s", ctime(&c_time));
3070 printf("modify time=%s", ctime(&m_time));
3071 printf("This system appears to have sticky create times\n");
3073 if (a_time % (60*60) == 0) {
3074 printf("access time=%s", ctime(&a_time));
3075 printf("This system appears to set a midnight access time\n");
3079 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3080 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3086 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3087 cli_open(cli, fname,
3088 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3089 cli_close(cli, fnum);
3090 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3091 &m_time_ts, &size, NULL, NULL);
3092 if (!NT_STATUS_IS_OK(status)) {
3093 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3096 if (w_time_ts.tv_sec < 60*60*24*2) {
3097 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3098 printf("This system appears to set a initial 0 write time\n");
3103 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3106 /* check if the server updates the directory modification time
3107 when creating a new file */
3108 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3109 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3113 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3114 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3115 if (!NT_STATUS_IS_OK(status)) {
3116 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3120 cli_open(cli, fname2,
3121 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3122 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
3123 cli_close(cli, fnum);
3124 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3125 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3126 if (!NT_STATUS_IS_OK(status)) {
3127 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3130 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3132 printf("This system does not update directory modification times\n");
3136 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3137 cli_rmdir(cli, dname);
3139 if (!torture_close_connection(cli)) {
3143 printf("trans2 test finished\n");
3149 This checks new W2K calls.
3152 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3154 uint8_t *buf = NULL;
3158 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3159 pcli->max_xmit, &buf, &len);
3160 if (!NT_STATUS_IS_OK(status)) {
3161 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3164 printf("qfileinfo: level %d, len = %u\n", level, len);
3165 dump_data(0, (uint8 *)buf, len);
3172 static bool run_w2ktest(int dummy)
3174 struct cli_state *cli;
3176 const char *fname = "\\w2ktest\\w2k.tst";
3178 bool correct = True;
3180 printf("starting w2k test\n");
3182 if (!torture_open_connection(&cli, 0)) {
3186 cli_open(cli, fname,
3187 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3189 for (level = 1004; level < 1040; level++) {
3190 new_trans(cli, fnum, level);
3193 cli_close(cli, fnum);
3195 if (!torture_close_connection(cli)) {
3199 printf("w2k test finished\n");
3206 this is a harness for some oplock tests
3208 static bool run_oplock1(int dummy)
3210 struct cli_state *cli1;
3211 const char *fname = "\\lockt1.lck";
3213 bool correct = True;
3215 printf("starting oplock test 1\n");
3217 if (!torture_open_connection(&cli1, 0)) {
3221 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3223 cli_sockopt(cli1, sockops);
3225 cli1->use_oplocks = True;
3227 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3228 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3232 cli1->use_oplocks = False;
3234 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3235 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3237 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3238 printf("close2 failed (%s)\n", cli_errstr(cli1));
3242 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3243 printf("unlink failed (%s)\n", cli_errstr(cli1));
3247 if (!torture_close_connection(cli1)) {
3251 printf("finished oplock test 1\n");
3256 static bool run_oplock2(int dummy)
3258 struct cli_state *cli1, *cli2;
3259 const char *fname = "\\lockt2.lck";
3260 uint16_t fnum1, fnum2;
3261 int saved_use_oplocks = use_oplocks;
3263 bool correct = True;
3264 volatile bool *shared_correct;
3266 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3267 *shared_correct = True;
3269 use_level_II_oplocks = True;
3272 printf("starting oplock test 2\n");
3274 if (!torture_open_connection(&cli1, 0)) {
3275 use_level_II_oplocks = False;
3276 use_oplocks = saved_use_oplocks;
3280 cli1->use_oplocks = True;
3281 cli1->use_level_II_oplocks = True;
3283 if (!torture_open_connection(&cli2, 1)) {
3284 use_level_II_oplocks = False;
3285 use_oplocks = saved_use_oplocks;
3289 cli2->use_oplocks = True;
3290 cli2->use_level_II_oplocks = True;
3292 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3294 cli_sockopt(cli1, sockops);
3295 cli_sockopt(cli2, sockops);
3297 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3298 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3302 /* Don't need the globals any more. */
3303 use_level_II_oplocks = False;
3304 use_oplocks = saved_use_oplocks;
3308 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3309 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3310 *shared_correct = False;
3316 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3317 printf("close2 failed (%s)\n", cli_errstr(cli1));
3318 *shared_correct = False;
3326 /* Ensure cli1 processes the break. Empty file should always return 0
3329 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3330 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3334 /* Should now be at level II. */
3335 /* Test if sending a write locks causes a break to none. */
3337 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3338 printf("lock failed (%s)\n", cli_errstr(cli1));
3342 cli_unlock(cli1, fnum1, 0, 4);
3346 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3347 printf("lock failed (%s)\n", cli_errstr(cli1));
3351 cli_unlock(cli1, fnum1, 0, 4);
3355 cli_read(cli1, fnum1, buf, 0, 4);
3358 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3359 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3364 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3365 printf("close1 failed (%s)\n", cli_errstr(cli1));
3371 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3372 printf("unlink failed (%s)\n", cli_errstr(cli1));
3376 if (!torture_close_connection(cli1)) {
3380 if (!*shared_correct) {
3384 printf("finished oplock test 2\n");
3389 /* handler for oplock 3 tests */
3390 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3392 printf("got oplock break fnum=%d level=%d\n",
3394 return cli_oplock_ack(cli, fnum, level);
3397 static bool run_oplock3(int dummy)
3399 struct cli_state *cli;
3400 const char *fname = "\\oplockt3.dat";
3402 char buf[4] = "abcd";
3403 bool correct = True;
3404 volatile bool *shared_correct;
3406 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3407 *shared_correct = True;
3409 printf("starting oplock test 3\n");
3414 use_level_II_oplocks = True;
3415 if (!torture_open_connection(&cli, 0)) {
3416 *shared_correct = False;
3420 /* try to trigger a oplock break in parent */
3421 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3422 cli_write(cli, fnum, 0, buf, 0, 4);
3428 use_level_II_oplocks = True;
3429 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3432 cli_oplock_handler(cli, oplock3_handler);
3433 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3434 cli_write(cli, fnum, 0, buf, 0, 4);
3435 cli_close(cli, fnum);
3436 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3437 cli->timeout = 20000;
3438 cli_receive_smb(cli);
3439 printf("finished oplock test 3\n");
3441 return (correct && *shared_correct);
3443 /* What are we looking for here? What's sucess and what's FAILURE? */
3446 /* handler for oplock 4 tests */
3447 bool *oplock4_shared_correct;
3449 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3451 printf("got oplock break fnum=%d level=%d\n",
3453 *oplock4_shared_correct = true;
3454 cli_oplock_ack(cli, fnum, level);
3455 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3458 static bool run_oplock4(int dummy)
3460 struct cli_state *cli1, *cli2;
3461 const char *fname = "\\lockt4.lck";
3462 const char *fname_ln = "\\lockt4_ln.lck";
3463 uint16_t fnum1, fnum2;
3464 int saved_use_oplocks = use_oplocks;
3466 bool correct = true;
3468 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3469 *oplock4_shared_correct = false;
3471 printf("starting oplock test 4\n");
3473 if (!torture_open_connection(&cli1, 0)) {
3474 use_level_II_oplocks = false;
3475 use_oplocks = saved_use_oplocks;
3479 if (!torture_open_connection(&cli2, 1)) {
3480 use_level_II_oplocks = false;
3481 use_oplocks = saved_use_oplocks;
3485 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3486 cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN);
3488 cli_sockopt(cli1, sockops);
3489 cli_sockopt(cli2, sockops);
3491 /* Create the file. */
3492 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3493 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3497 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3498 printf("close1 failed (%s)\n", cli_errstr(cli1));
3502 /* Now create a hardlink. */
3503 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3504 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3508 /* Prove that opening hardlinks cause deny modes to conflict. */
3509 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3510 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3514 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3515 if (NT_STATUS_IS_OK(status)) {
3516 printf("open of %s succeeded - should fail with sharing violation.\n",
3521 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3522 printf("open of %s should fail with sharing violation. Got %s\n",
3523 fname_ln, nt_errstr(status));
3527 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3528 printf("close1 failed (%s)\n", cli_errstr(cli1));
3532 cli1->use_oplocks = true;
3533 cli1->use_level_II_oplocks = true;
3535 cli2->use_oplocks = true;
3536 cli2->use_level_II_oplocks = true;
3538 cli_oplock_handler(cli1, oplock4_handler);
3539 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3540 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3546 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3547 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3548 *oplock4_shared_correct = false;
3552 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3553 printf("close2 failed (%s)\n", cli_errstr(cli1));
3554 *oplock4_shared_correct = false;
3562 /* Process the oplock break. */
3563 cli_receive_smb(cli1);
3565 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3566 printf("close1 failed (%s)\n", cli_errstr(cli1));
3570 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3571 printf("unlink failed (%s)\n", cli_errstr(cli1));
3574 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN))) {
3575 printf("unlink failed (%s)\n", cli_errstr(cli1));
3579 if (!torture_close_connection(cli1)) {
3583 if (!*oplock4_shared_correct) {
3587 printf("finished oplock test 4\n");
3594 Test delete on close semantics.
3596 static bool run_deletetest(int dummy)
3598 struct cli_state *cli1 = NULL;
3599 struct cli_state *cli2 = NULL;
3600 const char *fname = "\\delete.file";
3601 uint16_t fnum1 = (uint16_t)-1;
3602 uint16_t fnum2 = (uint16_t)-1;
3603 bool correct = True;
3605 printf("starting delete test\n");
3607 if (!torture_open_connection(&cli1, 0)) {
3611 cli_sockopt(cli1, sockops);
3613 /* Test 1 - this should delete the file on close. */
3615 cli_setatr(cli1, fname, 0, 0);
3616 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3618 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3619 0, FILE_OVERWRITE_IF,
3620 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3621 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3626 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3627 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3632 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3633 printf("[1] open of %s succeeded (should fail)\n", fname);
3638 printf("first delete on close test succeeded.\n");
3640 /* Test 2 - this should delete the file on close. */
3642 cli_setatr(cli1, fname, 0, 0);
3643 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3645 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3646 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3647 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3648 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3653 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3654 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3659 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3660 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3665 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3666 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3667 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3668 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3672 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3674 printf("second delete on close test succeeded.\n");
3677 cli_setatr(cli1, fname, 0, 0);
3678 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3680 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3681 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3682 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3687 /* This should fail with a sharing violation - open for delete is only compatible
3688 with SHARE_DELETE. */
3690 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3691 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3692 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3697 /* This should succeed. */
3699 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3700 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3701 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3706 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3707 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3712 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3713 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3718 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3719 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3724 /* This should fail - file should no longer be there. */
3726 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3727 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3728 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3729 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3731 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3735 printf("third delete on close test succeeded.\n");
3738 cli_setatr(cli1, fname, 0, 0);
3739 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3741 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3742 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3743 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3748 /* This should succeed. */
3749 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3750 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3751 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3756 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3757 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3762 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3763 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3768 /* This should fail - no more opens once delete on close set. */
3769 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3770 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3771 FILE_OPEN, 0, 0, &fnum2))) {
3772 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3776 printf("fourth delete on close test succeeded.\n");
3778 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3779 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3785 cli_setatr(cli1, fname, 0, 0);
3786 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3788 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3789 printf("[5] 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("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3802 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3803 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3808 printf("fifth 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,
3815 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3816 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3817 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3822 /* This should fail - only allowed on NT opens with DELETE access. */
3824 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3825 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3830 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3831 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3836 printf("sixth delete on close test succeeded.\n");
3839 cli_setatr(cli1, fname, 0, 0);
3840 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3842 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3843 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3844 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3849 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3850 printf("[7] setting delete_on_close on file failed !\n");
3855 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3856 printf("[7] unsetting delete_on_close on file failed !\n");
3861 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3862 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3867 /* This next open should succeed - we reset the flag. */
3869 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3870 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3875 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3876 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3881 printf("seventh delete on close test succeeded.\n");
3884 cli_setatr(cli1, fname, 0, 0);
3885 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3887 if (!torture_open_connection(&cli2, 1)) {
3888 printf("[8] failed to open second connection.\n");
3893 cli_sockopt(cli1, sockops);
3895 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3896 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3897 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3898 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3903 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3904 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3905 FILE_OPEN, 0, 0, &fnum2))) {
3906 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3911 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3912 printf("[8] setting delete_on_close on file failed !\n");
3917 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3918 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3923 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3924 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3929 /* This should fail.. */
3930 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3931 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3935 printf("eighth delete on close test succeeded.\n");
3937 /* This should fail - we need to set DELETE_ACCESS. */
3938 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3939 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3940 printf("[9] open of %s succeeded should have failed!\n", fname);
3945 printf("ninth delete on close test succeeded.\n");
3947 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3948 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3949 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3954 /* This should delete the file. */
3955 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3956 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3961 /* This should fail.. */
3962 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3963 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3967 printf("tenth delete on close test succeeded.\n");
3969 cli_setatr(cli1, fname, 0, 0);
3970 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3972 /* What error do we get when attempting to open a read-only file with
3975 /* Create a readonly file. */
3976 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3977 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3978 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3983 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3984 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3989 /* Now try open for delete access. */
3990 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3991 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3992 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3993 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3994 cli_close(cli1, fnum1);
3998 NTSTATUS nterr = cli_nt_error(cli1);
3999 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4000 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4004 printf("eleventh delete on close test succeeded.\n");
4008 printf("finished delete test\n");
4011 /* FIXME: This will crash if we aborted before cli2 got
4012 * intialized, because these functions don't handle
4013 * uninitialized connections. */
4015 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4016 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4017 cli_setatr(cli1, fname, 0, 0);
4018 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4020 if (cli1 && !torture_close_connection(cli1)) {
4023 if (cli2 && !torture_close_connection(cli2)) {
4029 static bool run_deletetest_ln(int dummy)
4031 struct cli_state *cli;
4032 const char *fname = "\\delete1";
4033 const char *fname_ln = "\\delete1_ln";
4037 bool correct = true;
4040 printf("starting deletetest-ln\n");
4042 if (!torture_open_connection(&cli, 0)) {
4046 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4047 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4049 cli_sockopt(cli, sockops);
4051 /* Create the file. */
4052 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4053 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4057 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4058 printf("close1 failed (%s)\n", cli_errstr(cli));
4062 /* Now create a hardlink. */
4063 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4064 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4068 /* Open the original file. */
4069 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4070 FILE_ATTRIBUTE_NORMAL,
4071 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4072 FILE_OPEN_IF, 0, 0, &fnum);
4073 if (!NT_STATUS_IS_OK(status)) {
4074 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4078 /* Unlink the hard link path. */
4079 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4080 FILE_ATTRIBUTE_NORMAL,
4081 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4082 FILE_OPEN_IF, 0, 0, &fnum1);
4083 if (!NT_STATUS_IS_OK(status)) {
4084 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4087 status = cli_nt_delete_on_close(cli, fnum1, true);
4088 if (!NT_STATUS_IS_OK(status)) {
4089 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4090 __location__, fname_ln, nt_errstr(status));
4094 status = cli_close(cli, fnum1);
4095 if (!NT_STATUS_IS_OK(status)) {
4096 printf("close %s failed (%s)\n",
4097 fname_ln, nt_errstr(status));
4101 status = cli_close(cli, fnum);
4102 if (!NT_STATUS_IS_OK(status)) {
4103 printf("close %s failed (%s)\n",
4104 fname, nt_errstr(status));
4108 /* Ensure the original file is still there. */
4109 status = cli_getatr(cli, fname, NULL, NULL, &t);
4110 if (!NT_STATUS_IS_OK(status)) {
4111 printf("%s getatr on file %s failed (%s)\n",
4118 /* Ensure the link path is gone. */
4119 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4120 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4121 printf("%s, getatr for file %s returned wrong error code %s "
4122 "- should have been deleted\n",
4124 fname_ln, nt_errstr(status));
4128 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4129 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4131 if (!torture_close_connection(cli)) {
4135 printf("finished deletetest-ln\n");
4141 print out server properties
4143 static bool run_properties(int dummy)
4145 struct cli_state *cli;
4146 bool correct = True;
4148 printf("starting properties test\n");
4152 if (!torture_open_connection(&cli, 0)) {
4156 cli_sockopt(cli, sockops);
4158 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4160 if (!torture_close_connection(cli)) {
4169 /* FIRST_DESIRED_ACCESS 0xf019f */
4170 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4171 FILE_READ_EA| /* 0xf */ \
4172 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4173 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4174 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4175 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4176 /* SECOND_DESIRED_ACCESS 0xe0080 */
4177 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4178 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4179 WRITE_OWNER_ACCESS /* 0xe0000 */
4182 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4183 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4185 WRITE_OWNER_ACCESS /* */
4189 Test ntcreate calls made by xcopy
4191 static bool run_xcopy(int dummy)
4193 static struct cli_state *cli1;
4194 const char *fname = "\\test.txt";
4195 bool correct = True;
4196 uint16_t fnum1, fnum2;
4198 printf("starting xcopy test\n");
4200 if (!torture_open_connection(&cli1, 0)) {
4204 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4205 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4206 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4207 0x4044, 0, &fnum1))) {
4208 printf("First open failed - %s\n", cli_errstr(cli1));
4212 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4213 SECOND_DESIRED_ACCESS, 0,
4214 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4215 0x200000, 0, &fnum2))) {
4216 printf("second open failed - %s\n", cli_errstr(cli1));
4220 if (!torture_close_connection(cli1)) {
4228 Test rename on files open with share delete and no share delete.
4230 static bool run_rename(int dummy)
4232 static struct cli_state *cli1;
4233 const char *fname = "\\test.txt";
4234 const char *fname1 = "\\test1.txt";
4235 bool correct = True;
4240 printf("starting rename test\n");
4242 if (!torture_open_connection(&cli1, 0)) {
4246 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4247 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4248 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4249 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4250 printf("First open failed - %s\n", cli_errstr(cli1));
4254 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4255 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4257 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4261 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4262 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4266 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4267 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4268 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4270 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4272 FILE_SHARE_DELETE|FILE_SHARE_READ,
4274 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4275 if (!NT_STATUS_IS_OK(status)) {
4276 printf("Second open failed - %s\n", cli_errstr(cli1));
4280 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4281 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4284 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4287 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4288 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4292 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4293 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4295 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4296 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4297 printf("Third open failed - %s\n", cli_errstr(cli1));
4306 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4307 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4308 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4311 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4312 printf("[8] setting delete_on_close on file failed !\n");
4316 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4317 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4323 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4324 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4327 printf("Third rename succeeded (SHARE_NONE)\n");
4330 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4331 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4335 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4336 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4340 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4341 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4342 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4346 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4347 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4349 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4353 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4354 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4358 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4359 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4363 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4364 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4365 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4369 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4370 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4374 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4378 * Now check if the first name still exists ...
4381 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4382 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4383 printf("Opening original file after rename of open file fails: %s\n",
4387 printf("Opening original file after rename of open file works ...\n");
4388 (void)cli_close(cli1, fnum2);
4392 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4393 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4397 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4398 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4399 printf("getatr on file %s failed - %s ! \n",
4404 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4405 printf("Renamed file %s has wrong attr 0x%x "
4406 "(should be 0x%x)\n",
4409 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4412 printf("Renamed file %s has archive bit set\n", fname1);
4416 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4417 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4419 if (!torture_close_connection(cli1)) {
4426 static bool run_pipe_number(int dummy)
4428 struct cli_state *cli1;
4429 const char *pipe_name = "\\SPOOLSS";
4433 printf("starting pipenumber test\n");
4434 if (!torture_open_connection(&cli1, 0)) {
4438 cli_sockopt(cli1, sockops);
4440 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4441 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4442 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4446 printf("\r%6d", num_pipes);
4449 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4450 torture_close_connection(cli1);
4455 Test open mode returns on read-only files.
4457 static bool run_opentest(int dummy)
4459 static struct cli_state *cli1;
4460 static struct cli_state *cli2;
4461 const char *fname = "\\readonly.file";
4462 uint16_t fnum1, fnum2;
4465 bool correct = True;
4469 printf("starting open test\n");
4471 if (!torture_open_connection(&cli1, 0)) {
4475 cli_setatr(cli1, fname, 0, 0);
4476 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4478 cli_sockopt(cli1, sockops);
4480 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4481 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4485 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4486 printf("close2 failed (%s)\n", cli_errstr(cli1));
4490 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4491 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4495 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4496 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4500 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4501 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4503 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4504 NT_STATUS_ACCESS_DENIED)) {
4505 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4508 printf("finished open test 1\n");
4510 cli_close(cli1, fnum1);
4512 /* Now try not readonly and ensure ERRbadshare is returned. */
4514 cli_setatr(cli1, fname, 0, 0);
4516 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4517 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4521 /* This will fail - but the error should be ERRshare. */
4522 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4524 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4525 NT_STATUS_SHARING_VIOLATION)) {
4526 printf("correct error code ERRDOS/ERRbadshare returned\n");
4529 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4530 printf("close2 failed (%s)\n", cli_errstr(cli1));
4534 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4536 printf("finished open test 2\n");
4538 /* Test truncate open disposition on file opened for read. */
4540 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4541 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4545 /* write 20 bytes. */
4547 memset(buf, '\0', 20);
4549 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4550 printf("write failed (%s)\n", cli_errstr(cli1));
4554 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4555 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4559 /* Ensure size == 20. */
4560 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4561 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4566 printf("(3) file size != 20\n");
4570 /* Now test if we can truncate a file opened for readonly. */
4572 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4573 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4577 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4578 printf("close2 failed (%s)\n", cli_errstr(cli1));
4582 /* Ensure size == 0. */
4583 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4584 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4589 printf("(3) file size != 0\n");
4592 printf("finished open test 3\n");
4594 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4596 printf("Do ctemp tests\n");
4597 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4598 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4601 printf("ctemp gave path %s\n", tmp_path);
4602 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4603 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4605 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4606 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4609 /* Test the non-io opens... */
4611 if (!torture_open_connection(&cli2, 1)) {
4615 cli_setatr(cli2, fname, 0, 0);
4616 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4618 cli_sockopt(cli2, sockops);
4620 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4622 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4623 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4624 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4628 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4629 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4630 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4634 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4635 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4638 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4639 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4643 printf("non-io open test #1 passed.\n");
4645 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4647 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4649 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4650 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4651 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4655 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4656 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4657 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4661 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4662 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4665 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4666 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4670 printf("non-io open test #2 passed.\n");
4672 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4674 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4676 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4677 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4678 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4682 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4683 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4684 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4688 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4689 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4692 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4693 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4697 printf("non-io open test #3 passed.\n");
4699 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4701 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4703 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4704 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4705 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4709 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4710 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4711 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4715 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4717 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4718 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4722 printf("non-io open test #4 passed.\n");
4724 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4726 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4728 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4729 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4730 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4734 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4735 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4736 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4740 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4741 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4745 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4746 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4750 printf("non-io open test #5 passed.\n");
4752 printf("TEST #6 testing 1 non-io open, one io open\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 #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4762 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4763 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4764 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4768 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4769 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4773 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4774 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4778 printf("non-io open test #6 passed.\n");
4780 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4782 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4784 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4785 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4786 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4790 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4791 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4792 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4796 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4798 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4799 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4803 printf("non-io open test #7 passed.\n");
4805 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4807 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4808 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4809 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4810 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4811 if (!NT_STATUS_IS_OK(status)) {
4812 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4817 /* Write to ensure we have to update the file time. */
4818 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4819 printf("TEST #8 cli_write failed: %s\n", cli_errstr(cli1));
4824 status = cli_close(cli1, fnum1);
4825 if (!NT_STATUS_IS_OK(status)) {
4826 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4832 if (!torture_close_connection(cli1)) {
4835 if (!torture_close_connection(cli2)) {
4842 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4844 uint16 major, minor;
4845 uint32 caplow, caphigh;
4848 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4849 printf("Server doesn't support UNIX CIFS extensions.\n");
4850 return NT_STATUS_NOT_SUPPORTED;
4853 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4855 if (!NT_STATUS_IS_OK(status)) {
4856 printf("Server didn't return UNIX CIFS extensions: %s\n",
4861 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4863 if (!NT_STATUS_IS_OK(status)) {
4864 printf("Server doesn't support setting UNIX CIFS extensions: "
4865 "%s.\n", nt_errstr(status));
4869 return NT_STATUS_OK;
4873 Test POSIX open /mkdir calls.
4875 static bool run_simple_posix_open_test(int dummy)
4877 static struct cli_state *cli1;
4878 const char *fname = "posix:file";
4879 const char *hname = "posix:hlink";
4880 const char *sname = "posix:symlink";
4881 const char *dname = "posix:dir";
4884 uint16_t fnum1 = (uint16_t)-1;
4885 SMB_STRUCT_STAT sbuf;
4886 bool correct = false;
4889 printf("Starting simple POSIX open test\n");
4891 if (!torture_open_connection(&cli1, 0)) {
4895 cli_sockopt(cli1, sockops);
4897 status = torture_setup_unix_extensions(cli1);
4898 if (!NT_STATUS_IS_OK(status)) {
4902 cli_setatr(cli1, fname, 0, 0);
4903 cli_posix_unlink(cli1, fname);
4904 cli_setatr(cli1, dname, 0, 0);
4905 cli_posix_rmdir(cli1, dname);
4906 cli_setatr(cli1, hname, 0, 0);
4907 cli_posix_unlink(cli1, hname);
4908 cli_setatr(cli1, sname, 0, 0);
4909 cli_posix_unlink(cli1, sname);
4911 /* Create a directory. */
4912 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4913 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4917 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4918 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4922 /* Test ftruncate - set file size. */
4923 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4924 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4928 /* Ensure st_size == 1000 */
4929 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4930 printf("stat failed (%s)\n", cli_errstr(cli1));
4934 if (sbuf.st_ex_size != 1000) {
4935 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4939 /* Test ftruncate - set file size back to zero. */
4940 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4941 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4945 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4946 printf("close failed (%s)\n", cli_errstr(cli1));
4950 /* Now open the file again for read only. */
4951 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4952 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4956 /* Now unlink while open. */
4957 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4958 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4962 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4963 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4967 /* Ensure the file has gone. */
4968 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4969 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4973 /* What happens when we try and POSIX open a directory ? */
4974 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4975 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4978 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4979 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4984 /* Create the file. */
4985 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4986 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4990 /* Write some data into it. */
4991 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4992 printf("cli_write failed: %s\n", cli_errstr(cli1));
4996 cli_close(cli1, fnum1);
4998 /* Now create a hardlink. */
4999 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5000 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5004 /* Now create a symlink. */
5005 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5006 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5010 /* Open the hardlink for read. */
5011 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5012 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5016 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5017 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5021 if (memcmp(buf, "TEST DATA\n", 10)) {
5022 printf("invalid data read from hardlink\n");
5026 /* Do a POSIX lock/unlock. */
5027 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5028 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5032 /* Punch a hole in the locked area. */
5033 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5034 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5038 cli_close(cli1, fnum1);
5040 /* Open the symlink for read - this should fail. A POSIX
5041 client should not be doing opens on a symlink. */
5042 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5043 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5046 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5047 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5048 printf("POSIX open of %s should have failed "
5049 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5050 "failed with %s instead.\n",
5051 sname, cli_errstr(cli1));
5056 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5057 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5061 if (strcmp(namebuf, fname) != 0) {
5062 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5063 sname, fname, namebuf);
5067 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5068 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5072 printf("Simple POSIX open test passed\n");
5077 if (fnum1 != (uint16_t)-1) {
5078 cli_close(cli1, fnum1);
5079 fnum1 = (uint16_t)-1;
5082 cli_setatr(cli1, sname, 0, 0);
5083 cli_posix_unlink(cli1, sname);
5084 cli_setatr(cli1, hname, 0, 0);
5085 cli_posix_unlink(cli1, hname);
5086 cli_setatr(cli1, fname, 0, 0);
5087 cli_posix_unlink(cli1, fname);
5088 cli_setatr(cli1, dname, 0, 0);
5089 cli_posix_rmdir(cli1, dname);
5091 if (!torture_close_connection(cli1)) {
5099 static uint32 open_attrs_table[] = {
5100 FILE_ATTRIBUTE_NORMAL,
5101 FILE_ATTRIBUTE_ARCHIVE,
5102 FILE_ATTRIBUTE_READONLY,
5103 FILE_ATTRIBUTE_HIDDEN,
5104 FILE_ATTRIBUTE_SYSTEM,
5106 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5107 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5108 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5109 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5110 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5111 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5113 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5114 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5115 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5116 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5119 struct trunc_open_results {
5126 static struct trunc_open_results attr_results[] = {
5127 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5128 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5129 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5130 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5131 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5132 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5133 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5134 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5135 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5136 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5137 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5138 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5139 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5140 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5141 { 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 },
5142 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5143 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5144 { 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 },
5145 { 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 },
5146 { 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 },
5147 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5148 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5149 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5150 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5151 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5152 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5155 static bool run_openattrtest(int dummy)
5157 static struct cli_state *cli1;
5158 const char *fname = "\\openattr.file";
5160 bool correct = True;
5162 unsigned int i, j, k, l;
5164 printf("starting open attr test\n");
5166 if (!torture_open_connection(&cli1, 0)) {
5170 cli_sockopt(cli1, sockops);
5172 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5173 cli_setatr(cli1, fname, 0, 0);
5174 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5175 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5176 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5177 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5181 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5182 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5186 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5187 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5188 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5189 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5190 if (attr_results[l].num == k) {
5191 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5192 k, open_attrs_table[i],
5193 open_attrs_table[j],
5194 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5198 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5199 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5200 k, open_attrs_table[i], open_attrs_table[j],
5205 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5211 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5212 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5216 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5217 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5222 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5223 k, open_attrs_table[i], open_attrs_table[j], attr );
5226 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5227 if (attr_results[l].num == k) {
5228 if (attr != attr_results[l].result_attr ||
5229 open_attrs_table[i] != attr_results[l].init_attr ||
5230 open_attrs_table[j] != attr_results[l].trunc_attr) {
5231 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5232 open_attrs_table[i],
5233 open_attrs_table[j],
5235 attr_results[l].result_attr);
5245 cli_setatr(cli1, fname, 0, 0);
5246 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5248 printf("open attr test %s.\n", correct ? "passed" : "failed");
5250 if (!torture_close_connection(cli1)) {
5256 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5257 const char *name, void *state)
5259 int *matched = (int *)state;
5260 if (matched != NULL) {
5263 return NT_STATUS_OK;
5267 test directory listing speed
5269 static bool run_dirtest(int dummy)
5272 static struct cli_state *cli;
5274 struct timeval core_start;
5275 bool correct = True;
5278 printf("starting directory test\n");
5280 if (!torture_open_connection(&cli, 0)) {
5284 cli_sockopt(cli, sockops);
5287 for (i=0;i<torture_numops;i++) {
5289 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5290 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5291 fprintf(stderr,"Failed to open %s\n", fname);
5294 cli_close(cli, fnum);
5297 core_start = timeval_current();
5300 cli_list(cli, "a*.*", 0, list_fn, &matched);
5301 printf("Matched %d\n", matched);
5304 cli_list(cli, "b*.*", 0, list_fn, &matched);
5305 printf("Matched %d\n", matched);
5308 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5309 printf("Matched %d\n", matched);
5311 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5314 for (i=0;i<torture_numops;i++) {
5316 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5317 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5320 if (!torture_close_connection(cli)) {
5324 printf("finished dirtest\n");
5329 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5332 struct cli_state *pcli = (struct cli_state *)state;
5334 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5336 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5337 return NT_STATUS_OK;
5339 if (finfo->mode & aDIR) {
5340 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5341 printf("del_fn: failed to rmdir %s\n,", fname );
5343 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5344 printf("del_fn: failed to unlink %s\n,", fname );
5346 return NT_STATUS_OK;
5351 sees what IOCTLs are supported
5353 bool torture_ioctl_test(int dummy)
5355 static struct cli_state *cli;
5356 uint16_t device, function;
5358 const char *fname = "\\ioctl.dat";
5362 if (!torture_open_connection(&cli, 0)) {
5366 printf("starting ioctl test\n");
5368 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5370 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5371 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5375 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5376 printf("ioctl device info: %s\n", nt_errstr(status));
5378 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5379 printf("ioctl job info: %s\n", nt_errstr(status));
5381 for (device=0;device<0x100;device++) {
5382 printf("ioctl test with device = 0x%x\n", device);
5383 for (function=0;function<0x100;function++) {
5384 uint32 code = (device<<16) | function;
5386 status = cli_raw_ioctl(cli, fnum, code, &blob);
5388 if (NT_STATUS_IS_OK(status)) {
5389 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5391 data_blob_free(&blob);
5396 if (!torture_close_connection(cli)) {
5405 tries varients of chkpath
5407 bool torture_chkpath_test(int dummy)
5409 static struct cli_state *cli;
5413 if (!torture_open_connection(&cli, 0)) {
5417 printf("starting chkpath test\n");
5419 /* cleanup from an old run */
5420 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5421 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5422 cli_rmdir(cli, "\\chkpath.dir");
5424 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5425 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5429 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5430 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5434 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5435 printf("open1 failed (%s)\n", cli_errstr(cli));
5438 cli_close(cli, fnum);
5440 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5441 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5445 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5446 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5450 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5451 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5452 NT_STATUS_NOT_A_DIRECTORY);
5454 printf("* chkpath on a file should fail\n");
5458 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5459 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5460 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5462 printf("* chkpath on a non existant file should fail\n");
5466 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5467 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5468 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5470 printf("* chkpath on a non existent component should fail\n");
5474 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5475 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5476 cli_rmdir(cli, "\\chkpath.dir");
5478 if (!torture_close_connection(cli)) {
5485 static bool run_eatest(int dummy)
5487 static struct cli_state *cli;
5488 const char *fname = "\\eatest.txt";
5489 bool correct = True;
5493 struct ea_struct *ea_list = NULL;
5494 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5497 printf("starting eatest\n");
5499 if (!torture_open_connection(&cli, 0)) {
5500 talloc_destroy(mem_ctx);
5504 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5505 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5506 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5507 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5508 0x4044, 0, &fnum))) {
5509 printf("open failed - %s\n", cli_errstr(cli));
5510 talloc_destroy(mem_ctx);
5514 for (i = 0; i < 10; i++) {
5515 fstring ea_name, ea_val;
5517 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5518 memset(ea_val, (char)i+1, i+1);
5519 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5520 if (!NT_STATUS_IS_OK(status)) {
5521 printf("ea_set of name %s failed - %s\n", ea_name,
5523 talloc_destroy(mem_ctx);
5528 cli_close(cli, fnum);
5529 for (i = 0; i < 10; i++) {
5530 fstring ea_name, ea_val;
5532 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5533 memset(ea_val, (char)i+1, i+1);
5534 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5535 if (!NT_STATUS_IS_OK(status)) {
5536 printf("ea_set of name %s failed - %s\n", ea_name,
5538 talloc_destroy(mem_ctx);
5543 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5544 if (!NT_STATUS_IS_OK(status)) {
5545 printf("ea_get list failed - %s\n", nt_errstr(status));
5549 printf("num_eas = %d\n", (int)num_eas);
5551 if (num_eas != 20) {
5552 printf("Should be 20 EA's stored... failing.\n");
5556 for (i = 0; i < num_eas; i++) {
5557 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5558 dump_data(0, ea_list[i].value.data,
5559 ea_list[i].value.length);
5562 /* Setting EA's to zero length deletes them. Test this */
5563 printf("Now deleting all EA's - case indepenent....\n");
5566 cli_set_ea_path(cli, fname, "", "", 0);
5568 for (i = 0; i < 20; i++) {
5570 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5571 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5572 if (!NT_STATUS_IS_OK(status)) {
5573 printf("ea_set of name %s failed - %s\n", ea_name,
5575 talloc_destroy(mem_ctx);
5581 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5582 if (!NT_STATUS_IS_OK(status)) {
5583 printf("ea_get list failed - %s\n", nt_errstr(status));
5587 printf("num_eas = %d\n", (int)num_eas);
5588 for (i = 0; i < num_eas; i++) {
5589 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5590 dump_data(0, ea_list[i].value.data,
5591 ea_list[i].value.length);
5595 printf("deleting EA's failed.\n");
5599 /* Try and delete a non existant EA. */
5600 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5601 if (!NT_STATUS_IS_OK(status)) {
5602 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5607 talloc_destroy(mem_ctx);
5608 if (!torture_close_connection(cli)) {
5615 static bool run_dirtest1(int dummy)
5618 static struct cli_state *cli;
5621 bool correct = True;
5623 printf("starting directory test\n");
5625 if (!torture_open_connection(&cli, 0)) {
5629 cli_sockopt(cli, sockops);
5631 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5632 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5633 cli_rmdir(cli, "\\LISTDIR");
5634 cli_mkdir(cli, "\\LISTDIR");
5636 /* Create 1000 files and 1000 directories. */
5637 for (i=0;i<1000;i++) {
5639 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5640 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5641 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5642 fprintf(stderr,"Failed to open %s\n", fname);
5645 cli_close(cli, fnum);
5647 for (i=0;i<1000;i++) {
5649 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5650 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5651 fprintf(stderr,"Failed to open %s\n", fname);
5656 /* Now ensure that doing an old list sees both files and directories. */
5658 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5659 printf("num_seen = %d\n", num_seen );
5660 /* We should see 100 files + 1000 directories + . and .. */
5661 if (num_seen != 2002)
5664 /* Ensure if we have the "must have" bits we only see the
5668 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5669 printf("num_seen = %d\n", num_seen );
5670 if (num_seen != 1002)
5674 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5675 printf("num_seen = %d\n", num_seen );
5676 if (num_seen != 1000)
5679 /* Delete everything. */
5680 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5681 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5682 cli_rmdir(cli, "\\LISTDIR");
5685 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5686 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5687 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5690 if (!torture_close_connection(cli)) {
5694 printf("finished dirtest1\n");
5699 static bool run_error_map_extract(int dummy) {
5701 static struct cli_state *c_dos;
5702 static struct cli_state *c_nt;
5707 uint32 flgs2, errnum;
5714 /* NT-Error connection */
5716 if (!(c_nt = open_nbt_connection())) {
5720 c_nt->use_spnego = False;
5722 status = cli_negprot(c_nt);
5724 if (!NT_STATUS_IS_OK(status)) {
5725 printf("%s rejected the NT-error negprot (%s)\n", host,
5731 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5733 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5737 /* DOS-Error connection */
5739 if (!(c_dos = open_nbt_connection())) {
5743 c_dos->use_spnego = False;
5744 c_dos->force_dos_errors = True;
5746 status = cli_negprot(c_dos);
5747 if (!NT_STATUS_IS_OK(status)) {
5748 printf("%s rejected the DOS-error negprot (%s)\n", host,
5750 cli_shutdown(c_dos);
5754 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5756 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5760 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5761 fstr_sprintf(user, "%X", error);
5763 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5764 password, strlen(password),
5765 password, strlen(password),
5767 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5770 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5772 /* Case #1: 32-bit NT errors */
5773 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5774 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5776 printf("/** Dos error on NT connection! (%s) */\n",
5778 nt_status = NT_STATUS(0xc0000000);
5781 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5782 password, strlen(password),
5783 password, strlen(password),
5785 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5787 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5789 /* Case #1: 32-bit NT errors */
5790 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5791 printf("/** NT error on DOS connection! (%s) */\n",
5793 errnum = errclass = 0;
5795 cli_dos_error(c_dos, &errclass, &errnum);
5798 if (NT_STATUS_V(nt_status) != error) {
5799 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5800 get_nt_error_c_code(NT_STATUS(error)),
5801 get_nt_error_c_code(nt_status));
5804 printf("\t{%s,\t%s,\t%s},\n",
5805 smb_dos_err_class(errclass),
5806 smb_dos_err_name(errclass, errnum),
5807 get_nt_error_c_code(NT_STATUS(error)));
5812 static bool run_sesssetup_bench(int dummy)
5814 static struct cli_state *c;
5815 const char *fname = "\\file.dat";
5820 if (!torture_open_connection(&c, 0)) {
5824 if (!NT_STATUS_IS_OK(cli_ntcreate(
5825 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5826 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5827 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5828 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5832 for (i=0; i<torture_numops; i++) {
5833 status = cli_session_setup(
5835 password, strlen(password),
5836 password, strlen(password),
5838 if (!NT_STATUS_IS_OK(status)) {
5839 d_printf("(%s) cli_session_setup failed: %s\n",
5840 __location__, nt_errstr(status));
5844 d_printf("\r%d ", (int)c->vuid);
5846 status = cli_ulogoff(c);
5847 if (!NT_STATUS_IS_OK(status)) {
5848 d_printf("(%s) cli_ulogoff failed: %s\n",
5849 __location__, nt_errstr(status));
5858 static bool subst_test(const char *str, const char *user, const char *domain,
5859 uid_t uid, gid_t gid, const char *expected)
5864 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5866 if (strcmp(subst, expected) != 0) {
5867 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5868 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5877 static void chain1_open_completion(struct tevent_req *req)
5881 status = cli_open_recv(req, &fnum);
5884 d_printf("cli_open_recv returned %s: %d\n",
5886 NT_STATUS_IS_OK(status) ? fnum : -1);
5889 static void chain1_write_completion(struct tevent_req *req)
5893 status = cli_write_andx_recv(req, &written);
5896 d_printf("cli_write_andx_recv returned %s: %d\n",
5898 NT_STATUS_IS_OK(status) ? (int)written : -1);
5901 static void chain1_close_completion(struct tevent_req *req)
5904 bool *done = (bool *)tevent_req_callback_data_void(req);
5906 status = cli_close_recv(req);
5911 d_printf("cli_close returned %s\n", nt_errstr(status));
5914 static bool run_chain1(int dummy)
5916 struct cli_state *cli1;
5917 struct event_context *evt = event_context_init(NULL);
5918 struct tevent_req *reqs[3], *smbreqs[3];
5920 const char *str = "foobar";
5923 printf("starting chain1 test\n");
5924 if (!torture_open_connection(&cli1, 0)) {
5928 cli_sockopt(cli1, sockops);
5930 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5931 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5932 if (reqs[0] == NULL) return false;
5933 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5936 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5937 (uint8_t *)str, 0, strlen(str)+1,
5938 smbreqs, 1, &smbreqs[1]);
5939 if (reqs[1] == NULL) return false;
5940 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5942 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5943 if (reqs[2] == NULL) return false;
5944 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5946 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5947 if (!NT_STATUS_IS_OK(status)) {
5952 event_loop_once(evt);
5955 torture_close_connection(cli1);
5959 static void chain2_sesssetup_completion(struct tevent_req *req)
5962 status = cli_session_setup_guest_recv(req);
5963 d_printf("sesssetup returned %s\n", nt_errstr(status));
5966 static void chain2_tcon_completion(struct tevent_req *req)
5968 bool *done = (bool *)tevent_req_callback_data_void(req);
5970 status = cli_tcon_andx_recv(req);
5971 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5975 static bool run_chain2(int dummy)
5977 struct cli_state *cli1;
5978 struct event_context *evt = event_context_init(NULL);
5979 struct tevent_req *reqs[2], *smbreqs[2];
5983 printf("starting chain2 test\n");
5984 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5985 port_to_use, Undefined, 0);
5986 if (!NT_STATUS_IS_OK(status)) {
5990 cli_sockopt(cli1, sockops);
5992 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5994 if (reqs[0] == NULL) return false;
5995 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5997 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5998 "?????", NULL, 0, &smbreqs[1]);
5999 if (reqs[1] == NULL) return false;
6000 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6002 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6003 if (!NT_STATUS_IS_OK(status)) {
6008 event_loop_once(evt);
6011 torture_close_connection(cli1);
6016 struct torture_createdel_state {
6017 struct tevent_context *ev;
6018 struct cli_state *cli;
6021 static void torture_createdel_created(struct tevent_req *subreq);
6022 static void torture_createdel_closed(struct tevent_req *subreq);
6024 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6025 struct tevent_context *ev,
6026 struct cli_state *cli,
6029 struct tevent_req *req, *subreq;
6030 struct torture_createdel_state *state;
6032 req = tevent_req_create(mem_ctx, &state,
6033 struct torture_createdel_state);
6040 subreq = cli_ntcreate_send(
6041 state, ev, cli, name, 0,
6042 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6043 FILE_ATTRIBUTE_NORMAL,
6044 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6045 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6047 if (tevent_req_nomem(subreq, req)) {
6048 return tevent_req_post(req, ev);
6050 tevent_req_set_callback(subreq, torture_createdel_created, req);
6054 static void torture_createdel_created(struct tevent_req *subreq)
6056 struct tevent_req *req = tevent_req_callback_data(
6057 subreq, struct tevent_req);
6058 struct torture_createdel_state *state = tevent_req_data(
6059 req, struct torture_createdel_state);
6063 status = cli_ntcreate_recv(subreq, &fnum);
6064 TALLOC_FREE(subreq);
6065 if (!NT_STATUS_IS_OK(status)) {
6066 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6067 nt_errstr(status)));
6068 tevent_req_nterror(req, status);
6072 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6073 if (tevent_req_nomem(subreq, req)) {
6076 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6079 static void torture_createdel_closed(struct tevent_req *subreq)
6081 struct tevent_req *req = tevent_req_callback_data(
6082 subreq, struct tevent_req);
6085 status = cli_close_recv(subreq);
6086 if (!NT_STATUS_IS_OK(status)) {
6087 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6088 tevent_req_nterror(req, status);
6091 tevent_req_done(req);
6094 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6096 return tevent_req_simple_recv_ntstatus(req);
6099 struct torture_createdels_state {
6100 struct tevent_context *ev;
6101 struct cli_state *cli;
6102 const char *base_name;
6106 struct tevent_req **reqs;
6109 static void torture_createdels_done(struct tevent_req *subreq);
6111 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6112 struct tevent_context *ev,
6113 struct cli_state *cli,
6114 const char *base_name,
6118 struct tevent_req *req;
6119 struct torture_createdels_state *state;
6122 req = tevent_req_create(mem_ctx, &state,
6123 struct torture_createdels_state);
6129 state->base_name = talloc_strdup(state, base_name);
6130 if (tevent_req_nomem(state->base_name, req)) {
6131 return tevent_req_post(req, ev);
6133 state->num_files = MAX(num_parallel, num_files);
6135 state->received = 0;
6137 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6138 if (tevent_req_nomem(state->reqs, req)) {
6139 return tevent_req_post(req, ev);
6142 for (i=0; i<num_parallel; i++) {
6145 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6147 if (tevent_req_nomem(name, req)) {
6148 return tevent_req_post(req, ev);
6150 state->reqs[i] = torture_createdel_send(
6151 state->reqs, state->ev, state->cli, name);
6152 if (tevent_req_nomem(state->reqs[i], req)) {
6153 return tevent_req_post(req, ev);
6155 name = talloc_move(state->reqs[i], &name);
6156 tevent_req_set_callback(state->reqs[i],
6157 torture_createdels_done, req);
6163 static void torture_createdels_done(struct tevent_req *subreq)
6165 struct tevent_req *req = tevent_req_callback_data(
6166 subreq, struct tevent_req);
6167 struct torture_createdels_state *state = tevent_req_data(
6168 req, struct torture_createdels_state);
6169 size_t num_parallel = talloc_array_length(state->reqs);
6174 status = torture_createdel_recv(subreq);
6175 if (!NT_STATUS_IS_OK(status)){
6176 DEBUG(10, ("torture_createdel_recv returned %s\n",
6177 nt_errstr(status)));
6178 TALLOC_FREE(subreq);
6179 tevent_req_nterror(req, status);
6183 for (i=0; i<num_parallel; i++) {
6184 if (subreq == state->reqs[i]) {
6188 if (i == num_parallel) {
6189 DEBUG(10, ("received something we did not send\n"));
6190 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6193 TALLOC_FREE(state->reqs[i]);
6195 if (state->sent >= state->num_files) {
6196 tevent_req_done(req);
6200 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6202 if (tevent_req_nomem(name, req)) {
6205 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6207 if (tevent_req_nomem(state->reqs[i], req)) {
6210 name = talloc_move(state->reqs[i], &name);
6211 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6215 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6217 return tevent_req_simple_recv_ntstatus(req);
6220 struct swallow_notify_state {
6221 struct tevent_context *ev;
6222 struct cli_state *cli;
6224 uint32_t completion_filter;
6226 bool (*fn)(uint32_t action, const char *name, void *priv);
6230 static void swallow_notify_done(struct tevent_req *subreq);
6232 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6233 struct tevent_context *ev,
6234 struct cli_state *cli,
6236 uint32_t completion_filter,
6238 bool (*fn)(uint32_t action,
6243 struct tevent_req *req, *subreq;
6244 struct swallow_notify_state *state;
6246 req = tevent_req_create(mem_ctx, &state,
6247 struct swallow_notify_state);
6254 state->completion_filter = completion_filter;
6255 state->recursive = recursive;
6259 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6260 0xffff, state->completion_filter,
6262 if (tevent_req_nomem(subreq, req)) {
6263 return tevent_req_post(req, ev);
6265 tevent_req_set_callback(subreq, swallow_notify_done, req);
6269 static void swallow_notify_done(struct tevent_req *subreq)
6271 struct tevent_req *req = tevent_req_callback_data(
6272 subreq, struct tevent_req);
6273 struct swallow_notify_state *state = tevent_req_data(
6274 req, struct swallow_notify_state);
6276 uint32_t i, num_changes;
6277 struct notify_change *changes;
6279 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6280 TALLOC_FREE(subreq);
6281 if (!NT_STATUS_IS_OK(status)) {
6282 DEBUG(10, ("cli_notify_recv returned %s\n",
6283 nt_errstr(status)));
6284 tevent_req_nterror(req, status);
6288 for (i=0; i<num_changes; i++) {
6289 state->fn(changes[i].action, changes[i].name, state->priv);
6291 TALLOC_FREE(changes);
6293 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6294 0xffff, state->completion_filter,
6296 if (tevent_req_nomem(subreq, req)) {
6299 tevent_req_set_callback(subreq, swallow_notify_done, req);
6302 static bool print_notifies(uint32_t action, const char *name, void *priv)
6304 if (DEBUGLEVEL > 5) {
6305 d_printf("%d %s\n", (int)action, name);
6310 static void notify_bench_done(struct tevent_req *req)
6312 int *num_finished = (int *)tevent_req_callback_data_void(req);
6316 static bool run_notify_bench(int dummy)
6318 const char *dname = "\\notify-bench";
6319 struct tevent_context *ev;
6322 struct tevent_req *req1;
6323 struct tevent_req *req2 = NULL;
6324 int i, num_unc_names;
6325 int num_finished = 0;
6327 printf("starting notify-bench test\n");
6329 if (use_multishare_conn) {
6331 unc_list = file_lines_load(multishare_conn_fname,
6332 &num_unc_names, 0, NULL);
6333 if (!unc_list || num_unc_names <= 0) {
6334 d_printf("Failed to load unc names list from '%s'\n",
6335 multishare_conn_fname);
6338 TALLOC_FREE(unc_list);
6343 ev = tevent_context_init(talloc_tos());
6345 d_printf("tevent_context_init failed\n");
6349 for (i=0; i<num_unc_names; i++) {
6350 struct cli_state *cli;
6353 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6355 if (base_fname == NULL) {
6359 if (!torture_open_connection(&cli, i)) {
6363 status = cli_ntcreate(cli, dname, 0,
6364 MAXIMUM_ALLOWED_ACCESS,
6365 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6367 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6370 if (!NT_STATUS_IS_OK(status)) {
6371 d_printf("Could not create %s: %s\n", dname,
6376 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6377 FILE_NOTIFY_CHANGE_FILE_NAME |
6378 FILE_NOTIFY_CHANGE_DIR_NAME |
6379 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6380 FILE_NOTIFY_CHANGE_LAST_WRITE,
6381 false, print_notifies, NULL);
6383 d_printf("Could not create notify request\n");
6387 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6388 base_fname, 10, torture_numops);
6390 d_printf("Could not create createdels request\n");
6393 TALLOC_FREE(base_fname);
6395 tevent_req_set_callback(req2, notify_bench_done,
6399 while (num_finished < num_unc_names) {
6401 ret = tevent_loop_once(ev);
6403 d_printf("tevent_loop_once failed\n");
6408 if (!tevent_req_poll(req2, ev)) {
6409 d_printf("tevent_req_poll failed\n");
6412 status = torture_createdels_recv(req2);
6413 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6418 static bool run_mangle1(int dummy)
6420 struct cli_state *cli;
6421 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6425 time_t change_time, access_time, write_time;
6429 printf("starting mangle1 test\n");
6430 if (!torture_open_connection(&cli, 0)) {
6434 cli_sockopt(cli, sockops);
6436 if (!NT_STATUS_IS_OK(cli_ntcreate(
6437 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6438 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6439 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6442 cli_close(cli, fnum);
6444 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6445 if (!NT_STATUS_IS_OK(status)) {
6446 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6450 d_printf("alt_name: %s\n", alt_name);
6452 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6453 d_printf("cli_open(%s) failed: %s\n", alt_name,
6457 cli_close(cli, fnum);
6459 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6460 &write_time, &size, &mode);
6461 if (!NT_STATUS_IS_OK(status)) {
6462 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6470 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6472 size_t *to_pull = (size_t *)priv;
6473 size_t thistime = *to_pull;
6475 thistime = MIN(thistime, n);
6476 if (thistime == 0) {
6480 memset(buf, 0, thistime);
6481 *to_pull -= thistime;
6485 static bool run_windows_write(int dummy)
6487 struct cli_state *cli1;
6491 const char *fname = "\\writetest.txt";
6492 struct timeval start_time;
6496 printf("starting windows_write test\n");
6497 if (!torture_open_connection(&cli1, 0)) {
6501 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6502 printf("open failed (%s)\n", cli_errstr(cli1));
6506 cli_sockopt(cli1, sockops);
6508 start_time = timeval_current();
6510 for (i=0; i<torture_numops; i++) {
6512 off_t start = i * torture_blocksize;
6514 size_t to_pull = torture_blocksize - 1;
6516 if (cli_write(cli1, fnum, 0, &c,
6517 start + torture_blocksize - 1, 1) != 1) {
6518 printf("cli_write failed: %s\n", cli_errstr(cli1));
6522 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6523 null_source, &to_pull);
6524 if (!NT_STATUS_IS_OK(status)) {
6525 printf("cli_push returned: %s\n", nt_errstr(status));
6530 seconds = timeval_elapsed(&start_time);
6531 kbytes = (double)torture_blocksize * torture_numops;
6534 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6535 (double)seconds, (int)(kbytes/seconds));
6539 cli_close(cli1, fnum);
6540 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6541 torture_close_connection(cli1);
6545 static bool run_cli_echo(int dummy)
6547 struct cli_state *cli;
6550 printf("starting cli_echo test\n");
6551 if (!torture_open_connection(&cli, 0)) {
6554 cli_sockopt(cli, sockops);
6556 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6558 d_printf("cli_echo returned %s\n", nt_errstr(status));
6560 torture_close_connection(cli);
6561 return NT_STATUS_IS_OK(status);
6564 static bool run_uid_regression_test(int dummy)
6566 static struct cli_state *cli;
6569 bool correct = True;
6572 printf("starting uid regression test\n");
6574 if (!torture_open_connection(&cli, 0)) {
6578 cli_sockopt(cli, sockops);
6580 /* Ok - now save then logoff our current user. */
6581 old_vuid = cli->vuid;
6583 status = cli_ulogoff(cli);
6584 if (!NT_STATUS_IS_OK(status)) {
6585 d_printf("(%s) cli_ulogoff failed: %s\n",
6586 __location__, nt_errstr(status));
6591 cli->vuid = old_vuid;
6593 /* Try an operation. */
6594 status = cli_mkdir(cli, "\\uid_reg_test");
6595 if (NT_STATUS_IS_OK(status)) {
6596 d_printf("(%s) cli_mkdir succeeded\n",
6601 /* Should be bad uid. */
6602 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6603 NT_STATUS_USER_SESSION_DELETED)) {
6609 old_cnum = cli->cnum;
6611 /* Now try a SMBtdis with the invald vuid set to zero. */
6614 /* This should succeed. */
6615 status = cli_tdis(cli);
6617 if (NT_STATUS_IS_OK(status)) {
6618 d_printf("First tdis with invalid vuid should succeed.\n");
6620 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6625 cli->vuid = old_vuid;
6626 cli->cnum = old_cnum;
6628 /* This should fail. */
6629 status = cli_tdis(cli);
6630 if (NT_STATUS_IS_OK(status)) {
6631 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6635 /* Should be bad tid. */
6636 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6637 NT_STATUS_NETWORK_NAME_DELETED)) {
6643 cli_rmdir(cli, "\\uid_reg_test");
6652 static const char *illegal_chars = "*\\/?<>|\":";
6653 static char force_shortname_chars[] = " +,.[];=\177";
6655 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6656 const char *mask, void *state)
6658 struct cli_state *pcli = (struct cli_state *)state;
6660 NTSTATUS status = NT_STATUS_OK;
6662 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6664 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6665 return NT_STATUS_OK;
6667 if (finfo->mode & aDIR) {
6668 status = cli_rmdir(pcli, fname);
6669 if (!NT_STATUS_IS_OK(status)) {
6670 printf("del_fn: failed to rmdir %s\n,", fname );
6673 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6674 if (!NT_STATUS_IS_OK(status)) {
6675 printf("del_fn: failed to unlink %s\n,", fname );
6687 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6688 const char *name, void *state)
6690 struct sn_state *s = (struct sn_state *)state;
6694 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6695 i, finfo->name, finfo->short_name);
6698 if (strchr(force_shortname_chars, i)) {
6699 if (!finfo->short_name[0]) {
6700 /* Shortname not created when it should be. */
6701 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6702 __location__, finfo->name, i);
6705 } else if (finfo->short_name[0]){
6706 /* Shortname created when it should not be. */
6707 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6708 __location__, finfo->short_name, finfo->name);
6712 return NT_STATUS_OK;
6715 static bool run_shortname_test(int dummy)
6717 static struct cli_state *cli;
6718 bool correct = True;
6723 printf("starting shortname test\n");
6725 if (!torture_open_connection(&cli, 0)) {
6729 cli_sockopt(cli, sockops);
6731 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6732 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6733 cli_rmdir(cli, "\\shortname");
6735 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6736 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6737 __location__, cli_errstr(cli));
6742 strlcpy(fname, "\\shortname\\", sizeof(fname));
6743 strlcat(fname, "test .txt", sizeof(fname));
6747 for (i = 32; i < 128; i++) {
6749 uint16_t fnum = (uint16_t)-1;
6753 if (strchr(illegal_chars, i)) {
6758 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6759 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6760 if (!NT_STATUS_IS_OK(status)) {
6761 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6762 __location__, fname, cli_errstr(cli));
6766 cli_close(cli, fnum);
6769 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6771 if (s.matched != 1) {
6772 d_printf("(%s) failed to list %s: %s\n",
6773 __location__, fname, cli_errstr(cli));
6777 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6778 d_printf("(%s) failed to delete %s: %s\n",
6779 __location__, fname, cli_errstr(cli));
6792 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6793 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6794 cli_rmdir(cli, "\\shortname");
6795 torture_close_connection(cli);
6799 static void pagedsearch_cb(struct tevent_req *req)
6802 struct tldap_message *msg;
6805 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6806 if (rc != TLDAP_SUCCESS) {
6807 d_printf("tldap_search_paged_recv failed: %s\n",
6808 tldap_err2string(rc));
6811 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6815 if (!tldap_entry_dn(msg, &dn)) {
6816 d_printf("tldap_entry_dn failed\n");
6819 d_printf("%s\n", dn);
6823 static bool run_tldap(int dummy)
6825 struct tldap_context *ld;
6828 struct sockaddr_storage addr;
6829 struct tevent_context *ev;
6830 struct tevent_req *req;
6834 if (!resolve_name(host, &addr, 0, false)) {
6835 d_printf("could not find host %s\n", host);
6838 status = open_socket_out(&addr, 389, 9999, &fd);
6839 if (!NT_STATUS_IS_OK(status)) {
6840 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6844 ld = tldap_context_create(talloc_tos(), fd);
6847 d_printf("tldap_context_create failed\n");
6851 rc = tldap_fetch_rootdse(ld);
6852 if (rc != TLDAP_SUCCESS) {
6853 d_printf("tldap_fetch_rootdse failed: %s\n",
6854 tldap_errstr(talloc_tos(), ld, rc));
6858 basedn = tldap_talloc_single_attribute(
6859 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6860 if (basedn == NULL) {
6861 d_printf("no defaultNamingContext\n");
6864 d_printf("defaultNamingContext: %s\n", basedn);
6866 ev = tevent_context_init(talloc_tos());
6868 d_printf("tevent_context_init failed\n");
6872 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6873 TLDAP_SCOPE_SUB, "(objectclass=*)",
6875 NULL, 0, NULL, 0, 0, 0, 0, 5);
6877 d_printf("tldap_search_paged_send failed\n");
6880 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6882 tevent_req_poll(req, ev);
6886 /* test search filters against rootDSE */
6887 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6888 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6890 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6891 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6892 talloc_tos(), NULL, NULL);
6893 if (rc != TLDAP_SUCCESS) {
6894 d_printf("tldap_search with complex filter failed: %s\n",
6895 tldap_errstr(talloc_tos(), ld, rc));
6903 /* Torture test to ensure no regression of :
6904 https://bugzilla.samba.org/show_bug.cgi?id=7084
6907 static bool run_dir_createtime(int dummy)
6909 struct cli_state *cli;
6910 const char *dname = "\\testdir";
6911 const char *fname = "\\testdir\\testfile";
6913 struct timespec create_time;
6914 struct timespec create_time1;
6918 if (!torture_open_connection(&cli, 0)) {
6922 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6923 cli_rmdir(cli, dname);
6925 status = cli_mkdir(cli, dname);
6926 if (!NT_STATUS_IS_OK(status)) {
6927 printf("mkdir failed: %s\n", nt_errstr(status));
6931 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6933 if (!NT_STATUS_IS_OK(status)) {
6934 printf("cli_qpathinfo2 returned %s\n",
6939 /* Sleep 3 seconds, then create a file. */
6942 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6944 if (!NT_STATUS_IS_OK(status)) {
6945 printf("cli_open failed: %s\n", nt_errstr(status));
6949 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6951 if (!NT_STATUS_IS_OK(status)) {
6952 printf("cli_qpathinfo2 (2) returned %s\n",
6957 if (timespec_compare(&create_time1, &create_time)) {
6958 printf("run_dir_createtime: create time was updated (error)\n");
6960 printf("run_dir_createtime: create time was not updated (correct)\n");
6966 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6967 cli_rmdir(cli, dname);
6968 if (!torture_close_connection(cli)) {
6975 static bool run_streamerror(int dummy)
6977 struct cli_state *cli;
6978 const char *dname = "\\testdir";
6979 const char *streamname =
6980 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6982 time_t change_time, access_time, write_time;
6984 uint16_t mode, fnum;
6987 if (!torture_open_connection(&cli, 0)) {
6991 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6992 cli_rmdir(cli, dname);
6994 status = cli_mkdir(cli, dname);
6995 if (!NT_STATUS_IS_OK(status)) {
6996 printf("mkdir failed: %s\n", nt_errstr(status));
7000 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7002 status = cli_nt_error(cli);
7004 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7005 printf("pathinfo returned %s, expected "
7006 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7011 status = cli_ntcreate(cli, streamname, 0x16,
7012 FILE_READ_DATA|FILE_READ_EA|
7013 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7014 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7015 FILE_OPEN, 0, 0, &fnum);
7017 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7018 printf("ntcreate returned %s, expected "
7019 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7025 cli_rmdir(cli, dname);
7029 static bool run_local_substitute(int dummy)
7033 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7034 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7035 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7036 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7037 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7038 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7039 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7040 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7042 /* Different captialization rules in sub_basic... */
7044 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7050 static bool run_local_base64(int dummy)
7055 for (i=1; i<2000; i++) {
7056 DATA_BLOB blob1, blob2;
7059 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7061 generate_random_buffer(blob1.data, blob1.length);
7063 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7065 d_fprintf(stderr, "base64_encode_data_blob failed "
7066 "for %d bytes\n", i);
7069 blob2 = base64_decode_data_blob(b64);
7072 if (data_blob_cmp(&blob1, &blob2)) {
7073 d_fprintf(stderr, "data_blob_cmp failed for %d "
7077 TALLOC_FREE(blob1.data);
7078 data_blob_free(&blob2);
7083 static bool run_local_gencache(int dummy)
7089 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7090 d_printf("%s: gencache_set() failed\n", __location__);
7094 if (!gencache_get("foo", NULL, NULL)) {
7095 d_printf("%s: gencache_get() failed\n", __location__);
7099 if (!gencache_get("foo", &val, &tm)) {
7100 d_printf("%s: gencache_get() failed\n", __location__);
7104 if (strcmp(val, "bar") != 0) {
7105 d_printf("%s: gencache_get() returned %s, expected %s\n",
7106 __location__, val, "bar");
7113 if (!gencache_del("foo")) {
7114 d_printf("%s: gencache_del() failed\n", __location__);
7117 if (gencache_del("foo")) {
7118 d_printf("%s: second gencache_del() succeeded\n",
7123 if (gencache_get("foo", &val, &tm)) {
7124 d_printf("%s: gencache_get() on deleted entry "
7125 "succeeded\n", __location__);
7129 blob = data_blob_string_const_null("bar");
7130 tm = time(NULL) + 60;
7132 if (!gencache_set_data_blob("foo", &blob, tm)) {
7133 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7137 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7138 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7142 if (strcmp((const char *)blob.data, "bar") != 0) {
7143 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7144 __location__, (const char *)blob.data, "bar");
7145 data_blob_free(&blob);
7149 data_blob_free(&blob);
7151 if (!gencache_del("foo")) {
7152 d_printf("%s: gencache_del() failed\n", __location__);
7155 if (gencache_del("foo")) {
7156 d_printf("%s: second gencache_del() succeeded\n",
7161 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7162 d_printf("%s: gencache_get_data_blob() on deleted entry "
7163 "succeeded\n", __location__);
7170 static bool rbt_testval(struct db_context *db, const char *key,
7173 struct db_record *rec;
7174 TDB_DATA data = string_tdb_data(value);
7178 rec = db->fetch_locked(db, db, string_tdb_data(key));
7180 d_fprintf(stderr, "fetch_locked failed\n");
7183 status = rec->store(rec, data, 0);
7184 if (!NT_STATUS_IS_OK(status)) {
7185 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7190 rec = db->fetch_locked(db, db, string_tdb_data(key));
7192 d_fprintf(stderr, "second fetch_locked failed\n");
7195 if ((rec->value.dsize != data.dsize)
7196 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7197 d_fprintf(stderr, "Got wrong data back\n");
7207 static bool run_local_rbtree(int dummy)
7209 struct db_context *db;
7213 db = db_open_rbt(NULL);
7216 d_fprintf(stderr, "db_open_rbt failed\n");
7220 for (i=0; i<1000; i++) {
7223 if (asprintf(&key, "key%ld", random()) == -1) {
7226 if (asprintf(&value, "value%ld", random()) == -1) {
7231 if (!rbt_testval(db, key, value)) {
7238 if (asprintf(&value, "value%ld", random()) == -1) {
7243 if (!rbt_testval(db, key, value)) {
7260 struct talloc_dict_test {
7264 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7266 int *count = (int *)priv;
7271 static bool run_local_talloc_dict(int dummy)
7273 struct talloc_dict *dict;
7274 struct talloc_dict_test *t;
7277 dict = talloc_dict_init(talloc_tos());
7282 t = talloc(talloc_tos(), struct talloc_dict_test);
7289 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7294 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7307 static bool run_local_string_to_sid(int dummy) {
7310 if (string_to_sid(&sid, "S--1-5-32-545")) {
7311 printf("allowing S--1-5-32-545\n");
7314 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7315 printf("allowing S-1-5-32-+545\n");
7318 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")) {
7319 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7322 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7323 printf("allowing S-1-5-32-545-abc\n");
7326 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7327 printf("could not parse S-1-5-32-545\n");
7330 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7331 printf("mis-parsed S-1-5-32-545 as %s\n",
7332 sid_string_tos(&sid));
7338 static bool run_local_binary_to_sid(int dummy) {
7339 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7340 static const char good_binary_sid[] = {
7341 0x1, /* revision number */
7343 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7344 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7345 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7346 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7347 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7348 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7349 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7350 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7351 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7352 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7353 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7354 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7355 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7356 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7357 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7358 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7361 static const char long_binary_sid[] = {
7362 0x1, /* revision number */
7364 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7365 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7366 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7367 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7368 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7369 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7370 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7371 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7372 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7373 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7374 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7375 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7376 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7377 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7378 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7379 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7380 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7381 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7382 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7385 static const char long_binary_sid2[] = {
7386 0x1, /* revision number */
7388 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7389 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7390 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7391 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7392 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7393 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7394 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7395 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7396 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7397 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7398 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7399 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7400 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7401 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7402 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7403 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7404 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7405 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7406 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7407 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7408 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7409 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7410 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7411 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7412 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7413 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7414 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7415 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7416 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7417 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7418 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7419 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7420 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7423 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7426 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7429 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7435 /* Split a path name into filename and stream name components. Canonicalise
7436 * such that an implicit $DATA token is always explicit.
7438 * The "specification" of this function can be found in the
7439 * run_local_stream_name() function in torture.c, I've tried those
7440 * combinations against a W2k3 server.
7443 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7444 char **pbase, char **pstream)
7447 char *stream = NULL;
7448 char *sname; /* stream name */
7449 const char *stype; /* stream type */
7451 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7453 sname = strchr_m(fname, ':');
7455 if (lp_posix_pathnames() || (sname == NULL)) {
7456 if (pbase != NULL) {
7457 base = talloc_strdup(mem_ctx, fname);
7458 NT_STATUS_HAVE_NO_MEMORY(base);
7463 if (pbase != NULL) {
7464 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7465 NT_STATUS_HAVE_NO_MEMORY(base);
7470 stype = strchr_m(sname, ':');
7472 if (stype == NULL) {
7473 sname = talloc_strdup(mem_ctx, sname);
7477 if (StrCaseCmp(stype, ":$DATA") != 0) {
7479 * If there is an explicit stream type, so far we only
7480 * allow $DATA. Is there anything else allowed? -- vl
7482 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7484 return NT_STATUS_OBJECT_NAME_INVALID;
7486 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7490 if (sname == NULL) {
7492 return NT_STATUS_NO_MEMORY;
7495 if (sname[0] == '\0') {
7497 * no stream name, so no stream
7502 if (pstream != NULL) {
7503 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7504 if (stream == NULL) {
7507 return NT_STATUS_NO_MEMORY;
7510 * upper-case the type field
7512 strupper_m(strchr_m(stream, ':')+1);
7516 if (pbase != NULL) {
7519 if (pstream != NULL) {
7522 return NT_STATUS_OK;
7525 static bool test_stream_name(const char *fname, const char *expected_base,
7526 const char *expected_stream,
7527 NTSTATUS expected_status)
7531 char *stream = NULL;
7533 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7534 if (!NT_STATUS_EQUAL(status, expected_status)) {
7538 if (!NT_STATUS_IS_OK(status)) {
7542 if (base == NULL) goto error;
7544 if (strcmp(expected_base, base) != 0) goto error;
7546 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7547 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7549 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7553 TALLOC_FREE(stream);
7557 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7558 fname, expected_base ? expected_base : "<NULL>",
7559 expected_stream ? expected_stream : "<NULL>",
7560 nt_errstr(expected_status));
7561 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7562 base ? base : "<NULL>", stream ? stream : "<NULL>",
7565 TALLOC_FREE(stream);
7569 static bool run_local_stream_name(int dummy)
7573 ret &= test_stream_name(
7574 "bla", "bla", NULL, NT_STATUS_OK);
7575 ret &= test_stream_name(
7576 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7577 ret &= test_stream_name(
7578 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7579 ret &= test_stream_name(
7580 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7581 ret &= test_stream_name(
7582 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7583 ret &= test_stream_name(
7584 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7585 ret &= test_stream_name(
7586 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7587 ret &= test_stream_name(
7588 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7593 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7595 if (a.length != b.length) {
7596 printf("a.length=%d != b.length=%d\n",
7597 (int)a.length, (int)b.length);
7600 if (memcmp(a.data, b.data, a.length) != 0) {
7601 printf("a.data and b.data differ\n");
7607 static bool run_local_memcache(int dummy)
7609 struct memcache *cache;
7611 DATA_BLOB d1, d2, d3;
7612 DATA_BLOB v1, v2, v3;
7614 TALLOC_CTX *mem_ctx;
7616 size_t size1, size2;
7619 cache = memcache_init(NULL, 100);
7621 if (cache == NULL) {
7622 printf("memcache_init failed\n");
7626 d1 = data_blob_const("d1", 2);
7627 d2 = data_blob_const("d2", 2);
7628 d3 = data_blob_const("d3", 2);
7630 k1 = data_blob_const("d1", 2);
7631 k2 = data_blob_const("d2", 2);
7633 memcache_add(cache, STAT_CACHE, k1, d1);
7634 memcache_add(cache, GETWD_CACHE, k2, d2);
7636 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7637 printf("could not find k1\n");
7640 if (!data_blob_equal(d1, v1)) {
7644 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7645 printf("could not find k2\n");
7648 if (!data_blob_equal(d2, v2)) {
7652 memcache_add(cache, STAT_CACHE, k1, d3);
7654 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7655 printf("could not find replaced k1\n");
7658 if (!data_blob_equal(d3, v3)) {
7662 memcache_add(cache, GETWD_CACHE, k1, d1);
7664 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7665 printf("Did find k2, should have been purged\n");
7671 cache = memcache_init(NULL, 0);
7673 mem_ctx = talloc_init("foo");
7675 str1 = talloc_strdup(mem_ctx, "string1");
7676 str2 = talloc_strdup(mem_ctx, "string2");
7678 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7679 data_blob_string_const("torture"), &str1);
7680 size1 = talloc_total_size(cache);
7682 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7683 data_blob_string_const("torture"), &str2);
7684 size2 = talloc_total_size(cache);
7686 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7688 if (size2 > size1) {
7689 printf("memcache leaks memory!\n");
7699 static void wbclient_done(struct tevent_req *req)
7702 struct winbindd_response *wb_resp;
7703 int *i = (int *)tevent_req_callback_data_void(req);
7705 wbc_err = wb_trans_recv(req, req, &wb_resp);
7708 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7711 static bool run_local_wbclient(int dummy)
7713 struct event_context *ev;
7714 struct wb_context **wb_ctx;
7715 struct winbindd_request wb_req;
7716 bool result = false;
7719 BlockSignals(True, SIGPIPE);
7721 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7726 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7727 if (wb_ctx == NULL) {
7731 ZERO_STRUCT(wb_req);
7732 wb_req.cmd = WINBINDD_PING;
7734 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7736 for (i=0; i<nprocs; i++) {
7737 wb_ctx[i] = wb_context_init(ev, NULL);
7738 if (wb_ctx[i] == NULL) {
7741 for (j=0; j<torture_numops; j++) {
7742 struct tevent_req *req;
7743 req = wb_trans_send(ev, ev, wb_ctx[i],
7744 (j % 2) == 0, &wb_req);
7748 tevent_req_set_callback(req, wbclient_done, &i);
7754 while (i < nprocs * torture_numops) {
7755 event_loop_once(ev);
7764 static void getaddrinfo_finished(struct tevent_req *req)
7766 char *name = (char *)tevent_req_callback_data_void(req);
7767 struct addrinfo *ainfo;
7770 res = getaddrinfo_recv(req, &ainfo);
7772 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7775 d_printf("gai(%s) succeeded\n", name);
7776 freeaddrinfo(ainfo);
7779 static bool run_getaddrinfo_send(int dummy)
7781 TALLOC_CTX *frame = talloc_stackframe();
7782 struct fncall_context *ctx;
7783 struct tevent_context *ev;
7784 bool result = false;
7785 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7786 "www.slashdot.org", "heise.de" };
7787 struct tevent_req *reqs[4];
7790 ev = event_context_init(frame);
7795 ctx = fncall_context_init(frame, 4);
7797 for (i=0; i<ARRAY_SIZE(names); i++) {
7798 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7800 if (reqs[i] == NULL) {
7803 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7807 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7808 tevent_loop_once(ev);
7817 static bool dbtrans_inc(struct db_context *db)
7819 struct db_record *rec;
7824 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7826 printf(__location__ "fetch_lock failed\n");
7830 if (rec->value.dsize != sizeof(uint32_t)) {
7831 printf(__location__ "value.dsize = %d\n",
7832 (int)rec->value.dsize);
7836 val = (uint32_t *)rec->value.dptr;
7839 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7842 if (!NT_STATUS_IS_OK(status)) {
7843 printf(__location__ "store failed: %s\n",
7854 static bool run_local_dbtrans(int dummy)
7856 struct db_context *db;
7857 struct db_record *rec;
7862 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7863 O_RDWR|O_CREAT, 0600);
7865 printf("Could not open transtest.db\n");
7869 res = db->transaction_start(db);
7871 printf(__location__ "transaction_start failed\n");
7875 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7877 printf(__location__ "fetch_lock failed\n");
7881 if (rec->value.dptr == NULL) {
7883 status = rec->store(
7884 rec, make_tdb_data((uint8_t *)&initial,
7887 if (!NT_STATUS_IS_OK(status)) {
7888 printf(__location__ "store returned %s\n",
7896 res = db->transaction_commit(db);
7898 printf(__location__ "transaction_commit failed\n");
7906 res = db->transaction_start(db);
7908 printf(__location__ "transaction_start failed\n");
7912 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7913 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7917 for (i=0; i<10; i++) {
7918 if (!dbtrans_inc(db)) {
7923 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7924 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7928 if (val2 != val + 10) {
7929 printf(__location__ "val=%d, val2=%d\n",
7930 (int)val, (int)val2);
7934 printf("val2=%d\r", val2);
7936 res = db->transaction_commit(db);
7938 printf(__location__ "transaction_commit failed\n");
7948 * Just a dummy test to be run under a debugger. There's no real way
7949 * to inspect the tevent_select specific function from outside of
7953 static bool run_local_tevent_select(int dummy)
7955 struct tevent_context *ev;
7956 struct tevent_fd *fd1, *fd2;
7957 bool result = false;
7959 ev = tevent_context_init_byname(NULL, "select");
7961 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7965 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7967 d_fprintf(stderr, "tevent_add_fd failed\n");
7970 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7972 d_fprintf(stderr, "tevent_add_fd failed\n");
7977 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7979 d_fprintf(stderr, "tevent_add_fd failed\n");
7989 static double create_procs(bool (*fn)(int), bool *result)
7992 volatile pid_t *child_status;
7993 volatile bool *child_status_out;
7996 struct timeval start;
8000 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8001 if (!child_status) {
8002 printf("Failed to setup shared memory\n");
8006 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8007 if (!child_status_out) {
8008 printf("Failed to setup result status shared memory\n");
8012 for (i = 0; i < nprocs; i++) {
8013 child_status[i] = 0;
8014 child_status_out[i] = True;
8017 start = timeval_current();
8019 for (i=0;i<nprocs;i++) {
8022 pid_t mypid = getpid();
8023 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8025 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8028 if (torture_open_connection(¤t_cli, i)) break;
8030 printf("pid %d failed to start\n", (int)getpid());
8036 child_status[i] = getpid();
8038 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8040 child_status_out[i] = fn(i);
8047 for (i=0;i<nprocs;i++) {
8048 if (child_status[i]) synccount++;
8050 if (synccount == nprocs) break;
8052 } while (timeval_elapsed(&start) < 30);
8054 if (synccount != nprocs) {
8055 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8057 return timeval_elapsed(&start);
8060 /* start the client load */
8061 start = timeval_current();
8063 for (i=0;i<nprocs;i++) {
8064 child_status[i] = 0;
8067 printf("%d clients started\n", nprocs);
8069 for (i=0;i<nprocs;i++) {
8070 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8075 for (i=0;i<nprocs;i++) {
8076 if (!child_status_out[i]) {
8080 return timeval_elapsed(&start);
8083 #define FLAG_MULTIPROC 1
8090 {"FDPASS", run_fdpasstest, 0},
8091 {"LOCK1", run_locktest1, 0},
8092 {"LOCK2", run_locktest2, 0},
8093 {"LOCK3", run_locktest3, 0},
8094 {"LOCK4", run_locktest4, 0},
8095 {"LOCK5", run_locktest5, 0},
8096 {"LOCK6", run_locktest6, 0},
8097 {"LOCK7", run_locktest7, 0},
8098 {"LOCK8", run_locktest8, 0},
8099 {"LOCK9", run_locktest9, 0},
8100 {"UNLINK", run_unlinktest, 0},
8101 {"BROWSE", run_browsetest, 0},
8102 {"ATTR", run_attrtest, 0},
8103 {"TRANS2", run_trans2test, 0},
8104 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8105 {"TORTURE",run_torture, FLAG_MULTIPROC},
8106 {"RANDOMIPC", run_randomipc, 0},
8107 {"NEGNOWAIT", run_negprot_nowait, 0},
8108 {"NBENCH", run_nbench, 0},
8109 {"NBENCH2", run_nbench2, 0},
8110 {"OPLOCK1", run_oplock1, 0},
8111 {"OPLOCK2", run_oplock2, 0},
8112 {"OPLOCK3", run_oplock3, 0},
8113 {"OPLOCK4", run_oplock4, 0},
8114 {"DIR", run_dirtest, 0},
8115 {"DIR1", run_dirtest1, 0},
8116 {"DIR-CREATETIME", run_dir_createtime, 0},
8117 {"DENY1", torture_denytest1, 0},
8118 {"DENY2", torture_denytest2, 0},
8119 {"TCON", run_tcon_test, 0},
8120 {"TCONDEV", run_tcon_devtype_test, 0},
8121 {"RW1", run_readwritetest, 0},
8122 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8123 {"RW3", run_readwritelarge, 0},
8124 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8125 {"OPEN", run_opentest, 0},
8126 {"POSIX", run_simple_posix_open_test, 0},
8127 {"POSIX-APPEND", run_posix_append, 0},
8128 {"ASYNC-ECHO", run_async_echo, 0},
8129 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8130 { "SHORTNAME-TEST", run_shortname_test, 0},
8131 { "ADDRCHANGE", run_addrchange, 0},
8133 {"OPENATTR", run_openattrtest, 0},
8135 {"XCOPY", run_xcopy, 0},
8136 {"RENAME", run_rename, 0},
8137 {"DELETE", run_deletetest, 0},
8138 {"DELETE-LN", run_deletetest_ln, 0},
8139 {"PROPERTIES", run_properties, 0},
8140 {"MANGLE", torture_mangle, 0},
8141 {"MANGLE1", run_mangle1, 0},
8142 {"W2K", run_w2ktest, 0},
8143 {"TRANS2SCAN", torture_trans2_scan, 0},
8144 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8145 {"UTABLE", torture_utable, 0},
8146 {"CASETABLE", torture_casetable, 0},
8147 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8148 {"PIPE_NUMBER", run_pipe_number, 0},
8149 {"TCON2", run_tcon2_test, 0},
8150 {"IOCTL", torture_ioctl_test, 0},
8151 {"CHKPATH", torture_chkpath_test, 0},
8152 {"FDSESS", run_fdsesstest, 0},
8153 { "EATEST", run_eatest, 0},
8154 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8155 { "CHAIN1", run_chain1, 0},
8156 { "CHAIN2", run_chain2, 0},
8157 { "WINDOWS-WRITE", run_windows_write, 0},
8158 { "CLI_ECHO", run_cli_echo, 0},
8159 { "GETADDRINFO", run_getaddrinfo_send, 0},
8160 { "TLDAP", run_tldap },
8161 { "STREAMERROR", run_streamerror },
8162 { "NOTIFY-BENCH", run_notify_bench },
8163 { "BAD-NBT-SESSION", run_bad_nbt_session },
8164 { "SMB-ANY-CONNECT", run_smb_any_connect },
8165 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8166 { "LOCAL-GENCACHE", run_local_gencache, 0},
8167 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8168 { "LOCAL-BASE64", run_local_base64, 0},
8169 { "LOCAL-RBTREE", run_local_rbtree, 0},
8170 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8171 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8172 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8173 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8174 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8175 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8176 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8181 /****************************************************************************
8182 run a specified test or "ALL"
8183 ****************************************************************************/
8184 static bool run_test(const char *name)
8191 if (strequal(name,"ALL")) {
8192 for (i=0;torture_ops[i].name;i++) {
8193 run_test(torture_ops[i].name);
8198 for (i=0;torture_ops[i].name;i++) {
8199 fstr_sprintf(randomfname, "\\XX%x",
8200 (unsigned)random());
8202 if (strequal(name, torture_ops[i].name)) {
8204 printf("Running %s\n", name);
8205 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8206 t = create_procs(torture_ops[i].fn, &result);
8209 printf("TEST %s FAILED!\n", name);
8212 struct timeval start;
8213 start = timeval_current();
8214 if (!torture_ops[i].fn(0)) {
8216 printf("TEST %s FAILED!\n", name);
8218 t = timeval_elapsed(&start);
8220 printf("%s took %g secs\n\n", name, t);
8225 printf("Did not find a test named %s\n", name);
8233 static void usage(void)
8237 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8238 printf("Please use samba4 torture.\n\n");
8240 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8242 printf("\t-d debuglevel\n");
8243 printf("\t-U user%%pass\n");
8244 printf("\t-k use kerberos\n");
8245 printf("\t-N numprocs\n");
8246 printf("\t-n my_netbios_name\n");
8247 printf("\t-W workgroup\n");
8248 printf("\t-o num_operations\n");
8249 printf("\t-O socket_options\n");
8250 printf("\t-m maximum protocol\n");
8251 printf("\t-L use oplocks\n");
8252 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8253 printf("\t-A showall\n");
8254 printf("\t-p port\n");
8255 printf("\t-s seed\n");
8256 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8259 printf("tests are:");
8260 for (i=0;torture_ops[i].name;i++) {
8261 printf(" %s", torture_ops[i].name);
8265 printf("default test is ALL\n");
8270 /****************************************************************************
8272 ****************************************************************************/
8273 int main(int argc,char *argv[])
8279 bool correct = True;
8280 TALLOC_CTX *frame = talloc_stackframe();
8281 int seed = time(NULL);
8283 #ifdef HAVE_SETBUFFER
8284 setbuffer(stdout, NULL, 0);
8287 setup_logging("smbtorture", DEBUG_STDOUT);
8291 if (is_default_dyn_CONFIGFILE()) {
8292 if(getenv("SMB_CONF_PATH")) {
8293 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8296 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8303 for(p = argv[1]; *p; p++)
8307 if (strncmp(argv[1], "//", 2)) {
8311 fstrcpy(host, &argv[1][2]);
8312 p = strchr_m(&host[2],'/');
8317 fstrcpy(share, p+1);
8319 fstrcpy(myname, get_myname(talloc_tos()));
8321 fprintf(stderr, "Failed to get my hostname.\n");
8325 if (*username == 0 && getenv("LOGNAME")) {
8326 fstrcpy(username,getenv("LOGNAME"));
8332 fstrcpy(workgroup, lp_workgroup());
8334 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8337 port_to_use = atoi(optarg);
8340 seed = atoi(optarg);
8343 fstrcpy(workgroup,optarg);
8346 max_protocol = interpret_protocol(optarg, max_protocol);
8349 nprocs = atoi(optarg);
8352 torture_numops = atoi(optarg);
8355 lp_set_cmdline("log level", optarg);
8364 local_path = optarg;
8367 torture_showall = True;
8370 fstrcpy(myname, optarg);
8373 client_txt = optarg;
8380 use_kerberos = True;
8382 d_printf("No kerberos support compiled in\n");
8388 fstrcpy(username,optarg);
8389 p = strchr_m(username,'%');
8392 fstrcpy(password, p+1);
8397 fstrcpy(multishare_conn_fname, optarg);
8398 use_multishare_conn = True;
8401 torture_blocksize = atoi(optarg);
8404 printf("Unknown option %c (%d)\n", (char)opt, opt);
8409 d_printf("using seed %d\n", seed);
8413 if(use_kerberos && !gotuser) gotpass = True;
8416 p = getpass("Password:");
8418 fstrcpy(password, p);
8423 printf("host=%s share=%s user=%s myname=%s\n",
8424 host, share, username, myname);
8426 if (argc == optind) {
8427 correct = run_test("ALL");
8429 for (i=optind;i<argc;i++) {
8430 if (!run_test(argv[i])) {