2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "system/shmem.h"
23 #include "wbc_async.h"
24 #include "torture/proto.h"
25 #include "libcli/security/security.h"
27 #include "tldap_util.h"
28 #include "../librpc/gen_ndr/svcctl.h"
30 #include "nsswitch/winbind_client.h"
32 #include "talloc_dict.h"
33 #include "async_smb.h"
34 #include "libsmb/clirap.h"
40 static fstring host, workgroup, share, password, username, myname;
41 static int max_protocol = PROTOCOL_NT1;
42 static const char *sockops="TCP_NODELAY";
44 static int port_to_use=0;
45 int torture_numops=100;
46 int torture_blocksize=1024*1024;
47 static int procnum; /* records process count number when forking */
48 static struct cli_state *current_cli;
49 static fstring randomfname;
50 static bool use_oplocks;
51 static bool use_level_II_oplocks;
52 static const char *client_txt = "client_oplocks.txt";
53 static bool use_kerberos;
54 static fstring multishare_conn_fname;
55 static bool use_multishare_conn = False;
56 static bool do_encrypt;
57 static const char *local_path = NULL;
58 static int signing_state = Undefined;
60 bool torture_showall = False;
62 static double create_procs(bool (*fn)(int), bool *result);
65 /* return a pointer to a anonymous shared memory segment of size "size"
66 which will persist across fork() but will disappear when all processes
69 The memory is not zeroed
71 This function uses system5 shared memory. It takes advantage of a property
72 that the memory is not destroyed if it is attached when the id is removed
74 void *shm_setup(int size)
80 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
82 printf("can't get shared memory\n");
85 shm_unlink("private");
86 if (ftruncate(shmid, size) == -1) {
87 printf("can't set shared memory size\n");
90 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
91 if (ret == MAP_FAILED) {
92 printf("can't map shared memory\n");
96 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
98 printf("can't get shared memory\n");
101 ret = (void *)shmat(shmid, 0, 0);
102 if (!ret || ret == (void *)-1) {
103 printf("can't attach to shared memory\n");
106 /* the following releases the ipc, but note that this process
107 and all its children will still have access to the memory, its
108 just that the shmid is no longer valid for other shm calls. This
109 means we don't leave behind lots of shm segments after we exit
111 See Stevens "advanced programming in unix env" for details
113 shmctl(shmid, IPC_RMID, 0);
119 /********************************************************************
120 Ensure a connection is encrypted.
121 ********************************************************************/
123 static bool force_cli_encryption(struct cli_state *c,
124 const char *sharename)
127 uint32 caplow, caphigh;
130 if (!SERVER_HAS_UNIX_CIFS(c)) {
131 d_printf("Encryption required and "
132 "server that doesn't support "
133 "UNIX extensions - failing connect\n");
137 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
139 if (!NT_STATUS_IS_OK(status)) {
140 d_printf("Encryption required and "
141 "can't get UNIX CIFS extensions "
142 "version from server: %s\n", nt_errstr(status));
146 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
147 d_printf("Encryption required and "
148 "share %s doesn't support "
149 "encryption.\n", sharename);
153 if (c->use_kerberos) {
154 status = cli_gss_smb_encryption_start(c);
156 status = cli_raw_ntlm_smb_encryption_start(c,
162 if (!NT_STATUS_IS_OK(status)) {
163 d_printf("Encryption required and "
164 "setup failed with error %s.\n",
173 static struct cli_state *open_nbt_connection(void)
175 struct nmb_name called, calling;
176 struct sockaddr_storage ss;
180 make_nmb_name(&calling, myname, 0x0);
181 make_nmb_name(&called , host, 0x20);
185 if (!(c = cli_initialise_ex(signing_state))) {
186 printf("Failed initialize cli_struct to connect with %s\n", host);
190 c->port = port_to_use;
192 status = cli_connect(c, host, &ss);
193 if (!NT_STATUS_IS_OK(status)) {
194 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
198 c->use_kerberos = use_kerberos;
200 c->timeout = 120000; /* set a really long timeout (2 minutes) */
201 if (use_oplocks) c->use_oplocks = True;
202 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
204 if (!cli_session_request(c, &calling, &called)) {
206 * Well, that failed, try *SMBSERVER ...
207 * However, we must reconnect as well ...
209 status = cli_connect(c, host, &ss);
210 if (!NT_STATUS_IS_OK(status)) {
211 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
215 make_nmb_name(&called, "*SMBSERVER", 0x20);
216 if (!cli_session_request(c, &calling, &called)) {
217 printf("%s rejected the session\n",host);
218 printf("We tried with a called name of %s & %s\n",
228 /****************************************************************************
229 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
230 ****************************************************************************/
232 static bool cli_bad_session_request(struct cli_state *cli,
233 struct nmb_name *calling, struct nmb_name *called)
240 memcpy(&(cli->calling), calling, sizeof(*calling));
241 memcpy(&(cli->called ), called , sizeof(*called ));
243 /* put in the destination name */
245 tmp = name_mangle(talloc_tos(), cli->called.name,
246 cli->called.name_type);
252 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
254 memcpy(p, tmp, namelen);
259 /* Deliberately corrupt the name len (first byte) */
264 tmp = name_mangle(talloc_tos(), cli->calling.name,
265 cli->calling.name_type);
271 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
273 memcpy(p, tmp, namelen);
277 /* Deliberately corrupt the name len (first byte) */
280 /* send a session request (RFC 1002) */
281 /* setup the packet length
282 * Remove four bytes from the length count, since the length
283 * field in the NBT Session Service header counts the number
284 * of bytes which follow. The cli_send_smb() function knows
285 * about this and accounts for those four bytes.
289 _smb_setlen(cli->outbuf,len);
290 SCVAL(cli->outbuf,0,0x81);
293 DEBUG(5,("Sent session request\n"));
295 if (!cli_receive_smb(cli))
298 if (CVAL(cli->inbuf,0) != 0x82) {
299 /* This is the wrong place to put the error... JRA. */
300 cli->rap_error = CVAL(cli->inbuf,4);
306 static struct cli_state *open_bad_nbt_connection(void)
308 struct nmb_name called, calling;
309 struct sockaddr_storage ss;
313 make_nmb_name(&calling, myname, 0x0);
314 make_nmb_name(&called , host, 0x20);
318 if (!(c = cli_initialise_ex(signing_state))) {
319 printf("Failed initialize cli_struct to connect with %s\n", host);
325 status = cli_connect(c, host, &ss);
326 if (!NT_STATUS_IS_OK(status)) {
327 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
331 c->timeout = 4000; /* set a short timeout (4 seconds) */
333 if (!cli_bad_session_request(c, &calling, &called)) {
334 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
342 /* Insert a NULL at the first separator of the given path and return a pointer
343 * to the remainder of the string.
346 terminate_path_at_separator(char * path)
354 if ((p = strchr_m(path, '/'))) {
359 if ((p = strchr_m(path, '\\'))) {
369 parse a //server/share type UNC name
371 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
372 char **hostname, char **sharename)
376 *hostname = *sharename = NULL;
378 if (strncmp(unc_name, "\\\\", 2) &&
379 strncmp(unc_name, "//", 2)) {
383 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
384 p = terminate_path_at_separator(*hostname);
387 *sharename = talloc_strdup(mem_ctx, p);
388 terminate_path_at_separator(*sharename);
391 if (*hostname && *sharename) {
395 TALLOC_FREE(*hostname);
396 TALLOC_FREE(*sharename);
400 static bool torture_open_connection_share(struct cli_state **c,
401 const char *hostname,
402 const char *sharename)
408 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
410 flags |= CLI_FULL_CONNECTION_OPLOCKS;
411 if (use_level_II_oplocks)
412 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
414 status = cli_full_connection(c, myname,
415 hostname, NULL, port_to_use,
418 password, flags, signing_state);
419 if (!NT_STATUS_IS_OK(status)) {
420 printf("failed to open share connection: //%s/%s port:%d - %s\n",
421 hostname, sharename, port_to_use, nt_errstr(status));
425 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
428 return force_cli_encryption(*c,
434 bool torture_open_connection(struct cli_state **c, int conn_index)
436 char **unc_list = NULL;
437 int num_unc_names = 0;
440 if (use_multishare_conn==True) {
442 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
443 if (!unc_list || num_unc_names <= 0) {
444 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
448 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
450 printf("Failed to parse UNC name %s\n",
451 unc_list[conn_index % num_unc_names]);
452 TALLOC_FREE(unc_list);
456 result = torture_open_connection_share(c, h, s);
458 /* h, s were copied earlier */
459 TALLOC_FREE(unc_list);
463 return torture_open_connection_share(c, host, share);
466 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
468 uint16 old_vuid = cli->vuid;
469 fstring old_user_name;
470 size_t passlen = strlen(password);
474 fstrcpy(old_user_name, cli->user_name);
476 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
480 *new_vuid = cli->vuid;
481 cli->vuid = old_vuid;
482 status = cli_set_username(cli, old_user_name);
483 if (!NT_STATUS_IS_OK(status)) {
490 bool torture_close_connection(struct cli_state *c)
495 status = cli_tdis(c);
496 if (!NT_STATUS_IS_OK(status)) {
497 printf("tdis failed (%s)\n", nt_errstr(status));
507 /* check if the server produced the expected error code */
508 static bool check_error(int line, struct cli_state *c,
509 uint8 eclass, uint32 ecode, NTSTATUS nterr)
511 if (cli_is_dos_error(c)) {
515 /* Check DOS error */
517 cli_dos_error(c, &cclass, &num);
519 if (eclass != cclass || ecode != num) {
520 printf("unexpected error code class=%d code=%d\n",
521 (int)cclass, (int)num);
522 printf(" expected %d/%d %s (line=%d)\n",
523 (int)eclass, (int)ecode, nt_errstr(nterr), line);
532 status = cli_nt_error(c);
534 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
535 printf("unexpected error code %s\n", nt_errstr(status));
536 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
545 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
547 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
548 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
554 static bool rw_torture(struct cli_state *c)
556 const char *lockfname = "\\torture.lck";
560 pid_t pid2, pid = getpid();
566 memset(buf, '\0', sizeof(buf));
568 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
570 if (!NT_STATUS_IS_OK(status)) {
571 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
573 if (!NT_STATUS_IS_OK(status)) {
574 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
578 for (i=0;i<torture_numops;i++) {
579 unsigned n = (unsigned)sys_random()%10;
581 printf("%d\r", i); fflush(stdout);
583 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
585 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
589 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
590 printf("open failed (%s)\n", cli_errstr(c));
595 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
596 printf("write failed (%s)\n", cli_errstr(c));
601 if (cli_write(c, fnum, 0, (char *)buf,
602 sizeof(pid)+(j*sizeof(buf)),
603 sizeof(buf)) != sizeof(buf)) {
604 printf("write failed (%s)\n", cli_errstr(c));
611 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
612 printf("read failed (%s)\n", cli_errstr(c));
617 printf("data corruption!\n");
621 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
622 printf("close failed (%s)\n", cli_errstr(c));
626 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
627 printf("unlink failed (%s)\n", cli_errstr(c));
631 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
632 printf("unlock failed (%s)\n", cli_errstr(c));
638 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
645 static bool run_torture(int dummy)
647 struct cli_state *cli;
652 cli_sockopt(cli, sockops);
654 ret = rw_torture(cli);
656 if (!torture_close_connection(cli)) {
663 static bool rw_torture3(struct cli_state *c, char *lockfname)
665 uint16_t fnum = (uint16_t)-1;
670 unsigned countprev = 0;
673 NTSTATUS status = NT_STATUS_OK;
676 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
678 SIVAL(buf, i, sys_random());
683 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, aSYSTEM | aHIDDEN))) {
684 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
687 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
688 DENY_NONE, &fnum))) {
689 printf("first open read/write of %s failed (%s)\n",
690 lockfname, cli_errstr(c));
696 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
698 status = cli_open(c, lockfname, O_RDONLY,
700 if (!NT_STATUS_IS_OK(status)) {
705 if (!NT_STATUS_IS_OK(status)) {
706 printf("second open read-only of %s failed (%s)\n",
707 lockfname, cli_errstr(c));
713 for (count = 0; count < sizeof(buf); count += sent)
715 if (count >= countprev) {
716 printf("%d %8d\r", i, count);
719 countprev += (sizeof(buf) / 20);
724 sent = ((unsigned)sys_random()%(20))+ 1;
725 if (sent > sizeof(buf) - count)
727 sent = sizeof(buf) - count;
730 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
731 printf("write failed (%s)\n", cli_errstr(c));
737 sent = cli_read(c, fnum, buf_rd+count, count,
741 printf("read failed offset:%d size:%ld (%s)\n",
742 count, (unsigned long)sizeof(buf)-count,
749 if (memcmp(buf_rd+count, buf+count, sent) != 0)
751 printf("read/write compare failed\n");
752 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
761 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
762 printf("close failed (%s)\n", cli_errstr(c));
769 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
771 const char *lockfname = "\\torture2.lck";
780 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
781 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
784 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
785 DENY_NONE, &fnum1))) {
786 printf("first open read/write of %s failed (%s)\n",
787 lockfname, cli_errstr(c1));
790 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
791 DENY_NONE, &fnum2))) {
792 printf("second open read-only of %s failed (%s)\n",
793 lockfname, cli_errstr(c2));
794 cli_close(c1, fnum1);
798 for (i=0;i<torture_numops;i++)
800 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
802 printf("%d\r", i); fflush(stdout);
805 generate_random_buffer((unsigned char *)buf, buf_size);
807 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
808 printf("write failed (%s)\n", cli_errstr(c1));
813 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
814 printf("read failed (%s)\n", cli_errstr(c2));
815 printf("read %d, expected %ld\n", (int)bytes_read,
816 (unsigned long)buf_size);
821 if (memcmp(buf_rd, buf, buf_size) != 0)
823 printf("read/write compare failed\n");
829 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
830 printf("close failed (%s)\n", cli_errstr(c2));
833 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
834 printf("close failed (%s)\n", cli_errstr(c1));
838 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
839 printf("unlink failed (%s)\n", cli_errstr(c1));
846 static bool run_readwritetest(int dummy)
848 struct cli_state *cli1, *cli2;
849 bool test1, test2 = False;
851 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
854 cli_sockopt(cli1, sockops);
855 cli_sockopt(cli2, sockops);
857 printf("starting readwritetest\n");
859 test1 = rw_torture2(cli1, cli2);
860 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
863 test2 = rw_torture2(cli1, cli1);
864 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
867 if (!torture_close_connection(cli1)) {
871 if (!torture_close_connection(cli2)) {
875 return (test1 && test2);
878 static bool run_readwritemulti(int dummy)
880 struct cli_state *cli;
885 cli_sockopt(cli, sockops);
887 printf("run_readwritemulti: fname %s\n", randomfname);
888 test = rw_torture3(cli, randomfname);
890 if (!torture_close_connection(cli)) {
897 static bool run_readwritelarge_internal(int max_xmit_k)
899 static struct cli_state *cli1;
901 const char *lockfname = "\\large.dat";
906 if (!torture_open_connection(&cli1, 0)) {
909 cli_sockopt(cli1, sockops);
910 memset(buf,'\0',sizeof(buf));
912 cli1->max_xmit = max_xmit_k*1024;
914 if (signing_state == Required) {
915 /* Horrible cheat to force
916 multiple signed outstanding
917 packets against a Samba server.
919 cli1->is_samba = false;
922 printf("starting readwritelarge_internal\n");
924 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
926 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
927 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
931 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
933 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
934 cli1, fnum1, NULL, &fsize, NULL, NULL,
935 NULL, NULL, NULL))) {
936 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
940 if (fsize == sizeof(buf))
941 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
942 (unsigned long)fsize);
944 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
945 (unsigned long)fsize);
949 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
950 printf("close failed (%s)\n", cli_errstr(cli1));
954 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
955 printf("unlink failed (%s)\n", cli_errstr(cli1));
959 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
960 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
964 cli1->max_xmit = 4*1024;
966 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
968 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
969 cli1, fnum1, NULL, &fsize, NULL, NULL,
970 NULL, NULL, NULL))) {
971 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
975 if (fsize == sizeof(buf))
976 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
977 (unsigned long)fsize);
979 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
980 (unsigned long)fsize);
985 /* ToDo - set allocation. JRA */
986 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
987 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
990 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
992 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
996 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
999 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1000 printf("close failed (%s)\n", cli_errstr(cli1));
1004 if (!torture_close_connection(cli1)) {
1010 static bool run_readwritelarge(int dummy)
1012 return run_readwritelarge_internal(128);
1015 static bool run_readwritelarge_signtest(int dummy)
1018 signing_state = Required;
1019 ret = run_readwritelarge_internal(2);
1020 signing_state = Undefined;
1027 #define ival(s) strtol(s, NULL, 0)
1029 /* run a test that simulates an approximate netbench client load */
1030 static bool run_netbench(int client)
1032 struct cli_state *cli;
1037 const char *params[20];
1038 bool correct = True;
1044 cli_sockopt(cli, sockops);
1048 slprintf(cname,sizeof(cname)-1, "client%d", client);
1050 f = fopen(client_txt, "r");
1057 while (fgets(line, sizeof(line)-1, f)) {
1061 line[strlen(line)-1] = 0;
1063 /* printf("[%d] %s\n", line_count, line); */
1065 all_string_sub(line,"client1", cname, sizeof(line));
1067 /* parse the command parameters */
1068 params[0] = strtok_r(line, " ", &saveptr);
1070 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1074 if (i < 2) continue;
1076 if (!strncmp(params[0],"SMB", 3)) {
1077 printf("ERROR: You are using a dbench 1 load file\n");
1081 if (!strcmp(params[0],"NTCreateX")) {
1082 nb_createx(params[1], ival(params[2]), ival(params[3]),
1084 } else if (!strcmp(params[0],"Close")) {
1085 nb_close(ival(params[1]));
1086 } else if (!strcmp(params[0],"Rename")) {
1087 nb_rename(params[1], params[2]);
1088 } else if (!strcmp(params[0],"Unlink")) {
1089 nb_unlink(params[1]);
1090 } else if (!strcmp(params[0],"Deltree")) {
1091 nb_deltree(params[1]);
1092 } else if (!strcmp(params[0],"Rmdir")) {
1093 nb_rmdir(params[1]);
1094 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1095 nb_qpathinfo(params[1]);
1096 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1097 nb_qfileinfo(ival(params[1]));
1098 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1099 nb_qfsinfo(ival(params[1]));
1100 } else if (!strcmp(params[0],"FIND_FIRST")) {
1101 nb_findfirst(params[1]);
1102 } else if (!strcmp(params[0],"WriteX")) {
1103 nb_writex(ival(params[1]),
1104 ival(params[2]), ival(params[3]), ival(params[4]));
1105 } else if (!strcmp(params[0],"ReadX")) {
1106 nb_readx(ival(params[1]),
1107 ival(params[2]), ival(params[3]), ival(params[4]));
1108 } else if (!strcmp(params[0],"Flush")) {
1109 nb_flush(ival(params[1]));
1111 printf("Unknown operation %s\n", params[0]);
1119 if (!torture_close_connection(cli)) {
1127 /* run a test that simulates an approximate netbench client load */
1128 static bool run_nbench(int dummy)
1131 bool correct = True;
1137 signal(SIGALRM, nb_alarm);
1139 t = create_procs(run_netbench, &correct);
1142 printf("\nThroughput %g MB/sec\n",
1143 1.0e-6 * nbio_total() / t);
1149 This test checks for two things:
1151 1) correct support for retaining locks over a close (ie. the server
1152 must not use posix semantics)
1153 2) support for lock timeouts
1155 static bool run_locktest1(int dummy)
1157 struct cli_state *cli1, *cli2;
1158 const char *fname = "\\lockt1.lck";
1159 uint16_t fnum1, fnum2, fnum3;
1161 unsigned lock_timeout;
1163 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1166 cli_sockopt(cli1, sockops);
1167 cli_sockopt(cli2, sockops);
1169 printf("starting locktest1\n");
1171 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1173 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1174 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1177 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1178 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1181 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1182 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1186 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1187 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1192 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1193 printf("lock2 succeeded! This is a locking bug\n");
1196 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1197 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1201 lock_timeout = (1 + (random() % 20));
1202 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1204 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1205 printf("lock3 succeeded! This is a locking bug\n");
1208 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1209 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1213 if (ABS(t2 - t1) < lock_timeout-1) {
1214 printf("error: This server appears not to support timed lock requests\n");
1217 printf("server slept for %u seconds for a %u second timeout\n",
1218 (unsigned int)(t2-t1), lock_timeout);
1220 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1221 printf("close1 failed (%s)\n", cli_errstr(cli1));
1225 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1226 printf("lock4 succeeded! This is a locking bug\n");
1229 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1230 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1233 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1234 printf("close2 failed (%s)\n", cli_errstr(cli1));
1238 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1239 printf("close3 failed (%s)\n", cli_errstr(cli2));
1243 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1244 printf("unlink failed (%s)\n", cli_errstr(cli1));
1249 if (!torture_close_connection(cli1)) {
1253 if (!torture_close_connection(cli2)) {
1257 printf("Passed locktest1\n");
1262 this checks to see if a secondary tconx can use open files from an
1265 static bool run_tcon_test(int dummy)
1267 static struct cli_state *cli;
1268 const char *fname = "\\tcontest.tmp";
1270 uint16 cnum1, cnum2, cnum3;
1271 uint16 vuid1, vuid2;
1276 memset(buf, '\0', sizeof(buf));
1278 if (!torture_open_connection(&cli, 0)) {
1281 cli_sockopt(cli, sockops);
1283 printf("starting tcontest\n");
1285 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1287 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1288 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1295 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1296 printf("initial write failed (%s)", cli_errstr(cli));
1300 status = cli_tcon_andx(cli, share, "?????",
1301 password, strlen(password)+1);
1302 if (!NT_STATUS_IS_OK(status)) {
1303 printf("%s refused 2nd tree connect (%s)\n", host,
1310 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1311 vuid2 = cli->vuid + 1;
1313 /* try a write with the wrong tid */
1316 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1317 printf("* server allows write with wrong TID\n");
1320 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1324 /* try a write with an invalid tid */
1327 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1328 printf("* server allows write with invalid TID\n");
1331 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1334 /* try a write with an invalid vuid */
1338 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1339 printf("* server allows write with invalid VUID\n");
1342 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1348 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1349 printf("close failed (%s)\n", cli_errstr(cli));
1355 status = cli_tdis(cli);
1356 if (!NT_STATUS_IS_OK(status)) {
1357 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1363 if (!torture_close_connection(cli)) {
1372 checks for old style tcon support
1374 static bool run_tcon2_test(int dummy)
1376 static struct cli_state *cli;
1377 uint16 cnum, max_xmit;
1381 if (!torture_open_connection(&cli, 0)) {
1384 cli_sockopt(cli, sockops);
1386 printf("starting tcon2 test\n");
1388 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1392 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1396 if (!NT_STATUS_IS_OK(status)) {
1397 printf("tcon2 failed : %s\n", nt_errstr(status));
1399 printf("tcon OK : max_xmit=%d cnum=%d\n",
1400 (int)max_xmit, (int)cnum);
1403 if (!torture_close_connection(cli)) {
1407 printf("Passed tcon2 test\n");
1411 static bool tcon_devtest(struct cli_state *cli,
1412 const char *myshare, const char *devtype,
1413 const char *return_devtype,
1414 NTSTATUS expected_error)
1419 status = cli_tcon_andx(cli, myshare, devtype,
1420 password, strlen(password)+1);
1422 if (NT_STATUS_IS_OK(expected_error)) {
1423 if (NT_STATUS_IS_OK(status)) {
1424 if (strcmp(cli->dev, return_devtype) == 0) {
1427 printf("tconX to share %s with type %s "
1428 "succeeded but returned the wrong "
1429 "device type (got [%s] but should have got [%s])\n",
1430 myshare, devtype, cli->dev, return_devtype);
1434 printf("tconX to share %s with type %s "
1435 "should have succeeded but failed\n",
1441 if (NT_STATUS_IS_OK(status)) {
1442 printf("tconx to share %s with type %s "
1443 "should have failed but succeeded\n",
1447 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1451 printf("Returned unexpected error\n");
1460 checks for correct tconX support
1462 static bool run_tcon_devtype_test(int dummy)
1464 static struct cli_state *cli1 = NULL;
1469 status = cli_full_connection(&cli1, myname,
1470 host, NULL, port_to_use,
1472 username, workgroup,
1473 password, flags, signing_state);
1475 if (!NT_STATUS_IS_OK(status)) {
1476 printf("could not open connection\n");
1480 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1483 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1486 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1489 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1492 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1495 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1498 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1501 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1504 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1507 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1513 printf("Passed tcondevtest\n");
1520 This test checks that
1522 1) the server supports multiple locking contexts on the one SMB
1523 connection, distinguished by PID.
1525 2) the server correctly fails overlapping locks made by the same PID (this
1526 goes against POSIX behaviour, which is why it is tricky to implement)
1528 3) the server denies unlock requests by an incorrect client PID
1530 static bool run_locktest2(int dummy)
1532 static struct cli_state *cli;
1533 const char *fname = "\\lockt2.lck";
1534 uint16_t fnum1, fnum2, fnum3;
1535 bool correct = True;
1537 if (!torture_open_connection(&cli, 0)) {
1541 cli_sockopt(cli, sockops);
1543 printf("starting locktest2\n");
1545 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1549 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1550 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1554 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1555 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1561 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1562 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1568 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1569 printf("lock1 failed (%s)\n", cli_errstr(cli));
1573 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1574 printf("WRITE lock1 succeeded! This is a locking bug\n");
1577 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1578 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1581 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1582 printf("WRITE lock2 succeeded! This is a locking bug\n");
1585 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1586 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1589 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1590 printf("READ lock2 succeeded! This is a locking bug\n");
1593 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1594 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1597 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1598 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1601 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1602 printf("unlock at 100 succeeded! This is a locking bug\n");
1606 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1607 printf("unlock1 succeeded! This is a locking bug\n");
1610 if (!check_error(__LINE__, cli,
1612 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1615 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1616 printf("unlock2 succeeded! This is a locking bug\n");
1619 if (!check_error(__LINE__, cli,
1621 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1624 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1625 printf("lock3 succeeded! This is a locking bug\n");
1628 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1633 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1634 printf("close1 failed (%s)\n", cli_errstr(cli));
1638 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1639 printf("close2 failed (%s)\n", cli_errstr(cli));
1643 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1644 printf("close3 failed (%s)\n", cli_errstr(cli));
1648 if (!torture_close_connection(cli)) {
1652 printf("locktest2 finished\n");
1659 This test checks that
1661 1) the server supports the full offset range in lock requests
1663 static bool run_locktest3(int dummy)
1665 static struct cli_state *cli1, *cli2;
1666 const char *fname = "\\lockt3.lck";
1667 uint16_t fnum1, fnum2;
1670 bool correct = True;
1672 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1674 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1677 cli_sockopt(cli1, sockops);
1678 cli_sockopt(cli2, sockops);
1680 printf("starting locktest3\n");
1682 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1684 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1685 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1688 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1689 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1693 for (offset=i=0;i<torture_numops;i++) {
1695 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1696 printf("lock1 %d failed (%s)\n",
1702 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1703 printf("lock2 %d failed (%s)\n",
1710 for (offset=i=0;i<torture_numops;i++) {
1713 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1714 printf("error: lock1 %d succeeded!\n", i);
1718 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1719 printf("error: lock2 %d succeeded!\n", i);
1723 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1724 printf("error: lock3 %d succeeded!\n", i);
1728 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1729 printf("error: lock4 %d succeeded!\n", i);
1734 for (offset=i=0;i<torture_numops;i++) {
1737 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1738 printf("unlock1 %d failed (%s)\n",
1744 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1745 printf("unlock2 %d failed (%s)\n",
1752 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1753 printf("close1 failed (%s)\n", cli_errstr(cli1));
1757 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1758 printf("close2 failed (%s)\n", cli_errstr(cli2));
1762 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1763 printf("unlink failed (%s)\n", cli_errstr(cli1));
1767 if (!torture_close_connection(cli1)) {
1771 if (!torture_close_connection(cli2)) {
1775 printf("finished locktest3\n");
1780 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1781 printf("** "); correct = False; \
1785 looks at overlapping locks
1787 static bool run_locktest4(int dummy)
1789 static struct cli_state *cli1, *cli2;
1790 const char *fname = "\\lockt4.lck";
1791 uint16_t fnum1, fnum2, f;
1794 bool correct = True;
1796 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1800 cli_sockopt(cli1, sockops);
1801 cli_sockopt(cli2, sockops);
1803 printf("starting locktest4\n");
1805 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1807 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1808 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1810 memset(buf, 0, sizeof(buf));
1812 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1813 printf("Failed to create file\n");
1818 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1819 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1820 EXPECTED(ret, False);
1821 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1823 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1824 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1825 EXPECTED(ret, True);
1826 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1828 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1829 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1830 EXPECTED(ret, False);
1831 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1833 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1834 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1835 EXPECTED(ret, True);
1836 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1838 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1839 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1840 EXPECTED(ret, False);
1841 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1843 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1844 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1845 EXPECTED(ret, True);
1846 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1848 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1849 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1850 EXPECTED(ret, True);
1851 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1853 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1854 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1855 EXPECTED(ret, False);
1856 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1858 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1859 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1860 EXPECTED(ret, False);
1861 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1863 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1864 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1865 EXPECTED(ret, True);
1866 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1868 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1869 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1870 EXPECTED(ret, False);
1871 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1873 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1874 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1875 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1876 EXPECTED(ret, False);
1877 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1880 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1881 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1882 EXPECTED(ret, False);
1883 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1885 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1886 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1887 EXPECTED(ret, False);
1888 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1891 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1892 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1893 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1894 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1895 EXPECTED(ret, True);
1896 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1899 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1900 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1901 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1902 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1903 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1904 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1905 EXPECTED(ret, True);
1906 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1908 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1909 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1910 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1911 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1912 EXPECTED(ret, True);
1913 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1915 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1916 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1917 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1918 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1919 EXPECTED(ret, True);
1920 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1922 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1923 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1924 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1925 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1926 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1927 EXPECTED(ret, True);
1928 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1930 cli_close(cli1, fnum1);
1931 cli_close(cli2, fnum2);
1932 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1933 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1934 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1935 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1936 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1937 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1938 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1940 cli_close(cli1, fnum1);
1941 EXPECTED(ret, True);
1942 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1945 cli_close(cli1, fnum1);
1946 cli_close(cli2, fnum2);
1947 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1948 torture_close_connection(cli1);
1949 torture_close_connection(cli2);
1951 printf("finished locktest4\n");
1956 looks at lock upgrade/downgrade.
1958 static bool run_locktest5(int dummy)
1960 static struct cli_state *cli1, *cli2;
1961 const char *fname = "\\lockt5.lck";
1962 uint16_t fnum1, fnum2, fnum3;
1965 bool correct = True;
1967 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1971 cli_sockopt(cli1, sockops);
1972 cli_sockopt(cli2, sockops);
1974 printf("starting locktest5\n");
1976 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1978 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1979 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1980 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1982 memset(buf, 0, sizeof(buf));
1984 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1985 printf("Failed to create file\n");
1990 /* Check for NT bug... */
1991 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1992 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1993 cli_close(cli1, fnum1);
1994 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1995 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1996 EXPECTED(ret, True);
1997 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1998 cli_close(cli1, fnum1);
1999 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2000 cli_unlock(cli1, fnum3, 0, 1);
2002 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
2003 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2004 EXPECTED(ret, True);
2005 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2007 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2008 EXPECTED(ret, False);
2010 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2012 /* Unlock the process 2 lock. */
2013 cli_unlock(cli2, fnum2, 0, 4);
2015 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2016 EXPECTED(ret, False);
2018 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2020 /* Unlock the process 1 fnum3 lock. */
2021 cli_unlock(cli1, fnum3, 0, 4);
2023 /* Stack 2 more locks here. */
2024 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2025 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2027 EXPECTED(ret, True);
2028 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2030 /* Unlock the first process lock, then check this was the WRITE lock that was
2033 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2034 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2036 EXPECTED(ret, True);
2037 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2039 /* Unlock the process 2 lock. */
2040 cli_unlock(cli2, fnum2, 0, 4);
2042 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2044 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2045 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2046 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2048 EXPECTED(ret, True);
2049 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2051 /* Ensure the next unlock fails. */
2052 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2053 EXPECTED(ret, False);
2054 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2056 /* Ensure connection 2 can get a write lock. */
2057 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2058 EXPECTED(ret, True);
2060 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2064 cli_close(cli1, fnum1);
2065 cli_close(cli2, fnum2);
2066 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2067 if (!torture_close_connection(cli1)) {
2070 if (!torture_close_connection(cli2)) {
2074 printf("finished locktest5\n");
2080 tries the unusual lockingX locktype bits
2082 static bool run_locktest6(int dummy)
2084 static struct cli_state *cli;
2085 const char *fname[1] = { "\\lock6.txt" };
2090 if (!torture_open_connection(&cli, 0)) {
2094 cli_sockopt(cli, sockops);
2096 printf("starting locktest6\n");
2099 printf("Testing %s\n", fname[i]);
2101 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2103 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2104 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2105 cli_close(cli, fnum);
2106 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2108 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2109 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2110 cli_close(cli, fnum);
2111 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2113 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2116 torture_close_connection(cli);
2118 printf("finished locktest6\n");
2122 static bool run_locktest7(int dummy)
2124 struct cli_state *cli1;
2125 const char *fname = "\\lockt7.lck";
2128 bool correct = False;
2130 if (!torture_open_connection(&cli1, 0)) {
2134 cli_sockopt(cli1, sockops);
2136 printf("starting locktest7\n");
2138 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2140 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2142 memset(buf, 0, sizeof(buf));
2144 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2145 printf("Failed to create file\n");
2149 cli_setpid(cli1, 1);
2151 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2152 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2155 printf("pid1 successfully locked range 130:4 for READ\n");
2158 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2159 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2162 printf("pid1 successfully read the range 130:4\n");
2165 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2166 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2167 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2168 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2172 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2176 cli_setpid(cli1, 2);
2178 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2179 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2181 printf("pid2 successfully read the range 130:4\n");
2184 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2185 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2186 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2187 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2191 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2195 cli_setpid(cli1, 1);
2196 cli_unlock(cli1, fnum1, 130, 4);
2198 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2199 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2202 printf("pid1 successfully locked range 130:4 for WRITE\n");
2205 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2206 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2209 printf("pid1 successfully read the range 130:4\n");
2212 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2213 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2216 printf("pid1 successfully wrote to the range 130:4\n");
2219 cli_setpid(cli1, 2);
2221 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2222 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2223 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2224 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2228 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2232 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2233 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2234 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2235 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2239 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2243 cli_unlock(cli1, fnum1, 130, 0);
2247 cli_close(cli1, fnum1);
2248 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2249 torture_close_connection(cli1);
2251 printf("finished locktest7\n");
2256 * This demonstrates a problem with our use of GPFS share modes: A file
2257 * descriptor sitting in the pending close queue holding a GPFS share mode
2258 * blocks opening a file another time. Happens with Word 2007 temp files.
2259 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2260 * open is denied with NT_STATUS_SHARING_VIOLATION.
2263 static bool run_locktest8(int dummy)
2265 struct cli_state *cli1;
2266 const char *fname = "\\lockt8.lck";
2267 uint16_t fnum1, fnum2;
2269 bool correct = False;
2272 if (!torture_open_connection(&cli1, 0)) {
2276 cli_sockopt(cli1, sockops);
2278 printf("starting locktest8\n");
2280 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2282 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2284 if (!NT_STATUS_IS_OK(status)) {
2285 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2289 memset(buf, 0, sizeof(buf));
2291 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2292 if (!NT_STATUS_IS_OK(status)) {
2293 d_fprintf(stderr, "cli_open second time returned %s\n",
2298 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2299 printf("Unable to apply read lock on range 1:1, error was "
2300 "%s\n", cli_errstr(cli1));
2304 status = cli_close(cli1, fnum1);
2305 if (!NT_STATUS_IS_OK(status)) {
2306 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2310 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2311 if (!NT_STATUS_IS_OK(status)) {
2312 d_fprintf(stderr, "cli_open third time returned %s\n",
2320 cli_close(cli1, fnum1);
2321 cli_close(cli1, fnum2);
2322 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2323 torture_close_connection(cli1);
2325 printf("finished locktest8\n");
2330 * This test is designed to be run in conjunction with
2331 * external NFS or POSIX locks taken in the filesystem.
2332 * It checks that the smbd server will block until the
2333 * lock is released and then acquire it. JRA.
2336 static bool got_alarm;
2337 static int alarm_fd;
2339 static void alarm_handler(int dummy)
2344 static void alarm_handler_parent(int dummy)
2349 static void do_local_lock(int read_fd, int write_fd)
2354 const char *local_pathname = NULL;
2357 local_pathname = talloc_asprintf(talloc_tos(),
2358 "%s/lockt9.lck", local_path);
2359 if (!local_pathname) {
2360 printf("child: alloc fail\n");
2364 unlink(local_pathname);
2365 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2367 printf("child: open of %s failed %s.\n",
2368 local_pathname, strerror(errno));
2372 /* Now take a fcntl lock. */
2373 lock.l_type = F_WRLCK;
2374 lock.l_whence = SEEK_SET;
2377 lock.l_pid = getpid();
2379 ret = fcntl(fd,F_SETLK,&lock);
2381 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2382 local_pathname, strerror(errno));
2385 printf("child: got lock 0:4 on file %s.\n",
2390 CatchSignal(SIGALRM, alarm_handler);
2392 /* Signal the parent. */
2393 if (write(write_fd, &c, 1) != 1) {
2394 printf("child: start signal fail %s.\n",
2401 /* Wait for the parent to be ready. */
2402 if (read(read_fd, &c, 1) != 1) {
2403 printf("child: reply signal fail %s.\n",
2411 printf("child: released lock 0:4 on file %s.\n",
2417 static bool run_locktest9(int dummy)
2419 struct cli_state *cli1;
2420 const char *fname = "\\lockt9.lck";
2422 bool correct = False;
2423 int pipe_in[2], pipe_out[2];
2427 struct timeval start;
2431 printf("starting locktest9\n");
2433 if (local_path == NULL) {
2434 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2438 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2443 if (child_pid == -1) {
2447 if (child_pid == 0) {
2449 do_local_lock(pipe_out[0], pipe_in[1]);
2459 ret = read(pipe_in[0], &c, 1);
2461 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2466 if (!torture_open_connection(&cli1, 0)) {
2470 cli_sockopt(cli1, sockops);
2472 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2474 if (!NT_STATUS_IS_OK(status)) {
2475 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2479 /* Ensure the child has the lock. */
2480 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2481 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2484 d_printf("Child has the lock.\n");
2487 /* Tell the child to wait 5 seconds then exit. */
2488 ret = write(pipe_out[1], &c, 1);
2490 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2495 /* Wait 20 seconds for the lock. */
2496 alarm_fd = cli1->fd;
2497 CatchSignal(SIGALRM, alarm_handler_parent);
2500 start = timeval_current();
2502 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2503 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2504 "%s\n", cli_errstr(cli1));
2509 seconds = timeval_elapsed(&start);
2511 printf("Parent got the lock after %.2f seconds.\n",
2514 status = cli_close(cli1, fnum);
2515 if (!NT_STATUS_IS_OK(status)) {
2516 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2523 cli_close(cli1, fnum);
2524 torture_close_connection(cli1);
2528 printf("finished locktest9\n");
2533 test whether fnums and tids open on one VC are available on another (a major
2536 static bool run_fdpasstest(int dummy)
2538 struct cli_state *cli1, *cli2;
2539 const char *fname = "\\fdpass.tst";
2543 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2546 cli_sockopt(cli1, sockops);
2547 cli_sockopt(cli2, sockops);
2549 printf("starting fdpasstest\n");
2551 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2553 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2554 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2558 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2559 printf("write failed (%s)\n", cli_errstr(cli1));
2563 cli2->vuid = cli1->vuid;
2564 cli2->cnum = cli1->cnum;
2565 cli2->pid = cli1->pid;
2567 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2568 printf("read succeeded! nasty security hole [%s]\n",
2573 cli_close(cli1, fnum1);
2574 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2576 torture_close_connection(cli1);
2577 torture_close_connection(cli2);
2579 printf("finished fdpasstest\n");
2583 static bool run_fdsesstest(int dummy)
2585 struct cli_state *cli;
2590 const char *fname = "\\fdsess.tst";
2591 const char *fname1 = "\\fdsess1.tst";
2597 if (!torture_open_connection(&cli, 0))
2599 cli_sockopt(cli, sockops);
2601 if (!torture_cli_session_setup2(cli, &new_vuid))
2604 saved_cnum = cli->cnum;
2605 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2607 new_cnum = cli->cnum;
2608 cli->cnum = saved_cnum;
2610 printf("starting fdsesstest\n");
2612 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2613 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2615 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2616 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2620 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2621 printf("write failed (%s)\n", cli_errstr(cli));
2625 saved_vuid = cli->vuid;
2626 cli->vuid = new_vuid;
2628 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2629 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2633 /* Try to open a file with different vuid, samba cnum. */
2634 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2635 printf("create with different vuid, same cnum succeeded.\n");
2636 cli_close(cli, fnum2);
2637 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2639 printf("create with different vuid, same cnum failed.\n");
2640 printf("This will cause problems with service clients.\n");
2644 cli->vuid = saved_vuid;
2646 /* Try with same vuid, different cnum. */
2647 cli->cnum = new_cnum;
2649 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2650 printf("read succeeded with different cnum![%s]\n",
2655 cli->cnum = saved_cnum;
2656 cli_close(cli, fnum1);
2657 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2659 torture_close_connection(cli);
2661 printf("finished fdsesstest\n");
2666 This test checks that
2668 1) the server does not allow an unlink on a file that is open
2670 static bool run_unlinktest(int dummy)
2672 struct cli_state *cli;
2673 const char *fname = "\\unlink.tst";
2675 bool correct = True;
2677 if (!torture_open_connection(&cli, 0)) {
2681 cli_sockopt(cli, sockops);
2683 printf("starting unlink test\n");
2685 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2689 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2690 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2694 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2695 printf("error: server allowed unlink on an open file\n");
2698 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2699 NT_STATUS_SHARING_VIOLATION);
2702 cli_close(cli, fnum);
2703 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2705 if (!torture_close_connection(cli)) {
2709 printf("unlink test finished\n");
2716 test how many open files this server supports on the one socket
2718 static bool run_maxfidtest(int dummy)
2720 struct cli_state *cli;
2721 const char *ftemplate = "\\maxfid.%d.%d";
2723 uint16_t fnums[0x11000];
2726 bool correct = True;
2731 printf("failed to connect\n");
2735 cli_sockopt(cli, sockops);
2737 for (i=0; i<0x11000; i++) {
2738 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2739 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2740 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2741 printf("open of %s failed (%s)\n",
2742 fname, cli_errstr(cli));
2743 printf("maximum fnum is %d\n", i);
2751 printf("cleaning up\n");
2753 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2754 cli_close(cli, fnums[i]);
2755 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2756 printf("unlink of %s failed (%s)\n",
2757 fname, cli_errstr(cli));
2764 printf("maxfid test finished\n");
2765 if (!torture_close_connection(cli)) {
2771 /* generate a random buffer */
2772 static void rand_buf(char *buf, int len)
2775 *buf = (char)sys_random();
2780 /* send smb negprot commands, not reading the response */
2781 static bool run_negprot_nowait(int dummy)
2783 struct tevent_context *ev;
2785 struct cli_state *cli;
2786 bool correct = True;
2788 printf("starting negprot nowait test\n");
2790 ev = tevent_context_init(talloc_tos());
2795 if (!(cli = open_nbt_connection())) {
2800 for (i=0;i<50000;i++) {
2801 struct tevent_req *req;
2803 req = cli_negprot_send(ev, ev, cli);
2808 if (!tevent_req_poll(req, ev)) {
2809 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2817 if (torture_close_connection(cli)) {
2821 printf("finished negprot nowait test\n");
2826 /* send smb negprot commands, not reading the response */
2827 static bool run_bad_nbt_session(int dummy)
2829 static struct cli_state *cli;
2831 printf("starting bad nbt session test\n");
2833 if (!(cli = open_bad_nbt_connection())) {
2838 printf("finished bad nbt session test\n");
2842 /* send random IPC commands */
2843 static bool run_randomipc(int dummy)
2845 char *rparam = NULL;
2847 unsigned int rdrcnt,rprcnt;
2849 int api, param_len, i;
2850 struct cli_state *cli;
2851 bool correct = True;
2854 printf("starting random ipc test\n");
2856 if (!torture_open_connection(&cli, 0)) {
2860 for (i=0;i<count;i++) {
2861 api = sys_random() % 500;
2862 param_len = (sys_random() % 64);
2864 rand_buf(param, param_len);
2869 param, param_len, 8,
2870 NULL, 0, BUFFER_SIZE,
2874 printf("%d/%d\r", i,count);
2877 printf("%d/%d\n", i, count);
2879 if (!torture_close_connection(cli)) {
2883 printf("finished random ipc test\n");
2890 static void browse_callback(const char *sname, uint32 stype,
2891 const char *comment, void *state)
2893 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2899 This test checks the browse list code
2902 static bool run_browsetest(int dummy)
2904 static struct cli_state *cli;
2905 bool correct = True;
2907 printf("starting browse test\n");
2909 if (!torture_open_connection(&cli, 0)) {
2913 printf("domain list:\n");
2914 cli_NetServerEnum(cli, cli->server_domain,
2915 SV_TYPE_DOMAIN_ENUM,
2916 browse_callback, NULL);
2918 printf("machine list:\n");
2919 cli_NetServerEnum(cli, cli->server_domain,
2921 browse_callback, NULL);
2923 if (!torture_close_connection(cli)) {
2927 printf("browse test finished\n");
2935 This checks how the getatr calls works
2937 static bool run_attrtest(int dummy)
2939 struct cli_state *cli;
2942 const char *fname = "\\attrib123456789.tst";
2943 bool correct = True;
2945 printf("starting attrib test\n");
2947 if (!torture_open_connection(&cli, 0)) {
2951 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2952 cli_open(cli, fname,
2953 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2954 cli_close(cli, fnum);
2955 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2956 printf("getatr failed (%s)\n", cli_errstr(cli));
2960 if (abs(t - time(NULL)) > 60*60*24*10) {
2961 printf("ERROR: SMBgetatr bug. time is %s",
2967 t2 = t-60*60*24; /* 1 day ago */
2969 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2970 printf("setatr failed (%s)\n", cli_errstr(cli));
2974 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2975 printf("getatr failed (%s)\n", cli_errstr(cli));
2980 printf("ERROR: getatr/setatr bug. times are\n%s",
2982 printf("%s", ctime(&t2));
2986 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2988 if (!torture_close_connection(cli)) {
2992 printf("attrib test finished\n");
2999 This checks a couple of trans2 calls
3001 static bool run_trans2test(int dummy)
3003 struct cli_state *cli;
3006 time_t c_time, a_time, m_time;
3007 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3008 const char *fname = "\\trans2.tst";
3009 const char *dname = "\\trans2";
3010 const char *fname2 = "\\trans2\\trans2.tst";
3012 bool correct = True;
3016 printf("starting trans2 test\n");
3018 if (!torture_open_connection(&cli, 0)) {
3022 status = cli_get_fs_attr_info(cli, &fs_attr);
3023 if (!NT_STATUS_IS_OK(status)) {
3024 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3029 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3030 cli_open(cli, fname,
3031 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3032 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3033 cli, fnum, NULL, &size, &c_time_ts,
3034 &a_time_ts, &w_time_ts,
3035 &m_time_ts, NULL))) {
3036 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3040 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3041 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3045 if (strcmp(pname, fname)) {
3046 printf("qfilename gave different name? [%s] [%s]\n",
3051 cli_close(cli, fnum);
3055 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3056 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3057 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3058 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3061 cli_close(cli, fnum);
3063 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3065 if (!NT_STATUS_IS_OK(status)) {
3066 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3069 if (c_time != m_time) {
3070 printf("create time=%s", ctime(&c_time));
3071 printf("modify time=%s", ctime(&m_time));
3072 printf("This system appears to have sticky create times\n");
3074 if (a_time % (60*60) == 0) {
3075 printf("access time=%s", ctime(&a_time));
3076 printf("This system appears to set a midnight access time\n");
3080 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3081 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3087 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3088 cli_open(cli, fname,
3089 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3090 cli_close(cli, fnum);
3091 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3092 &m_time_ts, &size, NULL, NULL);
3093 if (!NT_STATUS_IS_OK(status)) {
3094 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3097 if (w_time_ts.tv_sec < 60*60*24*2) {
3098 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3099 printf("This system appears to set a initial 0 write time\n");
3104 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3107 /* check if the server updates the directory modification time
3108 when creating a new file */
3109 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3110 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3114 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3115 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3116 if (!NT_STATUS_IS_OK(status)) {
3117 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3121 cli_open(cli, fname2,
3122 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3123 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
3124 cli_close(cli, fnum);
3125 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3126 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3127 if (!NT_STATUS_IS_OK(status)) {
3128 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3131 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3133 printf("This system does not update directory modification times\n");
3137 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3138 cli_rmdir(cli, dname);
3140 if (!torture_close_connection(cli)) {
3144 printf("trans2 test finished\n");
3150 This checks new W2K calls.
3153 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3155 uint8_t *buf = NULL;
3159 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3160 pcli->max_xmit, &buf, &len);
3161 if (!NT_STATUS_IS_OK(status)) {
3162 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3165 printf("qfileinfo: level %d, len = %u\n", level, len);
3166 dump_data(0, (uint8 *)buf, len);
3173 static bool run_w2ktest(int dummy)
3175 struct cli_state *cli;
3177 const char *fname = "\\w2ktest\\w2k.tst";
3179 bool correct = True;
3181 printf("starting w2k test\n");
3183 if (!torture_open_connection(&cli, 0)) {
3187 cli_open(cli, fname,
3188 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3190 for (level = 1004; level < 1040; level++) {
3191 new_trans(cli, fnum, level);
3194 cli_close(cli, fnum);
3196 if (!torture_close_connection(cli)) {
3200 printf("w2k test finished\n");
3207 this is a harness for some oplock tests
3209 static bool run_oplock1(int dummy)
3211 struct cli_state *cli1;
3212 const char *fname = "\\lockt1.lck";
3214 bool correct = True;
3216 printf("starting oplock test 1\n");
3218 if (!torture_open_connection(&cli1, 0)) {
3222 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3224 cli_sockopt(cli1, sockops);
3226 cli1->use_oplocks = True;
3228 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3229 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3233 cli1->use_oplocks = False;
3235 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3236 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3238 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3239 printf("close2 failed (%s)\n", cli_errstr(cli1));
3243 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3244 printf("unlink failed (%s)\n", cli_errstr(cli1));
3248 if (!torture_close_connection(cli1)) {
3252 printf("finished oplock test 1\n");
3257 static bool run_oplock2(int dummy)
3259 struct cli_state *cli1, *cli2;
3260 const char *fname = "\\lockt2.lck";
3261 uint16_t fnum1, fnum2;
3262 int saved_use_oplocks = use_oplocks;
3264 bool correct = True;
3265 volatile bool *shared_correct;
3267 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3268 *shared_correct = True;
3270 use_level_II_oplocks = True;
3273 printf("starting oplock test 2\n");
3275 if (!torture_open_connection(&cli1, 0)) {
3276 use_level_II_oplocks = False;
3277 use_oplocks = saved_use_oplocks;
3281 cli1->use_oplocks = True;
3282 cli1->use_level_II_oplocks = True;
3284 if (!torture_open_connection(&cli2, 1)) {
3285 use_level_II_oplocks = False;
3286 use_oplocks = saved_use_oplocks;
3290 cli2->use_oplocks = True;
3291 cli2->use_level_II_oplocks = True;
3293 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3295 cli_sockopt(cli1, sockops);
3296 cli_sockopt(cli2, sockops);
3298 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3299 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3303 /* Don't need the globals any more. */
3304 use_level_II_oplocks = False;
3305 use_oplocks = saved_use_oplocks;
3309 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3310 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3311 *shared_correct = False;
3317 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3318 printf("close2 failed (%s)\n", cli_errstr(cli1));
3319 *shared_correct = False;
3327 /* Ensure cli1 processes the break. Empty file should always return 0
3330 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3331 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3335 /* Should now be at level II. */
3336 /* Test if sending a write locks causes a break to none. */
3338 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3339 printf("lock failed (%s)\n", cli_errstr(cli1));
3343 cli_unlock(cli1, fnum1, 0, 4);
3347 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3348 printf("lock failed (%s)\n", cli_errstr(cli1));
3352 cli_unlock(cli1, fnum1, 0, 4);
3356 cli_read(cli1, fnum1, buf, 0, 4);
3359 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3360 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3365 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3366 printf("close1 failed (%s)\n", cli_errstr(cli1));
3372 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3373 printf("unlink failed (%s)\n", cli_errstr(cli1));
3377 if (!torture_close_connection(cli1)) {
3381 if (!*shared_correct) {
3385 printf("finished oplock test 2\n");
3390 /* handler for oplock 3 tests */
3391 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3393 printf("got oplock break fnum=%d level=%d\n",
3395 return cli_oplock_ack(cli, fnum, level);
3398 static bool run_oplock3(int dummy)
3400 struct cli_state *cli;
3401 const char *fname = "\\oplockt3.dat";
3403 char buf[4] = "abcd";
3404 bool correct = True;
3405 volatile bool *shared_correct;
3407 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3408 *shared_correct = True;
3410 printf("starting oplock test 3\n");
3415 use_level_II_oplocks = True;
3416 if (!torture_open_connection(&cli, 0)) {
3417 *shared_correct = False;
3421 /* try to trigger a oplock break in parent */
3422 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3423 cli_write(cli, fnum, 0, buf, 0, 4);
3429 use_level_II_oplocks = True;
3430 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3433 cli_oplock_handler(cli, oplock3_handler);
3434 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3435 cli_write(cli, fnum, 0, buf, 0, 4);
3436 cli_close(cli, fnum);
3437 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3438 cli->timeout = 20000;
3439 cli_receive_smb(cli);
3440 printf("finished oplock test 3\n");
3442 return (correct && *shared_correct);
3444 /* What are we looking for here? What's sucess and what's FAILURE? */
3447 /* handler for oplock 4 tests */
3448 bool *oplock4_shared_correct;
3450 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3452 printf("got oplock break fnum=%d level=%d\n",
3454 *oplock4_shared_correct = true;
3455 cli_oplock_ack(cli, fnum, level);
3456 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3459 static bool run_oplock4(int dummy)
3461 struct cli_state *cli1, *cli2;
3462 const char *fname = "\\lockt4.lck";
3463 const char *fname_ln = "\\lockt4_ln.lck";
3464 uint16_t fnum1, fnum2;
3465 int saved_use_oplocks = use_oplocks;
3467 bool correct = true;
3469 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3470 *oplock4_shared_correct = false;
3472 printf("starting oplock test 4\n");
3474 if (!torture_open_connection(&cli1, 0)) {
3475 use_level_II_oplocks = false;
3476 use_oplocks = saved_use_oplocks;
3480 if (!torture_open_connection(&cli2, 1)) {
3481 use_level_II_oplocks = false;
3482 use_oplocks = saved_use_oplocks;
3486 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3487 cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN);
3489 cli_sockopt(cli1, sockops);
3490 cli_sockopt(cli2, sockops);
3492 /* Create the file. */
3493 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3494 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3498 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3499 printf("close1 failed (%s)\n", cli_errstr(cli1));
3503 /* Now create a hardlink. */
3504 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3505 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3509 /* Prove that opening hardlinks cause deny modes to conflict. */
3510 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3511 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3515 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3516 if (NT_STATUS_IS_OK(status)) {
3517 printf("open of %s succeeded - should fail with sharing violation.\n",
3522 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3523 printf("open of %s should fail with sharing violation. Got %s\n",
3524 fname_ln, nt_errstr(status));
3528 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3529 printf("close1 failed (%s)\n", cli_errstr(cli1));
3533 cli1->use_oplocks = true;
3534 cli1->use_level_II_oplocks = true;
3536 cli2->use_oplocks = true;
3537 cli2->use_level_II_oplocks = true;
3539 cli_oplock_handler(cli1, oplock4_handler);
3540 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3541 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3547 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3548 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3549 *oplock4_shared_correct = false;
3553 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3554 printf("close2 failed (%s)\n", cli_errstr(cli1));
3555 *oplock4_shared_correct = false;
3563 /* Process the oplock break. */
3564 cli_receive_smb(cli1);
3566 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3567 printf("close1 failed (%s)\n", cli_errstr(cli1));
3571 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3572 printf("unlink failed (%s)\n", cli_errstr(cli1));
3575 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN))) {
3576 printf("unlink failed (%s)\n", cli_errstr(cli1));
3580 if (!torture_close_connection(cli1)) {
3584 if (!*oplock4_shared_correct) {
3588 printf("finished oplock test 4\n");
3595 Test delete on close semantics.
3597 static bool run_deletetest(int dummy)
3599 struct cli_state *cli1 = NULL;
3600 struct cli_state *cli2 = NULL;
3601 const char *fname = "\\delete.file";
3602 uint16_t fnum1 = (uint16_t)-1;
3603 uint16_t fnum2 = (uint16_t)-1;
3604 bool correct = True;
3606 printf("starting delete test\n");
3608 if (!torture_open_connection(&cli1, 0)) {
3612 cli_sockopt(cli1, sockops);
3614 /* Test 1 - this should delete the file on close. */
3616 cli_setatr(cli1, fname, 0, 0);
3617 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3619 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3620 0, FILE_OVERWRITE_IF,
3621 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3622 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3627 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3628 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3633 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3634 printf("[1] open of %s succeeded (should fail)\n", fname);
3639 printf("first delete on close test succeeded.\n");
3641 /* Test 2 - this should delete the file on close. */
3643 cli_setatr(cli1, fname, 0, 0);
3644 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3646 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3647 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3648 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3649 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3654 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3655 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3660 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3661 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3666 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3667 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3668 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3669 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3673 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3675 printf("second delete on close test succeeded.\n");
3678 cli_setatr(cli1, fname, 0, 0);
3679 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3681 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3682 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3683 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3688 /* This should fail with a sharing violation - open for delete is only compatible
3689 with SHARE_DELETE. */
3691 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3692 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3693 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3698 /* This should succeed. */
3700 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3701 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3702 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3707 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3708 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3713 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3714 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3719 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3720 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3725 /* This should fail - file should no longer be there. */
3727 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3728 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3729 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3730 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3732 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3736 printf("third delete on close test succeeded.\n");
3739 cli_setatr(cli1, fname, 0, 0);
3740 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3742 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3743 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3744 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3749 /* This should succeed. */
3750 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3751 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3752 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3757 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3758 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3763 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3764 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3769 /* This should fail - no more opens once delete on close set. */
3770 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3771 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3772 FILE_OPEN, 0, 0, &fnum2))) {
3773 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3777 printf("fourth delete on close test succeeded.\n");
3779 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3780 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3786 cli_setatr(cli1, fname, 0, 0);
3787 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3789 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3790 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3795 /* This should fail - only allowed on NT opens with DELETE access. */
3797 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3798 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3803 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3804 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3809 printf("fifth delete on close test succeeded.\n");
3812 cli_setatr(cli1, fname, 0, 0);
3813 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3815 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3816 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3817 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3818 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3823 /* This should fail - only allowed on NT opens with DELETE access. */
3825 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3826 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3831 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3832 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3837 printf("sixth delete on close test succeeded.\n");
3840 cli_setatr(cli1, fname, 0, 0);
3841 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3843 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3844 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3845 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3850 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3851 printf("[7] setting delete_on_close on file failed !\n");
3856 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3857 printf("[7] unsetting delete_on_close on file failed !\n");
3862 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3863 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3868 /* This next open should succeed - we reset the flag. */
3870 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3871 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3876 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3877 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3882 printf("seventh delete on close test succeeded.\n");
3885 cli_setatr(cli1, fname, 0, 0);
3886 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3888 if (!torture_open_connection(&cli2, 1)) {
3889 printf("[8] failed to open second connection.\n");
3894 cli_sockopt(cli1, sockops);
3896 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3897 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3898 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3899 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3904 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3905 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3906 FILE_OPEN, 0, 0, &fnum2))) {
3907 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3912 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3913 printf("[8] setting delete_on_close on file failed !\n");
3918 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3919 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3924 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3925 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3930 /* This should fail.. */
3931 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3932 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3936 printf("eighth delete on close test succeeded.\n");
3938 /* This should fail - we need to set DELETE_ACCESS. */
3939 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3940 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3941 printf("[9] open of %s succeeded should have failed!\n", fname);
3946 printf("ninth delete on close test succeeded.\n");
3948 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3949 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3950 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3955 /* This should delete the file. */
3956 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3957 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3962 /* This should fail.. */
3963 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3964 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3968 printf("tenth delete on close test succeeded.\n");
3970 cli_setatr(cli1, fname, 0, 0);
3971 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3973 /* What error do we get when attempting to open a read-only file with
3976 /* Create a readonly file. */
3977 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3978 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3979 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3984 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3985 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3990 /* Now try open for delete access. */
3991 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3992 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3993 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3994 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3995 cli_close(cli1, fnum1);
3999 NTSTATUS nterr = cli_nt_error(cli1);
4000 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
4001 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4005 printf("eleventh delete on close test succeeded.\n");
4009 printf("finished delete test\n");
4012 /* FIXME: This will crash if we aborted before cli2 got
4013 * intialized, because these functions don't handle
4014 * uninitialized connections. */
4016 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4017 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4018 cli_setatr(cli1, fname, 0, 0);
4019 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4021 if (cli1 && !torture_close_connection(cli1)) {
4024 if (cli2 && !torture_close_connection(cli2)) {
4030 static bool run_deletetest_ln(int dummy)
4032 struct cli_state *cli;
4033 const char *fname = "\\delete1";
4034 const char *fname_ln = "\\delete1_ln";
4038 bool correct = true;
4041 printf("starting deletetest-ln\n");
4043 if (!torture_open_connection(&cli, 0)) {
4047 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4048 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4050 cli_sockopt(cli, sockops);
4052 /* Create the file. */
4053 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4054 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4058 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4059 printf("close1 failed (%s)\n", cli_errstr(cli));
4063 /* Now create a hardlink. */
4064 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4065 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4069 /* Open the original file. */
4070 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4071 FILE_ATTRIBUTE_NORMAL,
4072 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4073 FILE_OPEN_IF, 0, 0, &fnum);
4074 if (!NT_STATUS_IS_OK(status)) {
4075 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4079 /* Unlink the hard link path. */
4080 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4081 FILE_ATTRIBUTE_NORMAL,
4082 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4083 FILE_OPEN_IF, 0, 0, &fnum1);
4084 if (!NT_STATUS_IS_OK(status)) {
4085 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4088 status = cli_nt_delete_on_close(cli, fnum1, true);
4089 if (!NT_STATUS_IS_OK(status)) {
4090 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4091 __location__, fname_ln, nt_errstr(status));
4095 status = cli_close(cli, fnum1);
4096 if (!NT_STATUS_IS_OK(status)) {
4097 printf("close %s failed (%s)\n",
4098 fname_ln, nt_errstr(status));
4102 status = cli_close(cli, fnum);
4103 if (!NT_STATUS_IS_OK(status)) {
4104 printf("close %s failed (%s)\n",
4105 fname, nt_errstr(status));
4109 /* Ensure the original file is still there. */
4110 status = cli_getatr(cli, fname, NULL, NULL, &t);
4111 if (!NT_STATUS_IS_OK(status)) {
4112 printf("%s getatr on file %s failed (%s)\n",
4119 /* Ensure the link path is gone. */
4120 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4121 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4122 printf("%s, getatr for file %s returned wrong error code %s "
4123 "- should have been deleted\n",
4125 fname_ln, nt_errstr(status));
4129 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4130 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4132 if (!torture_close_connection(cli)) {
4136 printf("finished deletetest-ln\n");
4142 print out server properties
4144 static bool run_properties(int dummy)
4146 struct cli_state *cli;
4147 bool correct = True;
4149 printf("starting properties test\n");
4153 if (!torture_open_connection(&cli, 0)) {
4157 cli_sockopt(cli, sockops);
4159 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4161 if (!torture_close_connection(cli)) {
4170 /* FIRST_DESIRED_ACCESS 0xf019f */
4171 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4172 FILE_READ_EA| /* 0xf */ \
4173 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4174 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4175 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4176 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4177 /* SECOND_DESIRED_ACCESS 0xe0080 */
4178 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4179 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4180 WRITE_OWNER_ACCESS /* 0xe0000 */
4183 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4184 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4186 WRITE_OWNER_ACCESS /* */
4190 Test ntcreate calls made by xcopy
4192 static bool run_xcopy(int dummy)
4194 static struct cli_state *cli1;
4195 const char *fname = "\\test.txt";
4196 bool correct = True;
4197 uint16_t fnum1, fnum2;
4199 printf("starting xcopy test\n");
4201 if (!torture_open_connection(&cli1, 0)) {
4205 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4206 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4207 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4208 0x4044, 0, &fnum1))) {
4209 printf("First open failed - %s\n", cli_errstr(cli1));
4213 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4214 SECOND_DESIRED_ACCESS, 0,
4215 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4216 0x200000, 0, &fnum2))) {
4217 printf("second open failed - %s\n", cli_errstr(cli1));
4221 if (!torture_close_connection(cli1)) {
4229 Test rename on files open with share delete and no share delete.
4231 static bool run_rename(int dummy)
4233 static struct cli_state *cli1;
4234 const char *fname = "\\test.txt";
4235 const char *fname1 = "\\test1.txt";
4236 bool correct = True;
4241 printf("starting rename test\n");
4243 if (!torture_open_connection(&cli1, 0)) {
4247 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4248 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4249 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4250 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4251 printf("First open failed - %s\n", cli_errstr(cli1));
4255 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4256 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4258 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4262 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4263 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4267 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4268 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4269 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4271 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4273 FILE_SHARE_DELETE|FILE_SHARE_READ,
4275 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4276 if (!NT_STATUS_IS_OK(status)) {
4277 printf("Second open failed - %s\n", cli_errstr(cli1));
4281 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4282 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4285 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4288 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4289 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4293 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4294 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4296 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4297 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4298 printf("Third open failed - %s\n", cli_errstr(cli1));
4307 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4308 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4309 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4312 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4313 printf("[8] setting delete_on_close on file failed !\n");
4317 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4318 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4324 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4325 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4328 printf("Third rename succeeded (SHARE_NONE)\n");
4331 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4332 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4336 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4337 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4341 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4342 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4343 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4347 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4348 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4350 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4354 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4355 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4359 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4360 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4364 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4365 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4366 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4370 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4371 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4375 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4379 * Now check if the first name still exists ...
4382 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4383 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4384 printf("Opening original file after rename of open file fails: %s\n",
4388 printf("Opening original file after rename of open file works ...\n");
4389 (void)cli_close(cli1, fnum2);
4393 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4394 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4398 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4399 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4400 printf("getatr on file %s failed - %s ! \n",
4405 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4406 printf("Renamed file %s has wrong attr 0x%x "
4407 "(should be 0x%x)\n",
4410 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4413 printf("Renamed file %s has archive bit set\n", fname1);
4417 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4418 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4420 if (!torture_close_connection(cli1)) {
4427 static bool run_pipe_number(int dummy)
4429 struct cli_state *cli1;
4430 const char *pipe_name = "\\SPOOLSS";
4434 printf("starting pipenumber test\n");
4435 if (!torture_open_connection(&cli1, 0)) {
4439 cli_sockopt(cli1, sockops);
4441 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4442 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4443 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4447 printf("\r%6d", num_pipes);
4450 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4451 torture_close_connection(cli1);
4456 Test open mode returns on read-only files.
4458 static bool run_opentest(int dummy)
4460 static struct cli_state *cli1;
4461 static struct cli_state *cli2;
4462 const char *fname = "\\readonly.file";
4463 uint16_t fnum1, fnum2;
4466 bool correct = True;
4470 printf("starting open test\n");
4472 if (!torture_open_connection(&cli1, 0)) {
4476 cli_setatr(cli1, fname, 0, 0);
4477 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4479 cli_sockopt(cli1, sockops);
4481 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4482 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4486 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4487 printf("close2 failed (%s)\n", cli_errstr(cli1));
4491 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4492 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4496 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4497 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4501 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4502 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4504 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4505 NT_STATUS_ACCESS_DENIED)) {
4506 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4509 printf("finished open test 1\n");
4511 cli_close(cli1, fnum1);
4513 /* Now try not readonly and ensure ERRbadshare is returned. */
4515 cli_setatr(cli1, fname, 0, 0);
4517 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4518 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4522 /* This will fail - but the error should be ERRshare. */
4523 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4525 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4526 NT_STATUS_SHARING_VIOLATION)) {
4527 printf("correct error code ERRDOS/ERRbadshare returned\n");
4530 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4531 printf("close2 failed (%s)\n", cli_errstr(cli1));
4535 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4537 printf("finished open test 2\n");
4539 /* Test truncate open disposition on file opened for read. */
4541 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4542 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4546 /* write 20 bytes. */
4548 memset(buf, '\0', 20);
4550 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4551 printf("write failed (%s)\n", cli_errstr(cli1));
4555 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4556 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4560 /* Ensure size == 20. */
4561 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4562 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4567 printf("(3) file size != 20\n");
4571 /* Now test if we can truncate a file opened for readonly. */
4573 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4574 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4578 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4579 printf("close2 failed (%s)\n", cli_errstr(cli1));
4583 /* Ensure size == 0. */
4584 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4585 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4590 printf("(3) file size != 0\n");
4593 printf("finished open test 3\n");
4595 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4597 printf("Do ctemp tests\n");
4598 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4599 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4602 printf("ctemp gave path %s\n", tmp_path);
4603 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4604 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4606 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4607 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4610 /* Test the non-io opens... */
4612 if (!torture_open_connection(&cli2, 1)) {
4616 cli_setatr(cli2, fname, 0, 0);
4617 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4619 cli_sockopt(cli2, sockops);
4621 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4623 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4624 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4625 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4629 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4630 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4631 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4635 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4636 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4639 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4640 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4644 printf("non-io open test #1 passed.\n");
4646 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4648 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4650 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4651 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4652 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4656 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4657 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4658 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4662 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4663 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4666 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4667 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4671 printf("non-io open test #2 passed.\n");
4673 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4675 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4677 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4678 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4679 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4683 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4684 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4685 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4689 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4690 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4693 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4694 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4698 printf("non-io open test #3 passed.\n");
4700 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4702 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4704 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4705 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4706 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4710 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4711 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4712 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4716 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4718 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4719 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4723 printf("non-io open test #4 passed.\n");
4725 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4727 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4729 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4730 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4731 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4735 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4736 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4737 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4741 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4742 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4746 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4747 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4751 printf("non-io open test #5 passed.\n");
4753 printf("TEST #6 testing 1 non-io open, one io open\n");
4755 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4757 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4758 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4759 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4763 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4764 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4765 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4769 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4770 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4774 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4775 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4779 printf("non-io open test #6 passed.\n");
4781 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4783 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4785 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4786 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4787 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4791 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4792 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4793 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4797 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4799 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4800 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4804 printf("non-io open test #7 passed.\n");
4806 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4808 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4809 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4810 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4811 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4812 if (!NT_STATUS_IS_OK(status)) {
4813 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4818 /* Write to ensure we have to update the file time. */
4819 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4820 printf("TEST #8 cli_write failed: %s\n", cli_errstr(cli1));
4825 status = cli_close(cli1, fnum1);
4826 if (!NT_STATUS_IS_OK(status)) {
4827 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4833 if (!torture_close_connection(cli1)) {
4836 if (!torture_close_connection(cli2)) {
4843 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4845 uint16 major, minor;
4846 uint32 caplow, caphigh;
4849 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4850 printf("Server doesn't support UNIX CIFS extensions.\n");
4851 return NT_STATUS_NOT_SUPPORTED;
4854 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4856 if (!NT_STATUS_IS_OK(status)) {
4857 printf("Server didn't return UNIX CIFS extensions: %s\n",
4862 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4864 if (!NT_STATUS_IS_OK(status)) {
4865 printf("Server doesn't support setting UNIX CIFS extensions: "
4866 "%s.\n", nt_errstr(status));
4870 return NT_STATUS_OK;
4874 Test POSIX open /mkdir calls.
4876 static bool run_simple_posix_open_test(int dummy)
4878 static struct cli_state *cli1;
4879 const char *fname = "posix:file";
4880 const char *hname = "posix:hlink";
4881 const char *sname = "posix:symlink";
4882 const char *dname = "posix:dir";
4885 uint16_t fnum1 = (uint16_t)-1;
4886 SMB_STRUCT_STAT sbuf;
4887 bool correct = false;
4890 printf("Starting simple POSIX open test\n");
4892 if (!torture_open_connection(&cli1, 0)) {
4896 cli_sockopt(cli1, sockops);
4898 status = torture_setup_unix_extensions(cli1);
4899 if (!NT_STATUS_IS_OK(status)) {
4903 cli_setatr(cli1, fname, 0, 0);
4904 cli_posix_unlink(cli1, fname);
4905 cli_setatr(cli1, dname, 0, 0);
4906 cli_posix_rmdir(cli1, dname);
4907 cli_setatr(cli1, hname, 0, 0);
4908 cli_posix_unlink(cli1, hname);
4909 cli_setatr(cli1, sname, 0, 0);
4910 cli_posix_unlink(cli1, sname);
4912 /* Create a directory. */
4913 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4914 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4918 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4919 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4923 /* Test ftruncate - set file size. */
4924 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4925 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4929 /* Ensure st_size == 1000 */
4930 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4931 printf("stat failed (%s)\n", cli_errstr(cli1));
4935 if (sbuf.st_ex_size != 1000) {
4936 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4940 /* Test ftruncate - set file size back to zero. */
4941 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4942 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4946 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4947 printf("close failed (%s)\n", cli_errstr(cli1));
4951 /* Now open the file again for read only. */
4952 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4953 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4957 /* Now unlink while open. */
4958 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4959 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4963 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4964 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4968 /* Ensure the file has gone. */
4969 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4970 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4974 /* What happens when we try and POSIX open a directory ? */
4975 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4976 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4979 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4980 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4985 /* Create the file. */
4986 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4987 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4991 /* Write some data into it. */
4992 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4993 printf("cli_write failed: %s\n", cli_errstr(cli1));
4997 cli_close(cli1, fnum1);
4999 /* Now create a hardlink. */
5000 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
5001 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5005 /* Now create a symlink. */
5006 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5007 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5011 /* Open the hardlink for read. */
5012 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5013 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5017 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5018 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5022 if (memcmp(buf, "TEST DATA\n", 10)) {
5023 printf("invalid data read from hardlink\n");
5027 /* Do a POSIX lock/unlock. */
5028 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5029 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5033 /* Punch a hole in the locked area. */
5034 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5035 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5039 cli_close(cli1, fnum1);
5041 /* Open the symlink for read - this should fail. A POSIX
5042 client should not be doing opens on a symlink. */
5043 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5044 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5047 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5048 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5049 printf("POSIX open of %s should have failed "
5050 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5051 "failed with %s instead.\n",
5052 sname, cli_errstr(cli1));
5057 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5058 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5062 if (strcmp(namebuf, fname) != 0) {
5063 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5064 sname, fname, namebuf);
5068 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5069 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5073 printf("Simple POSIX open test passed\n");
5078 if (fnum1 != (uint16_t)-1) {
5079 cli_close(cli1, fnum1);
5080 fnum1 = (uint16_t)-1;
5083 cli_setatr(cli1, sname, 0, 0);
5084 cli_posix_unlink(cli1, sname);
5085 cli_setatr(cli1, hname, 0, 0);
5086 cli_posix_unlink(cli1, hname);
5087 cli_setatr(cli1, fname, 0, 0);
5088 cli_posix_unlink(cli1, fname);
5089 cli_setatr(cli1, dname, 0, 0);
5090 cli_posix_rmdir(cli1, dname);
5092 if (!torture_close_connection(cli1)) {
5100 static uint32 open_attrs_table[] = {
5101 FILE_ATTRIBUTE_NORMAL,
5102 FILE_ATTRIBUTE_ARCHIVE,
5103 FILE_ATTRIBUTE_READONLY,
5104 FILE_ATTRIBUTE_HIDDEN,
5105 FILE_ATTRIBUTE_SYSTEM,
5107 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5108 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5109 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5110 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5111 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5112 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5114 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5115 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5116 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5117 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5120 struct trunc_open_results {
5127 static struct trunc_open_results attr_results[] = {
5128 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5129 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5130 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5131 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5132 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5133 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5134 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5135 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5136 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5137 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5138 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5139 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5140 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5141 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5142 { 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 },
5143 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5144 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5145 { 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 },
5146 { 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 },
5147 { 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 },
5148 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5149 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5150 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5151 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5152 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5153 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5156 static bool run_openattrtest(int dummy)
5158 static struct cli_state *cli1;
5159 const char *fname = "\\openattr.file";
5161 bool correct = True;
5163 unsigned int i, j, k, l;
5165 printf("starting open attr test\n");
5167 if (!torture_open_connection(&cli1, 0)) {
5171 cli_sockopt(cli1, sockops);
5173 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5174 cli_setatr(cli1, fname, 0, 0);
5175 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5176 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5177 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5178 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5182 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5183 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5187 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5188 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5189 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5190 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5191 if (attr_results[l].num == k) {
5192 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5193 k, open_attrs_table[i],
5194 open_attrs_table[j],
5195 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5199 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5200 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5201 k, open_attrs_table[i], open_attrs_table[j],
5206 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5212 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5213 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5217 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5218 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5223 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5224 k, open_attrs_table[i], open_attrs_table[j], attr );
5227 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5228 if (attr_results[l].num == k) {
5229 if (attr != attr_results[l].result_attr ||
5230 open_attrs_table[i] != attr_results[l].init_attr ||
5231 open_attrs_table[j] != attr_results[l].trunc_attr) {
5232 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5233 open_attrs_table[i],
5234 open_attrs_table[j],
5236 attr_results[l].result_attr);
5246 cli_setatr(cli1, fname, 0, 0);
5247 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5249 printf("open attr test %s.\n", correct ? "passed" : "failed");
5251 if (!torture_close_connection(cli1)) {
5257 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5258 const char *name, void *state)
5260 int *matched = (int *)state;
5261 if (matched != NULL) {
5264 return NT_STATUS_OK;
5268 test directory listing speed
5270 static bool run_dirtest(int dummy)
5273 static struct cli_state *cli;
5275 struct timeval core_start;
5276 bool correct = True;
5279 printf("starting directory test\n");
5281 if (!torture_open_connection(&cli, 0)) {
5285 cli_sockopt(cli, sockops);
5288 for (i=0;i<torture_numops;i++) {
5290 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5291 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5292 fprintf(stderr,"Failed to open %s\n", fname);
5295 cli_close(cli, fnum);
5298 core_start = timeval_current();
5301 cli_list(cli, "a*.*", 0, list_fn, &matched);
5302 printf("Matched %d\n", matched);
5305 cli_list(cli, "b*.*", 0, list_fn, &matched);
5306 printf("Matched %d\n", matched);
5309 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5310 printf("Matched %d\n", matched);
5312 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5315 for (i=0;i<torture_numops;i++) {
5317 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5318 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5321 if (!torture_close_connection(cli)) {
5325 printf("finished dirtest\n");
5330 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5333 struct cli_state *pcli = (struct cli_state *)state;
5335 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5337 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5338 return NT_STATUS_OK;
5340 if (finfo->mode & aDIR) {
5341 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5342 printf("del_fn: failed to rmdir %s\n,", fname );
5344 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5345 printf("del_fn: failed to unlink %s\n,", fname );
5347 return NT_STATUS_OK;
5352 sees what IOCTLs are supported
5354 bool torture_ioctl_test(int dummy)
5356 static struct cli_state *cli;
5357 uint16_t device, function;
5359 const char *fname = "\\ioctl.dat";
5363 if (!torture_open_connection(&cli, 0)) {
5367 printf("starting ioctl test\n");
5369 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5371 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5372 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5376 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5377 printf("ioctl device info: %s\n", nt_errstr(status));
5379 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5380 printf("ioctl job info: %s\n", nt_errstr(status));
5382 for (device=0;device<0x100;device++) {
5383 printf("ioctl test with device = 0x%x\n", device);
5384 for (function=0;function<0x100;function++) {
5385 uint32 code = (device<<16) | function;
5387 status = cli_raw_ioctl(cli, fnum, code, &blob);
5389 if (NT_STATUS_IS_OK(status)) {
5390 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5392 data_blob_free(&blob);
5397 if (!torture_close_connection(cli)) {
5406 tries varients of chkpath
5408 bool torture_chkpath_test(int dummy)
5410 static struct cli_state *cli;
5414 if (!torture_open_connection(&cli, 0)) {
5418 printf("starting chkpath test\n");
5420 /* cleanup from an old run */
5421 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5422 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5423 cli_rmdir(cli, "\\chkpath.dir");
5425 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5426 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5430 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5431 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5435 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5436 printf("open1 failed (%s)\n", cli_errstr(cli));
5439 cli_close(cli, fnum);
5441 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5442 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5446 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5447 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5451 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5452 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5453 NT_STATUS_NOT_A_DIRECTORY);
5455 printf("* chkpath on a file should fail\n");
5459 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5460 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5461 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5463 printf("* chkpath on a non existant file should fail\n");
5467 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5468 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5469 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5471 printf("* chkpath on a non existent component should fail\n");
5475 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5476 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5477 cli_rmdir(cli, "\\chkpath.dir");
5479 if (!torture_close_connection(cli)) {
5486 static bool run_eatest(int dummy)
5488 static struct cli_state *cli;
5489 const char *fname = "\\eatest.txt";
5490 bool correct = True;
5494 struct ea_struct *ea_list = NULL;
5495 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5498 printf("starting eatest\n");
5500 if (!torture_open_connection(&cli, 0)) {
5501 talloc_destroy(mem_ctx);
5505 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5506 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5507 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5508 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5509 0x4044, 0, &fnum))) {
5510 printf("open failed - %s\n", cli_errstr(cli));
5511 talloc_destroy(mem_ctx);
5515 for (i = 0; i < 10; i++) {
5516 fstring ea_name, ea_val;
5518 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5519 memset(ea_val, (char)i+1, i+1);
5520 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5521 if (!NT_STATUS_IS_OK(status)) {
5522 printf("ea_set of name %s failed - %s\n", ea_name,
5524 talloc_destroy(mem_ctx);
5529 cli_close(cli, fnum);
5530 for (i = 0; i < 10; i++) {
5531 fstring ea_name, ea_val;
5533 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5534 memset(ea_val, (char)i+1, i+1);
5535 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5536 if (!NT_STATUS_IS_OK(status)) {
5537 printf("ea_set of name %s failed - %s\n", ea_name,
5539 talloc_destroy(mem_ctx);
5544 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5545 if (!NT_STATUS_IS_OK(status)) {
5546 printf("ea_get list failed - %s\n", nt_errstr(status));
5550 printf("num_eas = %d\n", (int)num_eas);
5552 if (num_eas != 20) {
5553 printf("Should be 20 EA's stored... failing.\n");
5557 for (i = 0; i < num_eas; i++) {
5558 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5559 dump_data(0, ea_list[i].value.data,
5560 ea_list[i].value.length);
5563 /* Setting EA's to zero length deletes them. Test this */
5564 printf("Now deleting all EA's - case indepenent....\n");
5567 cli_set_ea_path(cli, fname, "", "", 0);
5569 for (i = 0; i < 20; i++) {
5571 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5572 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5573 if (!NT_STATUS_IS_OK(status)) {
5574 printf("ea_set of name %s failed - %s\n", ea_name,
5576 talloc_destroy(mem_ctx);
5582 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5583 if (!NT_STATUS_IS_OK(status)) {
5584 printf("ea_get list failed - %s\n", nt_errstr(status));
5588 printf("num_eas = %d\n", (int)num_eas);
5589 for (i = 0; i < num_eas; i++) {
5590 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5591 dump_data(0, ea_list[i].value.data,
5592 ea_list[i].value.length);
5596 printf("deleting EA's failed.\n");
5600 /* Try and delete a non existant EA. */
5601 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5602 if (!NT_STATUS_IS_OK(status)) {
5603 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5608 talloc_destroy(mem_ctx);
5609 if (!torture_close_connection(cli)) {
5616 static bool run_dirtest1(int dummy)
5619 static struct cli_state *cli;
5622 bool correct = True;
5624 printf("starting directory test\n");
5626 if (!torture_open_connection(&cli, 0)) {
5630 cli_sockopt(cli, sockops);
5632 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5633 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5634 cli_rmdir(cli, "\\LISTDIR");
5635 cli_mkdir(cli, "\\LISTDIR");
5637 /* Create 1000 files and 1000 directories. */
5638 for (i=0;i<1000;i++) {
5640 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5641 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5642 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5643 fprintf(stderr,"Failed to open %s\n", fname);
5646 cli_close(cli, fnum);
5648 for (i=0;i<1000;i++) {
5650 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5651 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5652 fprintf(stderr,"Failed to open %s\n", fname);
5657 /* Now ensure that doing an old list sees both files and directories. */
5659 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5660 printf("num_seen = %d\n", num_seen );
5661 /* We should see 100 files + 1000 directories + . and .. */
5662 if (num_seen != 2002)
5665 /* Ensure if we have the "must have" bits we only see the
5669 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5670 printf("num_seen = %d\n", num_seen );
5671 if (num_seen != 1002)
5675 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5676 printf("num_seen = %d\n", num_seen );
5677 if (num_seen != 1000)
5680 /* Delete everything. */
5681 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5682 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5683 cli_rmdir(cli, "\\LISTDIR");
5686 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5687 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5688 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5691 if (!torture_close_connection(cli)) {
5695 printf("finished dirtest1\n");
5700 static bool run_error_map_extract(int dummy) {
5702 static struct cli_state *c_dos;
5703 static struct cli_state *c_nt;
5708 uint32 flgs2, errnum;
5715 /* NT-Error connection */
5717 if (!(c_nt = open_nbt_connection())) {
5721 c_nt->use_spnego = False;
5723 status = cli_negprot(c_nt);
5725 if (!NT_STATUS_IS_OK(status)) {
5726 printf("%s rejected the NT-error negprot (%s)\n", host,
5732 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5734 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5738 /* DOS-Error connection */
5740 if (!(c_dos = open_nbt_connection())) {
5744 c_dos->use_spnego = False;
5745 c_dos->force_dos_errors = True;
5747 status = cli_negprot(c_dos);
5748 if (!NT_STATUS_IS_OK(status)) {
5749 printf("%s rejected the DOS-error negprot (%s)\n", host,
5751 cli_shutdown(c_dos);
5755 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5757 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5761 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5762 fstr_sprintf(user, "%X", error);
5764 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5765 password, strlen(password),
5766 password, strlen(password),
5768 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5771 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5773 /* Case #1: 32-bit NT errors */
5774 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5775 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5777 printf("/** Dos error on NT connection! (%s) */\n",
5779 nt_status = NT_STATUS(0xc0000000);
5782 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5783 password, strlen(password),
5784 password, strlen(password),
5786 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5788 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5790 /* Case #1: 32-bit NT errors */
5791 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5792 printf("/** NT error on DOS connection! (%s) */\n",
5794 errnum = errclass = 0;
5796 cli_dos_error(c_dos, &errclass, &errnum);
5799 if (NT_STATUS_V(nt_status) != error) {
5800 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5801 get_nt_error_c_code(NT_STATUS(error)),
5802 get_nt_error_c_code(nt_status));
5805 printf("\t{%s,\t%s,\t%s},\n",
5806 smb_dos_err_class(errclass),
5807 smb_dos_err_name(errclass, errnum),
5808 get_nt_error_c_code(NT_STATUS(error)));
5813 static bool run_sesssetup_bench(int dummy)
5815 static struct cli_state *c;
5816 const char *fname = "\\file.dat";
5821 if (!torture_open_connection(&c, 0)) {
5825 if (!NT_STATUS_IS_OK(cli_ntcreate(
5826 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5827 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5828 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5829 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5833 for (i=0; i<torture_numops; i++) {
5834 status = cli_session_setup(
5836 password, strlen(password),
5837 password, strlen(password),
5839 if (!NT_STATUS_IS_OK(status)) {
5840 d_printf("(%s) cli_session_setup failed: %s\n",
5841 __location__, nt_errstr(status));
5845 d_printf("\r%d ", (int)c->vuid);
5847 status = cli_ulogoff(c);
5848 if (!NT_STATUS_IS_OK(status)) {
5849 d_printf("(%s) cli_ulogoff failed: %s\n",
5850 __location__, nt_errstr(status));
5859 static bool subst_test(const char *str, const char *user, const char *domain,
5860 uid_t uid, gid_t gid, const char *expected)
5865 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5867 if (strcmp(subst, expected) != 0) {
5868 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5869 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5878 static void chain1_open_completion(struct tevent_req *req)
5882 status = cli_open_recv(req, &fnum);
5885 d_printf("cli_open_recv returned %s: %d\n",
5887 NT_STATUS_IS_OK(status) ? fnum : -1);
5890 static void chain1_write_completion(struct tevent_req *req)
5894 status = cli_write_andx_recv(req, &written);
5897 d_printf("cli_write_andx_recv returned %s: %d\n",
5899 NT_STATUS_IS_OK(status) ? (int)written : -1);
5902 static void chain1_close_completion(struct tevent_req *req)
5905 bool *done = (bool *)tevent_req_callback_data_void(req);
5907 status = cli_close_recv(req);
5912 d_printf("cli_close returned %s\n", nt_errstr(status));
5915 static bool run_chain1(int dummy)
5917 struct cli_state *cli1;
5918 struct event_context *evt = event_context_init(NULL);
5919 struct tevent_req *reqs[3], *smbreqs[3];
5921 const char *str = "foobar";
5924 printf("starting chain1 test\n");
5925 if (!torture_open_connection(&cli1, 0)) {
5929 cli_sockopt(cli1, sockops);
5931 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5932 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5933 if (reqs[0] == NULL) return false;
5934 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5937 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5938 (uint8_t *)str, 0, strlen(str)+1,
5939 smbreqs, 1, &smbreqs[1]);
5940 if (reqs[1] == NULL) return false;
5941 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5943 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5944 if (reqs[2] == NULL) return false;
5945 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5947 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5948 if (!NT_STATUS_IS_OK(status)) {
5953 event_loop_once(evt);
5956 torture_close_connection(cli1);
5960 static void chain2_sesssetup_completion(struct tevent_req *req)
5963 status = cli_session_setup_guest_recv(req);
5964 d_printf("sesssetup returned %s\n", nt_errstr(status));
5967 static void chain2_tcon_completion(struct tevent_req *req)
5969 bool *done = (bool *)tevent_req_callback_data_void(req);
5971 status = cli_tcon_andx_recv(req);
5972 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5976 static bool run_chain2(int dummy)
5978 struct cli_state *cli1;
5979 struct event_context *evt = event_context_init(NULL);
5980 struct tevent_req *reqs[2], *smbreqs[2];
5984 printf("starting chain2 test\n");
5985 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5986 port_to_use, Undefined, 0);
5987 if (!NT_STATUS_IS_OK(status)) {
5991 cli_sockopt(cli1, sockops);
5993 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5995 if (reqs[0] == NULL) return false;
5996 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5998 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5999 "?????", NULL, 0, &smbreqs[1]);
6000 if (reqs[1] == NULL) return false;
6001 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
6003 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6004 if (!NT_STATUS_IS_OK(status)) {
6009 event_loop_once(evt);
6012 torture_close_connection(cli1);
6017 struct torture_createdel_state {
6018 struct tevent_context *ev;
6019 struct cli_state *cli;
6022 static void torture_createdel_created(struct tevent_req *subreq);
6023 static void torture_createdel_closed(struct tevent_req *subreq);
6025 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6026 struct tevent_context *ev,
6027 struct cli_state *cli,
6030 struct tevent_req *req, *subreq;
6031 struct torture_createdel_state *state;
6033 req = tevent_req_create(mem_ctx, &state,
6034 struct torture_createdel_state);
6041 subreq = cli_ntcreate_send(
6042 state, ev, cli, name, 0,
6043 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6044 FILE_ATTRIBUTE_NORMAL,
6045 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6046 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6048 if (tevent_req_nomem(subreq, req)) {
6049 return tevent_req_post(req, ev);
6051 tevent_req_set_callback(subreq, torture_createdel_created, req);
6055 static void torture_createdel_created(struct tevent_req *subreq)
6057 struct tevent_req *req = tevent_req_callback_data(
6058 subreq, struct tevent_req);
6059 struct torture_createdel_state *state = tevent_req_data(
6060 req, struct torture_createdel_state);
6064 status = cli_ntcreate_recv(subreq, &fnum);
6065 TALLOC_FREE(subreq);
6066 if (!NT_STATUS_IS_OK(status)) {
6067 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6068 nt_errstr(status)));
6069 tevent_req_nterror(req, status);
6073 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6074 if (tevent_req_nomem(subreq, req)) {
6077 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6080 static void torture_createdel_closed(struct tevent_req *subreq)
6082 struct tevent_req *req = tevent_req_callback_data(
6083 subreq, struct tevent_req);
6086 status = cli_close_recv(subreq);
6087 if (!NT_STATUS_IS_OK(status)) {
6088 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6089 tevent_req_nterror(req, status);
6092 tevent_req_done(req);
6095 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6097 return tevent_req_simple_recv_ntstatus(req);
6100 struct torture_createdels_state {
6101 struct tevent_context *ev;
6102 struct cli_state *cli;
6103 const char *base_name;
6107 struct tevent_req **reqs;
6110 static void torture_createdels_done(struct tevent_req *subreq);
6112 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6113 struct tevent_context *ev,
6114 struct cli_state *cli,
6115 const char *base_name,
6119 struct tevent_req *req;
6120 struct torture_createdels_state *state;
6123 req = tevent_req_create(mem_ctx, &state,
6124 struct torture_createdels_state);
6130 state->base_name = talloc_strdup(state, base_name);
6131 if (tevent_req_nomem(state->base_name, req)) {
6132 return tevent_req_post(req, ev);
6134 state->num_files = MAX(num_parallel, num_files);
6136 state->received = 0;
6138 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6139 if (tevent_req_nomem(state->reqs, req)) {
6140 return tevent_req_post(req, ev);
6143 for (i=0; i<num_parallel; i++) {
6146 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6148 if (tevent_req_nomem(name, req)) {
6149 return tevent_req_post(req, ev);
6151 state->reqs[i] = torture_createdel_send(
6152 state->reqs, state->ev, state->cli, name);
6153 if (tevent_req_nomem(state->reqs[i], req)) {
6154 return tevent_req_post(req, ev);
6156 name = talloc_move(state->reqs[i], &name);
6157 tevent_req_set_callback(state->reqs[i],
6158 torture_createdels_done, req);
6164 static void torture_createdels_done(struct tevent_req *subreq)
6166 struct tevent_req *req = tevent_req_callback_data(
6167 subreq, struct tevent_req);
6168 struct torture_createdels_state *state = tevent_req_data(
6169 req, struct torture_createdels_state);
6170 size_t num_parallel = talloc_array_length(state->reqs);
6175 status = torture_createdel_recv(subreq);
6176 if (!NT_STATUS_IS_OK(status)){
6177 DEBUG(10, ("torture_createdel_recv returned %s\n",
6178 nt_errstr(status)));
6179 TALLOC_FREE(subreq);
6180 tevent_req_nterror(req, status);
6184 for (i=0; i<num_parallel; i++) {
6185 if (subreq == state->reqs[i]) {
6189 if (i == num_parallel) {
6190 DEBUG(10, ("received something we did not send\n"));
6191 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6194 TALLOC_FREE(state->reqs[i]);
6196 if (state->sent >= state->num_files) {
6197 tevent_req_done(req);
6201 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6203 if (tevent_req_nomem(name, req)) {
6206 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6208 if (tevent_req_nomem(state->reqs[i], req)) {
6211 name = talloc_move(state->reqs[i], &name);
6212 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6216 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6218 return tevent_req_simple_recv_ntstatus(req);
6221 struct swallow_notify_state {
6222 struct tevent_context *ev;
6223 struct cli_state *cli;
6225 uint32_t completion_filter;
6227 bool (*fn)(uint32_t action, const char *name, void *priv);
6231 static void swallow_notify_done(struct tevent_req *subreq);
6233 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6234 struct tevent_context *ev,
6235 struct cli_state *cli,
6237 uint32_t completion_filter,
6239 bool (*fn)(uint32_t action,
6244 struct tevent_req *req, *subreq;
6245 struct swallow_notify_state *state;
6247 req = tevent_req_create(mem_ctx, &state,
6248 struct swallow_notify_state);
6255 state->completion_filter = completion_filter;
6256 state->recursive = recursive;
6260 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6261 0xffff, state->completion_filter,
6263 if (tevent_req_nomem(subreq, req)) {
6264 return tevent_req_post(req, ev);
6266 tevent_req_set_callback(subreq, swallow_notify_done, req);
6270 static void swallow_notify_done(struct tevent_req *subreq)
6272 struct tevent_req *req = tevent_req_callback_data(
6273 subreq, struct tevent_req);
6274 struct swallow_notify_state *state = tevent_req_data(
6275 req, struct swallow_notify_state);
6277 uint32_t i, num_changes;
6278 struct notify_change *changes;
6280 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6281 TALLOC_FREE(subreq);
6282 if (!NT_STATUS_IS_OK(status)) {
6283 DEBUG(10, ("cli_notify_recv returned %s\n",
6284 nt_errstr(status)));
6285 tevent_req_nterror(req, status);
6289 for (i=0; i<num_changes; i++) {
6290 state->fn(changes[i].action, changes[i].name, state->priv);
6292 TALLOC_FREE(changes);
6294 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6295 0xffff, state->completion_filter,
6297 if (tevent_req_nomem(subreq, req)) {
6300 tevent_req_set_callback(subreq, swallow_notify_done, req);
6303 static bool print_notifies(uint32_t action, const char *name, void *priv)
6305 if (DEBUGLEVEL > 5) {
6306 d_printf("%d %s\n", (int)action, name);
6311 static void notify_bench_done(struct tevent_req *req)
6313 int *num_finished = (int *)tevent_req_callback_data_void(req);
6317 static bool run_notify_bench(int dummy)
6319 const char *dname = "\\notify-bench";
6320 struct tevent_context *ev;
6323 struct tevent_req *req1;
6324 struct tevent_req *req2 = NULL;
6325 int i, num_unc_names;
6326 int num_finished = 0;
6328 printf("starting notify-bench test\n");
6330 if (use_multishare_conn) {
6332 unc_list = file_lines_load(multishare_conn_fname,
6333 &num_unc_names, 0, NULL);
6334 if (!unc_list || num_unc_names <= 0) {
6335 d_printf("Failed to load unc names list from '%s'\n",
6336 multishare_conn_fname);
6339 TALLOC_FREE(unc_list);
6344 ev = tevent_context_init(talloc_tos());
6346 d_printf("tevent_context_init failed\n");
6350 for (i=0; i<num_unc_names; i++) {
6351 struct cli_state *cli;
6354 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6356 if (base_fname == NULL) {
6360 if (!torture_open_connection(&cli, i)) {
6364 status = cli_ntcreate(cli, dname, 0,
6365 MAXIMUM_ALLOWED_ACCESS,
6366 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6368 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6371 if (!NT_STATUS_IS_OK(status)) {
6372 d_printf("Could not create %s: %s\n", dname,
6377 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6378 FILE_NOTIFY_CHANGE_FILE_NAME |
6379 FILE_NOTIFY_CHANGE_DIR_NAME |
6380 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6381 FILE_NOTIFY_CHANGE_LAST_WRITE,
6382 false, print_notifies, NULL);
6384 d_printf("Could not create notify request\n");
6388 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6389 base_fname, 10, torture_numops);
6391 d_printf("Could not create createdels request\n");
6394 TALLOC_FREE(base_fname);
6396 tevent_req_set_callback(req2, notify_bench_done,
6400 while (num_finished < num_unc_names) {
6402 ret = tevent_loop_once(ev);
6404 d_printf("tevent_loop_once failed\n");
6409 if (!tevent_req_poll(req2, ev)) {
6410 d_printf("tevent_req_poll failed\n");
6413 status = torture_createdels_recv(req2);
6414 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6419 static bool run_mangle1(int dummy)
6421 struct cli_state *cli;
6422 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6426 time_t change_time, access_time, write_time;
6430 printf("starting mangle1 test\n");
6431 if (!torture_open_connection(&cli, 0)) {
6435 cli_sockopt(cli, sockops);
6437 if (!NT_STATUS_IS_OK(cli_ntcreate(
6438 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6439 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6440 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6443 cli_close(cli, fnum);
6445 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6446 if (!NT_STATUS_IS_OK(status)) {
6447 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6451 d_printf("alt_name: %s\n", alt_name);
6453 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6454 d_printf("cli_open(%s) failed: %s\n", alt_name,
6458 cli_close(cli, fnum);
6460 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6461 &write_time, &size, &mode);
6462 if (!NT_STATUS_IS_OK(status)) {
6463 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6471 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6473 size_t *to_pull = (size_t *)priv;
6474 size_t thistime = *to_pull;
6476 thistime = MIN(thistime, n);
6477 if (thistime == 0) {
6481 memset(buf, 0, thistime);
6482 *to_pull -= thistime;
6486 static bool run_windows_write(int dummy)
6488 struct cli_state *cli1;
6492 const char *fname = "\\writetest.txt";
6493 struct timeval start_time;
6497 printf("starting windows_write test\n");
6498 if (!torture_open_connection(&cli1, 0)) {
6502 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6503 printf("open failed (%s)\n", cli_errstr(cli1));
6507 cli_sockopt(cli1, sockops);
6509 start_time = timeval_current();
6511 for (i=0; i<torture_numops; i++) {
6513 off_t start = i * torture_blocksize;
6515 size_t to_pull = torture_blocksize - 1;
6517 if (cli_write(cli1, fnum, 0, &c,
6518 start + torture_blocksize - 1, 1) != 1) {
6519 printf("cli_write failed: %s\n", cli_errstr(cli1));
6523 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6524 null_source, &to_pull);
6525 if (!NT_STATUS_IS_OK(status)) {
6526 printf("cli_push returned: %s\n", nt_errstr(status));
6531 seconds = timeval_elapsed(&start_time);
6532 kbytes = (double)torture_blocksize * torture_numops;
6535 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6536 (double)seconds, (int)(kbytes/seconds));
6540 cli_close(cli1, fnum);
6541 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6542 torture_close_connection(cli1);
6546 static bool run_cli_echo(int dummy)
6548 struct cli_state *cli;
6551 printf("starting cli_echo test\n");
6552 if (!torture_open_connection(&cli, 0)) {
6555 cli_sockopt(cli, sockops);
6557 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6559 d_printf("cli_echo returned %s\n", nt_errstr(status));
6561 torture_close_connection(cli);
6562 return NT_STATUS_IS_OK(status);
6565 static bool run_uid_regression_test(int dummy)
6567 static struct cli_state *cli;
6570 bool correct = True;
6573 printf("starting uid regression test\n");
6575 if (!torture_open_connection(&cli, 0)) {
6579 cli_sockopt(cli, sockops);
6581 /* Ok - now save then logoff our current user. */
6582 old_vuid = cli->vuid;
6584 status = cli_ulogoff(cli);
6585 if (!NT_STATUS_IS_OK(status)) {
6586 d_printf("(%s) cli_ulogoff failed: %s\n",
6587 __location__, nt_errstr(status));
6592 cli->vuid = old_vuid;
6594 /* Try an operation. */
6595 status = cli_mkdir(cli, "\\uid_reg_test");
6596 if (NT_STATUS_IS_OK(status)) {
6597 d_printf("(%s) cli_mkdir succeeded\n",
6602 /* Should be bad uid. */
6603 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6604 NT_STATUS_USER_SESSION_DELETED)) {
6610 old_cnum = cli->cnum;
6612 /* Now try a SMBtdis with the invald vuid set to zero. */
6615 /* This should succeed. */
6616 status = cli_tdis(cli);
6618 if (NT_STATUS_IS_OK(status)) {
6619 d_printf("First tdis with invalid vuid should succeed.\n");
6621 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6626 cli->vuid = old_vuid;
6627 cli->cnum = old_cnum;
6629 /* This should fail. */
6630 status = cli_tdis(cli);
6631 if (NT_STATUS_IS_OK(status)) {
6632 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6636 /* Should be bad tid. */
6637 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6638 NT_STATUS_NETWORK_NAME_DELETED)) {
6644 cli_rmdir(cli, "\\uid_reg_test");
6653 static const char *illegal_chars = "*\\/?<>|\":";
6654 static char force_shortname_chars[] = " +,.[];=\177";
6656 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6657 const char *mask, void *state)
6659 struct cli_state *pcli = (struct cli_state *)state;
6661 NTSTATUS status = NT_STATUS_OK;
6663 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6665 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6666 return NT_STATUS_OK;
6668 if (finfo->mode & aDIR) {
6669 status = cli_rmdir(pcli, fname);
6670 if (!NT_STATUS_IS_OK(status)) {
6671 printf("del_fn: failed to rmdir %s\n,", fname );
6674 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6675 if (!NT_STATUS_IS_OK(status)) {
6676 printf("del_fn: failed to unlink %s\n,", fname );
6688 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6689 const char *name, void *state)
6691 struct sn_state *s = (struct sn_state *)state;
6695 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6696 i, finfo->name, finfo->short_name);
6699 if (strchr(force_shortname_chars, i)) {
6700 if (!finfo->short_name[0]) {
6701 /* Shortname not created when it should be. */
6702 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6703 __location__, finfo->name, i);
6706 } else if (finfo->short_name[0]){
6707 /* Shortname created when it should not be. */
6708 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6709 __location__, finfo->short_name, finfo->name);
6713 return NT_STATUS_OK;
6716 static bool run_shortname_test(int dummy)
6718 static struct cli_state *cli;
6719 bool correct = True;
6724 printf("starting shortname test\n");
6726 if (!torture_open_connection(&cli, 0)) {
6730 cli_sockopt(cli, sockops);
6732 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6733 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6734 cli_rmdir(cli, "\\shortname");
6736 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6737 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6738 __location__, cli_errstr(cli));
6743 strlcpy(fname, "\\shortname\\", sizeof(fname));
6744 strlcat(fname, "test .txt", sizeof(fname));
6748 for (i = 32; i < 128; i++) {
6750 uint16_t fnum = (uint16_t)-1;
6754 if (strchr(illegal_chars, i)) {
6759 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6760 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6761 if (!NT_STATUS_IS_OK(status)) {
6762 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6763 __location__, fname, cli_errstr(cli));
6767 cli_close(cli, fnum);
6770 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6772 if (s.matched != 1) {
6773 d_printf("(%s) failed to list %s: %s\n",
6774 __location__, fname, cli_errstr(cli));
6778 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6779 d_printf("(%s) failed to delete %s: %s\n",
6780 __location__, fname, cli_errstr(cli));
6793 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6794 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6795 cli_rmdir(cli, "\\shortname");
6796 torture_close_connection(cli);
6800 static void pagedsearch_cb(struct tevent_req *req)
6803 struct tldap_message *msg;
6806 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6807 if (rc != TLDAP_SUCCESS) {
6808 d_printf("tldap_search_paged_recv failed: %s\n",
6809 tldap_err2string(rc));
6812 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6816 if (!tldap_entry_dn(msg, &dn)) {
6817 d_printf("tldap_entry_dn failed\n");
6820 d_printf("%s\n", dn);
6824 static bool run_tldap(int dummy)
6826 struct tldap_context *ld;
6829 struct sockaddr_storage addr;
6830 struct tevent_context *ev;
6831 struct tevent_req *req;
6835 if (!resolve_name(host, &addr, 0, false)) {
6836 d_printf("could not find host %s\n", host);
6839 status = open_socket_out(&addr, 389, 9999, &fd);
6840 if (!NT_STATUS_IS_OK(status)) {
6841 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6845 ld = tldap_context_create(talloc_tos(), fd);
6848 d_printf("tldap_context_create failed\n");
6852 rc = tldap_fetch_rootdse(ld);
6853 if (rc != TLDAP_SUCCESS) {
6854 d_printf("tldap_fetch_rootdse failed: %s\n",
6855 tldap_errstr(talloc_tos(), ld, rc));
6859 basedn = tldap_talloc_single_attribute(
6860 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6861 if (basedn == NULL) {
6862 d_printf("no defaultNamingContext\n");
6865 d_printf("defaultNamingContext: %s\n", basedn);
6867 ev = tevent_context_init(talloc_tos());
6869 d_printf("tevent_context_init failed\n");
6873 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6874 TLDAP_SCOPE_SUB, "(objectclass=*)",
6876 NULL, 0, NULL, 0, 0, 0, 0, 5);
6878 d_printf("tldap_search_paged_send failed\n");
6881 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6883 tevent_req_poll(req, ev);
6887 /* test search filters against rootDSE */
6888 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6889 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6891 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6892 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6893 talloc_tos(), NULL, NULL);
6894 if (rc != TLDAP_SUCCESS) {
6895 d_printf("tldap_search with complex filter failed: %s\n",
6896 tldap_errstr(talloc_tos(), ld, rc));
6904 /* Torture test to ensure no regression of :
6905 https://bugzilla.samba.org/show_bug.cgi?id=7084
6908 static bool run_dir_createtime(int dummy)
6910 struct cli_state *cli;
6911 const char *dname = "\\testdir";
6912 const char *fname = "\\testdir\\testfile";
6914 struct timespec create_time;
6915 struct timespec create_time1;
6919 if (!torture_open_connection(&cli, 0)) {
6923 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6924 cli_rmdir(cli, dname);
6926 status = cli_mkdir(cli, dname);
6927 if (!NT_STATUS_IS_OK(status)) {
6928 printf("mkdir failed: %s\n", nt_errstr(status));
6932 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6934 if (!NT_STATUS_IS_OK(status)) {
6935 printf("cli_qpathinfo2 returned %s\n",
6940 /* Sleep 3 seconds, then create a file. */
6943 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6945 if (!NT_STATUS_IS_OK(status)) {
6946 printf("cli_open failed: %s\n", nt_errstr(status));
6950 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6952 if (!NT_STATUS_IS_OK(status)) {
6953 printf("cli_qpathinfo2 (2) returned %s\n",
6958 if (timespec_compare(&create_time1, &create_time)) {
6959 printf("run_dir_createtime: create time was updated (error)\n");
6961 printf("run_dir_createtime: create time was not updated (correct)\n");
6967 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6968 cli_rmdir(cli, dname);
6969 if (!torture_close_connection(cli)) {
6976 static bool run_streamerror(int dummy)
6978 struct cli_state *cli;
6979 const char *dname = "\\testdir";
6980 const char *streamname =
6981 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6983 time_t change_time, access_time, write_time;
6985 uint16_t mode, fnum;
6988 if (!torture_open_connection(&cli, 0)) {
6992 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6993 cli_rmdir(cli, dname);
6995 status = cli_mkdir(cli, dname);
6996 if (!NT_STATUS_IS_OK(status)) {
6997 printf("mkdir failed: %s\n", nt_errstr(status));
7001 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
7003 status = cli_nt_error(cli);
7005 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7006 printf("pathinfo returned %s, expected "
7007 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7012 status = cli_ntcreate(cli, streamname, 0x16,
7013 FILE_READ_DATA|FILE_READ_EA|
7014 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7015 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7016 FILE_OPEN, 0, 0, &fnum);
7018 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7019 printf("ntcreate returned %s, expected "
7020 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7026 cli_rmdir(cli, dname);
7030 static bool run_local_substitute(int dummy)
7034 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7035 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7036 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7037 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7038 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7039 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7040 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7041 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7043 /* Different captialization rules in sub_basic... */
7045 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7051 static bool run_local_base64(int dummy)
7056 for (i=1; i<2000; i++) {
7057 DATA_BLOB blob1, blob2;
7060 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7062 generate_random_buffer(blob1.data, blob1.length);
7064 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7066 d_fprintf(stderr, "base64_encode_data_blob failed "
7067 "for %d bytes\n", i);
7070 blob2 = base64_decode_data_blob(b64);
7073 if (data_blob_cmp(&blob1, &blob2)) {
7074 d_fprintf(stderr, "data_blob_cmp failed for %d "
7078 TALLOC_FREE(blob1.data);
7079 data_blob_free(&blob2);
7084 static bool run_local_gencache(int dummy)
7090 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7091 d_printf("%s: gencache_set() failed\n", __location__);
7095 if (!gencache_get("foo", NULL, NULL)) {
7096 d_printf("%s: gencache_get() failed\n", __location__);
7100 if (!gencache_get("foo", &val, &tm)) {
7101 d_printf("%s: gencache_get() failed\n", __location__);
7105 if (strcmp(val, "bar") != 0) {
7106 d_printf("%s: gencache_get() returned %s, expected %s\n",
7107 __location__, val, "bar");
7114 if (!gencache_del("foo")) {
7115 d_printf("%s: gencache_del() failed\n", __location__);
7118 if (gencache_del("foo")) {
7119 d_printf("%s: second gencache_del() succeeded\n",
7124 if (gencache_get("foo", &val, &tm)) {
7125 d_printf("%s: gencache_get() on deleted entry "
7126 "succeeded\n", __location__);
7130 blob = data_blob_string_const_null("bar");
7131 tm = time(NULL) + 60;
7133 if (!gencache_set_data_blob("foo", &blob, tm)) {
7134 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7138 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7139 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7143 if (strcmp((const char *)blob.data, "bar") != 0) {
7144 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7145 __location__, (const char *)blob.data, "bar");
7146 data_blob_free(&blob);
7150 data_blob_free(&blob);
7152 if (!gencache_del("foo")) {
7153 d_printf("%s: gencache_del() failed\n", __location__);
7156 if (gencache_del("foo")) {
7157 d_printf("%s: second gencache_del() succeeded\n",
7162 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7163 d_printf("%s: gencache_get_data_blob() on deleted entry "
7164 "succeeded\n", __location__);
7171 static bool rbt_testval(struct db_context *db, const char *key,
7174 struct db_record *rec;
7175 TDB_DATA data = string_tdb_data(value);
7179 rec = db->fetch_locked(db, db, string_tdb_data(key));
7181 d_fprintf(stderr, "fetch_locked failed\n");
7184 status = rec->store(rec, data, 0);
7185 if (!NT_STATUS_IS_OK(status)) {
7186 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7191 rec = db->fetch_locked(db, db, string_tdb_data(key));
7193 d_fprintf(stderr, "second fetch_locked failed\n");
7196 if ((rec->value.dsize != data.dsize)
7197 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7198 d_fprintf(stderr, "Got wrong data back\n");
7208 static bool run_local_rbtree(int dummy)
7210 struct db_context *db;
7214 db = db_open_rbt(NULL);
7217 d_fprintf(stderr, "db_open_rbt failed\n");
7221 for (i=0; i<1000; i++) {
7224 if (asprintf(&key, "key%ld", random()) == -1) {
7227 if (asprintf(&value, "value%ld", random()) == -1) {
7232 if (!rbt_testval(db, key, value)) {
7239 if (asprintf(&value, "value%ld", random()) == -1) {
7244 if (!rbt_testval(db, key, value)) {
7261 struct talloc_dict_test {
7265 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7267 int *count = (int *)priv;
7272 static bool run_local_talloc_dict(int dummy)
7274 struct talloc_dict *dict;
7275 struct talloc_dict_test *t;
7278 dict = talloc_dict_init(talloc_tos());
7283 t = talloc(talloc_tos(), struct talloc_dict_test);
7290 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7295 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7308 static bool run_local_string_to_sid(int dummy) {
7311 if (string_to_sid(&sid, "S--1-5-32-545")) {
7312 printf("allowing S--1-5-32-545\n");
7315 if (string_to_sid(&sid, "S-1-5-32-+545")) {
7316 printf("allowing S-1-5-32-+545\n");
7319 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")) {
7320 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7323 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7324 printf("allowing S-1-5-32-545-abc\n");
7327 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7328 printf("could not parse S-1-5-32-545\n");
7331 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7332 printf("mis-parsed S-1-5-32-545 as %s\n",
7333 sid_string_tos(&sid));
7339 static bool run_local_binary_to_sid(int dummy) {
7340 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7341 static const char good_binary_sid[] = {
7342 0x1, /* revision number */
7344 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7345 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7346 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7347 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7348 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7349 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7350 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7351 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7352 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7353 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7354 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7355 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7356 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7357 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7358 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7359 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7362 static const char long_binary_sid[] = {
7363 0x1, /* revision number */
7365 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7366 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7367 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7368 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7369 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7370 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7371 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7372 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7373 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7374 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7375 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7376 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7377 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7378 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7379 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7380 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7381 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7382 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7383 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7386 static const char long_binary_sid2[] = {
7387 0x1, /* revision number */
7389 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7390 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7391 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7392 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7393 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7394 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7395 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7396 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7397 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7398 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7399 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7400 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7401 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7402 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7403 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7404 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7405 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7406 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7407 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7408 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7409 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7410 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7411 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7412 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7413 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7414 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7415 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7416 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7417 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7418 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7419 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7420 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7421 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7424 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7427 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7430 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7436 /* Split a path name into filename and stream name components. Canonicalise
7437 * such that an implicit $DATA token is always explicit.
7439 * The "specification" of this function can be found in the
7440 * run_local_stream_name() function in torture.c, I've tried those
7441 * combinations against a W2k3 server.
7444 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7445 char **pbase, char **pstream)
7448 char *stream = NULL;
7449 char *sname; /* stream name */
7450 const char *stype; /* stream type */
7452 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7454 sname = strchr_m(fname, ':');
7456 if (lp_posix_pathnames() || (sname == NULL)) {
7457 if (pbase != NULL) {
7458 base = talloc_strdup(mem_ctx, fname);
7459 NT_STATUS_HAVE_NO_MEMORY(base);
7464 if (pbase != NULL) {
7465 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7466 NT_STATUS_HAVE_NO_MEMORY(base);
7471 stype = strchr_m(sname, ':');
7473 if (stype == NULL) {
7474 sname = talloc_strdup(mem_ctx, sname);
7478 if (StrCaseCmp(stype, ":$DATA") != 0) {
7480 * If there is an explicit stream type, so far we only
7481 * allow $DATA. Is there anything else allowed? -- vl
7483 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7485 return NT_STATUS_OBJECT_NAME_INVALID;
7487 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7491 if (sname == NULL) {
7493 return NT_STATUS_NO_MEMORY;
7496 if (sname[0] == '\0') {
7498 * no stream name, so no stream
7503 if (pstream != NULL) {
7504 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7505 if (stream == NULL) {
7508 return NT_STATUS_NO_MEMORY;
7511 * upper-case the type field
7513 strupper_m(strchr_m(stream, ':')+1);
7517 if (pbase != NULL) {
7520 if (pstream != NULL) {
7523 return NT_STATUS_OK;
7526 static bool test_stream_name(const char *fname, const char *expected_base,
7527 const char *expected_stream,
7528 NTSTATUS expected_status)
7532 char *stream = NULL;
7534 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7535 if (!NT_STATUS_EQUAL(status, expected_status)) {
7539 if (!NT_STATUS_IS_OK(status)) {
7543 if (base == NULL) goto error;
7545 if (strcmp(expected_base, base) != 0) goto error;
7547 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7548 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7550 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7554 TALLOC_FREE(stream);
7558 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7559 fname, expected_base ? expected_base : "<NULL>",
7560 expected_stream ? expected_stream : "<NULL>",
7561 nt_errstr(expected_status));
7562 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7563 base ? base : "<NULL>", stream ? stream : "<NULL>",
7566 TALLOC_FREE(stream);
7570 static bool run_local_stream_name(int dummy)
7574 ret &= test_stream_name(
7575 "bla", "bla", NULL, NT_STATUS_OK);
7576 ret &= test_stream_name(
7577 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7578 ret &= test_stream_name(
7579 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7580 ret &= test_stream_name(
7581 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7582 ret &= test_stream_name(
7583 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7584 ret &= test_stream_name(
7585 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7586 ret &= test_stream_name(
7587 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7588 ret &= test_stream_name(
7589 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7594 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7596 if (a.length != b.length) {
7597 printf("a.length=%d != b.length=%d\n",
7598 (int)a.length, (int)b.length);
7601 if (memcmp(a.data, b.data, a.length) != 0) {
7602 printf("a.data and b.data differ\n");
7608 static bool run_local_memcache(int dummy)
7610 struct memcache *cache;
7612 DATA_BLOB d1, d2, d3;
7613 DATA_BLOB v1, v2, v3;
7615 TALLOC_CTX *mem_ctx;
7617 size_t size1, size2;
7620 cache = memcache_init(NULL, 100);
7622 if (cache == NULL) {
7623 printf("memcache_init failed\n");
7627 d1 = data_blob_const("d1", 2);
7628 d2 = data_blob_const("d2", 2);
7629 d3 = data_blob_const("d3", 2);
7631 k1 = data_blob_const("d1", 2);
7632 k2 = data_blob_const("d2", 2);
7634 memcache_add(cache, STAT_CACHE, k1, d1);
7635 memcache_add(cache, GETWD_CACHE, k2, d2);
7637 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7638 printf("could not find k1\n");
7641 if (!data_blob_equal(d1, v1)) {
7645 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7646 printf("could not find k2\n");
7649 if (!data_blob_equal(d2, v2)) {
7653 memcache_add(cache, STAT_CACHE, k1, d3);
7655 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7656 printf("could not find replaced k1\n");
7659 if (!data_blob_equal(d3, v3)) {
7663 memcache_add(cache, GETWD_CACHE, k1, d1);
7665 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7666 printf("Did find k2, should have been purged\n");
7672 cache = memcache_init(NULL, 0);
7674 mem_ctx = talloc_init("foo");
7676 str1 = talloc_strdup(mem_ctx, "string1");
7677 str2 = talloc_strdup(mem_ctx, "string2");
7679 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7680 data_blob_string_const("torture"), &str1);
7681 size1 = talloc_total_size(cache);
7683 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7684 data_blob_string_const("torture"), &str2);
7685 size2 = talloc_total_size(cache);
7687 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7689 if (size2 > size1) {
7690 printf("memcache leaks memory!\n");
7700 static void wbclient_done(struct tevent_req *req)
7703 struct winbindd_response *wb_resp;
7704 int *i = (int *)tevent_req_callback_data_void(req);
7706 wbc_err = wb_trans_recv(req, req, &wb_resp);
7709 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7712 static bool run_local_wbclient(int dummy)
7714 struct event_context *ev;
7715 struct wb_context **wb_ctx;
7716 struct winbindd_request wb_req;
7717 bool result = false;
7720 BlockSignals(True, SIGPIPE);
7722 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7727 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7728 if (wb_ctx == NULL) {
7732 ZERO_STRUCT(wb_req);
7733 wb_req.cmd = WINBINDD_PING;
7735 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7737 for (i=0; i<nprocs; i++) {
7738 wb_ctx[i] = wb_context_init(ev, NULL);
7739 if (wb_ctx[i] == NULL) {
7742 for (j=0; j<torture_numops; j++) {
7743 struct tevent_req *req;
7744 req = wb_trans_send(ev, ev, wb_ctx[i],
7745 (j % 2) == 0, &wb_req);
7749 tevent_req_set_callback(req, wbclient_done, &i);
7755 while (i < nprocs * torture_numops) {
7756 event_loop_once(ev);
7765 static void getaddrinfo_finished(struct tevent_req *req)
7767 char *name = (char *)tevent_req_callback_data_void(req);
7768 struct addrinfo *ainfo;
7771 res = getaddrinfo_recv(req, &ainfo);
7773 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7776 d_printf("gai(%s) succeeded\n", name);
7777 freeaddrinfo(ainfo);
7780 static bool run_getaddrinfo_send(int dummy)
7782 TALLOC_CTX *frame = talloc_stackframe();
7783 struct fncall_context *ctx;
7784 struct tevent_context *ev;
7785 bool result = false;
7786 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7787 "www.slashdot.org", "heise.de" };
7788 struct tevent_req *reqs[4];
7791 ev = event_context_init(frame);
7796 ctx = fncall_context_init(frame, 4);
7798 for (i=0; i<ARRAY_SIZE(names); i++) {
7799 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7801 if (reqs[i] == NULL) {
7804 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7808 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7809 tevent_loop_once(ev);
7818 static bool dbtrans_inc(struct db_context *db)
7820 struct db_record *rec;
7825 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7827 printf(__location__ "fetch_lock failed\n");
7831 if (rec->value.dsize != sizeof(uint32_t)) {
7832 printf(__location__ "value.dsize = %d\n",
7833 (int)rec->value.dsize);
7837 val = (uint32_t *)rec->value.dptr;
7840 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7843 if (!NT_STATUS_IS_OK(status)) {
7844 printf(__location__ "store failed: %s\n",
7855 static bool run_local_dbtrans(int dummy)
7857 struct db_context *db;
7858 struct db_record *rec;
7863 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7864 O_RDWR|O_CREAT, 0600);
7866 printf("Could not open transtest.db\n");
7870 res = db->transaction_start(db);
7872 printf(__location__ "transaction_start failed\n");
7876 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7878 printf(__location__ "fetch_lock failed\n");
7882 if (rec->value.dptr == NULL) {
7884 status = rec->store(
7885 rec, make_tdb_data((uint8_t *)&initial,
7888 if (!NT_STATUS_IS_OK(status)) {
7889 printf(__location__ "store returned %s\n",
7897 res = db->transaction_commit(db);
7899 printf(__location__ "transaction_commit failed\n");
7907 res = db->transaction_start(db);
7909 printf(__location__ "transaction_start failed\n");
7913 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7914 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7918 for (i=0; i<10; i++) {
7919 if (!dbtrans_inc(db)) {
7924 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7925 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7929 if (val2 != val + 10) {
7930 printf(__location__ "val=%d, val2=%d\n",
7931 (int)val, (int)val2);
7935 printf("val2=%d\r", val2);
7937 res = db->transaction_commit(db);
7939 printf(__location__ "transaction_commit failed\n");
7949 * Just a dummy test to be run under a debugger. There's no real way
7950 * to inspect the tevent_select specific function from outside of
7954 static bool run_local_tevent_select(int dummy)
7956 struct tevent_context *ev;
7957 struct tevent_fd *fd1, *fd2;
7958 bool result = false;
7960 ev = tevent_context_init_byname(NULL, "select");
7962 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7966 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7968 d_fprintf(stderr, "tevent_add_fd failed\n");
7971 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7973 d_fprintf(stderr, "tevent_add_fd failed\n");
7978 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7980 d_fprintf(stderr, "tevent_add_fd failed\n");
7990 static double create_procs(bool (*fn)(int), bool *result)
7993 volatile pid_t *child_status;
7994 volatile bool *child_status_out;
7997 struct timeval start;
8001 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
8002 if (!child_status) {
8003 printf("Failed to setup shared memory\n");
8007 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8008 if (!child_status_out) {
8009 printf("Failed to setup result status shared memory\n");
8013 for (i = 0; i < nprocs; i++) {
8014 child_status[i] = 0;
8015 child_status_out[i] = True;
8018 start = timeval_current();
8020 for (i=0;i<nprocs;i++) {
8023 pid_t mypid = getpid();
8024 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8026 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8029 if (torture_open_connection(¤t_cli, i)) break;
8031 printf("pid %d failed to start\n", (int)getpid());
8037 child_status[i] = getpid();
8039 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8041 child_status_out[i] = fn(i);
8048 for (i=0;i<nprocs;i++) {
8049 if (child_status[i]) synccount++;
8051 if (synccount == nprocs) break;
8053 } while (timeval_elapsed(&start) < 30);
8055 if (synccount != nprocs) {
8056 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8058 return timeval_elapsed(&start);
8061 /* start the client load */
8062 start = timeval_current();
8064 for (i=0;i<nprocs;i++) {
8065 child_status[i] = 0;
8068 printf("%d clients started\n", nprocs);
8070 for (i=0;i<nprocs;i++) {
8071 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8076 for (i=0;i<nprocs;i++) {
8077 if (!child_status_out[i]) {
8081 return timeval_elapsed(&start);
8084 #define FLAG_MULTIPROC 1
8091 {"FDPASS", run_fdpasstest, 0},
8092 {"LOCK1", run_locktest1, 0},
8093 {"LOCK2", run_locktest2, 0},
8094 {"LOCK3", run_locktest3, 0},
8095 {"LOCK4", run_locktest4, 0},
8096 {"LOCK5", run_locktest5, 0},
8097 {"LOCK6", run_locktest6, 0},
8098 {"LOCK7", run_locktest7, 0},
8099 {"LOCK8", run_locktest8, 0},
8100 {"LOCK9", run_locktest9, 0},
8101 {"UNLINK", run_unlinktest, 0},
8102 {"BROWSE", run_browsetest, 0},
8103 {"ATTR", run_attrtest, 0},
8104 {"TRANS2", run_trans2test, 0},
8105 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8106 {"TORTURE",run_torture, FLAG_MULTIPROC},
8107 {"RANDOMIPC", run_randomipc, 0},
8108 {"NEGNOWAIT", run_negprot_nowait, 0},
8109 {"NBENCH", run_nbench, 0},
8110 {"NBENCH2", run_nbench2, 0},
8111 {"OPLOCK1", run_oplock1, 0},
8112 {"OPLOCK2", run_oplock2, 0},
8113 {"OPLOCK3", run_oplock3, 0},
8114 {"OPLOCK4", run_oplock4, 0},
8115 {"DIR", run_dirtest, 0},
8116 {"DIR1", run_dirtest1, 0},
8117 {"DIR-CREATETIME", run_dir_createtime, 0},
8118 {"DENY1", torture_denytest1, 0},
8119 {"DENY2", torture_denytest2, 0},
8120 {"TCON", run_tcon_test, 0},
8121 {"TCONDEV", run_tcon_devtype_test, 0},
8122 {"RW1", run_readwritetest, 0},
8123 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8124 {"RW3", run_readwritelarge, 0},
8125 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8126 {"OPEN", run_opentest, 0},
8127 {"POSIX", run_simple_posix_open_test, 0},
8128 {"POSIX-APPEND", run_posix_append, 0},
8129 {"ASYNC-ECHO", run_async_echo, 0},
8130 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8131 { "SHORTNAME-TEST", run_shortname_test, 0},
8132 { "ADDRCHANGE", run_addrchange, 0},
8134 {"OPENATTR", run_openattrtest, 0},
8136 {"XCOPY", run_xcopy, 0},
8137 {"RENAME", run_rename, 0},
8138 {"DELETE", run_deletetest, 0},
8139 {"DELETE-LN", run_deletetest_ln, 0},
8140 {"PROPERTIES", run_properties, 0},
8141 {"MANGLE", torture_mangle, 0},
8142 {"MANGLE1", run_mangle1, 0},
8143 {"W2K", run_w2ktest, 0},
8144 {"TRANS2SCAN", torture_trans2_scan, 0},
8145 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8146 {"UTABLE", torture_utable, 0},
8147 {"CASETABLE", torture_casetable, 0},
8148 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8149 {"PIPE_NUMBER", run_pipe_number, 0},
8150 {"TCON2", run_tcon2_test, 0},
8151 {"IOCTL", torture_ioctl_test, 0},
8152 {"CHKPATH", torture_chkpath_test, 0},
8153 {"FDSESS", run_fdsesstest, 0},
8154 { "EATEST", run_eatest, 0},
8155 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8156 { "CHAIN1", run_chain1, 0},
8157 { "CHAIN2", run_chain2, 0},
8158 { "WINDOWS-WRITE", run_windows_write, 0},
8159 { "CLI_ECHO", run_cli_echo, 0},
8160 { "GETADDRINFO", run_getaddrinfo_send, 0},
8161 { "TLDAP", run_tldap },
8162 { "STREAMERROR", run_streamerror },
8163 { "NOTIFY-BENCH", run_notify_bench },
8164 { "BAD-NBT-SESSION", run_bad_nbt_session },
8165 { "SMB-ANY-CONNECT", run_smb_any_connect },
8166 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8167 { "LOCAL-GENCACHE", run_local_gencache, 0},
8168 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8169 { "LOCAL-BASE64", run_local_base64, 0},
8170 { "LOCAL-RBTREE", run_local_rbtree, 0},
8171 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8172 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8173 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8174 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8175 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8176 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8177 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8182 /****************************************************************************
8183 run a specified test or "ALL"
8184 ****************************************************************************/
8185 static bool run_test(const char *name)
8192 if (strequal(name,"ALL")) {
8193 for (i=0;torture_ops[i].name;i++) {
8194 run_test(torture_ops[i].name);
8199 for (i=0;torture_ops[i].name;i++) {
8200 fstr_sprintf(randomfname, "\\XX%x",
8201 (unsigned)random());
8203 if (strequal(name, torture_ops[i].name)) {
8205 printf("Running %s\n", name);
8206 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8207 t = create_procs(torture_ops[i].fn, &result);
8210 printf("TEST %s FAILED!\n", name);
8213 struct timeval start;
8214 start = timeval_current();
8215 if (!torture_ops[i].fn(0)) {
8217 printf("TEST %s FAILED!\n", name);
8219 t = timeval_elapsed(&start);
8221 printf("%s took %g secs\n\n", name, t);
8226 printf("Did not find a test named %s\n", name);
8234 static void usage(void)
8238 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8239 printf("Please use samba4 torture.\n\n");
8241 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8243 printf("\t-d debuglevel\n");
8244 printf("\t-U user%%pass\n");
8245 printf("\t-k use kerberos\n");
8246 printf("\t-N numprocs\n");
8247 printf("\t-n my_netbios_name\n");
8248 printf("\t-W workgroup\n");
8249 printf("\t-o num_operations\n");
8250 printf("\t-O socket_options\n");
8251 printf("\t-m maximum protocol\n");
8252 printf("\t-L use oplocks\n");
8253 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8254 printf("\t-A showall\n");
8255 printf("\t-p port\n");
8256 printf("\t-s seed\n");
8257 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8260 printf("tests are:");
8261 for (i=0;torture_ops[i].name;i++) {
8262 printf(" %s", torture_ops[i].name);
8266 printf("default test is ALL\n");
8271 /****************************************************************************
8273 ****************************************************************************/
8274 int main(int argc,char *argv[])
8280 bool correct = True;
8281 TALLOC_CTX *frame = talloc_stackframe();
8282 int seed = time(NULL);
8284 #ifdef HAVE_SETBUFFER
8285 setbuffer(stdout, NULL, 0);
8288 setup_logging("smbtorture", DEBUG_STDOUT);
8292 if (is_default_dyn_CONFIGFILE()) {
8293 if(getenv("SMB_CONF_PATH")) {
8294 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8297 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8304 for(p = argv[1]; *p; p++)
8308 if (strncmp(argv[1], "//", 2)) {
8312 fstrcpy(host, &argv[1][2]);
8313 p = strchr_m(&host[2],'/');
8318 fstrcpy(share, p+1);
8320 fstrcpy(myname, get_myname(talloc_tos()));
8322 fprintf(stderr, "Failed to get my hostname.\n");
8326 if (*username == 0 && getenv("LOGNAME")) {
8327 fstrcpy(username,getenv("LOGNAME"));
8333 fstrcpy(workgroup, lp_workgroup());
8335 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8338 port_to_use = atoi(optarg);
8341 seed = atoi(optarg);
8344 fstrcpy(workgroup,optarg);
8347 max_protocol = interpret_protocol(optarg, max_protocol);
8350 nprocs = atoi(optarg);
8353 torture_numops = atoi(optarg);
8356 lp_set_cmdline("log level", optarg);
8365 local_path = optarg;
8368 torture_showall = True;
8371 fstrcpy(myname, optarg);
8374 client_txt = optarg;
8381 use_kerberos = True;
8383 d_printf("No kerberos support compiled in\n");
8389 fstrcpy(username,optarg);
8390 p = strchr_m(username,'%');
8393 fstrcpy(password, p+1);
8398 fstrcpy(multishare_conn_fname, optarg);
8399 use_multishare_conn = True;
8402 torture_blocksize = atoi(optarg);
8405 printf("Unknown option %c (%d)\n", (char)opt, opt);
8410 d_printf("using seed %d\n", seed);
8414 if(use_kerberos && !gotuser) gotpass = True;
8417 p = getpass("Password:");
8419 fstrcpy(password, p);
8424 printf("host=%s share=%s user=%s myname=%s\n",
8425 host, share, username, myname);
8427 if (argc == optind) {
8428 correct = run_test("ALL");
8430 for (i=optind;i<argc;i++) {
8431 if (!run_test(argv[i])) {