2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1997-1998
5 Copyright (C) Jeremy Allison 2009
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/security.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
29 #include "nsswitch/winbind_client.h"
31 #include "talloc_dict.h"
32 #include "async_smb.h"
33 #include "libsmb/clirap.h"
38 static fstring host, workgroup, share, password, username, myname;
39 static int max_protocol = PROTOCOL_NT1;
40 static const char *sockops="TCP_NODELAY";
42 static int port_to_use=0;
43 int torture_numops=100;
44 int torture_blocksize=1024*1024;
45 static int procnum; /* records process count number when forking */
46 static struct cli_state *current_cli;
47 static fstring randomfname;
48 static bool use_oplocks;
49 static bool use_level_II_oplocks;
50 static const char *client_txt = "client_oplocks.txt";
51 static bool use_kerberos;
52 static fstring multishare_conn_fname;
53 static bool use_multishare_conn = False;
54 static bool do_encrypt;
55 static const char *local_path = NULL;
56 static int signing_state = Undefined;
58 bool torture_showall = False;
60 static double create_procs(bool (*fn)(int), bool *result);
63 /* return a pointer to a anonymous shared memory segment of size "size"
64 which will persist across fork() but will disappear when all processes
67 The memory is not zeroed
69 This function uses system5 shared memory. It takes advantage of a property
70 that the memory is not destroyed if it is attached when the id is removed
72 void *shm_setup(int size)
78 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
80 printf("can't get shared memory\n");
83 shm_unlink("private");
84 if (ftruncate(shmid, size) == -1) {
85 printf("can't set shared memory size\n");
88 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
89 if (ret == MAP_FAILED) {
90 printf("can't map shared memory\n");
94 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
96 printf("can't get shared memory\n");
99 ret = (void *)shmat(shmid, 0, 0);
100 if (!ret || ret == (void *)-1) {
101 printf("can't attach to shared memory\n");
104 /* the following releases the ipc, but note that this process
105 and all its children will still have access to the memory, its
106 just that the shmid is no longer valid for other shm calls. This
107 means we don't leave behind lots of shm segments after we exit
109 See Stevens "advanced programming in unix env" for details
111 shmctl(shmid, IPC_RMID, 0);
117 /********************************************************************
118 Ensure a connection is encrypted.
119 ********************************************************************/
121 static bool force_cli_encryption(struct cli_state *c,
122 const char *sharename)
125 uint32 caplow, caphigh;
128 if (!SERVER_HAS_UNIX_CIFS(c)) {
129 d_printf("Encryption required and "
130 "server that doesn't support "
131 "UNIX extensions - failing connect\n");
135 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
137 if (!NT_STATUS_IS_OK(status)) {
138 d_printf("Encryption required and "
139 "can't get UNIX CIFS extensions "
140 "version from server: %s\n", nt_errstr(status));
144 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
145 d_printf("Encryption required and "
146 "share %s doesn't support "
147 "encryption.\n", sharename);
151 if (c->use_kerberos) {
152 status = cli_gss_smb_encryption_start(c);
154 status = cli_raw_ntlm_smb_encryption_start(c,
160 if (!NT_STATUS_IS_OK(status)) {
161 d_printf("Encryption required and "
162 "setup failed with error %s.\n",
171 static struct cli_state *open_nbt_connection(void)
173 struct nmb_name called, calling;
174 struct sockaddr_storage ss;
178 make_nmb_name(&calling, myname, 0x0);
179 make_nmb_name(&called , host, 0x20);
183 if (!(c = cli_initialise_ex(signing_state))) {
184 printf("Failed initialize cli_struct to connect with %s\n", host);
188 c->port = port_to_use;
190 status = cli_connect(c, host, &ss);
191 if (!NT_STATUS_IS_OK(status)) {
192 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
196 c->use_kerberos = use_kerberos;
198 c->timeout = 120000; /* set a really long timeout (2 minutes) */
199 if (use_oplocks) c->use_oplocks = True;
200 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
202 if (!cli_session_request(c, &calling, &called)) {
204 * Well, that failed, try *SMBSERVER ...
205 * However, we must reconnect as well ...
207 status = cli_connect(c, host, &ss);
208 if (!NT_STATUS_IS_OK(status)) {
209 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
213 make_nmb_name(&called, "*SMBSERVER", 0x20);
214 if (!cli_session_request(c, &calling, &called)) {
215 printf("%s rejected the session\n",host);
216 printf("We tried with a called name of %s & %s\n",
226 /****************************************************************************
227 Send a corrupt session request. See rfc1002.txt 4.3 and 4.3.2.
228 ****************************************************************************/
230 static bool cli_bad_session_request(struct cli_state *cli,
231 struct nmb_name *calling, struct nmb_name *called)
238 memcpy(&(cli->calling), calling, sizeof(*calling));
239 memcpy(&(cli->called ), called , sizeof(*called ));
241 /* put in the destination name */
243 tmp = name_mangle(talloc_tos(), cli->called.name,
244 cli->called.name_type);
250 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
252 memcpy(p, tmp, namelen);
257 /* Deliberately corrupt the name len (first byte) */
262 tmp = name_mangle(talloc_tos(), cli->calling.name,
263 cli->calling.name_type);
269 namelen = name_len((unsigned char *)tmp, talloc_get_size(tmp));
271 memcpy(p, tmp, namelen);
275 /* Deliberately corrupt the name len (first byte) */
278 /* send a session request (RFC 1002) */
279 /* setup the packet length
280 * Remove four bytes from the length count, since the length
281 * field in the NBT Session Service header counts the number
282 * of bytes which follow. The cli_send_smb() function knows
283 * about this and accounts for those four bytes.
287 _smb_setlen(cli->outbuf,len);
288 SCVAL(cli->outbuf,0,0x81);
291 DEBUG(5,("Sent session request\n"));
293 if (!cli_receive_smb(cli))
296 if (CVAL(cli->inbuf,0) != 0x82) {
297 /* This is the wrong place to put the error... JRA. */
298 cli->rap_error = CVAL(cli->inbuf,4);
304 static struct cli_state *open_bad_nbt_connection(void)
306 struct nmb_name called, calling;
307 struct sockaddr_storage ss;
311 make_nmb_name(&calling, myname, 0x0);
312 make_nmb_name(&called , host, 0x20);
316 if (!(c = cli_initialise_ex(signing_state))) {
317 printf("Failed initialize cli_struct to connect with %s\n", host);
323 status = cli_connect(c, host, &ss);
324 if (!NT_STATUS_IS_OK(status)) {
325 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
329 c->timeout = 4000; /* set a short timeout (4 seconds) */
331 if (!cli_bad_session_request(c, &calling, &called)) {
332 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
340 /* Insert a NULL at the first separator of the given path and return a pointer
341 * to the remainder of the string.
344 terminate_path_at_separator(char * path)
352 if ((p = strchr_m(path, '/'))) {
357 if ((p = strchr_m(path, '\\'))) {
367 parse a //server/share type UNC name
369 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
370 char **hostname, char **sharename)
374 *hostname = *sharename = NULL;
376 if (strncmp(unc_name, "\\\\", 2) &&
377 strncmp(unc_name, "//", 2)) {
381 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
382 p = terminate_path_at_separator(*hostname);
385 *sharename = talloc_strdup(mem_ctx, p);
386 terminate_path_at_separator(*sharename);
389 if (*hostname && *sharename) {
393 TALLOC_FREE(*hostname);
394 TALLOC_FREE(*sharename);
398 static bool torture_open_connection_share(struct cli_state **c,
399 const char *hostname,
400 const char *sharename)
406 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
408 flags |= CLI_FULL_CONNECTION_OPLOCKS;
409 if (use_level_II_oplocks)
410 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
412 status = cli_full_connection(c, myname,
413 hostname, NULL, port_to_use,
416 password, flags, signing_state);
417 if (!NT_STATUS_IS_OK(status)) {
418 printf("failed to open share connection: //%s/%s port:%d - %s\n",
419 hostname, sharename, port_to_use, nt_errstr(status));
423 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
426 return force_cli_encryption(*c,
432 bool torture_open_connection(struct cli_state **c, int conn_index)
434 char **unc_list = NULL;
435 int num_unc_names = 0;
438 if (use_multishare_conn==True) {
440 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
441 if (!unc_list || num_unc_names <= 0) {
442 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
446 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
448 printf("Failed to parse UNC name %s\n",
449 unc_list[conn_index % num_unc_names]);
450 TALLOC_FREE(unc_list);
454 result = torture_open_connection_share(c, h, s);
456 /* h, s were copied earlier */
457 TALLOC_FREE(unc_list);
461 return torture_open_connection_share(c, host, share);
464 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
466 uint16 old_vuid = cli->vuid;
467 fstring old_user_name;
468 size_t passlen = strlen(password);
472 fstrcpy(old_user_name, cli->user_name);
474 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
478 *new_vuid = cli->vuid;
479 cli->vuid = old_vuid;
480 status = cli_set_username(cli, old_user_name);
481 if (!NT_STATUS_IS_OK(status)) {
488 bool torture_close_connection(struct cli_state *c)
493 status = cli_tdis(c);
494 if (!NT_STATUS_IS_OK(status)) {
495 printf("tdis failed (%s)\n", nt_errstr(status));
505 /* check if the server produced the expected error code */
506 static bool check_error(int line, struct cli_state *c,
507 uint8 eclass, uint32 ecode, NTSTATUS nterr)
509 if (cli_is_dos_error(c)) {
513 /* Check DOS error */
515 cli_dos_error(c, &cclass, &num);
517 if (eclass != cclass || ecode != num) {
518 printf("unexpected error code class=%d code=%d\n",
519 (int)cclass, (int)num);
520 printf(" expected %d/%d %s (line=%d)\n",
521 (int)eclass, (int)ecode, nt_errstr(nterr), line);
530 status = cli_nt_error(c);
532 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
533 printf("unexpected error code %s\n", nt_errstr(status));
534 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
543 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
545 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
546 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
552 static bool rw_torture(struct cli_state *c)
554 const char *lockfname = "\\torture.lck";
558 pid_t pid2, pid = getpid();
564 memset(buf, '\0', sizeof(buf));
566 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
568 if (!NT_STATUS_IS_OK(status)) {
569 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
571 if (!NT_STATUS_IS_OK(status)) {
572 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
576 for (i=0;i<torture_numops;i++) {
577 unsigned n = (unsigned)sys_random()%10;
579 printf("%d\r", i); fflush(stdout);
581 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
583 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
587 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
588 printf("open failed (%s)\n", cli_errstr(c));
593 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
594 printf("write failed (%s)\n", cli_errstr(c));
599 if (cli_write(c, fnum, 0, (char *)buf,
600 sizeof(pid)+(j*sizeof(buf)),
601 sizeof(buf)) != sizeof(buf)) {
602 printf("write failed (%s)\n", cli_errstr(c));
609 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
610 printf("read failed (%s)\n", cli_errstr(c));
615 printf("data corruption!\n");
619 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
620 printf("close failed (%s)\n", cli_errstr(c));
624 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
625 printf("unlink failed (%s)\n", cli_errstr(c));
629 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
630 printf("unlock failed (%s)\n", cli_errstr(c));
636 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
643 static bool run_torture(int dummy)
645 struct cli_state *cli;
650 cli_sockopt(cli, sockops);
652 ret = rw_torture(cli);
654 if (!torture_close_connection(cli)) {
661 static bool rw_torture3(struct cli_state *c, char *lockfname)
663 uint16_t fnum = (uint16_t)-1;
668 unsigned countprev = 0;
671 NTSTATUS status = NT_STATUS_OK;
674 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
676 SIVAL(buf, i, sys_random());
681 if (!NT_STATUS_IS_OK(cli_unlink(c, lockfname, aSYSTEM | aHIDDEN))) {
682 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c));
685 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
686 DENY_NONE, &fnum))) {
687 printf("first open read/write of %s failed (%s)\n",
688 lockfname, cli_errstr(c));
694 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
696 status = cli_open(c, lockfname, O_RDONLY,
698 if (!NT_STATUS_IS_OK(status)) {
703 if (!NT_STATUS_IS_OK(status)) {
704 printf("second open read-only of %s failed (%s)\n",
705 lockfname, cli_errstr(c));
711 for (count = 0; count < sizeof(buf); count += sent)
713 if (count >= countprev) {
714 printf("%d %8d\r", i, count);
717 countprev += (sizeof(buf) / 20);
722 sent = ((unsigned)sys_random()%(20))+ 1;
723 if (sent > sizeof(buf) - count)
725 sent = sizeof(buf) - count;
728 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
729 printf("write failed (%s)\n", cli_errstr(c));
735 sent = cli_read(c, fnum, buf_rd+count, count,
739 printf("read failed offset:%d size:%ld (%s)\n",
740 count, (unsigned long)sizeof(buf)-count,
747 if (memcmp(buf_rd+count, buf+count, sent) != 0)
749 printf("read/write compare failed\n");
750 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
759 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
760 printf("close failed (%s)\n", cli_errstr(c));
767 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
769 const char *lockfname = "\\torture2.lck";
778 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
779 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
782 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
783 DENY_NONE, &fnum1))) {
784 printf("first open read/write of %s failed (%s)\n",
785 lockfname, cli_errstr(c1));
788 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
789 DENY_NONE, &fnum2))) {
790 printf("second open read-only of %s failed (%s)\n",
791 lockfname, cli_errstr(c2));
792 cli_close(c1, fnum1);
796 for (i=0;i<torture_numops;i++)
798 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
800 printf("%d\r", i); fflush(stdout);
803 generate_random_buffer((unsigned char *)buf, buf_size);
805 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
806 printf("write failed (%s)\n", cli_errstr(c1));
811 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
812 printf("read failed (%s)\n", cli_errstr(c2));
813 printf("read %d, expected %ld\n", (int)bytes_read,
814 (unsigned long)buf_size);
819 if (memcmp(buf_rd, buf, buf_size) != 0)
821 printf("read/write compare failed\n");
827 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
828 printf("close failed (%s)\n", cli_errstr(c2));
831 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
832 printf("close failed (%s)\n", cli_errstr(c1));
836 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
837 printf("unlink failed (%s)\n", cli_errstr(c1));
844 static bool run_readwritetest(int dummy)
846 struct cli_state *cli1, *cli2;
847 bool test1, test2 = False;
849 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
852 cli_sockopt(cli1, sockops);
853 cli_sockopt(cli2, sockops);
855 printf("starting readwritetest\n");
857 test1 = rw_torture2(cli1, cli2);
858 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
861 test2 = rw_torture2(cli1, cli1);
862 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
865 if (!torture_close_connection(cli1)) {
869 if (!torture_close_connection(cli2)) {
873 return (test1 && test2);
876 static bool run_readwritemulti(int dummy)
878 struct cli_state *cli;
883 cli_sockopt(cli, sockops);
885 printf("run_readwritemulti: fname %s\n", randomfname);
886 test = rw_torture3(cli, randomfname);
888 if (!torture_close_connection(cli)) {
895 static bool run_readwritelarge_internal(int max_xmit_k)
897 static struct cli_state *cli1;
899 const char *lockfname = "\\large.dat";
904 if (!torture_open_connection(&cli1, 0)) {
907 cli_sockopt(cli1, sockops);
908 memset(buf,'\0',sizeof(buf));
910 cli1->max_xmit = max_xmit_k*1024;
912 if (signing_state == Required) {
913 /* Horrible cheat to force
914 multiple signed outstanding
915 packets against a Samba server.
917 cli1->is_samba = false;
920 printf("starting readwritelarge_internal\n");
922 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
924 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
925 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
929 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
931 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
932 cli1, fnum1, NULL, &fsize, NULL, NULL,
933 NULL, NULL, NULL))) {
934 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
938 if (fsize == sizeof(buf))
939 printf("readwritelarge_internal test 1 succeeded (size = %lx)\n",
940 (unsigned long)fsize);
942 printf("readwritelarge_internal test 1 failed (size = %lx)\n",
943 (unsigned long)fsize);
947 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
948 printf("close failed (%s)\n", cli_errstr(cli1));
952 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
953 printf("unlink failed (%s)\n", cli_errstr(cli1));
957 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
958 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
962 cli1->max_xmit = 4*1024;
964 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf), NULL);
966 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
967 cli1, fnum1, NULL, &fsize, NULL, NULL,
968 NULL, NULL, NULL))) {
969 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
973 if (fsize == sizeof(buf))
974 printf("readwritelarge_internal test 2 succeeded (size = %lx)\n",
975 (unsigned long)fsize);
977 printf("readwritelarge_internal test 2 failed (size = %lx)\n",
978 (unsigned long)fsize);
983 /* ToDo - set allocation. JRA */
984 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
985 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
988 if (!cli_qfileinfo_basic(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL,
990 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
994 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
997 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
998 printf("close failed (%s)\n", cli_errstr(cli1));
1002 if (!torture_close_connection(cli1)) {
1008 static bool run_readwritelarge(int dummy)
1010 return run_readwritelarge_internal(128);
1013 static bool run_readwritelarge_signtest(int dummy)
1016 signing_state = Required;
1017 ret = run_readwritelarge_internal(2);
1018 signing_state = Undefined;
1025 #define ival(s) strtol(s, NULL, 0)
1027 /* run a test that simulates an approximate netbench client load */
1028 static bool run_netbench(int client)
1030 struct cli_state *cli;
1035 const char *params[20];
1036 bool correct = True;
1042 cli_sockopt(cli, sockops);
1046 slprintf(cname,sizeof(cname)-1, "client%d", client);
1048 f = fopen(client_txt, "r");
1055 while (fgets(line, sizeof(line)-1, f)) {
1059 line[strlen(line)-1] = 0;
1061 /* printf("[%d] %s\n", line_count, line); */
1063 all_string_sub(line,"client1", cname, sizeof(line));
1065 /* parse the command parameters */
1066 params[0] = strtok_r(line, " ", &saveptr);
1068 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
1072 if (i < 2) continue;
1074 if (!strncmp(params[0],"SMB", 3)) {
1075 printf("ERROR: You are using a dbench 1 load file\n");
1079 if (!strcmp(params[0],"NTCreateX")) {
1080 nb_createx(params[1], ival(params[2]), ival(params[3]),
1082 } else if (!strcmp(params[0],"Close")) {
1083 nb_close(ival(params[1]));
1084 } else if (!strcmp(params[0],"Rename")) {
1085 nb_rename(params[1], params[2]);
1086 } else if (!strcmp(params[0],"Unlink")) {
1087 nb_unlink(params[1]);
1088 } else if (!strcmp(params[0],"Deltree")) {
1089 nb_deltree(params[1]);
1090 } else if (!strcmp(params[0],"Rmdir")) {
1091 nb_rmdir(params[1]);
1092 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
1093 nb_qpathinfo(params[1]);
1094 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
1095 nb_qfileinfo(ival(params[1]));
1096 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
1097 nb_qfsinfo(ival(params[1]));
1098 } else if (!strcmp(params[0],"FIND_FIRST")) {
1099 nb_findfirst(params[1]);
1100 } else if (!strcmp(params[0],"WriteX")) {
1101 nb_writex(ival(params[1]),
1102 ival(params[2]), ival(params[3]), ival(params[4]));
1103 } else if (!strcmp(params[0],"ReadX")) {
1104 nb_readx(ival(params[1]),
1105 ival(params[2]), ival(params[3]), ival(params[4]));
1106 } else if (!strcmp(params[0],"Flush")) {
1107 nb_flush(ival(params[1]));
1109 printf("Unknown operation %s\n", params[0]);
1117 if (!torture_close_connection(cli)) {
1125 /* run a test that simulates an approximate netbench client load */
1126 static bool run_nbench(int dummy)
1129 bool correct = True;
1135 signal(SIGALRM, nb_alarm);
1137 t = create_procs(run_netbench, &correct);
1140 printf("\nThroughput %g MB/sec\n",
1141 1.0e-6 * nbio_total() / t);
1147 This test checks for two things:
1149 1) correct support for retaining locks over a close (ie. the server
1150 must not use posix semantics)
1151 2) support for lock timeouts
1153 static bool run_locktest1(int dummy)
1155 struct cli_state *cli1, *cli2;
1156 const char *fname = "\\lockt1.lck";
1157 uint16_t fnum1, fnum2, fnum3;
1159 unsigned lock_timeout;
1161 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1164 cli_sockopt(cli1, sockops);
1165 cli_sockopt(cli2, sockops);
1167 printf("starting locktest1\n");
1169 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1171 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1172 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1175 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1176 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1179 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1180 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1184 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1185 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1190 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1191 printf("lock2 succeeded! This is a locking bug\n");
1194 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1195 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1199 lock_timeout = (1 + (random() % 20));
1200 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1202 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1203 printf("lock3 succeeded! This is a locking bug\n");
1206 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1207 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1211 if (ABS(t2 - t1) < lock_timeout-1) {
1212 printf("error: This server appears not to support timed lock requests\n");
1215 printf("server slept for %u seconds for a %u second timeout\n",
1216 (unsigned int)(t2-t1), lock_timeout);
1218 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1219 printf("close1 failed (%s)\n", cli_errstr(cli1));
1223 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1224 printf("lock4 succeeded! This is a locking bug\n");
1227 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1228 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1231 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1232 printf("close2 failed (%s)\n", cli_errstr(cli1));
1236 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1237 printf("close3 failed (%s)\n", cli_errstr(cli2));
1241 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1242 printf("unlink failed (%s)\n", cli_errstr(cli1));
1247 if (!torture_close_connection(cli1)) {
1251 if (!torture_close_connection(cli2)) {
1255 printf("Passed locktest1\n");
1260 this checks to see if a secondary tconx can use open files from an
1263 static bool run_tcon_test(int dummy)
1265 static struct cli_state *cli;
1266 const char *fname = "\\tcontest.tmp";
1268 uint16 cnum1, cnum2, cnum3;
1269 uint16 vuid1, vuid2;
1274 memset(buf, '\0', sizeof(buf));
1276 if (!torture_open_connection(&cli, 0)) {
1279 cli_sockopt(cli, sockops);
1281 printf("starting tcontest\n");
1283 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1285 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1286 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1293 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1294 printf("initial write failed (%s)", cli_errstr(cli));
1298 status = cli_tcon_andx(cli, share, "?????",
1299 password, strlen(password)+1);
1300 if (!NT_STATUS_IS_OK(status)) {
1301 printf("%s refused 2nd tree connect (%s)\n", host,
1308 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1309 vuid2 = cli->vuid + 1;
1311 /* try a write with the wrong tid */
1314 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1315 printf("* server allows write with wrong TID\n");
1318 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1322 /* try a write with an invalid tid */
1325 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1326 printf("* server allows write with invalid TID\n");
1329 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1332 /* try a write with an invalid vuid */
1336 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1337 printf("* server allows write with invalid VUID\n");
1340 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1346 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1347 printf("close failed (%s)\n", cli_errstr(cli));
1353 status = cli_tdis(cli);
1354 if (!NT_STATUS_IS_OK(status)) {
1355 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1361 if (!torture_close_connection(cli)) {
1370 checks for old style tcon support
1372 static bool run_tcon2_test(int dummy)
1374 static struct cli_state *cli;
1375 uint16 cnum, max_xmit;
1379 if (!torture_open_connection(&cli, 0)) {
1382 cli_sockopt(cli, sockops);
1384 printf("starting tcon2 test\n");
1386 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1390 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1392 if (!NT_STATUS_IS_OK(status)) {
1393 printf("tcon2 failed : %s\n", nt_errstr(status));
1395 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1396 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1399 if (!torture_close_connection(cli)) {
1403 printf("Passed tcon2 test\n");
1407 static bool tcon_devtest(struct cli_state *cli,
1408 const char *myshare, const char *devtype,
1409 const char *return_devtype,
1410 NTSTATUS expected_error)
1415 status = cli_tcon_andx(cli, myshare, devtype,
1416 password, strlen(password)+1);
1418 if (NT_STATUS_IS_OK(expected_error)) {
1419 if (NT_STATUS_IS_OK(status)) {
1420 if (strcmp(cli->dev, return_devtype) == 0) {
1423 printf("tconX to share %s with type %s "
1424 "succeeded but returned the wrong "
1425 "device type (got [%s] but should have got [%s])\n",
1426 myshare, devtype, cli->dev, return_devtype);
1430 printf("tconX to share %s with type %s "
1431 "should have succeeded but failed\n",
1437 if (NT_STATUS_IS_OK(status)) {
1438 printf("tconx to share %s with type %s "
1439 "should have failed but succeeded\n",
1443 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1447 printf("Returned unexpected error\n");
1456 checks for correct tconX support
1458 static bool run_tcon_devtype_test(int dummy)
1460 static struct cli_state *cli1 = NULL;
1465 status = cli_full_connection(&cli1, myname,
1466 host, NULL, port_to_use,
1468 username, workgroup,
1469 password, flags, signing_state);
1471 if (!NT_STATUS_IS_OK(status)) {
1472 printf("could not open connection\n");
1476 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1479 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1482 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1485 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1488 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1491 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1494 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1497 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1500 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1503 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1509 printf("Passed tcondevtest\n");
1516 This test checks that
1518 1) the server supports multiple locking contexts on the one SMB
1519 connection, distinguished by PID.
1521 2) the server correctly fails overlapping locks made by the same PID (this
1522 goes against POSIX behaviour, which is why it is tricky to implement)
1524 3) the server denies unlock requests by an incorrect client PID
1526 static bool run_locktest2(int dummy)
1528 static struct cli_state *cli;
1529 const char *fname = "\\lockt2.lck";
1530 uint16_t fnum1, fnum2, fnum3;
1531 bool correct = True;
1533 if (!torture_open_connection(&cli, 0)) {
1537 cli_sockopt(cli, sockops);
1539 printf("starting locktest2\n");
1541 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1545 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1546 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1550 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1551 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1557 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1558 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1564 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1565 printf("lock1 failed (%s)\n", cli_errstr(cli));
1569 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1570 printf("WRITE lock1 succeeded! This is a locking bug\n");
1573 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1574 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1577 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1578 printf("WRITE lock2 succeeded! This is a locking bug\n");
1581 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1582 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1585 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1586 printf("READ lock2 succeeded! This is a locking bug\n");
1589 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1590 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1593 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1594 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1597 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1598 printf("unlock at 100 succeeded! This is a locking bug\n");
1602 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1603 printf("unlock1 succeeded! This is a locking bug\n");
1606 if (!check_error(__LINE__, cli,
1608 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1611 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1612 printf("unlock2 succeeded! This is a locking bug\n");
1615 if (!check_error(__LINE__, cli,
1617 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1620 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1621 printf("lock3 succeeded! This is a locking bug\n");
1624 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1629 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1630 printf("close1 failed (%s)\n", cli_errstr(cli));
1634 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1635 printf("close2 failed (%s)\n", cli_errstr(cli));
1639 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1640 printf("close3 failed (%s)\n", cli_errstr(cli));
1644 if (!torture_close_connection(cli)) {
1648 printf("locktest2 finished\n");
1655 This test checks that
1657 1) the server supports the full offset range in lock requests
1659 static bool run_locktest3(int dummy)
1661 static struct cli_state *cli1, *cli2;
1662 const char *fname = "\\lockt3.lck";
1663 uint16_t fnum1, fnum2;
1666 bool correct = True;
1668 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1670 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1673 cli_sockopt(cli1, sockops);
1674 cli_sockopt(cli2, sockops);
1676 printf("starting locktest3\n");
1678 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1680 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1681 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1684 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1685 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1689 for (offset=i=0;i<torture_numops;i++) {
1691 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1692 printf("lock1 %d failed (%s)\n",
1698 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1699 printf("lock2 %d failed (%s)\n",
1706 for (offset=i=0;i<torture_numops;i++) {
1709 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1710 printf("error: lock1 %d succeeded!\n", i);
1714 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1715 printf("error: lock2 %d succeeded!\n", i);
1719 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1720 printf("error: lock3 %d succeeded!\n", i);
1724 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1725 printf("error: lock4 %d succeeded!\n", i);
1730 for (offset=i=0;i<torture_numops;i++) {
1733 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1734 printf("unlock1 %d failed (%s)\n",
1740 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1741 printf("unlock2 %d failed (%s)\n",
1748 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1749 printf("close1 failed (%s)\n", cli_errstr(cli1));
1753 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1754 printf("close2 failed (%s)\n", cli_errstr(cli2));
1758 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1759 printf("unlink failed (%s)\n", cli_errstr(cli1));
1763 if (!torture_close_connection(cli1)) {
1767 if (!torture_close_connection(cli2)) {
1771 printf("finished locktest3\n");
1776 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1777 printf("** "); correct = False; \
1781 looks at overlapping locks
1783 static bool run_locktest4(int dummy)
1785 static struct cli_state *cli1, *cli2;
1786 const char *fname = "\\lockt4.lck";
1787 uint16_t fnum1, fnum2, f;
1790 bool correct = True;
1792 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1796 cli_sockopt(cli1, sockops);
1797 cli_sockopt(cli2, sockops);
1799 printf("starting locktest4\n");
1801 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1803 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1804 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1806 memset(buf, 0, sizeof(buf));
1808 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1809 printf("Failed to create file\n");
1814 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1815 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1816 EXPECTED(ret, False);
1817 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1819 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1820 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1821 EXPECTED(ret, True);
1822 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1824 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1825 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1826 EXPECTED(ret, False);
1827 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1829 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1830 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1831 EXPECTED(ret, True);
1832 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1834 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1835 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1836 EXPECTED(ret, False);
1837 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1839 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1840 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1841 EXPECTED(ret, True);
1842 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1844 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1845 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1846 EXPECTED(ret, True);
1847 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1849 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1850 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1851 EXPECTED(ret, False);
1852 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1854 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1855 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1856 EXPECTED(ret, False);
1857 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1859 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1860 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1861 EXPECTED(ret, True);
1862 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1864 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1865 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1866 EXPECTED(ret, False);
1867 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1869 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1870 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1871 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1872 EXPECTED(ret, False);
1873 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1876 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1877 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1878 EXPECTED(ret, False);
1879 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1881 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1882 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1883 EXPECTED(ret, False);
1884 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1887 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1888 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1889 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1890 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1891 EXPECTED(ret, True);
1892 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1895 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1896 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1897 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1898 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1899 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1900 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1901 EXPECTED(ret, True);
1902 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1904 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1905 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1906 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1907 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1908 EXPECTED(ret, True);
1909 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1911 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1912 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1913 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1914 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1915 EXPECTED(ret, True);
1916 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1918 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1919 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1920 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1921 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1922 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1923 EXPECTED(ret, True);
1924 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1926 cli_close(cli1, fnum1);
1927 cli_close(cli2, fnum2);
1928 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1929 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1930 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1931 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1932 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1933 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1934 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1936 cli_close(cli1, fnum1);
1937 EXPECTED(ret, True);
1938 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1941 cli_close(cli1, fnum1);
1942 cli_close(cli2, fnum2);
1943 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1944 torture_close_connection(cli1);
1945 torture_close_connection(cli2);
1947 printf("finished locktest4\n");
1952 looks at lock upgrade/downgrade.
1954 static bool run_locktest5(int dummy)
1956 static struct cli_state *cli1, *cli2;
1957 const char *fname = "\\lockt5.lck";
1958 uint16_t fnum1, fnum2, fnum3;
1961 bool correct = True;
1963 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1967 cli_sockopt(cli1, sockops);
1968 cli_sockopt(cli2, sockops);
1970 printf("starting locktest5\n");
1972 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1974 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1975 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1976 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1978 memset(buf, 0, sizeof(buf));
1980 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1981 printf("Failed to create file\n");
1986 /* Check for NT bug... */
1987 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1988 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1989 cli_close(cli1, fnum1);
1990 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1991 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1992 EXPECTED(ret, True);
1993 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1994 cli_close(cli1, fnum1);
1995 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1996 cli_unlock(cli1, fnum3, 0, 1);
1998 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1999 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
2000 EXPECTED(ret, True);
2001 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
2003 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2004 EXPECTED(ret, False);
2006 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
2008 /* Unlock the process 2 lock. */
2009 cli_unlock(cli2, fnum2, 0, 4);
2011 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
2012 EXPECTED(ret, False);
2014 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
2016 /* Unlock the process 1 fnum3 lock. */
2017 cli_unlock(cli1, fnum3, 0, 4);
2019 /* Stack 2 more locks here. */
2020 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
2021 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
2023 EXPECTED(ret, True);
2024 printf("the same process %s stack read locks\n", ret?"can":"cannot");
2026 /* Unlock the first process lock, then check this was the WRITE lock that was
2029 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2030 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
2032 EXPECTED(ret, True);
2033 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
2035 /* Unlock the process 2 lock. */
2036 cli_unlock(cli2, fnum2, 0, 4);
2038 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
2040 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
2041 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
2042 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2044 EXPECTED(ret, True);
2045 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
2047 /* Ensure the next unlock fails. */
2048 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
2049 EXPECTED(ret, False);
2050 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
2052 /* Ensure connection 2 can get a write lock. */
2053 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
2054 EXPECTED(ret, True);
2056 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
2060 cli_close(cli1, fnum1);
2061 cli_close(cli2, fnum2);
2062 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2063 if (!torture_close_connection(cli1)) {
2066 if (!torture_close_connection(cli2)) {
2070 printf("finished locktest5\n");
2076 tries the unusual lockingX locktype bits
2078 static bool run_locktest6(int dummy)
2080 static struct cli_state *cli;
2081 const char *fname[1] = { "\\lock6.txt" };
2086 if (!torture_open_connection(&cli, 0)) {
2090 cli_sockopt(cli, sockops);
2092 printf("starting locktest6\n");
2095 printf("Testing %s\n", fname[i]);
2097 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2099 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
2100 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
2101 cli_close(cli, fnum);
2102 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
2104 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
2105 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
2106 cli_close(cli, fnum);
2107 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
2109 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
2112 torture_close_connection(cli);
2114 printf("finished locktest6\n");
2118 static bool run_locktest7(int dummy)
2120 struct cli_state *cli1;
2121 const char *fname = "\\lockt7.lck";
2124 bool correct = False;
2126 if (!torture_open_connection(&cli1, 0)) {
2130 cli_sockopt(cli1, sockops);
2132 printf("starting locktest7\n");
2134 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2136 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
2138 memset(buf, 0, sizeof(buf));
2140 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
2141 printf("Failed to create file\n");
2145 cli_setpid(cli1, 1);
2147 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2148 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2151 printf("pid1 successfully locked range 130:4 for READ\n");
2154 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2155 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2158 printf("pid1 successfully read the range 130:4\n");
2161 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2162 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2163 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2164 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2168 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2172 cli_setpid(cli1, 2);
2174 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2175 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2177 printf("pid2 successfully read the range 130:4\n");
2180 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2181 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2182 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2183 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2187 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2191 cli_setpid(cli1, 1);
2192 cli_unlock(cli1, fnum1, 130, 4);
2194 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2195 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2198 printf("pid1 successfully locked range 130:4 for WRITE\n");
2201 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2202 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2205 printf("pid1 successfully read the range 130:4\n");
2208 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2209 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2212 printf("pid1 successfully wrote to the range 130:4\n");
2215 cli_setpid(cli1, 2);
2217 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2218 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2219 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2220 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2224 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2228 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2229 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2230 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2231 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2235 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2239 cli_unlock(cli1, fnum1, 130, 0);
2243 cli_close(cli1, fnum1);
2244 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2245 torture_close_connection(cli1);
2247 printf("finished locktest7\n");
2252 * This demonstrates a problem with our use of GPFS share modes: A file
2253 * descriptor sitting in the pending close queue holding a GPFS share mode
2254 * blocks opening a file another time. Happens with Word 2007 temp files.
2255 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2256 * open is denied with NT_STATUS_SHARING_VIOLATION.
2259 static bool run_locktest8(int dummy)
2261 struct cli_state *cli1;
2262 const char *fname = "\\lockt8.lck";
2263 uint16_t fnum1, fnum2;
2265 bool correct = False;
2268 if (!torture_open_connection(&cli1, 0)) {
2272 cli_sockopt(cli1, sockops);
2274 printf("starting locktest8\n");
2276 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2278 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2280 if (!NT_STATUS_IS_OK(status)) {
2281 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2285 memset(buf, 0, sizeof(buf));
2287 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2288 if (!NT_STATUS_IS_OK(status)) {
2289 d_fprintf(stderr, "cli_open second time returned %s\n",
2294 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2295 printf("Unable to apply read lock on range 1:1, error was "
2296 "%s\n", cli_errstr(cli1));
2300 status = cli_close(cli1, fnum1);
2301 if (!NT_STATUS_IS_OK(status)) {
2302 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2306 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2307 if (!NT_STATUS_IS_OK(status)) {
2308 d_fprintf(stderr, "cli_open third time returned %s\n",
2316 cli_close(cli1, fnum1);
2317 cli_close(cli1, fnum2);
2318 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2319 torture_close_connection(cli1);
2321 printf("finished locktest8\n");
2326 * This test is designed to be run in conjunction with
2327 * external NFS or POSIX locks taken in the filesystem.
2328 * It checks that the smbd server will block until the
2329 * lock is released and then acquire it. JRA.
2332 static bool got_alarm;
2333 static int alarm_fd;
2335 static void alarm_handler(int dummy)
2340 static void alarm_handler_parent(int dummy)
2345 static void do_local_lock(int read_fd, int write_fd)
2350 const char *local_pathname = NULL;
2353 local_pathname = talloc_asprintf(talloc_tos(),
2354 "%s/lockt9.lck", local_path);
2355 if (!local_pathname) {
2356 printf("child: alloc fail\n");
2360 unlink(local_pathname);
2361 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2363 printf("child: open of %s failed %s.\n",
2364 local_pathname, strerror(errno));
2368 /* Now take a fcntl lock. */
2369 lock.l_type = F_WRLCK;
2370 lock.l_whence = SEEK_SET;
2373 lock.l_pid = getpid();
2375 ret = fcntl(fd,F_SETLK,&lock);
2377 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2378 local_pathname, strerror(errno));
2381 printf("child: got lock 0:4 on file %s.\n",
2386 CatchSignal(SIGALRM, alarm_handler);
2388 /* Signal the parent. */
2389 if (write(write_fd, &c, 1) != 1) {
2390 printf("child: start signal fail %s.\n",
2397 /* Wait for the parent to be ready. */
2398 if (read(read_fd, &c, 1) != 1) {
2399 printf("child: reply signal fail %s.\n",
2407 printf("child: released lock 0:4 on file %s.\n",
2413 static bool run_locktest9(int dummy)
2415 struct cli_state *cli1;
2416 const char *fname = "\\lockt9.lck";
2418 bool correct = False;
2419 int pipe_in[2], pipe_out[2];
2423 struct timeval start;
2427 printf("starting locktest9\n");
2429 if (local_path == NULL) {
2430 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2434 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2439 if (child_pid == -1) {
2443 if (child_pid == 0) {
2445 do_local_lock(pipe_out[0], pipe_in[1]);
2455 ret = read(pipe_in[0], &c, 1);
2457 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2462 if (!torture_open_connection(&cli1, 0)) {
2466 cli_sockopt(cli1, sockops);
2468 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2470 if (!NT_STATUS_IS_OK(status)) {
2471 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2475 /* Ensure the child has the lock. */
2476 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2477 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2480 d_printf("Child has the lock.\n");
2483 /* Tell the child to wait 5 seconds then exit. */
2484 ret = write(pipe_out[1], &c, 1);
2486 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2491 /* Wait 20 seconds for the lock. */
2492 alarm_fd = cli1->fd;
2493 CatchSignal(SIGALRM, alarm_handler_parent);
2496 start = timeval_current();
2498 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2499 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2500 "%s\n", cli_errstr(cli1));
2505 seconds = timeval_elapsed(&start);
2507 printf("Parent got the lock after %.2f seconds.\n",
2510 status = cli_close(cli1, fnum);
2511 if (!NT_STATUS_IS_OK(status)) {
2512 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2519 cli_close(cli1, fnum);
2520 torture_close_connection(cli1);
2524 printf("finished locktest9\n");
2529 test whether fnums and tids open on one VC are available on another (a major
2532 static bool run_fdpasstest(int dummy)
2534 struct cli_state *cli1, *cli2;
2535 const char *fname = "\\fdpass.tst";
2539 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2542 cli_sockopt(cli1, sockops);
2543 cli_sockopt(cli2, sockops);
2545 printf("starting fdpasstest\n");
2547 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2549 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2550 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2554 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2555 printf("write failed (%s)\n", cli_errstr(cli1));
2559 cli2->vuid = cli1->vuid;
2560 cli2->cnum = cli1->cnum;
2561 cli2->pid = cli1->pid;
2563 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2564 printf("read succeeded! nasty security hole [%s]\n",
2569 cli_close(cli1, fnum1);
2570 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2572 torture_close_connection(cli1);
2573 torture_close_connection(cli2);
2575 printf("finished fdpasstest\n");
2579 static bool run_fdsesstest(int dummy)
2581 struct cli_state *cli;
2586 const char *fname = "\\fdsess.tst";
2587 const char *fname1 = "\\fdsess1.tst";
2593 if (!torture_open_connection(&cli, 0))
2595 cli_sockopt(cli, sockops);
2597 if (!torture_cli_session_setup2(cli, &new_vuid))
2600 saved_cnum = cli->cnum;
2601 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2603 new_cnum = cli->cnum;
2604 cli->cnum = saved_cnum;
2606 printf("starting fdsesstest\n");
2608 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2609 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2611 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2612 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2616 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2617 printf("write failed (%s)\n", cli_errstr(cli));
2621 saved_vuid = cli->vuid;
2622 cli->vuid = new_vuid;
2624 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2625 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2629 /* Try to open a file with different vuid, samba cnum. */
2630 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2631 printf("create with different vuid, same cnum succeeded.\n");
2632 cli_close(cli, fnum2);
2633 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2635 printf("create with different vuid, same cnum failed.\n");
2636 printf("This will cause problems with service clients.\n");
2640 cli->vuid = saved_vuid;
2642 /* Try with same vuid, different cnum. */
2643 cli->cnum = new_cnum;
2645 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2646 printf("read succeeded with different cnum![%s]\n",
2651 cli->cnum = saved_cnum;
2652 cli_close(cli, fnum1);
2653 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2655 torture_close_connection(cli);
2657 printf("finished fdsesstest\n");
2662 This test checks that
2664 1) the server does not allow an unlink on a file that is open
2666 static bool run_unlinktest(int dummy)
2668 struct cli_state *cli;
2669 const char *fname = "\\unlink.tst";
2671 bool correct = True;
2673 if (!torture_open_connection(&cli, 0)) {
2677 cli_sockopt(cli, sockops);
2679 printf("starting unlink test\n");
2681 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2685 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2686 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2690 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2691 printf("error: server allowed unlink on an open file\n");
2694 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2695 NT_STATUS_SHARING_VIOLATION);
2698 cli_close(cli, fnum);
2699 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2701 if (!torture_close_connection(cli)) {
2705 printf("unlink test finished\n");
2712 test how many open files this server supports on the one socket
2714 static bool run_maxfidtest(int dummy)
2716 struct cli_state *cli;
2717 const char *ftemplate = "\\maxfid.%d.%d";
2719 uint16_t fnums[0x11000];
2722 bool correct = True;
2727 printf("failed to connect\n");
2731 cli_sockopt(cli, sockops);
2733 for (i=0; i<0x11000; i++) {
2734 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2735 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2736 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2737 printf("open of %s failed (%s)\n",
2738 fname, cli_errstr(cli));
2739 printf("maximum fnum is %d\n", i);
2747 printf("cleaning up\n");
2749 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2750 cli_close(cli, fnums[i]);
2751 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2752 printf("unlink of %s failed (%s)\n",
2753 fname, cli_errstr(cli));
2760 printf("maxfid test finished\n");
2761 if (!torture_close_connection(cli)) {
2767 /* generate a random buffer */
2768 static void rand_buf(char *buf, int len)
2771 *buf = (char)sys_random();
2776 /* send smb negprot commands, not reading the response */
2777 static bool run_negprot_nowait(int dummy)
2779 struct tevent_context *ev;
2781 struct cli_state *cli;
2782 bool correct = True;
2784 printf("starting negprot nowait test\n");
2786 ev = tevent_context_init(talloc_tos());
2791 if (!(cli = open_nbt_connection())) {
2796 for (i=0;i<50000;i++) {
2797 struct tevent_req *req;
2799 req = cli_negprot_send(ev, ev, cli);
2804 if (!tevent_req_poll(req, ev)) {
2805 d_fprintf(stderr, "tevent_req_poll failed: %s\n",
2813 if (torture_close_connection(cli)) {
2817 printf("finished negprot nowait test\n");
2822 /* send smb negprot commands, not reading the response */
2823 static bool run_bad_nbt_session(int dummy)
2825 static struct cli_state *cli;
2827 printf("starting bad nbt session test\n");
2829 if (!(cli = open_bad_nbt_connection())) {
2834 printf("finished bad nbt session test\n");
2838 /* send random IPC commands */
2839 static bool run_randomipc(int dummy)
2841 char *rparam = NULL;
2843 unsigned int rdrcnt,rprcnt;
2845 int api, param_len, i;
2846 struct cli_state *cli;
2847 bool correct = True;
2850 printf("starting random ipc test\n");
2852 if (!torture_open_connection(&cli, 0)) {
2856 for (i=0;i<count;i++) {
2857 api = sys_random() % 500;
2858 param_len = (sys_random() % 64);
2860 rand_buf(param, param_len);
2865 param, param_len, 8,
2866 NULL, 0, BUFFER_SIZE,
2870 printf("%d/%d\r", i,count);
2873 printf("%d/%d\n", i, count);
2875 if (!torture_close_connection(cli)) {
2879 printf("finished random ipc test\n");
2886 static void browse_callback(const char *sname, uint32 stype,
2887 const char *comment, void *state)
2889 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2895 This test checks the browse list code
2898 static bool run_browsetest(int dummy)
2900 static struct cli_state *cli;
2901 bool correct = True;
2903 printf("starting browse test\n");
2905 if (!torture_open_connection(&cli, 0)) {
2909 printf("domain list:\n");
2910 cli_NetServerEnum(cli, cli->server_domain,
2911 SV_TYPE_DOMAIN_ENUM,
2912 browse_callback, NULL);
2914 printf("machine list:\n");
2915 cli_NetServerEnum(cli, cli->server_domain,
2917 browse_callback, NULL);
2919 if (!torture_close_connection(cli)) {
2923 printf("browse test finished\n");
2931 This checks how the getatr calls works
2933 static bool run_attrtest(int dummy)
2935 struct cli_state *cli;
2938 const char *fname = "\\attrib123456789.tst";
2939 bool correct = True;
2941 printf("starting attrib test\n");
2943 if (!torture_open_connection(&cli, 0)) {
2947 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2948 cli_open(cli, fname,
2949 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2950 cli_close(cli, fnum);
2951 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2952 printf("getatr failed (%s)\n", cli_errstr(cli));
2956 if (abs(t - time(NULL)) > 60*60*24*10) {
2957 printf("ERROR: SMBgetatr bug. time is %s",
2963 t2 = t-60*60*24; /* 1 day ago */
2965 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2966 printf("setatr failed (%s)\n", cli_errstr(cli));
2970 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2971 printf("getatr failed (%s)\n", cli_errstr(cli));
2976 printf("ERROR: getatr/setatr bug. times are\n%s",
2978 printf("%s", ctime(&t2));
2982 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2984 if (!torture_close_connection(cli)) {
2988 printf("attrib test finished\n");
2995 This checks a couple of trans2 calls
2997 static bool run_trans2test(int dummy)
2999 struct cli_state *cli;
3002 time_t c_time, a_time, m_time;
3003 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
3004 const char *fname = "\\trans2.tst";
3005 const char *dname = "\\trans2";
3006 const char *fname2 = "\\trans2\\trans2.tst";
3008 bool correct = True;
3012 printf("starting trans2 test\n");
3014 if (!torture_open_connection(&cli, 0)) {
3018 status = cli_get_fs_attr_info(cli, &fs_attr);
3019 if (!NT_STATUS_IS_OK(status)) {
3020 printf("ERROR: cli_get_fs_attr_info returned %s\n",
3025 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3026 cli_open(cli, fname,
3027 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3028 if (!NT_STATUS_IS_OK(cli_qfileinfo_basic(
3029 cli, fnum, NULL, &size, &c_time_ts,
3030 &a_time_ts, &w_time_ts,
3031 &m_time_ts, NULL))) {
3032 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
3036 if (!NT_STATUS_IS_OK(cli_qfilename(cli, fnum, pname, sizeof(pname)))) {
3037 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
3041 if (strcmp(pname, fname)) {
3042 printf("qfilename gave different name? [%s] [%s]\n",
3047 cli_close(cli, fnum);
3051 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3052 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
3053 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
3054 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
3057 cli_close(cli, fnum);
3059 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
3061 if (!NT_STATUS_IS_OK(status)) {
3062 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
3065 if (c_time != m_time) {
3066 printf("create time=%s", ctime(&c_time));
3067 printf("modify time=%s", ctime(&m_time));
3068 printf("This system appears to have sticky create times\n");
3070 if (a_time % (60*60) == 0) {
3071 printf("access time=%s", ctime(&a_time));
3072 printf("This system appears to set a midnight access time\n");
3076 if (abs(m_time - time(NULL)) > 60*60*24*7) {
3077 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
3083 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3084 cli_open(cli, fname,
3085 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3086 cli_close(cli, fnum);
3087 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
3088 &m_time_ts, &size, NULL, NULL);
3089 if (!NT_STATUS_IS_OK(status)) {
3090 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3093 if (w_time_ts.tv_sec < 60*60*24*2) {
3094 printf("write time=%s", ctime(&w_time_ts.tv_sec));
3095 printf("This system appears to set a initial 0 write time\n");
3100 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
3103 /* check if the server updates the directory modification time
3104 when creating a new file */
3105 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
3106 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
3110 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3111 &w_time_ts, &m_time_ts, &size, NULL, NULL);
3112 if (!NT_STATUS_IS_OK(status)) {
3113 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3117 cli_open(cli, fname2,
3118 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
3119 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
3120 cli_close(cli, fnum);
3121 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
3122 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
3123 if (!NT_STATUS_IS_OK(status)) {
3124 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
3127 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
3129 printf("This system does not update directory modification times\n");
3133 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
3134 cli_rmdir(cli, dname);
3136 if (!torture_close_connection(cli)) {
3140 printf("trans2 test finished\n");
3146 This checks new W2K calls.
3149 static NTSTATUS new_trans(struct cli_state *pcli, int fnum, int level)
3151 uint8_t *buf = NULL;
3155 status = cli_qfileinfo(talloc_tos(), pcli, fnum, level, 0,
3156 pcli->max_xmit, &buf, &len);
3157 if (!NT_STATUS_IS_OK(status)) {
3158 printf("ERROR: qfileinfo (%d) failed (%s)\n", level,
3161 printf("qfileinfo: level %d, len = %u\n", level, len);
3162 dump_data(0, (uint8 *)buf, len);
3169 static bool run_w2ktest(int dummy)
3171 struct cli_state *cli;
3173 const char *fname = "\\w2ktest\\w2k.tst";
3175 bool correct = True;
3177 printf("starting w2k test\n");
3179 if (!torture_open_connection(&cli, 0)) {
3183 cli_open(cli, fname,
3184 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3186 for (level = 1004; level < 1040; level++) {
3187 new_trans(cli, fnum, level);
3190 cli_close(cli, fnum);
3192 if (!torture_close_connection(cli)) {
3196 printf("w2k test finished\n");
3203 this is a harness for some oplock tests
3205 static bool run_oplock1(int dummy)
3207 struct cli_state *cli1;
3208 const char *fname = "\\lockt1.lck";
3210 bool correct = True;
3212 printf("starting oplock test 1\n");
3214 if (!torture_open_connection(&cli1, 0)) {
3218 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3220 cli_sockopt(cli1, sockops);
3222 cli1->use_oplocks = True;
3224 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3225 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3229 cli1->use_oplocks = False;
3231 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3232 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3234 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3235 printf("close2 failed (%s)\n", cli_errstr(cli1));
3239 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3240 printf("unlink failed (%s)\n", cli_errstr(cli1));
3244 if (!torture_close_connection(cli1)) {
3248 printf("finished oplock test 1\n");
3253 static bool run_oplock2(int dummy)
3255 struct cli_state *cli1, *cli2;
3256 const char *fname = "\\lockt2.lck";
3257 uint16_t fnum1, fnum2;
3258 int saved_use_oplocks = use_oplocks;
3260 bool correct = True;
3261 volatile bool *shared_correct;
3263 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3264 *shared_correct = True;
3266 use_level_II_oplocks = True;
3269 printf("starting oplock test 2\n");
3271 if (!torture_open_connection(&cli1, 0)) {
3272 use_level_II_oplocks = False;
3273 use_oplocks = saved_use_oplocks;
3277 cli1->use_oplocks = True;
3278 cli1->use_level_II_oplocks = True;
3280 if (!torture_open_connection(&cli2, 1)) {
3281 use_level_II_oplocks = False;
3282 use_oplocks = saved_use_oplocks;
3286 cli2->use_oplocks = True;
3287 cli2->use_level_II_oplocks = True;
3289 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3291 cli_sockopt(cli1, sockops);
3292 cli_sockopt(cli2, sockops);
3294 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3295 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3299 /* Don't need the globals any more. */
3300 use_level_II_oplocks = False;
3301 use_oplocks = saved_use_oplocks;
3305 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3306 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3307 *shared_correct = False;
3313 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3314 printf("close2 failed (%s)\n", cli_errstr(cli1));
3315 *shared_correct = False;
3323 /* Ensure cli1 processes the break. Empty file should always return 0
3326 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3327 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3331 /* Should now be at level II. */
3332 /* Test if sending a write locks causes a break to none. */
3334 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3335 printf("lock failed (%s)\n", cli_errstr(cli1));
3339 cli_unlock(cli1, fnum1, 0, 4);
3343 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3344 printf("lock failed (%s)\n", cli_errstr(cli1));
3348 cli_unlock(cli1, fnum1, 0, 4);
3352 cli_read(cli1, fnum1, buf, 0, 4);
3355 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3356 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3361 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3362 printf("close1 failed (%s)\n", cli_errstr(cli1));
3368 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3369 printf("unlink failed (%s)\n", cli_errstr(cli1));
3373 if (!torture_close_connection(cli1)) {
3377 if (!*shared_correct) {
3381 printf("finished oplock test 2\n");
3386 /* handler for oplock 3 tests */
3387 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3389 printf("got oplock break fnum=%d level=%d\n",
3391 return cli_oplock_ack(cli, fnum, level);
3394 static bool run_oplock3(int dummy)
3396 struct cli_state *cli;
3397 const char *fname = "\\oplockt3.dat";
3399 char buf[4] = "abcd";
3400 bool correct = True;
3401 volatile bool *shared_correct;
3403 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3404 *shared_correct = True;
3406 printf("starting oplock test 3\n");
3411 use_level_II_oplocks = True;
3412 if (!torture_open_connection(&cli, 0)) {
3413 *shared_correct = False;
3417 /* try to trigger a oplock break in parent */
3418 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3419 cli_write(cli, fnum, 0, buf, 0, 4);
3425 use_level_II_oplocks = True;
3426 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3429 cli_oplock_handler(cli, oplock3_handler);
3430 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3431 cli_write(cli, fnum, 0, buf, 0, 4);
3432 cli_close(cli, fnum);
3433 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3434 cli->timeout = 20000;
3435 cli_receive_smb(cli);
3436 printf("finished oplock test 3\n");
3438 return (correct && *shared_correct);
3440 /* What are we looking for here? What's sucess and what's FAILURE? */
3443 /* handler for oplock 4 tests */
3444 bool *oplock4_shared_correct;
3446 static NTSTATUS oplock4_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3448 printf("got oplock break fnum=%d level=%d\n",
3450 *oplock4_shared_correct = true;
3451 cli_oplock_ack(cli, fnum, level);
3452 return NT_STATUS_UNSUCCESSFUL; /* Cause cli_receive_smb to return. */
3455 static bool run_oplock4(int dummy)
3457 struct cli_state *cli1, *cli2;
3458 const char *fname = "\\lockt4.lck";
3459 const char *fname_ln = "\\lockt4_ln.lck";
3460 uint16_t fnum1, fnum2;
3461 int saved_use_oplocks = use_oplocks;
3463 bool correct = true;
3465 oplock4_shared_correct = (bool *)shm_setup(sizeof(bool));
3466 *oplock4_shared_correct = false;
3468 printf("starting oplock test 4\n");
3470 if (!torture_open_connection(&cli1, 0)) {
3471 use_level_II_oplocks = false;
3472 use_oplocks = saved_use_oplocks;
3476 if (!torture_open_connection(&cli2, 1)) {
3477 use_level_II_oplocks = false;
3478 use_oplocks = saved_use_oplocks;
3482 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3483 cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN);
3485 cli_sockopt(cli1, sockops);
3486 cli_sockopt(cli2, sockops);
3488 /* Create the file. */
3489 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3490 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3494 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3495 printf("close1 failed (%s)\n", cli_errstr(cli1));
3499 /* Now create a hardlink. */
3500 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli1, fname, fname_ln))) {
3501 printf("nt hardlink failed (%s)\n", cli_errstr(cli1));
3505 /* Prove that opening hardlinks cause deny modes to conflict. */
3506 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum1))) {
3507 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3511 status = cli_open(cli1, fname_ln, O_RDWR, DENY_NONE, &fnum2);
3512 if (NT_STATUS_IS_OK(status)) {
3513 printf("open of %s succeeded - should fail with sharing violation.\n",
3518 if (!NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
3519 printf("open of %s should fail with sharing violation. Got %s\n",
3520 fname_ln, nt_errstr(status));
3524 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3525 printf("close1 failed (%s)\n", cli_errstr(cli1));
3529 cli1->use_oplocks = true;
3530 cli1->use_level_II_oplocks = true;
3532 cli2->use_oplocks = true;
3533 cli2->use_level_II_oplocks = true;
3535 cli_oplock_handler(cli1, oplock4_handler);
3536 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3537 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3543 if (!NT_STATUS_IS_OK(cli_open(cli2, fname_ln, O_RDWR, DENY_NONE, &fnum2))) {
3544 printf("open of %s failed (%s)\n", fname_ln, cli_errstr(cli1));
3545 *oplock4_shared_correct = false;
3549 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3550 printf("close2 failed (%s)\n", cli_errstr(cli1));
3551 *oplock4_shared_correct = false;
3559 /* Process the oplock break. */
3560 cli_receive_smb(cli1);
3562 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3563 printf("close1 failed (%s)\n", cli_errstr(cli1));
3567 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3568 printf("unlink failed (%s)\n", cli_errstr(cli1));
3571 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname_ln, aSYSTEM | aHIDDEN))) {
3572 printf("unlink failed (%s)\n", cli_errstr(cli1));
3576 if (!torture_close_connection(cli1)) {
3580 if (!*oplock4_shared_correct) {
3584 printf("finished oplock test 4\n");
3591 Test delete on close semantics.
3593 static bool run_deletetest(int dummy)
3595 struct cli_state *cli1 = NULL;
3596 struct cli_state *cli2 = NULL;
3597 const char *fname = "\\delete.file";
3598 uint16_t fnum1 = (uint16_t)-1;
3599 uint16_t fnum2 = (uint16_t)-1;
3600 bool correct = True;
3602 printf("starting delete test\n");
3604 if (!torture_open_connection(&cli1, 0)) {
3608 cli_sockopt(cli1, sockops);
3610 /* Test 1 - this should delete the file on close. */
3612 cli_setatr(cli1, fname, 0, 0);
3613 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3615 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3616 0, FILE_OVERWRITE_IF,
3617 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3618 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3623 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3624 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3629 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3630 printf("[1] open of %s succeeded (should fail)\n", fname);
3635 printf("first delete on close test succeeded.\n");
3637 /* Test 2 - this should delete the file on close. */
3639 cli_setatr(cli1, fname, 0, 0);
3640 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3642 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3643 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3644 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3645 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3650 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3651 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3656 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3657 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3662 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3663 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3664 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3665 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3669 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3671 printf("second delete on close test succeeded.\n");
3674 cli_setatr(cli1, fname, 0, 0);
3675 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3677 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3678 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3679 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3684 /* This should fail with a sharing violation - open for delete is only compatible
3685 with SHARE_DELETE. */
3687 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3688 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3689 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3694 /* This should succeed. */
3696 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3697 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3698 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3703 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3704 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3709 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3710 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3715 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3716 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3721 /* This should fail - file should no longer be there. */
3723 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3724 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3725 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3726 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3728 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3732 printf("third delete on close test succeeded.\n");
3735 cli_setatr(cli1, fname, 0, 0);
3736 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3738 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3739 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3740 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3745 /* This should succeed. */
3746 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3747 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3748 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3753 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3754 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3759 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3760 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3765 /* This should fail - no more opens once delete on close set. */
3766 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3767 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3768 FILE_OPEN, 0, 0, &fnum2))) {
3769 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3773 printf("fourth delete on close test succeeded.\n");
3775 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3776 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3782 cli_setatr(cli1, fname, 0, 0);
3783 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3785 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3786 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3791 /* This should fail - only allowed on NT opens with DELETE access. */
3793 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3794 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3799 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3800 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3805 printf("fifth delete on close test succeeded.\n");
3808 cli_setatr(cli1, fname, 0, 0);
3809 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3811 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3812 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3813 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3814 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3819 /* This should fail - only allowed on NT opens with DELETE access. */
3821 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3822 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3827 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3828 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3833 printf("sixth delete on close test succeeded.\n");
3836 cli_setatr(cli1, fname, 0, 0);
3837 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3839 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3840 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3841 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3846 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3847 printf("[7] setting delete_on_close on file failed !\n");
3852 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3853 printf("[7] unsetting delete_on_close on file failed !\n");
3858 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3859 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3864 /* This next open should succeed - we reset the flag. */
3866 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3867 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3872 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3873 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3878 printf("seventh delete on close test succeeded.\n");
3881 cli_setatr(cli1, fname, 0, 0);
3882 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3884 if (!torture_open_connection(&cli2, 1)) {
3885 printf("[8] failed to open second connection.\n");
3890 cli_sockopt(cli1, sockops);
3892 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3893 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3894 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3895 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3900 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3901 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3902 FILE_OPEN, 0, 0, &fnum2))) {
3903 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3908 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3909 printf("[8] setting delete_on_close on file failed !\n");
3914 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3915 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3920 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3921 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3926 /* This should fail.. */
3927 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3928 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3932 printf("eighth delete on close test succeeded.\n");
3934 /* This should fail - we need to set DELETE_ACCESS. */
3935 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3936 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3937 printf("[9] open of %s succeeded should have failed!\n", fname);
3942 printf("ninth delete on close test succeeded.\n");
3944 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3945 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3946 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3951 /* This should delete the file. */
3952 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3953 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3958 /* This should fail.. */
3959 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3960 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3964 printf("tenth delete on close test succeeded.\n");
3966 cli_setatr(cli1, fname, 0, 0);
3967 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3969 /* What error do we get when attempting to open a read-only file with
3972 /* Create a readonly file. */
3973 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3974 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3975 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3980 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3981 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3986 /* Now try open for delete access. */
3987 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3988 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3989 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3990 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3991 cli_close(cli1, fnum1);
3995 NTSTATUS nterr = cli_nt_error(cli1);
3996 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3997 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
4001 printf("eleventh delete on close test succeeded.\n");
4005 printf("finished delete test\n");
4008 /* FIXME: This will crash if we aborted before cli2 got
4009 * intialized, because these functions don't handle
4010 * uninitialized connections. */
4012 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
4013 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
4014 cli_setatr(cli1, fname, 0, 0);
4015 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4017 if (cli1 && !torture_close_connection(cli1)) {
4020 if (cli2 && !torture_close_connection(cli2)) {
4026 static bool run_deletetest_ln(int dummy)
4028 struct cli_state *cli;
4029 const char *fname = "\\delete1";
4030 const char *fname_ln = "\\delete1_ln";
4034 bool correct = true;
4037 printf("starting deletetest-ln\n");
4039 if (!torture_open_connection(&cli, 0)) {
4043 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4044 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4046 cli_sockopt(cli, sockops);
4048 /* Create the file. */
4049 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4050 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4054 if (!NT_STATUS_IS_OK(cli_close(cli, fnum))) {
4055 printf("close1 failed (%s)\n", cli_errstr(cli));
4059 /* Now create a hardlink. */
4060 if (!NT_STATUS_IS_OK(cli_nt_hardlink(cli, fname, fname_ln))) {
4061 printf("nt hardlink failed (%s)\n", cli_errstr(cli));
4065 /* Open the original file. */
4066 status = cli_ntcreate(cli, fname, 0, FILE_READ_DATA,
4067 FILE_ATTRIBUTE_NORMAL,
4068 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4069 FILE_OPEN_IF, 0, 0, &fnum);
4070 if (!NT_STATUS_IS_OK(status)) {
4071 printf("ntcreate of %s failed (%s)\n", fname, nt_errstr(status));
4075 /* Unlink the hard link path. */
4076 status = cli_ntcreate(cli, fname_ln, 0, DELETE_ACCESS,
4077 FILE_ATTRIBUTE_NORMAL,
4078 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4079 FILE_OPEN_IF, 0, 0, &fnum1);
4080 if (!NT_STATUS_IS_OK(status)) {
4081 printf("ntcreate of %s failed (%s)\n", fname_ln, nt_errstr(status));
4084 status = cli_nt_delete_on_close(cli, fnum1, true);
4085 if (!NT_STATUS_IS_OK(status)) {
4086 d_printf("(%s) failed to set delete_on_close %s: %s\n",
4087 __location__, fname_ln, nt_errstr(status));
4091 status = cli_close(cli, fnum1);
4092 if (!NT_STATUS_IS_OK(status)) {
4093 printf("close %s failed (%s)\n",
4094 fname_ln, nt_errstr(status));
4098 status = cli_close(cli, fnum);
4099 if (!NT_STATUS_IS_OK(status)) {
4100 printf("close %s failed (%s)\n",
4101 fname, nt_errstr(status));
4105 /* Ensure the original file is still there. */
4106 status = cli_getatr(cli, fname, NULL, NULL, &t);
4107 if (!NT_STATUS_IS_OK(status)) {
4108 printf("%s getatr on file %s failed (%s)\n",
4115 /* Ensure the link path is gone. */
4116 status = cli_getatr(cli, fname_ln, NULL, NULL, &t);
4117 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4118 printf("%s, getatr for file %s returned wrong error code %s "
4119 "- should have been deleted\n",
4121 fname_ln, nt_errstr(status));
4125 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4126 cli_unlink(cli, fname_ln, aSYSTEM | aHIDDEN);
4128 if (!torture_close_connection(cli)) {
4132 printf("finished deletetest-ln\n");
4138 print out server properties
4140 static bool run_properties(int dummy)
4142 struct cli_state *cli;
4143 bool correct = True;
4145 printf("starting properties test\n");
4149 if (!torture_open_connection(&cli, 0)) {
4153 cli_sockopt(cli, sockops);
4155 d_printf("Capabilities 0x%08x\n", cli->capabilities);
4157 if (!torture_close_connection(cli)) {
4166 /* FIRST_DESIRED_ACCESS 0xf019f */
4167 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
4168 FILE_READ_EA| /* 0xf */ \
4169 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
4170 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
4171 DELETE_ACCESS|READ_CONTROL_ACCESS|\
4172 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
4173 /* SECOND_DESIRED_ACCESS 0xe0080 */
4174 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4175 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4176 WRITE_OWNER_ACCESS /* 0xe0000 */
4179 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
4180 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
4182 WRITE_OWNER_ACCESS /* */
4186 Test ntcreate calls made by xcopy
4188 static bool run_xcopy(int dummy)
4190 static struct cli_state *cli1;
4191 const char *fname = "\\test.txt";
4192 bool correct = True;
4193 uint16_t fnum1, fnum2;
4195 printf("starting xcopy test\n");
4197 if (!torture_open_connection(&cli1, 0)) {
4201 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4202 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
4203 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
4204 0x4044, 0, &fnum1))) {
4205 printf("First open failed - %s\n", cli_errstr(cli1));
4209 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
4210 SECOND_DESIRED_ACCESS, 0,
4211 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
4212 0x200000, 0, &fnum2))) {
4213 printf("second open failed - %s\n", cli_errstr(cli1));
4217 if (!torture_close_connection(cli1)) {
4225 Test rename on files open with share delete and no share delete.
4227 static bool run_rename(int dummy)
4229 static struct cli_state *cli1;
4230 const char *fname = "\\test.txt";
4231 const char *fname1 = "\\test1.txt";
4232 bool correct = True;
4237 printf("starting rename test\n");
4239 if (!torture_open_connection(&cli1, 0)) {
4243 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4244 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4245 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4246 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4247 printf("First open failed - %s\n", cli_errstr(cli1));
4251 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4252 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
4254 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
4258 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4259 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
4263 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4264 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4265 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4267 FILE_SHARE_DELETE|FILE_SHARE_NONE,
4269 FILE_SHARE_DELETE|FILE_SHARE_READ,
4271 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4272 if (!NT_STATUS_IS_OK(status)) {
4273 printf("Second open failed - %s\n", cli_errstr(cli1));
4277 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4278 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
4281 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
4284 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4285 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
4289 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4290 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4292 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
4293 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4294 printf("Third open failed - %s\n", cli_errstr(cli1));
4303 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
4304 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4305 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4308 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
4309 printf("[8] setting delete_on_close on file failed !\n");
4313 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
4314 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4320 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4321 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
4324 printf("Third rename succeeded (SHARE_NONE)\n");
4327 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4328 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
4332 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4333 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4337 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4338 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4339 printf("Fourth open failed - %s\n", cli_errstr(cli1));
4343 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4344 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
4346 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
4350 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4351 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
4355 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4356 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4360 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4361 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4362 printf("Fifth open failed - %s\n", cli_errstr(cli1));
4366 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
4367 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
4371 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
4375 * Now check if the first name still exists ...
4378 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
4379 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
4380 printf("Opening original file after rename of open file fails: %s\n",
4384 printf("Opening original file after rename of open file works ...\n");
4385 (void)cli_close(cli1, fnum2);
4389 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4390 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
4394 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
4395 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
4396 printf("getatr on file %s failed - %s ! \n",
4401 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
4402 printf("Renamed file %s has wrong attr 0x%x "
4403 "(should be 0x%x)\n",
4406 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
4409 printf("Renamed file %s has archive bit set\n", fname1);
4413 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4414 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
4416 if (!torture_close_connection(cli1)) {
4423 static bool run_pipe_number(int dummy)
4425 struct cli_state *cli1;
4426 const char *pipe_name = "\\SPOOLSS";
4430 printf("starting pipenumber test\n");
4431 if (!torture_open_connection(&cli1, 0)) {
4435 cli_sockopt(cli1, sockops);
4437 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4438 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4439 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4443 printf("\r%6d", num_pipes);
4446 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4447 torture_close_connection(cli1);
4452 Test open mode returns on read-only files.
4454 static bool run_opentest(int dummy)
4456 static struct cli_state *cli1;
4457 static struct cli_state *cli2;
4458 const char *fname = "\\readonly.file";
4459 uint16_t fnum1, fnum2;
4462 bool correct = True;
4466 printf("starting open test\n");
4468 if (!torture_open_connection(&cli1, 0)) {
4472 cli_setatr(cli1, fname, 0, 0);
4473 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4475 cli_sockopt(cli1, sockops);
4477 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4478 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4482 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4483 printf("close2 failed (%s)\n", cli_errstr(cli1));
4487 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4488 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4492 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4493 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4497 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4498 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4500 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4501 NT_STATUS_ACCESS_DENIED)) {
4502 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4505 printf("finished open test 1\n");
4507 cli_close(cli1, fnum1);
4509 /* Now try not readonly and ensure ERRbadshare is returned. */
4511 cli_setatr(cli1, fname, 0, 0);
4513 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4514 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4518 /* This will fail - but the error should be ERRshare. */
4519 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4521 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4522 NT_STATUS_SHARING_VIOLATION)) {
4523 printf("correct error code ERRDOS/ERRbadshare returned\n");
4526 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4527 printf("close2 failed (%s)\n", cli_errstr(cli1));
4531 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4533 printf("finished open test 2\n");
4535 /* Test truncate open disposition on file opened for read. */
4537 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4538 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4542 /* write 20 bytes. */
4544 memset(buf, '\0', 20);
4546 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4547 printf("write failed (%s)\n", cli_errstr(cli1));
4551 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4552 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4556 /* Ensure size == 20. */
4557 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4558 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4563 printf("(3) file size != 20\n");
4567 /* Now test if we can truncate a file opened for readonly. */
4569 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4570 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4574 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4575 printf("close2 failed (%s)\n", cli_errstr(cli1));
4579 /* Ensure size == 0. */
4580 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4581 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4586 printf("(3) file size != 0\n");
4589 printf("finished open test 3\n");
4591 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4593 printf("Do ctemp tests\n");
4594 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4595 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4598 printf("ctemp gave path %s\n", tmp_path);
4599 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4600 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4602 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4603 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4606 /* Test the non-io opens... */
4608 if (!torture_open_connection(&cli2, 1)) {
4612 cli_setatr(cli2, fname, 0, 0);
4613 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4615 cli_sockopt(cli2, sockops);
4617 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4619 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4620 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4621 printf("TEST #1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4625 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4626 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4627 printf("TEST #1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4631 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4632 printf("TEST #1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4635 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4636 printf("TEST #1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4640 printf("non-io open test #1 passed.\n");
4642 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4644 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4646 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4647 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4648 printf("TEST #2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4652 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4653 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4654 printf("TEST #2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4658 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4659 printf("TEST #2 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4662 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4663 printf("TEST #2 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4667 printf("non-io open test #2 passed.\n");
4669 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4671 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4673 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4674 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4675 printf("TEST #3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4679 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4680 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4681 printf("TEST #3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4685 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4686 printf("TEST #3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4689 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4690 printf("TEST #3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4694 printf("non-io open test #3 passed.\n");
4696 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4698 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4700 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4701 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4702 printf("TEST #4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4706 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4707 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4708 printf("TEST #4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4712 printf("TEST #4 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4714 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4715 printf("TEST #4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4719 printf("non-io open test #4 passed.\n");
4721 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4723 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4725 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4726 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4727 printf("TEST #5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4731 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4732 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4733 printf("TEST #5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4737 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4738 printf("TEST #5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4742 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4743 printf("TEST #5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4747 printf("non-io open test #5 passed.\n");
4749 printf("TEST #6 testing 1 non-io open, one io open\n");
4751 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4753 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4754 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4755 printf("TEST #6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4759 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4760 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4761 printf("TEST #6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4765 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4766 printf("TEST #6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4770 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4771 printf("TEST #6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4775 printf("non-io open test #6 passed.\n");
4777 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4779 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4781 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4782 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4783 printf("TEST #7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4787 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4788 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4789 printf("TEST #7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4793 printf("TEST #7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4795 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4796 printf("TEST #7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4800 printf("non-io open test #7 passed.\n");
4802 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4804 printf("TEST #8 testing open without WRITE_ATTRIBUTES, updating close write time.\n");
4805 status = cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, FILE_ATTRIBUTE_NORMAL,
4806 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
4807 FILE_OVERWRITE_IF, 0, 0, &fnum1);
4808 if (!NT_STATUS_IS_OK(status)) {
4809 printf("TEST #8 open of %s failed (%s)\n", fname, nt_errstr(status));
4814 /* Write to ensure we have to update the file time. */
4815 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4816 printf("TEST #8 cli_write failed: %s\n", cli_errstr(cli1));
4821 status = cli_close(cli1, fnum1);
4822 if (!NT_STATUS_IS_OK(status)) {
4823 printf("TEST #8 close of %s failed (%s)\n", fname, nt_errstr(status));
4829 if (!torture_close_connection(cli1)) {
4832 if (!torture_close_connection(cli2)) {
4839 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4841 uint16 major, minor;
4842 uint32 caplow, caphigh;
4845 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4846 printf("Server doesn't support UNIX CIFS extensions.\n");
4847 return NT_STATUS_NOT_SUPPORTED;
4850 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4852 if (!NT_STATUS_IS_OK(status)) {
4853 printf("Server didn't return UNIX CIFS extensions: %s\n",
4858 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4860 if (!NT_STATUS_IS_OK(status)) {
4861 printf("Server doesn't support setting UNIX CIFS extensions: "
4862 "%s.\n", nt_errstr(status));
4866 return NT_STATUS_OK;
4870 Test POSIX open /mkdir calls.
4872 static bool run_simple_posix_open_test(int dummy)
4874 static struct cli_state *cli1;
4875 const char *fname = "posix:file";
4876 const char *hname = "posix:hlink";
4877 const char *sname = "posix:symlink";
4878 const char *dname = "posix:dir";
4881 uint16_t fnum1 = (uint16_t)-1;
4882 SMB_STRUCT_STAT sbuf;
4883 bool correct = false;
4886 printf("Starting simple POSIX open test\n");
4888 if (!torture_open_connection(&cli1, 0)) {
4892 cli_sockopt(cli1, sockops);
4894 status = torture_setup_unix_extensions(cli1);
4895 if (!NT_STATUS_IS_OK(status)) {
4899 cli_setatr(cli1, fname, 0, 0);
4900 cli_posix_unlink(cli1, fname);
4901 cli_setatr(cli1, dname, 0, 0);
4902 cli_posix_rmdir(cli1, dname);
4903 cli_setatr(cli1, hname, 0, 0);
4904 cli_posix_unlink(cli1, hname);
4905 cli_setatr(cli1, sname, 0, 0);
4906 cli_posix_unlink(cli1, sname);
4908 /* Create a directory. */
4909 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4910 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4914 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4915 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4919 /* Test ftruncate - set file size. */
4920 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4921 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4925 /* Ensure st_size == 1000 */
4926 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4927 printf("stat failed (%s)\n", cli_errstr(cli1));
4931 if (sbuf.st_ex_size != 1000) {
4932 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4936 /* Test ftruncate - set file size back to zero. */
4937 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4938 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4942 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4943 printf("close failed (%s)\n", cli_errstr(cli1));
4947 /* Now open the file again for read only. */
4948 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4949 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4953 /* Now unlink while open. */
4954 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4955 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4959 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4960 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4964 /* Ensure the file has gone. */
4965 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4966 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4970 /* What happens when we try and POSIX open a directory ? */
4971 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4972 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4975 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4976 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4981 /* Create the file. */
4982 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4983 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4987 /* Write some data into it. */
4988 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4989 printf("cli_write failed: %s\n", cli_errstr(cli1));
4993 cli_close(cli1, fnum1);
4995 /* Now create a hardlink. */
4996 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4997 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
5001 /* Now create a symlink. */
5002 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
5003 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
5007 /* Open the hardlink for read. */
5008 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
5009 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
5013 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
5014 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
5018 if (memcmp(buf, "TEST DATA\n", 10)) {
5019 printf("invalid data read from hardlink\n");
5023 /* Do a POSIX lock/unlock. */
5024 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
5025 printf("POSIX lock failed %s\n", cli_errstr(cli1));
5029 /* Punch a hole in the locked area. */
5030 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
5031 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
5035 cli_close(cli1, fnum1);
5037 /* Open the symlink for read - this should fail. A POSIX
5038 client should not be doing opens on a symlink. */
5039 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
5040 printf("POSIX open of %s succeeded (should have failed)\n", sname);
5043 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
5044 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
5045 printf("POSIX open of %s should have failed "
5046 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
5047 "failed with %s instead.\n",
5048 sname, cli_errstr(cli1));
5053 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
5054 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
5058 if (strcmp(namebuf, fname) != 0) {
5059 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
5060 sname, fname, namebuf);
5064 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
5065 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
5069 printf("Simple POSIX open test passed\n");
5074 if (fnum1 != (uint16_t)-1) {
5075 cli_close(cli1, fnum1);
5076 fnum1 = (uint16_t)-1;
5079 cli_setatr(cli1, sname, 0, 0);
5080 cli_posix_unlink(cli1, sname);
5081 cli_setatr(cli1, hname, 0, 0);
5082 cli_posix_unlink(cli1, hname);
5083 cli_setatr(cli1, fname, 0, 0);
5084 cli_posix_unlink(cli1, fname);
5085 cli_setatr(cli1, dname, 0, 0);
5086 cli_posix_rmdir(cli1, dname);
5088 if (!torture_close_connection(cli1)) {
5096 static uint32 open_attrs_table[] = {
5097 FILE_ATTRIBUTE_NORMAL,
5098 FILE_ATTRIBUTE_ARCHIVE,
5099 FILE_ATTRIBUTE_READONLY,
5100 FILE_ATTRIBUTE_HIDDEN,
5101 FILE_ATTRIBUTE_SYSTEM,
5103 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
5104 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
5105 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
5106 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5107 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5108 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5110 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
5111 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
5112 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
5113 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
5116 struct trunc_open_results {
5123 static struct trunc_open_results attr_results[] = {
5124 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5125 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5126 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5127 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
5128 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
5129 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
5130 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5131 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5132 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5133 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5134 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5135 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
5136 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5137 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5138 { 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 },
5139 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5140 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5141 { 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 },
5142 { 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 },
5143 { 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 },
5144 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5145 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
5146 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
5147 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5148 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
5149 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
5152 static bool run_openattrtest(int dummy)
5154 static struct cli_state *cli1;
5155 const char *fname = "\\openattr.file";
5157 bool correct = True;
5159 unsigned int i, j, k, l;
5161 printf("starting open attr test\n");
5163 if (!torture_open_connection(&cli1, 0)) {
5167 cli_sockopt(cli1, sockops);
5169 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
5170 cli_setatr(cli1, fname, 0, 0);
5171 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5172 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
5173 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
5174 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5178 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5179 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
5183 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
5184 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
5185 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
5186 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5187 if (attr_results[l].num == k) {
5188 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
5189 k, open_attrs_table[i],
5190 open_attrs_table[j],
5191 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
5195 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
5196 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
5197 k, open_attrs_table[i], open_attrs_table[j],
5202 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
5208 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
5209 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
5213 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
5214 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
5219 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
5220 k, open_attrs_table[i], open_attrs_table[j], attr );
5223 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
5224 if (attr_results[l].num == k) {
5225 if (attr != attr_results[l].result_attr ||
5226 open_attrs_table[i] != attr_results[l].init_attr ||
5227 open_attrs_table[j] != attr_results[l].trunc_attr) {
5228 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
5229 open_attrs_table[i],
5230 open_attrs_table[j],
5232 attr_results[l].result_attr);
5242 cli_setatr(cli1, fname, 0, 0);
5243 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
5245 printf("open attr test %s.\n", correct ? "passed" : "failed");
5247 if (!torture_close_connection(cli1)) {
5253 static NTSTATUS list_fn(const char *mnt, struct file_info *finfo,
5254 const char *name, void *state)
5256 int *matched = (int *)state;
5257 if (matched != NULL) {
5260 return NT_STATUS_OK;
5264 test directory listing speed
5266 static bool run_dirtest(int dummy)
5269 static struct cli_state *cli;
5271 struct timeval core_start;
5272 bool correct = True;
5275 printf("starting directory test\n");
5277 if (!torture_open_connection(&cli, 0)) {
5281 cli_sockopt(cli, sockops);
5284 for (i=0;i<torture_numops;i++) {
5286 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5287 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
5288 fprintf(stderr,"Failed to open %s\n", fname);
5291 cli_close(cli, fnum);
5294 core_start = timeval_current();
5297 cli_list(cli, "a*.*", 0, list_fn, &matched);
5298 printf("Matched %d\n", matched);
5301 cli_list(cli, "b*.*", 0, list_fn, &matched);
5302 printf("Matched %d\n", matched);
5305 cli_list(cli, "xyzabc", 0, list_fn, &matched);
5306 printf("Matched %d\n", matched);
5308 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
5311 for (i=0;i<torture_numops;i++) {
5313 slprintf(fname, sizeof(fname), "\\%x", (int)random());
5314 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5317 if (!torture_close_connection(cli)) {
5321 printf("finished dirtest\n");
5326 static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask,
5329 struct cli_state *pcli = (struct cli_state *)state;
5331 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
5333 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
5334 return NT_STATUS_OK;
5336 if (finfo->mode & aDIR) {
5337 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
5338 printf("del_fn: failed to rmdir %s\n,", fname );
5340 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
5341 printf("del_fn: failed to unlink %s\n,", fname );
5343 return NT_STATUS_OK;
5348 sees what IOCTLs are supported
5350 bool torture_ioctl_test(int dummy)
5352 static struct cli_state *cli;
5353 uint16_t device, function;
5355 const char *fname = "\\ioctl.dat";
5359 if (!torture_open_connection(&cli, 0)) {
5363 printf("starting ioctl test\n");
5365 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5367 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5368 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
5372 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
5373 printf("ioctl device info: %s\n", nt_errstr(status));
5375 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
5376 printf("ioctl job info: %s\n", nt_errstr(status));
5378 for (device=0;device<0x100;device++) {
5379 printf("ioctl test with device = 0x%x\n", device);
5380 for (function=0;function<0x100;function++) {
5381 uint32 code = (device<<16) | function;
5383 status = cli_raw_ioctl(cli, fnum, code, &blob);
5385 if (NT_STATUS_IS_OK(status)) {
5386 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
5388 data_blob_free(&blob);
5393 if (!torture_close_connection(cli)) {
5402 tries varients of chkpath
5404 bool torture_chkpath_test(int dummy)
5406 static struct cli_state *cli;
5410 if (!torture_open_connection(&cli, 0)) {
5414 printf("starting chkpath test\n");
5416 /* cleanup from an old run */
5417 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5418 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5419 cli_rmdir(cli, "\\chkpath.dir");
5421 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
5422 printf("mkdir1 failed : %s\n", cli_errstr(cli));
5426 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
5427 printf("mkdir2 failed : %s\n", cli_errstr(cli));
5431 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
5432 printf("open1 failed (%s)\n", cli_errstr(cli));
5435 cli_close(cli, fnum);
5437 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
5438 printf("chkpath1 failed: %s\n", cli_errstr(cli));
5442 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
5443 printf("chkpath2 failed: %s\n", cli_errstr(cli));
5447 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
5448 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5449 NT_STATUS_NOT_A_DIRECTORY);
5451 printf("* chkpath on a file should fail\n");
5455 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
5456 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5457 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5459 printf("* chkpath on a non existant file should fail\n");
5463 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5464 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5465 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5467 printf("* chkpath on a non existent component should fail\n");
5471 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5472 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5473 cli_rmdir(cli, "\\chkpath.dir");
5475 if (!torture_close_connection(cli)) {
5482 static bool run_eatest(int dummy)
5484 static struct cli_state *cli;
5485 const char *fname = "\\eatest.txt";
5486 bool correct = True;
5490 struct ea_struct *ea_list = NULL;
5491 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5494 printf("starting eatest\n");
5496 if (!torture_open_connection(&cli, 0)) {
5497 talloc_destroy(mem_ctx);
5501 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5502 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5503 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5504 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5505 0x4044, 0, &fnum))) {
5506 printf("open failed - %s\n", cli_errstr(cli));
5507 talloc_destroy(mem_ctx);
5511 for (i = 0; i < 10; i++) {
5512 fstring ea_name, ea_val;
5514 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5515 memset(ea_val, (char)i+1, i+1);
5516 status = cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1);
5517 if (!NT_STATUS_IS_OK(status)) {
5518 printf("ea_set of name %s failed - %s\n", ea_name,
5520 talloc_destroy(mem_ctx);
5525 cli_close(cli, fnum);
5526 for (i = 0; i < 10; i++) {
5527 fstring ea_name, ea_val;
5529 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5530 memset(ea_val, (char)i+1, i+1);
5531 status = cli_set_ea_path(cli, fname, ea_name, ea_val, i+1);
5532 if (!NT_STATUS_IS_OK(status)) {
5533 printf("ea_set of name %s failed - %s\n", ea_name,
5535 talloc_destroy(mem_ctx);
5540 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5541 if (!NT_STATUS_IS_OK(status)) {
5542 printf("ea_get list failed - %s\n", nt_errstr(status));
5546 printf("num_eas = %d\n", (int)num_eas);
5548 if (num_eas != 20) {
5549 printf("Should be 20 EA's stored... failing.\n");
5553 for (i = 0; i < num_eas; i++) {
5554 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5555 dump_data(0, ea_list[i].value.data,
5556 ea_list[i].value.length);
5559 /* Setting EA's to zero length deletes them. Test this */
5560 printf("Now deleting all EA's - case indepenent....\n");
5563 cli_set_ea_path(cli, fname, "", "", 0);
5565 for (i = 0; i < 20; i++) {
5567 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5568 status = cli_set_ea_path(cli, fname, ea_name, "", 0);
5569 if (!NT_STATUS_IS_OK(status)) {
5570 printf("ea_set of name %s failed - %s\n", ea_name,
5572 talloc_destroy(mem_ctx);
5578 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5579 if (!NT_STATUS_IS_OK(status)) {
5580 printf("ea_get list failed - %s\n", nt_errstr(status));
5584 printf("num_eas = %d\n", (int)num_eas);
5585 for (i = 0; i < num_eas; i++) {
5586 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5587 dump_data(0, ea_list[i].value.data,
5588 ea_list[i].value.length);
5592 printf("deleting EA's failed.\n");
5596 /* Try and delete a non existant EA. */
5597 status = cli_set_ea_path(cli, fname, "foo", "", 0);
5598 if (!NT_STATUS_IS_OK(status)) {
5599 printf("deleting non-existant EA 'foo' should succeed. %s\n",
5604 talloc_destroy(mem_ctx);
5605 if (!torture_close_connection(cli)) {
5612 static bool run_dirtest1(int dummy)
5615 static struct cli_state *cli;
5618 bool correct = True;
5620 printf("starting directory test\n");
5622 if (!torture_open_connection(&cli, 0)) {
5626 cli_sockopt(cli, sockops);
5628 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5629 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5630 cli_rmdir(cli, "\\LISTDIR");
5631 cli_mkdir(cli, "\\LISTDIR");
5633 /* Create 1000 files and 1000 directories. */
5634 for (i=0;i<1000;i++) {
5636 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5637 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5638 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5639 fprintf(stderr,"Failed to open %s\n", fname);
5642 cli_close(cli, fnum);
5644 for (i=0;i<1000;i++) {
5646 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5647 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5648 fprintf(stderr,"Failed to open %s\n", fname);
5653 /* Now ensure that doing an old list sees both files and directories. */
5655 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5656 printf("num_seen = %d\n", num_seen );
5657 /* We should see 100 files + 1000 directories + . and .. */
5658 if (num_seen != 2002)
5661 /* Ensure if we have the "must have" bits we only see the
5665 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5666 printf("num_seen = %d\n", num_seen );
5667 if (num_seen != 1002)
5671 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5672 printf("num_seen = %d\n", num_seen );
5673 if (num_seen != 1000)
5676 /* Delete everything. */
5677 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5678 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5679 cli_rmdir(cli, "\\LISTDIR");
5682 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5683 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5684 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5687 if (!torture_close_connection(cli)) {
5691 printf("finished dirtest1\n");
5696 static bool run_error_map_extract(int dummy) {
5698 static struct cli_state *c_dos;
5699 static struct cli_state *c_nt;
5704 uint32 flgs2, errnum;
5711 /* NT-Error connection */
5713 if (!(c_nt = open_nbt_connection())) {
5717 c_nt->use_spnego = False;
5719 status = cli_negprot(c_nt);
5721 if (!NT_STATUS_IS_OK(status)) {
5722 printf("%s rejected the NT-error negprot (%s)\n", host,
5728 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5730 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5734 /* DOS-Error connection */
5736 if (!(c_dos = open_nbt_connection())) {
5740 c_dos->use_spnego = False;
5741 c_dos->force_dos_errors = True;
5743 status = cli_negprot(c_dos);
5744 if (!NT_STATUS_IS_OK(status)) {
5745 printf("%s rejected the DOS-error negprot (%s)\n", host,
5747 cli_shutdown(c_dos);
5751 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5753 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5757 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5758 fstr_sprintf(user, "%X", error);
5760 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5761 password, strlen(password),
5762 password, strlen(password),
5764 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5767 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5769 /* Case #1: 32-bit NT errors */
5770 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5771 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5773 printf("/** Dos error on NT connection! (%s) */\n",
5775 nt_status = NT_STATUS(0xc0000000);
5778 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5779 password, strlen(password),
5780 password, strlen(password),
5782 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5784 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5786 /* Case #1: 32-bit NT errors */
5787 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5788 printf("/** NT error on DOS connection! (%s) */\n",
5790 errnum = errclass = 0;
5792 cli_dos_error(c_dos, &errclass, &errnum);
5795 if (NT_STATUS_V(nt_status) != error) {
5796 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5797 get_nt_error_c_code(NT_STATUS(error)),
5798 get_nt_error_c_code(nt_status));
5801 printf("\t{%s,\t%s,\t%s},\n",
5802 smb_dos_err_class(errclass),
5803 smb_dos_err_name(errclass, errnum),
5804 get_nt_error_c_code(NT_STATUS(error)));
5809 static bool run_sesssetup_bench(int dummy)
5811 static struct cli_state *c;
5812 const char *fname = "\\file.dat";
5817 if (!torture_open_connection(&c, 0)) {
5821 if (!NT_STATUS_IS_OK(cli_ntcreate(
5822 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5823 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5824 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5825 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5829 for (i=0; i<torture_numops; i++) {
5830 status = cli_session_setup(
5832 password, strlen(password),
5833 password, strlen(password),
5835 if (!NT_STATUS_IS_OK(status)) {
5836 d_printf("(%s) cli_session_setup failed: %s\n",
5837 __location__, nt_errstr(status));
5841 d_printf("\r%d ", (int)c->vuid);
5843 status = cli_ulogoff(c);
5844 if (!NT_STATUS_IS_OK(status)) {
5845 d_printf("(%s) cli_ulogoff failed: %s\n",
5846 __location__, nt_errstr(status));
5855 static bool subst_test(const char *str, const char *user, const char *domain,
5856 uid_t uid, gid_t gid, const char *expected)
5861 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5863 if (strcmp(subst, expected) != 0) {
5864 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5865 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5874 static void chain1_open_completion(struct tevent_req *req)
5878 status = cli_open_recv(req, &fnum);
5881 d_printf("cli_open_recv returned %s: %d\n",
5883 NT_STATUS_IS_OK(status) ? fnum : -1);
5886 static void chain1_write_completion(struct tevent_req *req)
5890 status = cli_write_andx_recv(req, &written);
5893 d_printf("cli_write_andx_recv returned %s: %d\n",
5895 NT_STATUS_IS_OK(status) ? (int)written : -1);
5898 static void chain1_close_completion(struct tevent_req *req)
5901 bool *done = (bool *)tevent_req_callback_data_void(req);
5903 status = cli_close_recv(req);
5908 d_printf("cli_close returned %s\n", nt_errstr(status));
5911 static bool run_chain1(int dummy)
5913 struct cli_state *cli1;
5914 struct event_context *evt = event_context_init(NULL);
5915 struct tevent_req *reqs[3], *smbreqs[3];
5917 const char *str = "foobar";
5920 printf("starting chain1 test\n");
5921 if (!torture_open_connection(&cli1, 0)) {
5925 cli_sockopt(cli1, sockops);
5927 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5928 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5929 if (reqs[0] == NULL) return false;
5930 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5933 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5934 (uint8_t *)str, 0, strlen(str)+1,
5935 smbreqs, 1, &smbreqs[1]);
5936 if (reqs[1] == NULL) return false;
5937 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5939 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5940 if (reqs[2] == NULL) return false;
5941 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5943 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5944 if (!NT_STATUS_IS_OK(status)) {
5949 event_loop_once(evt);
5952 torture_close_connection(cli1);
5956 static void chain2_sesssetup_completion(struct tevent_req *req)
5959 status = cli_session_setup_guest_recv(req);
5960 d_printf("sesssetup returned %s\n", nt_errstr(status));
5963 static void chain2_tcon_completion(struct tevent_req *req)
5965 bool *done = (bool *)tevent_req_callback_data_void(req);
5967 status = cli_tcon_andx_recv(req);
5968 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5972 static bool run_chain2(int dummy)
5974 struct cli_state *cli1;
5975 struct event_context *evt = event_context_init(NULL);
5976 struct tevent_req *reqs[2], *smbreqs[2];
5980 printf("starting chain2 test\n");
5981 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5982 port_to_use, Undefined, 0);
5983 if (!NT_STATUS_IS_OK(status)) {
5987 cli_sockopt(cli1, sockops);
5989 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5991 if (reqs[0] == NULL) return false;
5992 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5994 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5995 "?????", NULL, 0, &smbreqs[1]);
5996 if (reqs[1] == NULL) return false;
5997 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5999 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
6000 if (!NT_STATUS_IS_OK(status)) {
6005 event_loop_once(evt);
6008 torture_close_connection(cli1);
6013 struct torture_createdel_state {
6014 struct tevent_context *ev;
6015 struct cli_state *cli;
6018 static void torture_createdel_created(struct tevent_req *subreq);
6019 static void torture_createdel_closed(struct tevent_req *subreq);
6021 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
6022 struct tevent_context *ev,
6023 struct cli_state *cli,
6026 struct tevent_req *req, *subreq;
6027 struct torture_createdel_state *state;
6029 req = tevent_req_create(mem_ctx, &state,
6030 struct torture_createdel_state);
6037 subreq = cli_ntcreate_send(
6038 state, ev, cli, name, 0,
6039 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
6040 FILE_ATTRIBUTE_NORMAL,
6041 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
6042 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
6044 if (tevent_req_nomem(subreq, req)) {
6045 return tevent_req_post(req, ev);
6047 tevent_req_set_callback(subreq, torture_createdel_created, req);
6051 static void torture_createdel_created(struct tevent_req *subreq)
6053 struct tevent_req *req = tevent_req_callback_data(
6054 subreq, struct tevent_req);
6055 struct torture_createdel_state *state = tevent_req_data(
6056 req, struct torture_createdel_state);
6060 status = cli_ntcreate_recv(subreq, &fnum);
6061 TALLOC_FREE(subreq);
6062 if (!NT_STATUS_IS_OK(status)) {
6063 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
6064 nt_errstr(status)));
6065 tevent_req_nterror(req, status);
6069 subreq = cli_close_send(state, state->ev, state->cli, fnum);
6070 if (tevent_req_nomem(subreq, req)) {
6073 tevent_req_set_callback(subreq, torture_createdel_closed, req);
6076 static void torture_createdel_closed(struct tevent_req *subreq)
6078 struct tevent_req *req = tevent_req_callback_data(
6079 subreq, struct tevent_req);
6082 status = cli_close_recv(subreq);
6083 if (!NT_STATUS_IS_OK(status)) {
6084 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
6085 tevent_req_nterror(req, status);
6088 tevent_req_done(req);
6091 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
6093 return tevent_req_simple_recv_ntstatus(req);
6096 struct torture_createdels_state {
6097 struct tevent_context *ev;
6098 struct cli_state *cli;
6099 const char *base_name;
6103 struct tevent_req **reqs;
6106 static void torture_createdels_done(struct tevent_req *subreq);
6108 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
6109 struct tevent_context *ev,
6110 struct cli_state *cli,
6111 const char *base_name,
6115 struct tevent_req *req;
6116 struct torture_createdels_state *state;
6119 req = tevent_req_create(mem_ctx, &state,
6120 struct torture_createdels_state);
6126 state->base_name = talloc_strdup(state, base_name);
6127 if (tevent_req_nomem(state->base_name, req)) {
6128 return tevent_req_post(req, ev);
6130 state->num_files = MAX(num_parallel, num_files);
6132 state->received = 0;
6134 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
6135 if (tevent_req_nomem(state->reqs, req)) {
6136 return tevent_req_post(req, ev);
6139 for (i=0; i<num_parallel; i++) {
6142 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6144 if (tevent_req_nomem(name, req)) {
6145 return tevent_req_post(req, ev);
6147 state->reqs[i] = torture_createdel_send(
6148 state->reqs, state->ev, state->cli, name);
6149 if (tevent_req_nomem(state->reqs[i], req)) {
6150 return tevent_req_post(req, ev);
6152 name = talloc_move(state->reqs[i], &name);
6153 tevent_req_set_callback(state->reqs[i],
6154 torture_createdels_done, req);
6160 static void torture_createdels_done(struct tevent_req *subreq)
6162 struct tevent_req *req = tevent_req_callback_data(
6163 subreq, struct tevent_req);
6164 struct torture_createdels_state *state = tevent_req_data(
6165 req, struct torture_createdels_state);
6166 size_t num_parallel = talloc_array_length(state->reqs);
6171 status = torture_createdel_recv(subreq);
6172 if (!NT_STATUS_IS_OK(status)){
6173 DEBUG(10, ("torture_createdel_recv returned %s\n",
6174 nt_errstr(status)));
6175 TALLOC_FREE(subreq);
6176 tevent_req_nterror(req, status);
6180 for (i=0; i<num_parallel; i++) {
6181 if (subreq == state->reqs[i]) {
6185 if (i == num_parallel) {
6186 DEBUG(10, ("received something we did not send\n"));
6187 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
6190 TALLOC_FREE(state->reqs[i]);
6192 if (state->sent >= state->num_files) {
6193 tevent_req_done(req);
6197 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
6199 if (tevent_req_nomem(name, req)) {
6202 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
6204 if (tevent_req_nomem(state->reqs[i], req)) {
6207 name = talloc_move(state->reqs[i], &name);
6208 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
6212 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
6214 return tevent_req_simple_recv_ntstatus(req);
6217 struct swallow_notify_state {
6218 struct tevent_context *ev;
6219 struct cli_state *cli;
6221 uint32_t completion_filter;
6223 bool (*fn)(uint32_t action, const char *name, void *priv);
6227 static void swallow_notify_done(struct tevent_req *subreq);
6229 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
6230 struct tevent_context *ev,
6231 struct cli_state *cli,
6233 uint32_t completion_filter,
6235 bool (*fn)(uint32_t action,
6240 struct tevent_req *req, *subreq;
6241 struct swallow_notify_state *state;
6243 req = tevent_req_create(mem_ctx, &state,
6244 struct swallow_notify_state);
6251 state->completion_filter = completion_filter;
6252 state->recursive = recursive;
6256 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6257 0xffff, state->completion_filter,
6259 if (tevent_req_nomem(subreq, req)) {
6260 return tevent_req_post(req, ev);
6262 tevent_req_set_callback(subreq, swallow_notify_done, req);
6266 static void swallow_notify_done(struct tevent_req *subreq)
6268 struct tevent_req *req = tevent_req_callback_data(
6269 subreq, struct tevent_req);
6270 struct swallow_notify_state *state = tevent_req_data(
6271 req, struct swallow_notify_state);
6273 uint32_t i, num_changes;
6274 struct notify_change *changes;
6276 status = cli_notify_recv(subreq, state, &num_changes, &changes);
6277 TALLOC_FREE(subreq);
6278 if (!NT_STATUS_IS_OK(status)) {
6279 DEBUG(10, ("cli_notify_recv returned %s\n",
6280 nt_errstr(status)));
6281 tevent_req_nterror(req, status);
6285 for (i=0; i<num_changes; i++) {
6286 state->fn(changes[i].action, changes[i].name, state->priv);
6288 TALLOC_FREE(changes);
6290 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
6291 0xffff, state->completion_filter,
6293 if (tevent_req_nomem(subreq, req)) {
6296 tevent_req_set_callback(subreq, swallow_notify_done, req);
6299 static bool print_notifies(uint32_t action, const char *name, void *priv)
6301 if (DEBUGLEVEL > 5) {
6302 d_printf("%d %s\n", (int)action, name);
6307 static void notify_bench_done(struct tevent_req *req)
6309 int *num_finished = (int *)tevent_req_callback_data_void(req);
6313 static bool run_notify_bench(int dummy)
6315 const char *dname = "\\notify-bench";
6316 struct tevent_context *ev;
6319 struct tevent_req *req1;
6320 struct tevent_req *req2 = NULL;
6321 int i, num_unc_names;
6322 int num_finished = 0;
6324 printf("starting notify-bench test\n");
6326 if (use_multishare_conn) {
6328 unc_list = file_lines_load(multishare_conn_fname,
6329 &num_unc_names, 0, NULL);
6330 if (!unc_list || num_unc_names <= 0) {
6331 d_printf("Failed to load unc names list from '%s'\n",
6332 multishare_conn_fname);
6335 TALLOC_FREE(unc_list);
6340 ev = tevent_context_init(talloc_tos());
6342 d_printf("tevent_context_init failed\n");
6346 for (i=0; i<num_unc_names; i++) {
6347 struct cli_state *cli;
6350 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
6352 if (base_fname == NULL) {
6356 if (!torture_open_connection(&cli, i)) {
6360 status = cli_ntcreate(cli, dname, 0,
6361 MAXIMUM_ALLOWED_ACCESS,
6362 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
6364 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
6367 if (!NT_STATUS_IS_OK(status)) {
6368 d_printf("Could not create %s: %s\n", dname,
6373 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
6374 FILE_NOTIFY_CHANGE_FILE_NAME |
6375 FILE_NOTIFY_CHANGE_DIR_NAME |
6376 FILE_NOTIFY_CHANGE_ATTRIBUTES |
6377 FILE_NOTIFY_CHANGE_LAST_WRITE,
6378 false, print_notifies, NULL);
6380 d_printf("Could not create notify request\n");
6384 req2 = torture_createdels_send(talloc_tos(), ev, cli,
6385 base_fname, 10, torture_numops);
6387 d_printf("Could not create createdels request\n");
6390 TALLOC_FREE(base_fname);
6392 tevent_req_set_callback(req2, notify_bench_done,
6396 while (num_finished < num_unc_names) {
6398 ret = tevent_loop_once(ev);
6400 d_printf("tevent_loop_once failed\n");
6405 if (!tevent_req_poll(req2, ev)) {
6406 d_printf("tevent_req_poll failed\n");
6409 status = torture_createdels_recv(req2);
6410 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
6415 static bool run_mangle1(int dummy)
6417 struct cli_state *cli;
6418 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
6422 time_t change_time, access_time, write_time;
6426 printf("starting mangle1 test\n");
6427 if (!torture_open_connection(&cli, 0)) {
6431 cli_sockopt(cli, sockops);
6433 if (!NT_STATUS_IS_OK(cli_ntcreate(
6434 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
6435 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
6436 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
6439 cli_close(cli, fnum);
6441 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
6442 if (!NT_STATUS_IS_OK(status)) {
6443 d_printf("cli_qpathinfo_alt_name failed: %s\n",
6447 d_printf("alt_name: %s\n", alt_name);
6449 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
6450 d_printf("cli_open(%s) failed: %s\n", alt_name,
6454 cli_close(cli, fnum);
6456 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
6457 &write_time, &size, &mode);
6458 if (!NT_STATUS_IS_OK(status)) {
6459 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6467 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6469 size_t *to_pull = (size_t *)priv;
6470 size_t thistime = *to_pull;
6472 thistime = MIN(thistime, n);
6473 if (thistime == 0) {
6477 memset(buf, 0, thistime);
6478 *to_pull -= thistime;
6482 static bool run_windows_write(int dummy)
6484 struct cli_state *cli1;
6488 const char *fname = "\\writetest.txt";
6489 struct timeval start_time;
6493 printf("starting windows_write test\n");
6494 if (!torture_open_connection(&cli1, 0)) {
6498 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6499 printf("open failed (%s)\n", cli_errstr(cli1));
6503 cli_sockopt(cli1, sockops);
6505 start_time = timeval_current();
6507 for (i=0; i<torture_numops; i++) {
6509 off_t start = i * torture_blocksize;
6511 size_t to_pull = torture_blocksize - 1;
6513 if (cli_write(cli1, fnum, 0, &c,
6514 start + torture_blocksize - 1, 1) != 1) {
6515 printf("cli_write failed: %s\n", cli_errstr(cli1));
6519 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6520 null_source, &to_pull);
6521 if (!NT_STATUS_IS_OK(status)) {
6522 printf("cli_push returned: %s\n", nt_errstr(status));
6527 seconds = timeval_elapsed(&start_time);
6528 kbytes = (double)torture_blocksize * torture_numops;
6531 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6532 (double)seconds, (int)(kbytes/seconds));
6536 cli_close(cli1, fnum);
6537 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6538 torture_close_connection(cli1);
6542 static bool run_cli_echo(int dummy)
6544 struct cli_state *cli;
6547 printf("starting cli_echo test\n");
6548 if (!torture_open_connection(&cli, 0)) {
6551 cli_sockopt(cli, sockops);
6553 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6555 d_printf("cli_echo returned %s\n", nt_errstr(status));
6557 torture_close_connection(cli);
6558 return NT_STATUS_IS_OK(status);
6561 static bool run_uid_regression_test(int dummy)
6563 static struct cli_state *cli;
6566 bool correct = True;
6569 printf("starting uid regression test\n");
6571 if (!torture_open_connection(&cli, 0)) {
6575 cli_sockopt(cli, sockops);
6577 /* Ok - now save then logoff our current user. */
6578 old_vuid = cli->vuid;
6580 status = cli_ulogoff(cli);
6581 if (!NT_STATUS_IS_OK(status)) {
6582 d_printf("(%s) cli_ulogoff failed: %s\n",
6583 __location__, nt_errstr(status));
6588 cli->vuid = old_vuid;
6590 /* Try an operation. */
6591 status = cli_mkdir(cli, "\\uid_reg_test");
6592 if (NT_STATUS_IS_OK(status)) {
6593 d_printf("(%s) cli_mkdir succeeded\n",
6598 /* Should be bad uid. */
6599 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6600 NT_STATUS_USER_SESSION_DELETED)) {
6606 old_cnum = cli->cnum;
6608 /* Now try a SMBtdis with the invald vuid set to zero. */
6611 /* This should succeed. */
6612 status = cli_tdis(cli);
6614 if (NT_STATUS_IS_OK(status)) {
6615 d_printf("First tdis with invalid vuid should succeed.\n");
6617 d_printf("First tdis failed (%s)\n", nt_errstr(status));
6622 cli->vuid = old_vuid;
6623 cli->cnum = old_cnum;
6625 /* This should fail. */
6626 status = cli_tdis(cli);
6627 if (NT_STATUS_IS_OK(status)) {
6628 d_printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6632 /* Should be bad tid. */
6633 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6634 NT_STATUS_NETWORK_NAME_DELETED)) {
6640 cli_rmdir(cli, "\\uid_reg_test");
6649 static const char *illegal_chars = "*\\/?<>|\":";
6650 static char force_shortname_chars[] = " +,.[];=\177";
6652 static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo,
6653 const char *mask, void *state)
6655 struct cli_state *pcli = (struct cli_state *)state;
6657 NTSTATUS status = NT_STATUS_OK;
6659 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6661 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6662 return NT_STATUS_OK;
6664 if (finfo->mode & aDIR) {
6665 status = cli_rmdir(pcli, fname);
6666 if (!NT_STATUS_IS_OK(status)) {
6667 printf("del_fn: failed to rmdir %s\n,", fname );
6670 status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN);
6671 if (!NT_STATUS_IS_OK(status)) {
6672 printf("del_fn: failed to unlink %s\n,", fname );
6684 static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo,
6685 const char *name, void *state)
6687 struct sn_state *s = (struct sn_state *)state;
6691 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6692 i, finfo->name, finfo->short_name);
6695 if (strchr(force_shortname_chars, i)) {
6696 if (!finfo->short_name[0]) {
6697 /* Shortname not created when it should be. */
6698 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6699 __location__, finfo->name, i);
6702 } else if (finfo->short_name[0]){
6703 /* Shortname created when it should not be. */
6704 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6705 __location__, finfo->short_name, finfo->name);
6709 return NT_STATUS_OK;
6712 static bool run_shortname_test(int dummy)
6714 static struct cli_state *cli;
6715 bool correct = True;
6720 printf("starting shortname test\n");
6722 if (!torture_open_connection(&cli, 0)) {
6726 cli_sockopt(cli, sockops);
6728 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6729 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6730 cli_rmdir(cli, "\\shortname");
6732 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6733 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6734 __location__, cli_errstr(cli));
6739 strlcpy(fname, "\\shortname\\", sizeof(fname));
6740 strlcat(fname, "test .txt", sizeof(fname));
6744 for (i = 32; i < 128; i++) {
6746 uint16_t fnum = (uint16_t)-1;
6750 if (strchr(illegal_chars, i)) {
6755 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6756 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6757 if (!NT_STATUS_IS_OK(status)) {
6758 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6759 __location__, fname, cli_errstr(cli));
6763 cli_close(cli, fnum);
6766 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6768 if (s.matched != 1) {
6769 d_printf("(%s) failed to list %s: %s\n",
6770 __location__, fname, cli_errstr(cli));
6774 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6775 d_printf("(%s) failed to delete %s: %s\n",
6776 __location__, fname, cli_errstr(cli));
6789 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6790 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6791 cli_rmdir(cli, "\\shortname");
6792 torture_close_connection(cli);
6796 static void pagedsearch_cb(struct tevent_req *req)
6799 struct tldap_message *msg;
6802 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6803 if (rc != TLDAP_SUCCESS) {
6804 d_printf("tldap_search_paged_recv failed: %s\n",
6805 tldap_err2string(rc));
6808 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6812 if (!tldap_entry_dn(msg, &dn)) {
6813 d_printf("tldap_entry_dn failed\n");
6816 d_printf("%s\n", dn);
6820 static bool run_tldap(int dummy)
6822 struct tldap_context *ld;
6825 struct sockaddr_storage addr;
6826 struct tevent_context *ev;
6827 struct tevent_req *req;
6831 if (!resolve_name(host, &addr, 0, false)) {
6832 d_printf("could not find host %s\n", host);
6835 status = open_socket_out(&addr, 389, 9999, &fd);
6836 if (!NT_STATUS_IS_OK(status)) {
6837 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6841 ld = tldap_context_create(talloc_tos(), fd);
6844 d_printf("tldap_context_create failed\n");
6848 rc = tldap_fetch_rootdse(ld);
6849 if (rc != TLDAP_SUCCESS) {
6850 d_printf("tldap_fetch_rootdse failed: %s\n",
6851 tldap_errstr(talloc_tos(), ld, rc));
6855 basedn = tldap_talloc_single_attribute(
6856 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6857 if (basedn == NULL) {
6858 d_printf("no defaultNamingContext\n");
6861 d_printf("defaultNamingContext: %s\n", basedn);
6863 ev = tevent_context_init(talloc_tos());
6865 d_printf("tevent_context_init failed\n");
6869 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6870 TLDAP_SCOPE_SUB, "(objectclass=*)",
6872 NULL, 0, NULL, 0, 0, 0, 0, 5);
6874 d_printf("tldap_search_paged_send failed\n");
6877 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6879 tevent_req_poll(req, ev);
6883 /* test search filters against rootDSE */
6884 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6885 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6887 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6888 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6889 talloc_tos(), NULL, NULL);
6890 if (rc != TLDAP_SUCCESS) {
6891 d_printf("tldap_search with complex filter failed: %s\n",
6892 tldap_errstr(talloc_tos(), ld, rc));
6900 /* Torture test to ensure no regression of :
6901 https://bugzilla.samba.org/show_bug.cgi?id=7084
6904 static bool run_dir_createtime(int dummy)
6906 struct cli_state *cli;
6907 const char *dname = "\\testdir";
6908 const char *fname = "\\testdir\\testfile";
6910 struct timespec create_time;
6911 struct timespec create_time1;
6915 if (!torture_open_connection(&cli, 0)) {
6919 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6920 cli_rmdir(cli, dname);
6922 status = cli_mkdir(cli, dname);
6923 if (!NT_STATUS_IS_OK(status)) {
6924 printf("mkdir failed: %s\n", nt_errstr(status));
6928 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6930 if (!NT_STATUS_IS_OK(status)) {
6931 printf("cli_qpathinfo2 returned %s\n",
6936 /* Sleep 3 seconds, then create a file. */
6939 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6941 if (!NT_STATUS_IS_OK(status)) {
6942 printf("cli_open failed: %s\n", nt_errstr(status));
6946 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6948 if (!NT_STATUS_IS_OK(status)) {
6949 printf("cli_qpathinfo2 (2) returned %s\n",
6954 if (timespec_compare(&create_time1, &create_time)) {
6955 printf("run_dir_createtime: create time was updated (error)\n");
6957 printf("run_dir_createtime: create time was not updated (correct)\n");
6963 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6964 cli_rmdir(cli, dname);
6965 if (!torture_close_connection(cli)) {
6972 static bool run_streamerror(int dummy)
6974 struct cli_state *cli;
6975 const char *dname = "\\testdir";
6976 const char *streamname =
6977 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6979 time_t change_time, access_time, write_time;
6981 uint16_t mode, fnum;
6984 if (!torture_open_connection(&cli, 0)) {
6988 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6989 cli_rmdir(cli, dname);
6991 status = cli_mkdir(cli, dname);
6992 if (!NT_STATUS_IS_OK(status)) {
6993 printf("mkdir failed: %s\n", nt_errstr(status));
6997 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6999 status = cli_nt_error(cli);
7001 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7002 printf("pathinfo returned %s, expected "
7003 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7008 status = cli_ntcreate(cli, streamname, 0x16,
7009 FILE_READ_DATA|FILE_READ_EA|
7010 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
7011 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
7012 FILE_OPEN, 0, 0, &fnum);
7014 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
7015 printf("ntcreate returned %s, expected "
7016 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
7022 cli_rmdir(cli, dname);
7026 static bool run_local_substitute(int dummy)
7030 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
7031 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
7032 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
7033 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
7034 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
7035 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
7036 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
7037 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
7039 /* Different captialization rules in sub_basic... */
7041 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
7047 static bool run_local_base64(int dummy)
7052 for (i=1; i<2000; i++) {
7053 DATA_BLOB blob1, blob2;
7056 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
7058 generate_random_buffer(blob1.data, blob1.length);
7060 b64 = base64_encode_data_blob(talloc_tos(), blob1);
7062 d_fprintf(stderr, "base64_encode_data_blob failed "
7063 "for %d bytes\n", i);
7066 blob2 = base64_decode_data_blob(b64);
7069 if (data_blob_cmp(&blob1, &blob2)) {
7070 d_fprintf(stderr, "data_blob_cmp failed for %d "
7074 TALLOC_FREE(blob1.data);
7075 data_blob_free(&blob2);
7080 static bool run_local_gencache(int dummy)
7086 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
7087 d_printf("%s: gencache_set() failed\n", __location__);
7091 if (!gencache_get("foo", NULL, NULL)) {
7092 d_printf("%s: gencache_get() failed\n", __location__);
7096 if (!gencache_get("foo", &val, &tm)) {
7097 d_printf("%s: gencache_get() failed\n", __location__);
7101 if (strcmp(val, "bar") != 0) {
7102 d_printf("%s: gencache_get() returned %s, expected %s\n",
7103 __location__, val, "bar");
7110 if (!gencache_del("foo")) {
7111 d_printf("%s: gencache_del() failed\n", __location__);
7114 if (gencache_del("foo")) {
7115 d_printf("%s: second gencache_del() succeeded\n",
7120 if (gencache_get("foo", &val, &tm)) {
7121 d_printf("%s: gencache_get() on deleted entry "
7122 "succeeded\n", __location__);
7126 blob = data_blob_string_const_null("bar");
7127 tm = time(NULL) + 60;
7129 if (!gencache_set_data_blob("foo", &blob, tm)) {
7130 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
7134 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7135 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
7139 if (strcmp((const char *)blob.data, "bar") != 0) {
7140 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
7141 __location__, (const char *)blob.data, "bar");
7142 data_blob_free(&blob);
7146 data_blob_free(&blob);
7148 if (!gencache_del("foo")) {
7149 d_printf("%s: gencache_del() failed\n", __location__);
7152 if (gencache_del("foo")) {
7153 d_printf("%s: second gencache_del() succeeded\n",
7158 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
7159 d_printf("%s: gencache_get_data_blob() on deleted entry "
7160 "succeeded\n", __location__);
7167 static bool rbt_testval(struct db_context *db, const char *key,
7170 struct db_record *rec;
7171 TDB_DATA data = string_tdb_data(value);
7175 rec = db->fetch_locked(db, db, string_tdb_data(key));
7177 d_fprintf(stderr, "fetch_locked failed\n");
7180 status = rec->store(rec, data, 0);
7181 if (!NT_STATUS_IS_OK(status)) {
7182 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
7187 rec = db->fetch_locked(db, db, string_tdb_data(key));
7189 d_fprintf(stderr, "second fetch_locked failed\n");
7192 if ((rec->value.dsize != data.dsize)
7193 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
7194 d_fprintf(stderr, "Got wrong data back\n");
7204 static bool run_local_rbtree(int dummy)
7206 struct db_context *db;
7210 db = db_open_rbt(NULL);
7213 d_fprintf(stderr, "db_open_rbt failed\n");
7217 for (i=0; i<1000; i++) {
7220 if (asprintf(&key, "key%ld", random()) == -1) {
7223 if (asprintf(&value, "value%ld", random()) == -1) {
7228 if (!rbt_testval(db, key, value)) {
7235 if (asprintf(&value, "value%ld", random()) == -1) {
7240 if (!rbt_testval(db, key, value)) {
7257 struct talloc_dict_test {
7261 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
7263 int *count = (int *)priv;
7268 static bool run_local_talloc_dict(int dummy)
7270 struct talloc_dict *dict;
7271 struct talloc_dict_test *t;
7274 dict = talloc_dict_init(talloc_tos());
7279 t = talloc(talloc_tos(), struct talloc_dict_test);
7286 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
7291 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
7304 static bool run_local_string_to_sid(int dummy) {
7307 if (string_to_sid(&sid, "S--1-5-32-545")) {
7308 printf("allowing S--1-5-32-545\n");
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-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0")) {
7316 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
7319 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
7320 printf("allowing S-1-5-32-545-abc\n");
7323 if (!string_to_sid(&sid, "S-1-5-32-545")) {
7324 printf("could not parse S-1-5-32-545\n");
7327 if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) {
7328 printf("mis-parsed S-1-5-32-545 as %s\n",
7329 sid_string_tos(&sid));
7335 static bool run_local_binary_to_sid(int dummy) {
7336 struct dom_sid *sid = talloc(NULL, struct dom_sid);
7337 static const char good_binary_sid[] = {
7338 0x1, /* revision number */
7340 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7341 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7342 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7343 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7344 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7345 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7346 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7347 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7348 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7349 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7350 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7351 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7352 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7353 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7354 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7355 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7358 static const char long_binary_sid[] = {
7359 0x1, /* revision number */
7361 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7362 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7363 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7364 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7365 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7366 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7367 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7368 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7369 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7370 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7371 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7372 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7373 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7374 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7375 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7376 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7377 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7378 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7379 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7382 static const char long_binary_sid2[] = {
7383 0x1, /* revision number */
7385 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, /* id_auth */
7386 0x1, 0x1, 0x1, 0x1, /* auth[0] */
7387 0x1, 0x1, 0x1, 0x1, /* auth[1] */
7388 0x1, 0x1, 0x1, 0x1, /* auth[2] */
7389 0x1, 0x1, 0x1, 0x1, /* auth[3] */
7390 0x1, 0x1, 0x1, 0x1, /* auth[4] */
7391 0x1, 0x1, 0x1, 0x1, /* auth[5] */
7392 0x1, 0x1, 0x1, 0x1, /* auth[6] */
7393 0x1, 0x1, 0x1, 0x1, /* auth[7] */
7394 0x1, 0x1, 0x1, 0x1, /* auth[8] */
7395 0x1, 0x1, 0x1, 0x1, /* auth[9] */
7396 0x1, 0x1, 0x1, 0x1, /* auth[10] */
7397 0x1, 0x1, 0x1, 0x1, /* auth[11] */
7398 0x1, 0x1, 0x1, 0x1, /* auth[12] */
7399 0x1, 0x1, 0x1, 0x1, /* auth[13] */
7400 0x1, 0x1, 0x1, 0x1, /* auth[14] */
7401 0x1, 0x1, 0x1, 0x1, /* auth[15] */
7402 0x1, 0x1, 0x1, 0x1, /* auth[16] */
7403 0x1, 0x1, 0x1, 0x1, /* auth[17] */
7404 0x1, 0x1, 0x1, 0x1, /* auth[18] */
7405 0x1, 0x1, 0x1, 0x1, /* auth[19] */
7406 0x1, 0x1, 0x1, 0x1, /* auth[20] */
7407 0x1, 0x1, 0x1, 0x1, /* auth[21] */
7408 0x1, 0x1, 0x1, 0x1, /* auth[22] */
7409 0x1, 0x1, 0x1, 0x1, /* auth[23] */
7410 0x1, 0x1, 0x1, 0x1, /* auth[24] */
7411 0x1, 0x1, 0x1, 0x1, /* auth[25] */
7412 0x1, 0x1, 0x1, 0x1, /* auth[26] */
7413 0x1, 0x1, 0x1, 0x1, /* auth[27] */
7414 0x1, 0x1, 0x1, 0x1, /* auth[28] */
7415 0x1, 0x1, 0x1, 0x1, /* auth[29] */
7416 0x1, 0x1, 0x1, 0x1, /* auth[30] */
7417 0x1, 0x1, 0x1, 0x1, /* auth[31] */
7420 if (!sid_parse(good_binary_sid, sizeof(good_binary_sid), sid)) {
7423 if (sid_parse(long_binary_sid2, sizeof(long_binary_sid2), sid)) {
7426 if (sid_parse(long_binary_sid, sizeof(long_binary_sid), sid)) {
7432 /* Split a path name into filename and stream name components. Canonicalise
7433 * such that an implicit $DATA token is always explicit.
7435 * The "specification" of this function can be found in the
7436 * run_local_stream_name() function in torture.c, I've tried those
7437 * combinations against a W2k3 server.
7440 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
7441 char **pbase, char **pstream)
7444 char *stream = NULL;
7445 char *sname; /* stream name */
7446 const char *stype; /* stream type */
7448 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
7450 sname = strchr_m(fname, ':');
7452 if (lp_posix_pathnames() || (sname == NULL)) {
7453 if (pbase != NULL) {
7454 base = talloc_strdup(mem_ctx, fname);
7455 NT_STATUS_HAVE_NO_MEMORY(base);
7460 if (pbase != NULL) {
7461 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
7462 NT_STATUS_HAVE_NO_MEMORY(base);
7467 stype = strchr_m(sname, ':');
7469 if (stype == NULL) {
7470 sname = talloc_strdup(mem_ctx, sname);
7474 if (StrCaseCmp(stype, ":$DATA") != 0) {
7476 * If there is an explicit stream type, so far we only
7477 * allow $DATA. Is there anything else allowed? -- vl
7479 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
7481 return NT_STATUS_OBJECT_NAME_INVALID;
7483 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
7487 if (sname == NULL) {
7489 return NT_STATUS_NO_MEMORY;
7492 if (sname[0] == '\0') {
7494 * no stream name, so no stream
7499 if (pstream != NULL) {
7500 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
7501 if (stream == NULL) {
7504 return NT_STATUS_NO_MEMORY;
7507 * upper-case the type field
7509 strupper_m(strchr_m(stream, ':')+1);
7513 if (pbase != NULL) {
7516 if (pstream != NULL) {
7519 return NT_STATUS_OK;
7522 static bool test_stream_name(const char *fname, const char *expected_base,
7523 const char *expected_stream,
7524 NTSTATUS expected_status)
7528 char *stream = NULL;
7530 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
7531 if (!NT_STATUS_EQUAL(status, expected_status)) {
7535 if (!NT_STATUS_IS_OK(status)) {
7539 if (base == NULL) goto error;
7541 if (strcmp(expected_base, base) != 0) goto error;
7543 if ((expected_stream != NULL) && (stream == NULL)) goto error;
7544 if ((expected_stream == NULL) && (stream != NULL)) goto error;
7546 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
7550 TALLOC_FREE(stream);
7554 d_fprintf(stderr, "Do test_stream(%s, %s, %s, %s)\n",
7555 fname, expected_base ? expected_base : "<NULL>",
7556 expected_stream ? expected_stream : "<NULL>",
7557 nt_errstr(expected_status));
7558 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
7559 base ? base : "<NULL>", stream ? stream : "<NULL>",
7562 TALLOC_FREE(stream);
7566 static bool run_local_stream_name(int dummy)
7570 ret &= test_stream_name(
7571 "bla", "bla", NULL, NT_STATUS_OK);
7572 ret &= test_stream_name(
7573 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
7574 ret &= test_stream_name(
7575 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7576 ret &= test_stream_name(
7577 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
7578 ret &= test_stream_name(
7579 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
7580 ret &= test_stream_name(
7581 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7582 ret &= test_stream_name(
7583 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7584 ret &= test_stream_name(
7585 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7590 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7592 if (a.length != b.length) {
7593 printf("a.length=%d != b.length=%d\n",
7594 (int)a.length, (int)b.length);
7597 if (memcmp(a.data, b.data, a.length) != 0) {
7598 printf("a.data and b.data differ\n");
7604 static bool run_local_memcache(int dummy)
7606 struct memcache *cache;
7608 DATA_BLOB d1, d2, d3;
7609 DATA_BLOB v1, v2, v3;
7611 TALLOC_CTX *mem_ctx;
7613 size_t size1, size2;
7616 cache = memcache_init(NULL, 100);
7618 if (cache == NULL) {
7619 printf("memcache_init failed\n");
7623 d1 = data_blob_const("d1", 2);
7624 d2 = data_blob_const("d2", 2);
7625 d3 = data_blob_const("d3", 2);
7627 k1 = data_blob_const("d1", 2);
7628 k2 = data_blob_const("d2", 2);
7630 memcache_add(cache, STAT_CACHE, k1, d1);
7631 memcache_add(cache, GETWD_CACHE, k2, d2);
7633 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7634 printf("could not find k1\n");
7637 if (!data_blob_equal(d1, v1)) {
7641 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7642 printf("could not find k2\n");
7645 if (!data_blob_equal(d2, v2)) {
7649 memcache_add(cache, STAT_CACHE, k1, d3);
7651 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7652 printf("could not find replaced k1\n");
7655 if (!data_blob_equal(d3, v3)) {
7659 memcache_add(cache, GETWD_CACHE, k1, d1);
7661 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7662 printf("Did find k2, should have been purged\n");
7668 cache = memcache_init(NULL, 0);
7670 mem_ctx = talloc_init("foo");
7672 str1 = talloc_strdup(mem_ctx, "string1");
7673 str2 = talloc_strdup(mem_ctx, "string2");
7675 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7676 data_blob_string_const("torture"), &str1);
7677 size1 = talloc_total_size(cache);
7679 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7680 data_blob_string_const("torture"), &str2);
7681 size2 = talloc_total_size(cache);
7683 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7685 if (size2 > size1) {
7686 printf("memcache leaks memory!\n");
7696 static void wbclient_done(struct tevent_req *req)
7699 struct winbindd_response *wb_resp;
7700 int *i = (int *)tevent_req_callback_data_void(req);
7702 wbc_err = wb_trans_recv(req, req, &wb_resp);
7705 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7708 static bool run_local_wbclient(int dummy)
7710 struct event_context *ev;
7711 struct wb_context **wb_ctx;
7712 struct winbindd_request wb_req;
7713 bool result = false;
7716 BlockSignals(True, SIGPIPE);
7718 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7723 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7724 if (wb_ctx == NULL) {
7728 ZERO_STRUCT(wb_req);
7729 wb_req.cmd = WINBINDD_PING;
7731 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7733 for (i=0; i<nprocs; i++) {
7734 wb_ctx[i] = wb_context_init(ev, NULL);
7735 if (wb_ctx[i] == NULL) {
7738 for (j=0; j<torture_numops; j++) {
7739 struct tevent_req *req;
7740 req = wb_trans_send(ev, ev, wb_ctx[i],
7741 (j % 2) == 0, &wb_req);
7745 tevent_req_set_callback(req, wbclient_done, &i);
7751 while (i < nprocs * torture_numops) {
7752 event_loop_once(ev);
7761 static void getaddrinfo_finished(struct tevent_req *req)
7763 char *name = (char *)tevent_req_callback_data_void(req);
7764 struct addrinfo *ainfo;
7767 res = getaddrinfo_recv(req, &ainfo);
7769 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7772 d_printf("gai(%s) succeeded\n", name);
7773 freeaddrinfo(ainfo);
7776 static bool run_getaddrinfo_send(int dummy)
7778 TALLOC_CTX *frame = talloc_stackframe();
7779 struct fncall_context *ctx;
7780 struct tevent_context *ev;
7781 bool result = false;
7782 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7783 "www.slashdot.org", "heise.de" };
7784 struct tevent_req *reqs[4];
7787 ev = event_context_init(frame);
7792 ctx = fncall_context_init(frame, 4);
7794 for (i=0; i<ARRAY_SIZE(names); i++) {
7795 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7797 if (reqs[i] == NULL) {
7800 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7804 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7805 tevent_loop_once(ev);
7814 static bool dbtrans_inc(struct db_context *db)
7816 struct db_record *rec;
7821 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7823 printf(__location__ "fetch_lock failed\n");
7827 if (rec->value.dsize != sizeof(uint32_t)) {
7828 printf(__location__ "value.dsize = %d\n",
7829 (int)rec->value.dsize);
7833 val = (uint32_t *)rec->value.dptr;
7836 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7839 if (!NT_STATUS_IS_OK(status)) {
7840 printf(__location__ "store failed: %s\n",
7851 static bool run_local_dbtrans(int dummy)
7853 struct db_context *db;
7854 struct db_record *rec;
7859 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7860 O_RDWR|O_CREAT, 0600);
7862 printf("Could not open transtest.db\n");
7866 res = db->transaction_start(db);
7868 printf(__location__ "transaction_start failed\n");
7872 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7874 printf(__location__ "fetch_lock failed\n");
7878 if (rec->value.dptr == NULL) {
7880 status = rec->store(
7881 rec, make_tdb_data((uint8_t *)&initial,
7884 if (!NT_STATUS_IS_OK(status)) {
7885 printf(__location__ "store returned %s\n",
7893 res = db->transaction_commit(db);
7895 printf(__location__ "transaction_commit failed\n");
7903 res = db->transaction_start(db);
7905 printf(__location__ "transaction_start failed\n");
7909 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7910 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7914 for (i=0; i<10; i++) {
7915 if (!dbtrans_inc(db)) {
7920 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7921 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7925 if (val2 != val + 10) {
7926 printf(__location__ "val=%d, val2=%d\n",
7927 (int)val, (int)val2);
7931 printf("val2=%d\r", val2);
7933 res = db->transaction_commit(db);
7935 printf(__location__ "transaction_commit failed\n");
7945 * Just a dummy test to be run under a debugger. There's no real way
7946 * to inspect the tevent_select specific function from outside of
7950 static bool run_local_tevent_select(int dummy)
7952 struct tevent_context *ev;
7953 struct tevent_fd *fd1, *fd2;
7954 bool result = false;
7956 ev = tevent_context_init_byname(NULL, "select");
7958 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7962 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7964 d_fprintf(stderr, "tevent_add_fd failed\n");
7967 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7969 d_fprintf(stderr, "tevent_add_fd failed\n");
7974 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7976 d_fprintf(stderr, "tevent_add_fd failed\n");
7986 static double create_procs(bool (*fn)(int), bool *result)
7989 volatile pid_t *child_status;
7990 volatile bool *child_status_out;
7993 struct timeval start;
7997 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7998 if (!child_status) {
7999 printf("Failed to setup shared memory\n");
8003 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
8004 if (!child_status_out) {
8005 printf("Failed to setup result status shared memory\n");
8009 for (i = 0; i < nprocs; i++) {
8010 child_status[i] = 0;
8011 child_status_out[i] = True;
8014 start = timeval_current();
8016 for (i=0;i<nprocs;i++) {
8019 pid_t mypid = getpid();
8020 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
8022 slprintf(myname,sizeof(myname),"CLIENT%d", i);
8025 if (torture_open_connection(¤t_cli, i)) break;
8027 printf("pid %d failed to start\n", (int)getpid());
8033 child_status[i] = getpid();
8035 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
8037 child_status_out[i] = fn(i);
8044 for (i=0;i<nprocs;i++) {
8045 if (child_status[i]) synccount++;
8047 if (synccount == nprocs) break;
8049 } while (timeval_elapsed(&start) < 30);
8051 if (synccount != nprocs) {
8052 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
8054 return timeval_elapsed(&start);
8057 /* start the client load */
8058 start = timeval_current();
8060 for (i=0;i<nprocs;i++) {
8061 child_status[i] = 0;
8064 printf("%d clients started\n", nprocs);
8066 for (i=0;i<nprocs;i++) {
8067 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
8072 for (i=0;i<nprocs;i++) {
8073 if (!child_status_out[i]) {
8077 return timeval_elapsed(&start);
8080 #define FLAG_MULTIPROC 1
8087 {"FDPASS", run_fdpasstest, 0},
8088 {"LOCK1", run_locktest1, 0},
8089 {"LOCK2", run_locktest2, 0},
8090 {"LOCK3", run_locktest3, 0},
8091 {"LOCK4", run_locktest4, 0},
8092 {"LOCK5", run_locktest5, 0},
8093 {"LOCK6", run_locktest6, 0},
8094 {"LOCK7", run_locktest7, 0},
8095 {"LOCK8", run_locktest8, 0},
8096 {"LOCK9", run_locktest9, 0},
8097 {"UNLINK", run_unlinktest, 0},
8098 {"BROWSE", run_browsetest, 0},
8099 {"ATTR", run_attrtest, 0},
8100 {"TRANS2", run_trans2test, 0},
8101 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
8102 {"TORTURE",run_torture, FLAG_MULTIPROC},
8103 {"RANDOMIPC", run_randomipc, 0},
8104 {"NEGNOWAIT", run_negprot_nowait, 0},
8105 {"NBENCH", run_nbench, 0},
8106 {"NBENCH2", run_nbench2, 0},
8107 {"OPLOCK1", run_oplock1, 0},
8108 {"OPLOCK2", run_oplock2, 0},
8109 {"OPLOCK3", run_oplock3, 0},
8110 {"OPLOCK4", run_oplock4, 0},
8111 {"DIR", run_dirtest, 0},
8112 {"DIR1", run_dirtest1, 0},
8113 {"DIR-CREATETIME", run_dir_createtime, 0},
8114 {"DENY1", torture_denytest1, 0},
8115 {"DENY2", torture_denytest2, 0},
8116 {"TCON", run_tcon_test, 0},
8117 {"TCONDEV", run_tcon_devtype_test, 0},
8118 {"RW1", run_readwritetest, 0},
8119 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
8120 {"RW3", run_readwritelarge, 0},
8121 {"RW-SIGNING", run_readwritelarge_signtest, 0},
8122 {"OPEN", run_opentest, 0},
8123 {"POSIX", run_simple_posix_open_test, 0},
8124 {"POSIX-APPEND", run_posix_append, 0},
8125 {"ASYNC-ECHO", run_async_echo, 0},
8126 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
8127 { "SHORTNAME-TEST", run_shortname_test, 0},
8128 { "ADDRCHANGE", run_addrchange, 0},
8130 {"OPENATTR", run_openattrtest, 0},
8132 {"XCOPY", run_xcopy, 0},
8133 {"RENAME", run_rename, 0},
8134 {"DELETE", run_deletetest, 0},
8135 {"DELETE-LN", run_deletetest_ln, 0},
8136 {"PROPERTIES", run_properties, 0},
8137 {"MANGLE", torture_mangle, 0},
8138 {"MANGLE1", run_mangle1, 0},
8139 {"W2K", run_w2ktest, 0},
8140 {"TRANS2SCAN", torture_trans2_scan, 0},
8141 {"NTTRANSSCAN", torture_nttrans_scan, 0},
8142 {"UTABLE", torture_utable, 0},
8143 {"CASETABLE", torture_casetable, 0},
8144 {"ERRMAPEXTRACT", run_error_map_extract, 0},
8145 {"PIPE_NUMBER", run_pipe_number, 0},
8146 {"TCON2", run_tcon2_test, 0},
8147 {"IOCTL", torture_ioctl_test, 0},
8148 {"CHKPATH", torture_chkpath_test, 0},
8149 {"FDSESS", run_fdsesstest, 0},
8150 { "EATEST", run_eatest, 0},
8151 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
8152 { "CHAIN1", run_chain1, 0},
8153 { "CHAIN2", run_chain2, 0},
8154 { "WINDOWS-WRITE", run_windows_write, 0},
8155 { "CLI_ECHO", run_cli_echo, 0},
8156 { "GETADDRINFO", run_getaddrinfo_send, 0},
8157 { "TLDAP", run_tldap },
8158 { "STREAMERROR", run_streamerror },
8159 { "NOTIFY-BENCH", run_notify_bench },
8160 { "BAD-NBT-SESSION", run_bad_nbt_session },
8161 { "SMB-ANY-CONNECT", run_smb_any_connect },
8162 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
8163 { "LOCAL-GENCACHE", run_local_gencache, 0},
8164 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
8165 { "LOCAL-BASE64", run_local_base64, 0},
8166 { "LOCAL-RBTREE", run_local_rbtree, 0},
8167 { "LOCAL-MEMCACHE", run_local_memcache, 0},
8168 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
8169 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
8170 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
8171 { "LOCAL-binary_to_sid", run_local_binary_to_sid, 0},
8172 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
8173 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
8178 /****************************************************************************
8179 run a specified test or "ALL"
8180 ****************************************************************************/
8181 static bool run_test(const char *name)
8188 if (strequal(name,"ALL")) {
8189 for (i=0;torture_ops[i].name;i++) {
8190 run_test(torture_ops[i].name);
8195 for (i=0;torture_ops[i].name;i++) {
8196 fstr_sprintf(randomfname, "\\XX%x",
8197 (unsigned)random());
8199 if (strequal(name, torture_ops[i].name)) {
8201 printf("Running %s\n", name);
8202 if (torture_ops[i].flags & FLAG_MULTIPROC) {
8203 t = create_procs(torture_ops[i].fn, &result);
8206 printf("TEST %s FAILED!\n", name);
8209 struct timeval start;
8210 start = timeval_current();
8211 if (!torture_ops[i].fn(0)) {
8213 printf("TEST %s FAILED!\n", name);
8215 t = timeval_elapsed(&start);
8217 printf("%s took %g secs\n\n", name, t);
8222 printf("Did not find a test named %s\n", name);
8230 static void usage(void)
8234 printf("WARNING samba4 test suite is much more complete nowadays.\n");
8235 printf("Please use samba4 torture.\n\n");
8237 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
8239 printf("\t-d debuglevel\n");
8240 printf("\t-U user%%pass\n");
8241 printf("\t-k use kerberos\n");
8242 printf("\t-N numprocs\n");
8243 printf("\t-n my_netbios_name\n");
8244 printf("\t-W workgroup\n");
8245 printf("\t-o num_operations\n");
8246 printf("\t-O socket_options\n");
8247 printf("\t-m maximum protocol\n");
8248 printf("\t-L use oplocks\n");
8249 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
8250 printf("\t-A showall\n");
8251 printf("\t-p port\n");
8252 printf("\t-s seed\n");
8253 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
8256 printf("tests are:");
8257 for (i=0;torture_ops[i].name;i++) {
8258 printf(" %s", torture_ops[i].name);
8262 printf("default test is ALL\n");
8267 /****************************************************************************
8269 ****************************************************************************/
8270 int main(int argc,char *argv[])
8276 bool correct = True;
8277 TALLOC_CTX *frame = talloc_stackframe();
8278 int seed = time(NULL);
8280 #ifdef HAVE_SETBUFFER
8281 setbuffer(stdout, NULL, 0);
8284 setup_logging("smbtorture", DEBUG_STDOUT);
8288 if (is_default_dyn_CONFIGFILE()) {
8289 if(getenv("SMB_CONF_PATH")) {
8290 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
8293 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
8300 for(p = argv[1]; *p; p++)
8304 if (strncmp(argv[1], "//", 2)) {
8308 fstrcpy(host, &argv[1][2]);
8309 p = strchr_m(&host[2],'/');
8314 fstrcpy(share, p+1);
8316 fstrcpy(myname, get_myname(talloc_tos()));
8318 fprintf(stderr, "Failed to get my hostname.\n");
8322 if (*username == 0 && getenv("LOGNAME")) {
8323 fstrcpy(username,getenv("LOGNAME"));
8329 fstrcpy(workgroup, lp_workgroup());
8331 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
8334 port_to_use = atoi(optarg);
8337 seed = atoi(optarg);
8340 fstrcpy(workgroup,optarg);
8343 max_protocol = interpret_protocol(optarg, max_protocol);
8346 nprocs = atoi(optarg);
8349 torture_numops = atoi(optarg);
8352 lp_set_cmdline("log level", optarg);
8361 local_path = optarg;
8364 torture_showall = True;
8367 fstrcpy(myname, optarg);
8370 client_txt = optarg;
8377 use_kerberos = True;
8379 d_printf("No kerberos support compiled in\n");
8385 fstrcpy(username,optarg);
8386 p = strchr_m(username,'%');
8389 fstrcpy(password, p+1);
8394 fstrcpy(multishare_conn_fname, optarg);
8395 use_multishare_conn = True;
8398 torture_blocksize = atoi(optarg);
8401 printf("Unknown option %c (%d)\n", (char)opt, opt);
8406 d_printf("using seed %d\n", seed);
8410 if(use_kerberos && !gotuser) gotpass = True;
8413 p = getpass("Password:");
8415 fstrcpy(password, p);
8420 printf("host=%s share=%s user=%s myname=%s\n",
8421 host, share, username, myname);
8423 if (argc == optind) {
8424 correct = run_test("ALL");
8426 for (i=optind;i<argc;i++) {
8427 if (!run_test(argv[i])) {