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 "nsswitch/libwbclient/wbc_async.h"
23 #include "torture/proto.h"
24 #include "libcli/security/dom_sid.h"
26 #include "tldap_util.h"
27 #include "../librpc/gen_ndr/svcctl.h"
29 #include "nsswitch/winbind_client.h"
35 static fstring host, workgroup, share, password, username, myname;
36 static int max_protocol = PROTOCOL_NT1;
37 static const char *sockops="TCP_NODELAY";
39 static int port_to_use=0;
40 int torture_numops=100;
41 int torture_blocksize=1024*1024;
42 static int procnum; /* records process count number when forking */
43 static struct cli_state *current_cli;
44 static fstring randomfname;
45 static bool use_oplocks;
46 static bool use_level_II_oplocks;
47 static const char *client_txt = "client_oplocks.txt";
48 static bool use_kerberos;
49 static fstring multishare_conn_fname;
50 static bool use_multishare_conn = False;
51 static bool do_encrypt;
52 static const char *local_path = NULL;
54 bool torture_showall = False;
56 static double create_procs(bool (*fn)(int), bool *result);
59 /* return a pointer to a anonymous shared memory segment of size "size"
60 which will persist across fork() but will disappear when all processes
63 The memory is not zeroed
65 This function uses system5 shared memory. It takes advantage of a property
66 that the memory is not destroyed if it is attached when the id is removed
68 void *shm_setup(int size)
74 shmid = shm_open("private", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
76 printf("can't get shared memory\n");
79 shm_unlink("private");
80 if (ftruncate(shmid, size) == -1) {
81 printf("can't set shared memory size\n");
84 ret = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, 0);
85 if (ret == MAP_FAILED) {
86 printf("can't map shared memory\n");
90 shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
92 printf("can't get shared memory\n");
95 ret = (void *)shmat(shmid, 0, 0);
96 if (!ret || ret == (void *)-1) {
97 printf("can't attach to shared memory\n");
100 /* the following releases the ipc, but note that this process
101 and all its children will still have access to the memory, its
102 just that the shmid is no longer valid for other shm calls. This
103 means we don't leave behind lots of shm segments after we exit
105 See Stevens "advanced programming in unix env" for details
107 shmctl(shmid, IPC_RMID, 0);
113 /********************************************************************
114 Ensure a connection is encrypted.
115 ********************************************************************/
117 static bool force_cli_encryption(struct cli_state *c,
118 const char *sharename)
121 uint32 caplow, caphigh;
124 if (!SERVER_HAS_UNIX_CIFS(c)) {
125 d_printf("Encryption required and "
126 "server that doesn't support "
127 "UNIX extensions - failing connect\n");
131 status = cli_unix_extensions_version(c, &major, &minor, &caplow,
133 if (!NT_STATUS_IS_OK(status)) {
134 d_printf("Encryption required and "
135 "can't get UNIX CIFS extensions "
136 "version from server: %s\n", nt_errstr(status));
140 if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
141 d_printf("Encryption required and "
142 "share %s doesn't support "
143 "encryption.\n", sharename);
147 if (c->use_kerberos) {
148 status = cli_gss_smb_encryption_start(c);
150 status = cli_raw_ntlm_smb_encryption_start(c,
156 if (!NT_STATUS_IS_OK(status)) {
157 d_printf("Encryption required and "
158 "setup failed with error %s.\n",
167 static struct cli_state *open_nbt_connection(void)
169 struct nmb_name called, calling;
170 struct sockaddr_storage ss;
174 make_nmb_name(&calling, myname, 0x0);
175 make_nmb_name(&called , host, 0x20);
179 if (!(c = cli_initialise())) {
180 printf("Failed initialize cli_struct to connect with %s\n", host);
184 c->port = port_to_use;
186 status = cli_connect(c, host, &ss);
187 if (!NT_STATUS_IS_OK(status)) {
188 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
192 c->use_kerberos = use_kerberos;
194 c->timeout = 120000; /* set a really long timeout (2 minutes) */
195 if (use_oplocks) c->use_oplocks = True;
196 if (use_level_II_oplocks) c->use_level_II_oplocks = True;
198 if (!cli_session_request(c, &calling, &called)) {
200 * Well, that failed, try *SMBSERVER ...
201 * However, we must reconnect as well ...
203 status = cli_connect(c, host, &ss);
204 if (!NT_STATUS_IS_OK(status)) {
205 printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
209 make_nmb_name(&called, "*SMBSERVER", 0x20);
210 if (!cli_session_request(c, &calling, &called)) {
211 printf("%s rejected the session\n",host);
212 printf("We tried with a called name of %s & %s\n",
222 /* Insert a NULL at the first separator of the given path and return a pointer
223 * to the remainder of the string.
226 terminate_path_at_separator(char * path)
234 if ((p = strchr_m(path, '/'))) {
239 if ((p = strchr_m(path, '\\'))) {
249 parse a //server/share type UNC name
251 bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
252 char **hostname, char **sharename)
256 *hostname = *sharename = NULL;
258 if (strncmp(unc_name, "\\\\", 2) &&
259 strncmp(unc_name, "//", 2)) {
263 *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
264 p = terminate_path_at_separator(*hostname);
267 *sharename = talloc_strdup(mem_ctx, p);
268 terminate_path_at_separator(*sharename);
271 if (*hostname && *sharename) {
275 TALLOC_FREE(*hostname);
276 TALLOC_FREE(*sharename);
280 static bool torture_open_connection_share(struct cli_state **c,
281 const char *hostname,
282 const char *sharename)
289 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
291 flags |= CLI_FULL_CONNECTION_OPLOCKS;
292 if (use_level_II_oplocks)
293 flags |= CLI_FULL_CONNECTION_LEVEL_II_OPLOCKS;
295 status = cli_full_connection(c, myname,
296 hostname, NULL, port_to_use,
299 password, flags, Undefined, &retry);
300 if (!NT_STATUS_IS_OK(status)) {
301 printf("failed to open share connection: //%s/%s port:%d - %s\n",
302 hostname, sharename, port_to_use, nt_errstr(status));
306 (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
309 return force_cli_encryption(*c,
315 bool torture_open_connection(struct cli_state **c, int conn_index)
317 char **unc_list = NULL;
318 int num_unc_names = 0;
321 if (use_multishare_conn==True) {
323 unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
324 if (!unc_list || num_unc_names <= 0) {
325 printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
329 if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
331 printf("Failed to parse UNC name %s\n",
332 unc_list[conn_index % num_unc_names]);
333 TALLOC_FREE(unc_list);
337 result = torture_open_connection_share(c, h, s);
339 /* h, s were copied earlier */
340 TALLOC_FREE(unc_list);
344 return torture_open_connection_share(c, host, share);
347 bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
349 uint16 old_vuid = cli->vuid;
350 fstring old_user_name;
351 size_t passlen = strlen(password);
355 fstrcpy(old_user_name, cli->user_name);
357 ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
361 *new_vuid = cli->vuid;
362 cli->vuid = old_vuid;
363 status = cli_set_username(cli, old_user_name);
364 if (!NT_STATUS_IS_OK(status)) {
371 bool torture_close_connection(struct cli_state *c)
376 status = cli_tdis(c);
377 if (!NT_STATUS_IS_OK(status)) {
378 printf("tdis failed (%s)\n", nt_errstr(status));
388 /* check if the server produced the expected error code */
389 static bool check_error(int line, struct cli_state *c,
390 uint8 eclass, uint32 ecode, NTSTATUS nterr)
392 if (cli_is_dos_error(c)) {
396 /* Check DOS error */
398 cli_dos_error(c, &cclass, &num);
400 if (eclass != cclass || ecode != num) {
401 printf("unexpected error code class=%d code=%d\n",
402 (int)cclass, (int)num);
403 printf(" expected %d/%d %s (line=%d)\n",
404 (int)eclass, (int)ecode, nt_errstr(nterr), line);
413 status = cli_nt_error(c);
415 if (NT_STATUS_V(nterr) != NT_STATUS_V(status)) {
416 printf("unexpected error code %s\n", nt_errstr(status));
417 printf(" expected %s (line=%d)\n", nt_errstr(nterr), line);
426 static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
428 while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
429 if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
435 static bool rw_torture(struct cli_state *c)
437 const char *lockfname = "\\torture.lck";
441 pid_t pid2, pid = getpid();
447 memset(buf, '\0', sizeof(buf));
449 status = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
451 if (!NT_STATUS_IS_OK(status)) {
452 status = cli_open(c, lockfname, O_RDWR, DENY_NONE, &fnum2);
454 if (!NT_STATUS_IS_OK(status)) {
455 printf("open of %s failed (%s)\n", lockfname, cli_errstr(c));
459 for (i=0;i<torture_numops;i++) {
460 unsigned n = (unsigned)sys_random()%10;
462 printf("%d\r", i); fflush(stdout);
464 slprintf(fname, sizeof(fstring) - 1, "\\torture.%u", n);
466 if (!wait_lock(c, fnum2, n*sizeof(int), sizeof(int))) {
470 if (!NT_STATUS_IS_OK(cli_open(c, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL, &fnum))) {
471 printf("open failed (%s)\n", cli_errstr(c));
476 if (cli_write(c, fnum, 0, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) {
477 printf("write failed (%s)\n", cli_errstr(c));
482 if (cli_write(c, fnum, 0, (char *)buf,
483 sizeof(pid)+(j*sizeof(buf)),
484 sizeof(buf)) != sizeof(buf)) {
485 printf("write failed (%s)\n", cli_errstr(c));
492 if (cli_read(c, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) {
493 printf("read failed (%s)\n", cli_errstr(c));
498 printf("data corruption!\n");
502 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
503 printf("close failed (%s)\n", cli_errstr(c));
507 if (!NT_STATUS_IS_OK(cli_unlink(c, fname, aSYSTEM | aHIDDEN))) {
508 printf("unlink failed (%s)\n", cli_errstr(c));
512 if (!NT_STATUS_IS_OK(cli_unlock(c, fnum2, n*sizeof(int), sizeof(int)))) {
513 printf("unlock failed (%s)\n", cli_errstr(c));
519 cli_unlink(c, lockfname, aSYSTEM | aHIDDEN);
526 static bool run_torture(int dummy)
528 struct cli_state *cli;
533 cli_sockopt(cli, sockops);
535 ret = rw_torture(cli);
537 if (!torture_close_connection(cli)) {
544 static bool rw_torture3(struct cli_state *c, char *lockfname)
546 uint16_t fnum = (uint16_t)-1;
551 unsigned countprev = 0;
557 for (i = 0; i < sizeof(buf); i += sizeof(uint32))
559 SIVAL(buf, i, sys_random());
564 if (!NT_STATUS_IS_OK(cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL,
565 DENY_NONE, &fnum))) {
566 printf("first open read/write of %s failed (%s)\n",
567 lockfname, cli_errstr(c));
573 for (i = 0; i < 500 && fnum == (uint16_t)-1; i++)
575 status = cli_open(c, lockfname, O_RDONLY,
577 if (!NT_STATUS_IS_OK(status)) {
582 if (!NT_STATUS_IS_OK(status)) {
583 printf("second open read-only of %s failed (%s)\n",
584 lockfname, cli_errstr(c));
590 for (count = 0; count < sizeof(buf); count += sent)
592 if (count >= countprev) {
593 printf("%d %8d\r", i, count);
596 countprev += (sizeof(buf) / 20);
601 sent = ((unsigned)sys_random()%(20))+ 1;
602 if (sent > sizeof(buf) - count)
604 sent = sizeof(buf) - count;
607 if (cli_write(c, fnum, 0, buf+count, count, (size_t)sent) != sent) {
608 printf("write failed (%s)\n", cli_errstr(c));
614 sent = cli_read(c, fnum, buf_rd+count, count,
618 printf("read failed offset:%d size:%ld (%s)\n",
619 count, (unsigned long)sizeof(buf)-count,
626 if (memcmp(buf_rd+count, buf+count, sent) != 0)
628 printf("read/write compare failed\n");
629 printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
638 if (!NT_STATUS_IS_OK(cli_close(c, fnum))) {
639 printf("close failed (%s)\n", cli_errstr(c));
646 static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
648 const char *lockfname = "\\torture2.lck";
657 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
658 printf("unlink failed (%s) (normal, this file should not exist)\n", cli_errstr(c1));
661 if (!NT_STATUS_IS_OK(cli_open(c1, lockfname, O_RDWR | O_CREAT | O_EXCL,
662 DENY_NONE, &fnum1))) {
663 printf("first open read/write of %s failed (%s)\n",
664 lockfname, cli_errstr(c1));
667 if (!NT_STATUS_IS_OK(cli_open(c2, lockfname, O_RDONLY,
668 DENY_NONE, &fnum2))) {
669 printf("second open read-only of %s failed (%s)\n",
670 lockfname, cli_errstr(c2));
671 cli_close(c1, fnum1);
675 for (i=0;i<torture_numops;i++)
677 size_t buf_size = ((unsigned)sys_random()%(sizeof(buf)-1))+ 1;
679 printf("%d\r", i); fflush(stdout);
682 generate_random_buffer((unsigned char *)buf, buf_size);
684 if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
685 printf("write failed (%s)\n", cli_errstr(c1));
690 if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
691 printf("read failed (%s)\n", cli_errstr(c2));
692 printf("read %d, expected %ld\n", (int)bytes_read,
693 (unsigned long)buf_size);
698 if (memcmp(buf_rd, buf, buf_size) != 0)
700 printf("read/write compare failed\n");
706 if (!NT_STATUS_IS_OK(cli_close(c2, fnum2))) {
707 printf("close failed (%s)\n", cli_errstr(c2));
710 if (!NT_STATUS_IS_OK(cli_close(c1, fnum1))) {
711 printf("close failed (%s)\n", cli_errstr(c1));
715 if (!NT_STATUS_IS_OK(cli_unlink(c1, lockfname, aSYSTEM | aHIDDEN))) {
716 printf("unlink failed (%s)\n", cli_errstr(c1));
723 static bool run_readwritetest(int dummy)
725 struct cli_state *cli1, *cli2;
726 bool test1, test2 = False;
728 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
731 cli_sockopt(cli1, sockops);
732 cli_sockopt(cli2, sockops);
734 printf("starting readwritetest\n");
736 test1 = rw_torture2(cli1, cli2);
737 printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
740 test2 = rw_torture2(cli1, cli1);
741 printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
744 if (!torture_close_connection(cli1)) {
748 if (!torture_close_connection(cli2)) {
752 return (test1 && test2);
755 static bool run_readwritemulti(int dummy)
757 struct cli_state *cli;
762 cli_sockopt(cli, sockops);
764 printf("run_readwritemulti: fname %s\n", randomfname);
765 test = rw_torture3(cli, randomfname);
767 if (!torture_close_connection(cli)) {
774 static bool run_readwritelarge(int dummy)
776 static struct cli_state *cli1;
778 const char *lockfname = "\\large.dat";
783 if (!torture_open_connection(&cli1, 0)) {
786 cli_sockopt(cli1, sockops);
787 memset(buf,'\0',sizeof(buf));
789 cli1->max_xmit = 128*1024;
791 printf("starting readwritelarge\n");
793 cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN);
795 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
796 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
800 cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
802 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
803 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
807 if (fsize == sizeof(buf))
808 printf("readwritelarge test 1 succeeded (size = %lx)\n",
809 (unsigned long)fsize);
811 printf("readwritelarge test 1 failed (size = %lx)\n",
812 (unsigned long)fsize);
816 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
817 printf("close failed (%s)\n", cli_errstr(cli1));
821 if (!NT_STATUS_IS_OK(cli_unlink(cli1, lockfname, aSYSTEM | aHIDDEN))) {
822 printf("unlink failed (%s)\n", cli_errstr(cli1));
826 if (!NT_STATUS_IS_OK(cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE, &fnum1))) {
827 printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
831 cli1->max_xmit = 4*1024;
833 cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
835 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
836 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
840 if (fsize == sizeof(buf))
841 printf("readwritelarge test 2 succeeded (size = %lx)\n",
842 (unsigned long)fsize);
844 printf("readwritelarge test 2 failed (size = %lx)\n",
845 (unsigned long)fsize);
850 /* ToDo - set allocation. JRA */
851 if(!cli_set_allocation_size(cli1, fnum1, 0)) {
852 printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
855 if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
856 printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
860 printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
863 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
864 printf("close failed (%s)\n", cli_errstr(cli1));
868 if (!torture_close_connection(cli1)) {
877 #define ival(s) strtol(s, NULL, 0)
879 /* run a test that simulates an approximate netbench client load */
880 static bool run_netbench(int client)
882 struct cli_state *cli;
887 const char *params[20];
894 cli_sockopt(cli, sockops);
898 slprintf(cname,sizeof(cname)-1, "client%d", client);
900 f = fopen(client_txt, "r");
907 while (fgets(line, sizeof(line)-1, f)) {
911 line[strlen(line)-1] = 0;
913 /* printf("[%d] %s\n", line_count, line); */
915 all_string_sub(line,"client1", cname, sizeof(line));
917 /* parse the command parameters */
918 params[0] = strtok_r(line, " ", &saveptr);
920 while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
926 if (!strncmp(params[0],"SMB", 3)) {
927 printf("ERROR: You are using a dbench 1 load file\n");
931 if (!strcmp(params[0],"NTCreateX")) {
932 nb_createx(params[1], ival(params[2]), ival(params[3]),
934 } else if (!strcmp(params[0],"Close")) {
935 nb_close(ival(params[1]));
936 } else if (!strcmp(params[0],"Rename")) {
937 nb_rename(params[1], params[2]);
938 } else if (!strcmp(params[0],"Unlink")) {
939 nb_unlink(params[1]);
940 } else if (!strcmp(params[0],"Deltree")) {
941 nb_deltree(params[1]);
942 } else if (!strcmp(params[0],"Rmdir")) {
944 } else if (!strcmp(params[0],"QUERY_PATH_INFORMATION")) {
945 nb_qpathinfo(params[1]);
946 } else if (!strcmp(params[0],"QUERY_FILE_INFORMATION")) {
947 nb_qfileinfo(ival(params[1]));
948 } else if (!strcmp(params[0],"QUERY_FS_INFORMATION")) {
949 nb_qfsinfo(ival(params[1]));
950 } else if (!strcmp(params[0],"FIND_FIRST")) {
951 nb_findfirst(params[1]);
952 } else if (!strcmp(params[0],"WriteX")) {
953 nb_writex(ival(params[1]),
954 ival(params[2]), ival(params[3]), ival(params[4]));
955 } else if (!strcmp(params[0],"ReadX")) {
956 nb_readx(ival(params[1]),
957 ival(params[2]), ival(params[3]), ival(params[4]));
958 } else if (!strcmp(params[0],"Flush")) {
959 nb_flush(ival(params[1]));
961 printf("Unknown operation %s\n", params[0]);
969 if (!torture_close_connection(cli)) {
977 /* run a test that simulates an approximate netbench client load */
978 static bool run_nbench(int dummy)
987 signal(SIGALRM, nb_alarm);
989 t = create_procs(run_netbench, &correct);
992 printf("\nThroughput %g MB/sec\n",
993 1.0e-6 * nbio_total() / t);
999 This test checks for two things:
1001 1) correct support for retaining locks over a close (ie. the server
1002 must not use posix semantics)
1003 2) support for lock timeouts
1005 static bool run_locktest1(int dummy)
1007 struct cli_state *cli1, *cli2;
1008 const char *fname = "\\lockt1.lck";
1009 uint16_t fnum1, fnum2, fnum3;
1011 unsigned lock_timeout;
1013 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1016 cli_sockopt(cli1, sockops);
1017 cli_sockopt(cli2, sockops);
1019 printf("starting locktest1\n");
1021 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1023 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1024 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1027 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum2))) {
1028 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
1031 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum3))) {
1032 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
1036 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
1037 printf("lock1 failed (%s)\n", cli_errstr(cli1));
1042 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1043 printf("lock2 succeeded! This is a locking bug\n");
1046 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1047 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1051 lock_timeout = (1 + (random() % 20));
1052 printf("Testing lock timeout with timeout=%u\n", lock_timeout);
1054 if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
1055 printf("lock3 succeeded! This is a locking bug\n");
1058 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1059 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1063 if (ABS(t2 - t1) < lock_timeout-1) {
1064 printf("error: This server appears not to support timed lock requests\n");
1067 printf("server slept for %u seconds for a %u second timeout\n",
1068 (unsigned int)(t2-t1), lock_timeout);
1070 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
1071 printf("close1 failed (%s)\n", cli_errstr(cli1));
1075 if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
1076 printf("lock4 succeeded! This is a locking bug\n");
1079 if (!check_error(__LINE__, cli2, ERRDOS, ERRlock,
1080 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1083 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1084 printf("close2 failed (%s)\n", cli_errstr(cli1));
1088 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum3))) {
1089 printf("close3 failed (%s)\n", cli_errstr(cli2));
1093 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1094 printf("unlink failed (%s)\n", cli_errstr(cli1));
1099 if (!torture_close_connection(cli1)) {
1103 if (!torture_close_connection(cli2)) {
1107 printf("Passed locktest1\n");
1112 this checks to see if a secondary tconx can use open files from an
1115 static bool run_tcon_test(int dummy)
1117 static struct cli_state *cli;
1118 const char *fname = "\\tcontest.tmp";
1120 uint16 cnum1, cnum2, cnum3;
1121 uint16 vuid1, vuid2;
1126 memset(buf, '\0', sizeof(buf));
1128 if (!torture_open_connection(&cli, 0)) {
1131 cli_sockopt(cli, sockops);
1133 printf("starting tcontest\n");
1135 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1137 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1138 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1145 if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
1146 printf("initial write failed (%s)", cli_errstr(cli));
1150 status = cli_tcon_andx(cli, share, "?????",
1151 password, strlen(password)+1);
1152 if (!NT_STATUS_IS_OK(status)) {
1153 printf("%s refused 2nd tree connect (%s)\n", host,
1160 cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
1161 vuid2 = cli->vuid + 1;
1163 /* try a write with the wrong tid */
1166 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1167 printf("* server allows write with wrong TID\n");
1170 printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
1174 /* try a write with an invalid tid */
1177 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1178 printf("* server allows write with invalid TID\n");
1181 printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
1184 /* try a write with an invalid vuid */
1188 if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
1189 printf("* server allows write with invalid VUID\n");
1192 printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
1198 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1199 printf("close failed (%s)\n", cli_errstr(cli));
1205 status = cli_tdis(cli);
1206 if (!NT_STATUS_IS_OK(status)) {
1207 printf("secondary tdis failed (%s)\n", nt_errstr(status));
1213 if (!torture_close_connection(cli)) {
1222 checks for old style tcon support
1224 static bool run_tcon2_test(int dummy)
1226 static struct cli_state *cli;
1227 uint16 cnum, max_xmit;
1231 if (!torture_open_connection(&cli, 0)) {
1234 cli_sockopt(cli, sockops);
1236 printf("starting tcon2 test\n");
1238 if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
1242 status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
1244 if (!NT_STATUS_IS_OK(status)) {
1245 printf("tcon2 failed : %s\n", cli_errstr(cli));
1247 printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n",
1248 (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
1251 if (!torture_close_connection(cli)) {
1255 printf("Passed tcon2 test\n");
1259 static bool tcon_devtest(struct cli_state *cli,
1260 const char *myshare, const char *devtype,
1261 const char *return_devtype,
1262 NTSTATUS expected_error)
1267 status = cli_tcon_andx(cli, myshare, devtype,
1268 password, strlen(password)+1);
1270 if (NT_STATUS_IS_OK(expected_error)) {
1271 if (NT_STATUS_IS_OK(status)) {
1272 if (strcmp(cli->dev, return_devtype) == 0) {
1275 printf("tconX to share %s with type %s "
1276 "succeeded but returned the wrong "
1277 "device type (got [%s] but should have got [%s])\n",
1278 myshare, devtype, cli->dev, return_devtype);
1282 printf("tconX to share %s with type %s "
1283 "should have succeeded but failed\n",
1289 if (NT_STATUS_IS_OK(status)) {
1290 printf("tconx to share %s with type %s "
1291 "should have failed but succeeded\n",
1295 if (NT_STATUS_EQUAL(cli_nt_error(cli),
1299 printf("Returned unexpected error\n");
1308 checks for correct tconX support
1310 static bool run_tcon_devtype_test(int dummy)
1312 static struct cli_state *cli1 = NULL;
1318 status = cli_full_connection(&cli1, myname,
1319 host, NULL, port_to_use,
1321 username, workgroup,
1322 password, flags, Undefined, &retry);
1324 if (!NT_STATUS_IS_OK(status)) {
1325 printf("could not open connection\n");
1329 if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1332 if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
1335 if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1338 if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
1341 if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1344 if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
1347 if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
1350 if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1353 if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1356 if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
1362 printf("Passed tcondevtest\n");
1369 This test checks that
1371 1) the server supports multiple locking contexts on the one SMB
1372 connection, distinguished by PID.
1374 2) the server correctly fails overlapping locks made by the same PID (this
1375 goes against POSIX behaviour, which is why it is tricky to implement)
1377 3) the server denies unlock requests by an incorrect client PID
1379 static bool run_locktest2(int dummy)
1381 static struct cli_state *cli;
1382 const char *fname = "\\lockt2.lck";
1383 uint16_t fnum1, fnum2, fnum3;
1384 bool correct = True;
1386 if (!torture_open_connection(&cli, 0)) {
1390 cli_sockopt(cli, sockops);
1392 printf("starting locktest2\n");
1394 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
1398 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1399 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
1403 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum2))) {
1404 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
1410 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum3))) {
1411 printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
1417 if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1418 printf("lock1 failed (%s)\n", cli_errstr(cli));
1422 if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
1423 printf("WRITE lock1 succeeded! This is a locking bug\n");
1426 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1427 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1430 if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
1431 printf("WRITE lock2 succeeded! This is a locking bug\n");
1434 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1435 NT_STATUS_LOCK_NOT_GRANTED)) return False;
1438 if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
1439 printf("READ lock2 succeeded! This is a locking bug\n");
1442 if (!check_error(__LINE__, cli, ERRDOS, ERRlock,
1443 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
1446 if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
1447 printf("lock at 100 failed (%s)\n", cli_errstr(cli));
1450 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 100, 4))) {
1451 printf("unlock at 100 succeeded! This is a locking bug\n");
1455 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 4))) {
1456 printf("unlock1 succeeded! This is a locking bug\n");
1459 if (!check_error(__LINE__, cli,
1461 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1464 if (NT_STATUS_IS_OK(cli_unlock(cli, fnum1, 0, 8))) {
1465 printf("unlock2 succeeded! This is a locking bug\n");
1468 if (!check_error(__LINE__, cli,
1470 NT_STATUS_RANGE_NOT_LOCKED)) return False;
1473 if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
1474 printf("lock3 succeeded! This is a locking bug\n");
1477 if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
1482 if (!NT_STATUS_IS_OK(cli_close(cli, fnum1))) {
1483 printf("close1 failed (%s)\n", cli_errstr(cli));
1487 if (!NT_STATUS_IS_OK(cli_close(cli, fnum2))) {
1488 printf("close2 failed (%s)\n", cli_errstr(cli));
1492 if (!NT_STATUS_IS_OK(cli_close(cli, fnum3))) {
1493 printf("close3 failed (%s)\n", cli_errstr(cli));
1497 if (!torture_close_connection(cli)) {
1501 printf("locktest2 finished\n");
1508 This test checks that
1510 1) the server supports the full offset range in lock requests
1512 static bool run_locktest3(int dummy)
1514 static struct cli_state *cli1, *cli2;
1515 const char *fname = "\\lockt3.lck";
1516 uint16_t fnum1, fnum2;
1519 bool correct = True;
1521 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
1523 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1526 cli_sockopt(cli1, sockops);
1527 cli_sockopt(cli2, sockops);
1529 printf("starting locktest3\n");
1531 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1533 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
1534 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
1537 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
1538 printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
1542 for (offset=i=0;i<torture_numops;i++) {
1544 if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1545 printf("lock1 %d failed (%s)\n",
1551 if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1552 printf("lock2 %d failed (%s)\n",
1559 for (offset=i=0;i<torture_numops;i++) {
1562 if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
1563 printf("error: lock1 %d succeeded!\n", i);
1567 if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
1568 printf("error: lock2 %d succeeded!\n", i);
1572 if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
1573 printf("error: lock3 %d succeeded!\n", i);
1577 if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
1578 printf("error: lock4 %d succeeded!\n", i);
1583 for (offset=i=0;i<torture_numops;i++) {
1586 if (!NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, offset-1, 1))) {
1587 printf("unlock1 %d failed (%s)\n",
1593 if (!NT_STATUS_IS_OK(cli_unlock(cli2, fnum2, offset-2, 1))) {
1594 printf("unlock2 %d failed (%s)\n",
1601 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
1602 printf("close1 failed (%s)\n", cli_errstr(cli1));
1606 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
1607 printf("close2 failed (%s)\n", cli_errstr(cli2));
1611 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
1612 printf("unlink failed (%s)\n", cli_errstr(cli1));
1616 if (!torture_close_connection(cli1)) {
1620 if (!torture_close_connection(cli2)) {
1624 printf("finished locktest3\n");
1629 #define EXPECTED(ret, v) if ((ret) != (v)) { \
1630 printf("** "); correct = False; \
1634 looks at overlapping locks
1636 static bool run_locktest4(int dummy)
1638 static struct cli_state *cli1, *cli2;
1639 const char *fname = "\\lockt4.lck";
1640 uint16_t fnum1, fnum2, f;
1643 bool correct = True;
1645 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1649 cli_sockopt(cli1, sockops);
1650 cli_sockopt(cli2, sockops);
1652 printf("starting locktest4\n");
1654 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1656 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1657 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1659 memset(buf, 0, sizeof(buf));
1661 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1662 printf("Failed to create file\n");
1667 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1668 cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
1669 EXPECTED(ret, False);
1670 printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
1672 ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
1673 cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
1674 EXPECTED(ret, True);
1675 printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
1677 ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
1678 cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
1679 EXPECTED(ret, False);
1680 printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
1682 ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
1683 cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
1684 EXPECTED(ret, True);
1685 printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
1687 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
1688 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
1689 EXPECTED(ret, False);
1690 printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
1692 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
1693 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
1694 EXPECTED(ret, True);
1695 printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
1697 ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
1698 cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
1699 EXPECTED(ret, True);
1700 printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
1702 ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
1703 cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
1704 EXPECTED(ret, False);
1705 printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
1707 ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
1708 cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
1709 EXPECTED(ret, False);
1710 printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
1712 ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
1713 cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
1714 EXPECTED(ret, True);
1715 printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1717 ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
1718 (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
1719 EXPECTED(ret, False);
1720 printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
1722 ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
1723 cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
1724 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 110, 6));
1725 EXPECTED(ret, False);
1726 printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
1729 ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
1730 (cli_read(cli2, fnum2, buf, 120, 4) == 4);
1731 EXPECTED(ret, False);
1732 printf("this server %s strict write locking\n", ret?"doesn't do":"does");
1734 ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
1735 (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
1736 EXPECTED(ret, False);
1737 printf("this server %s strict read locking\n", ret?"doesn't do":"does");
1740 ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1741 cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
1742 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4)) &&
1743 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 140, 4));
1744 EXPECTED(ret, True);
1745 printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
1748 ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
1749 cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
1750 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4)) &&
1751 (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
1752 !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
1753 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 150, 4));
1754 EXPECTED(ret, True);
1755 printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
1757 ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
1758 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 160, 4)) &&
1759 (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&
1760 (cli_read(cli2, fnum2, buf, 160, 4) == 4);
1761 EXPECTED(ret, True);
1762 printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
1764 ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
1765 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 170, 4)) &&
1766 (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&
1767 (cli_read(cli2, fnum2, buf, 170, 4) == 4);
1768 EXPECTED(ret, True);
1769 printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
1771 ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
1772 cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
1773 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 190, 4)) &&
1774 !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&
1775 (cli_read(cli2, fnum2, buf, 190, 4) == 4);
1776 EXPECTED(ret, True);
1777 printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
1779 cli_close(cli1, fnum1);
1780 cli_close(cli2, fnum2);
1781 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1782 cli_open(cli1, fname, O_RDWR, DENY_NONE, &f);
1783 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1784 cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
1785 NT_STATUS_IS_OK(cli_close(cli1, fnum1)) &&
1786 NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1)) &&
1787 cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1789 cli_close(cli1, fnum1);
1790 EXPECTED(ret, True);
1791 printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
1794 cli_close(cli1, fnum1);
1795 cli_close(cli2, fnum2);
1796 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1797 torture_close_connection(cli1);
1798 torture_close_connection(cli2);
1800 printf("finished locktest4\n");
1805 looks at lock upgrade/downgrade.
1807 static bool run_locktest5(int dummy)
1809 static struct cli_state *cli1, *cli2;
1810 const char *fname = "\\lockt5.lck";
1811 uint16_t fnum1, fnum2, fnum3;
1814 bool correct = True;
1816 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
1820 cli_sockopt(cli1, sockops);
1821 cli_sockopt(cli2, sockops);
1823 printf("starting locktest5\n");
1825 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1827 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1828 cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2);
1829 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum3);
1831 memset(buf, 0, sizeof(buf));
1833 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1834 printf("Failed to create file\n");
1839 /* Check for NT bug... */
1840 ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
1841 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
1842 cli_close(cli1, fnum1);
1843 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1844 ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
1845 EXPECTED(ret, True);
1846 printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
1847 cli_close(cli1, fnum1);
1848 cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
1849 cli_unlock(cli1, fnum3, 0, 1);
1851 ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
1852 cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
1853 EXPECTED(ret, True);
1854 printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
1856 ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1857 EXPECTED(ret, False);
1859 printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
1861 /* Unlock the process 2 lock. */
1862 cli_unlock(cli2, fnum2, 0, 4);
1864 ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
1865 EXPECTED(ret, False);
1867 printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
1869 /* Unlock the process 1 fnum3 lock. */
1870 cli_unlock(cli1, fnum3, 0, 4);
1872 /* Stack 2 more locks here. */
1873 ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
1874 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
1876 EXPECTED(ret, True);
1877 printf("the same process %s stack read locks\n", ret?"can":"cannot");
1879 /* Unlock the first process lock, then check this was the WRITE lock that was
1882 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1883 cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
1885 EXPECTED(ret, True);
1886 printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
1888 /* Unlock the process 2 lock. */
1889 cli_unlock(cli2, fnum2, 0, 4);
1891 /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
1893 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 1, 1)) &&
1894 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4)) &&
1895 NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1897 EXPECTED(ret, True);
1898 printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot");
1900 /* Ensure the next unlock fails. */
1901 ret = NT_STATUS_IS_OK(cli_unlock(cli1, fnum1, 0, 4));
1902 EXPECTED(ret, False);
1903 printf("the same process %s count the lock stack\n", !ret?"can":"cannot");
1905 /* Ensure connection 2 can get a write lock. */
1906 ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
1907 EXPECTED(ret, True);
1909 printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
1913 cli_close(cli1, fnum1);
1914 cli_close(cli2, fnum2);
1915 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1916 if (!torture_close_connection(cli1)) {
1919 if (!torture_close_connection(cli2)) {
1923 printf("finished locktest5\n");
1929 tries the unusual lockingX locktype bits
1931 static bool run_locktest6(int dummy)
1933 static struct cli_state *cli;
1934 const char *fname[1] = { "\\lock6.txt" };
1939 if (!torture_open_connection(&cli, 0)) {
1943 cli_sockopt(cli, sockops);
1945 printf("starting locktest6\n");
1948 printf("Testing %s\n", fname[i]);
1950 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1952 cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum);
1953 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
1954 cli_close(cli, fnum);
1955 printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
1957 cli_open(cli, fname[i], O_RDWR, DENY_NONE, &fnum);
1958 status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
1959 cli_close(cli, fnum);
1960 printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
1962 cli_unlink(cli, fname[i], aSYSTEM | aHIDDEN);
1965 torture_close_connection(cli);
1967 printf("finished locktest6\n");
1971 static bool run_locktest7(int dummy)
1973 struct cli_state *cli1;
1974 const char *fname = "\\lockt7.lck";
1977 bool correct = False;
1979 if (!torture_open_connection(&cli1, 0)) {
1983 cli_sockopt(cli1, sockops);
1985 printf("starting locktest7\n");
1987 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
1989 cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1);
1991 memset(buf, 0, sizeof(buf));
1993 if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
1994 printf("Failed to create file\n");
1998 cli_setpid(cli1, 1);
2000 if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
2001 printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
2004 printf("pid1 successfully locked range 130:4 for READ\n");
2007 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2008 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2011 printf("pid1 successfully read the range 130:4\n");
2014 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2015 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2016 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2017 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2021 printf("pid1 successfully wrote to the range 130:4 (should be denied)\n");
2025 cli_setpid(cli1, 2);
2027 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2028 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2030 printf("pid2 successfully read the range 130:4\n");
2033 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2034 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2035 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2036 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2040 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2044 cli_setpid(cli1, 1);
2045 cli_unlock(cli1, fnum1, 130, 4);
2047 if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
2048 printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
2051 printf("pid1 successfully locked range 130:4 for WRITE\n");
2054 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2055 printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2058 printf("pid1 successfully read the range 130:4\n");
2061 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2062 printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2065 printf("pid1 successfully wrote to the range 130:4\n");
2068 cli_setpid(cli1, 2);
2070 if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
2071 printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
2072 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2073 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2077 printf("pid2 successfully read the range 130:4 (should be denied)\n");
2081 if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
2082 printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
2083 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
2084 printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
2088 printf("pid2 successfully wrote to the range 130:4 (should be denied)\n");
2092 cli_unlock(cli1, fnum1, 130, 0);
2096 cli_close(cli1, fnum1);
2097 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2098 torture_close_connection(cli1);
2100 printf("finished locktest7\n");
2105 * This demonstrates a problem with our use of GPFS share modes: A file
2106 * descriptor sitting in the pending close queue holding a GPFS share mode
2107 * blocks opening a file another time. Happens with Word 2007 temp files.
2108 * With "posix locking = yes" and "gpfs:sharemodes = yes" enabled, the third
2109 * open is denied with NT_STATUS_SHARING_VIOLATION.
2112 static bool run_locktest8(int dummy)
2114 struct cli_state *cli1;
2115 const char *fname = "\\lockt8.lck";
2116 uint16_t fnum1, fnum2;
2118 bool correct = False;
2121 if (!torture_open_connection(&cli1, 0)) {
2125 cli_sockopt(cli1, sockops);
2127 printf("starting locktest8\n");
2129 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2131 status = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_WRITE,
2133 if (!NT_STATUS_IS_OK(status)) {
2134 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2138 memset(buf, 0, sizeof(buf));
2140 status = cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum2);
2141 if (!NT_STATUS_IS_OK(status)) {
2142 d_fprintf(stderr, "cli_open second time returned %s\n",
2147 if (!cli_lock(cli1, fnum2, 1, 1, 0, READ_LOCK)) {
2148 printf("Unable to apply read lock on range 1:1, error was "
2149 "%s\n", cli_errstr(cli1));
2153 status = cli_close(cli1, fnum1);
2154 if (!NT_STATUS_IS_OK(status)) {
2155 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2159 status = cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1);
2160 if (!NT_STATUS_IS_OK(status)) {
2161 d_fprintf(stderr, "cli_open third time returned %s\n",
2169 cli_close(cli1, fnum1);
2170 cli_close(cli1, fnum2);
2171 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2172 torture_close_connection(cli1);
2174 printf("finished locktest8\n");
2179 * This test is designed to be run in conjunction with
2180 * external NFS or POSIX locks taken in the filesystem.
2181 * It checks that the smbd server will block until the
2182 * lock is released and then acquire it. JRA.
2185 static bool got_alarm;
2186 static int alarm_fd;
2188 static void alarm_handler(int dummy)
2193 static void alarm_handler_parent(int dummy)
2198 static void do_local_lock(int read_fd, int write_fd)
2203 const char *local_pathname = NULL;
2206 local_pathname = talloc_asprintf(talloc_tos(),
2207 "%s/lockt9.lck", local_path);
2208 if (!local_pathname) {
2209 printf("child: alloc fail\n");
2213 unlink(local_pathname);
2214 fd = open(local_pathname, O_RDWR|O_CREAT, 0666);
2216 printf("child: open of %s failed %s.\n",
2217 local_pathname, strerror(errno));
2221 /* Now take a fcntl lock. */
2222 lock.l_type = F_WRLCK;
2223 lock.l_whence = SEEK_SET;
2226 lock.l_pid = getpid();
2228 ret = fcntl(fd,F_SETLK,&lock);
2230 printf("child: failed to get lock 0:4 on file %s. Error %s\n",
2231 local_pathname, strerror(errno));
2234 printf("child: got lock 0:4 on file %s.\n",
2239 CatchSignal(SIGALRM, alarm_handler);
2241 /* Signal the parent. */
2242 if (write(write_fd, &c, 1) != 1) {
2243 printf("child: start signal fail %s.\n",
2250 /* Wait for the parent to be ready. */
2251 if (read(read_fd, &c, 1) != 1) {
2252 printf("child: reply signal fail %s.\n",
2260 printf("child: released lock 0:4 on file %s.\n",
2266 static bool run_locktest9(int dummy)
2268 struct cli_state *cli1;
2269 const char *fname = "\\lockt9.lck";
2271 bool correct = False;
2272 int pipe_in[2], pipe_out[2];
2276 struct timeval start;
2280 printf("starting locktest9\n");
2282 if (local_path == NULL) {
2283 d_fprintf(stderr, "locktest9 must be given a local path via -l <localpath>\n");
2287 if (pipe(pipe_in) == -1 || pipe(pipe_out) == -1) {
2292 if (child_pid == -1) {
2296 if (child_pid == 0) {
2298 do_local_lock(pipe_out[0], pipe_in[1]);
2308 ret = read(pipe_in[0], &c, 1);
2310 d_fprintf(stderr, "failed to read start signal from child. %s\n",
2315 if (!torture_open_connection(&cli1, 0)) {
2319 cli_sockopt(cli1, sockops);
2321 status = cli_open(cli1, fname, O_RDWR, DENY_NONE,
2323 if (!NT_STATUS_IS_OK(status)) {
2324 d_fprintf(stderr, "cli_open returned %s\n", cli_errstr(cli1));
2328 /* Ensure the child has the lock. */
2329 if (cli_lock(cli1, fnum, 0, 4, 0, WRITE_LOCK)) {
2330 d_fprintf(stderr, "Got the lock on range 0:4 - this should not happen !\n");
2333 d_printf("Child has the lock.\n");
2336 /* Tell the child to wait 5 seconds then exit. */
2337 ret = write(pipe_out[1], &c, 1);
2339 d_fprintf(stderr, "failed to send exit signal to child. %s\n",
2344 /* Wait 20 seconds for the lock. */
2345 alarm_fd = cli1->fd;
2346 CatchSignal(SIGALRM, alarm_handler_parent);
2349 start = timeval_current();
2351 if (!cli_lock(cli1, fnum, 0, 4, -1, WRITE_LOCK)) {
2352 d_fprintf(stderr, "Unable to apply write lock on range 0:4, error was "
2353 "%s\n", cli_errstr(cli1));
2358 seconds = timeval_elapsed(&start);
2360 printf("Parent got the lock after %.2f seconds.\n",
2363 status = cli_close(cli1, fnum);
2364 if (!NT_STATUS_IS_OK(status)) {
2365 d_fprintf(stderr, "cli_close(fnum1) %s\n", cli_errstr(cli1));
2372 cli_close(cli1, fnum);
2373 torture_close_connection(cli1);
2377 printf("finished locktest9\n");
2382 test whether fnums and tids open on one VC are available on another (a major
2385 static bool run_fdpasstest(int dummy)
2387 struct cli_state *cli1, *cli2;
2388 const char *fname = "\\fdpass.tst";
2392 if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
2395 cli_sockopt(cli1, sockops);
2396 cli_sockopt(cli2, sockops);
2398 printf("starting fdpasstest\n");
2400 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2402 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2403 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
2407 if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
2408 printf("write failed (%s)\n", cli_errstr(cli1));
2412 cli2->vuid = cli1->vuid;
2413 cli2->cnum = cli1->cnum;
2414 cli2->pid = cli1->pid;
2416 if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
2417 printf("read succeeded! nasty security hole [%s]\n",
2422 cli_close(cli1, fnum1);
2423 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
2425 torture_close_connection(cli1);
2426 torture_close_connection(cli2);
2428 printf("finished fdpasstest\n");
2432 static bool run_fdsesstest(int dummy)
2434 struct cli_state *cli;
2439 const char *fname = "\\fdsess.tst";
2440 const char *fname1 = "\\fdsess1.tst";
2446 if (!torture_open_connection(&cli, 0))
2448 cli_sockopt(cli, sockops);
2450 if (!torture_cli_session_setup2(cli, &new_vuid))
2453 saved_cnum = cli->cnum;
2454 if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
2456 new_cnum = cli->cnum;
2457 cli->cnum = saved_cnum;
2459 printf("starting fdsesstest\n");
2461 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2462 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2464 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
2465 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2469 if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
2470 printf("write failed (%s)\n", cli_errstr(cli));
2474 saved_vuid = cli->vuid;
2475 cli->vuid = new_vuid;
2477 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2478 printf("read succeeded with different vuid! nasty security hole [%s]\n",
2482 /* Try to open a file with different vuid, samba cnum. */
2483 if (NT_STATUS_IS_OK(cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum2))) {
2484 printf("create with different vuid, same cnum succeeded.\n");
2485 cli_close(cli, fnum2);
2486 cli_unlink(cli, fname1, aSYSTEM | aHIDDEN);
2488 printf("create with different vuid, same cnum failed.\n");
2489 printf("This will cause problems with service clients.\n");
2493 cli->vuid = saved_vuid;
2495 /* Try with same vuid, different cnum. */
2496 cli->cnum = new_cnum;
2498 if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
2499 printf("read succeeded with different cnum![%s]\n",
2504 cli->cnum = saved_cnum;
2505 cli_close(cli, fnum1);
2506 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2508 torture_close_connection(cli);
2510 printf("finished fdsesstest\n");
2515 This test checks that
2517 1) the server does not allow an unlink on a file that is open
2519 static bool run_unlinktest(int dummy)
2521 struct cli_state *cli;
2522 const char *fname = "\\unlink.tst";
2524 bool correct = True;
2526 if (!torture_open_connection(&cli, 0)) {
2530 cli_sockopt(cli, sockops);
2532 printf("starting unlink test\n");
2534 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2538 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
2539 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2543 if (NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2544 printf("error: server allowed unlink on an open file\n");
2547 correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare,
2548 NT_STATUS_SHARING_VIOLATION);
2551 cli_close(cli, fnum);
2552 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2554 if (!torture_close_connection(cli)) {
2558 printf("unlink test finished\n");
2565 test how many open files this server supports on the one socket
2567 static bool run_maxfidtest(int dummy)
2569 struct cli_state *cli;
2570 const char *ftemplate = "\\maxfid.%d.%d";
2572 uint16_t fnums[0x11000];
2575 bool correct = True;
2580 printf("failed to connect\n");
2584 cli_sockopt(cli, sockops);
2586 for (i=0; i<0x11000; i++) {
2587 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2588 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2589 O_RDWR|O_CREAT|O_TRUNC, DENY_NONE, &fnums[i]))) {
2590 printf("open of %s failed (%s)\n",
2591 fname, cli_errstr(cli));
2592 printf("maximum fnum is %d\n", i);
2600 printf("cleaning up\n");
2602 slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
2603 cli_close(cli, fnums[i]);
2604 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
2605 printf("unlink of %s failed (%s)\n",
2606 fname, cli_errstr(cli));
2613 printf("maxfid test finished\n");
2614 if (!torture_close_connection(cli)) {
2620 /* generate a random buffer */
2621 static void rand_buf(char *buf, int len)
2624 *buf = (char)sys_random();
2629 /* send smb negprot commands, not reading the response */
2630 static bool run_negprot_nowait(int dummy)
2633 static struct cli_state *cli;
2634 bool correct = True;
2636 printf("starting negprot nowait test\n");
2638 if (!(cli = open_nbt_connection())) {
2642 for (i=0;i<50000;i++) {
2643 cli_negprot_sendsync(cli);
2646 if (!torture_close_connection(cli)) {
2650 printf("finished negprot nowait test\n");
2656 /* send random IPC commands */
2657 static bool run_randomipc(int dummy)
2659 char *rparam = NULL;
2661 unsigned int rdrcnt,rprcnt;
2663 int api, param_len, i;
2664 struct cli_state *cli;
2665 bool correct = True;
2668 printf("starting random ipc test\n");
2670 if (!torture_open_connection(&cli, 0)) {
2674 for (i=0;i<count;i++) {
2675 api = sys_random() % 500;
2676 param_len = (sys_random() % 64);
2678 rand_buf(param, param_len);
2683 param, param_len, 8,
2684 NULL, 0, BUFFER_SIZE,
2688 printf("%d/%d\r", i,count);
2691 printf("%d/%d\n", i, count);
2693 if (!torture_close_connection(cli)) {
2697 printf("finished random ipc test\n");
2704 static void browse_callback(const char *sname, uint32 stype,
2705 const char *comment, void *state)
2707 printf("\t%20.20s %08x %s\n", sname, stype, comment);
2713 This test checks the browse list code
2716 static bool run_browsetest(int dummy)
2718 static struct cli_state *cli;
2719 bool correct = True;
2721 printf("starting browse test\n");
2723 if (!torture_open_connection(&cli, 0)) {
2727 printf("domain list:\n");
2728 cli_NetServerEnum(cli, cli->server_domain,
2729 SV_TYPE_DOMAIN_ENUM,
2730 browse_callback, NULL);
2732 printf("machine list:\n");
2733 cli_NetServerEnum(cli, cli->server_domain,
2735 browse_callback, NULL);
2737 if (!torture_close_connection(cli)) {
2741 printf("browse test finished\n");
2749 This checks how the getatr calls works
2751 static bool run_attrtest(int dummy)
2753 struct cli_state *cli;
2756 const char *fname = "\\attrib123456789.tst";
2757 bool correct = True;
2759 printf("starting attrib test\n");
2761 if (!torture_open_connection(&cli, 0)) {
2765 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2766 cli_open(cli, fname,
2767 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2768 cli_close(cli, fnum);
2769 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2770 printf("getatr failed (%s)\n", cli_errstr(cli));
2774 if (abs(t - time(NULL)) > 60*60*24*10) {
2775 printf("ERROR: SMBgetatr bug. time is %s",
2781 t2 = t-60*60*24; /* 1 day ago */
2783 if (!NT_STATUS_IS_OK(cli_setatr(cli, fname, 0, t2))) {
2784 printf("setatr failed (%s)\n", cli_errstr(cli));
2788 if (!NT_STATUS_IS_OK(cli_getatr(cli, fname, NULL, NULL, &t))) {
2789 printf("getatr failed (%s)\n", cli_errstr(cli));
2794 printf("ERROR: getatr/setatr bug. times are\n%s",
2796 printf("%s", ctime(&t2));
2800 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2802 if (!torture_close_connection(cli)) {
2806 printf("attrib test finished\n");
2813 This checks a couple of trans2 calls
2815 static bool run_trans2test(int dummy)
2817 struct cli_state *cli;
2820 time_t c_time, a_time, m_time;
2821 struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
2822 const char *fname = "\\trans2.tst";
2823 const char *dname = "\\trans2";
2824 const char *fname2 = "\\trans2\\trans2.tst";
2826 bool correct = True;
2830 printf("starting trans2 test\n");
2832 if (!torture_open_connection(&cli, 0)) {
2836 status = cli_get_fs_attr_info(cli, &fs_attr);
2837 if (!NT_STATUS_IS_OK(status)) {
2838 printf("ERROR: cli_get_fs_attr_info returned %s\n",
2843 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2844 cli_open(cli, fname,
2845 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2846 if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
2847 &m_time_ts, NULL)) {
2848 printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
2852 if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
2853 printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
2857 if (strcmp(pname, fname)) {
2858 printf("qfilename gave different name? [%s] [%s]\n",
2863 cli_close(cli, fnum);
2867 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2868 if (!NT_STATUS_IS_OK(cli_open(cli, fname,
2869 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum))) {
2870 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
2873 cli_close(cli, fnum);
2875 status = cli_qpathinfo1(cli, fname, &c_time, &a_time, &m_time, &size,
2877 if (!NT_STATUS_IS_OK(status)) {
2878 printf("ERROR: qpathinfo failed (%s)\n", nt_errstr(status));
2881 if (c_time != m_time) {
2882 printf("create time=%s", ctime(&c_time));
2883 printf("modify time=%s", ctime(&m_time));
2884 printf("This system appears to have sticky create times\n");
2886 if (a_time % (60*60) == 0) {
2887 printf("access time=%s", ctime(&a_time));
2888 printf("This system appears to set a midnight access time\n");
2892 if (abs(m_time - time(NULL)) > 60*60*24*7) {
2893 printf("ERROR: totally incorrect times - maybe word reversed? mtime=%s", ctime(&m_time));
2899 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2900 cli_open(cli, fname,
2901 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2902 cli_close(cli, fnum);
2903 status = cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts,
2904 &m_time_ts, &size, NULL, NULL);
2905 if (!NT_STATUS_IS_OK(status)) {
2906 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2909 if (w_time_ts.tv_sec < 60*60*24*2) {
2910 printf("write time=%s", ctime(&w_time_ts.tv_sec));
2911 printf("This system appears to set a initial 0 write time\n");
2916 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
2919 /* check if the server updates the directory modification time
2920 when creating a new file */
2921 if (!NT_STATUS_IS_OK(cli_mkdir(cli, dname))) {
2922 printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
2926 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2927 &w_time_ts, &m_time_ts, &size, NULL, NULL);
2928 if (!NT_STATUS_IS_OK(status)) {
2929 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2933 cli_open(cli, fname2,
2934 O_RDWR | O_CREAT | O_TRUNC, DENY_NONE, &fnum);
2935 cli_write(cli, fnum, 0, (char *)&fnum, 0, sizeof(fnum));
2936 cli_close(cli, fnum);
2937 status = cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts,
2938 &w_time_ts, &m_time2_ts, &size, NULL, NULL);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 printf("ERROR: qpathinfo2 failed (%s)\n", nt_errstr(status));
2943 if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
2945 printf("This system does not update directory modification times\n");
2949 cli_unlink(cli, fname2, aSYSTEM | aHIDDEN);
2950 cli_rmdir(cli, dname);
2952 if (!torture_close_connection(cli)) {
2956 printf("trans2 test finished\n");
2962 This checks new W2K calls.
2965 static bool new_trans(struct cli_state *pcli, int fnum, int level)
2969 bool correct = True;
2971 if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
2972 printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
2975 printf("qfileinfo: level %d, len = %u\n", level, len);
2976 dump_data(0, (uint8 *)buf, len);
2983 static bool run_w2ktest(int dummy)
2985 struct cli_state *cli;
2987 const char *fname = "\\w2ktest\\w2k.tst";
2989 bool correct = True;
2991 printf("starting w2k test\n");
2993 if (!torture_open_connection(&cli, 0)) {
2997 cli_open(cli, fname,
2998 O_RDWR | O_CREAT , DENY_NONE, &fnum);
3000 for (level = 1004; level < 1040; level++) {
3001 new_trans(cli, fnum, level);
3004 cli_close(cli, fnum);
3006 if (!torture_close_connection(cli)) {
3010 printf("w2k test finished\n");
3017 this is a harness for some oplock tests
3019 static bool run_oplock1(int dummy)
3021 struct cli_state *cli1;
3022 const char *fname = "\\lockt1.lck";
3024 bool correct = True;
3026 printf("starting oplock test 1\n");
3028 if (!torture_open_connection(&cli1, 0)) {
3032 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3034 cli_sockopt(cli1, sockops);
3036 cli1->use_oplocks = True;
3038 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3039 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3043 cli1->use_oplocks = False;
3045 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3046 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3048 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3049 printf("close2 failed (%s)\n", cli_errstr(cli1));
3053 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3054 printf("unlink failed (%s)\n", cli_errstr(cli1));
3058 if (!torture_close_connection(cli1)) {
3062 printf("finished oplock test 1\n");
3067 static bool run_oplock2(int dummy)
3069 struct cli_state *cli1, *cli2;
3070 const char *fname = "\\lockt2.lck";
3071 uint16_t fnum1, fnum2;
3072 int saved_use_oplocks = use_oplocks;
3074 bool correct = True;
3075 volatile bool *shared_correct;
3077 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3078 *shared_correct = True;
3080 use_level_II_oplocks = True;
3083 printf("starting oplock test 2\n");
3085 if (!torture_open_connection(&cli1, 0)) {
3086 use_level_II_oplocks = False;
3087 use_oplocks = saved_use_oplocks;
3091 cli1->use_oplocks = True;
3092 cli1->use_level_II_oplocks = True;
3094 if (!torture_open_connection(&cli2, 1)) {
3095 use_level_II_oplocks = False;
3096 use_oplocks = saved_use_oplocks;
3100 cli2->use_oplocks = True;
3101 cli2->use_level_II_oplocks = True;
3103 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3105 cli_sockopt(cli1, sockops);
3106 cli_sockopt(cli2, sockops);
3108 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
3109 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
3113 /* Don't need the globals any more. */
3114 use_level_II_oplocks = False;
3115 use_oplocks = saved_use_oplocks;
3119 if (!NT_STATUS_IS_OK(cli_open(cli2, fname, O_RDWR, DENY_NONE, &fnum2))) {
3120 printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
3121 *shared_correct = False;
3127 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3128 printf("close2 failed (%s)\n", cli_errstr(cli1));
3129 *shared_correct = False;
3137 /* Ensure cli1 processes the break. Empty file should always return 0
3140 if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
3141 printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
3145 /* Should now be at level II. */
3146 /* Test if sending a write locks causes a break to none. */
3148 if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
3149 printf("lock failed (%s)\n", cli_errstr(cli1));
3153 cli_unlock(cli1, fnum1, 0, 4);
3157 if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
3158 printf("lock failed (%s)\n", cli_errstr(cli1));
3162 cli_unlock(cli1, fnum1, 0, 4);
3166 cli_read(cli1, fnum1, buf, 0, 4);
3169 if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
3170 printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
3175 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3176 printf("close1 failed (%s)\n", cli_errstr(cli1));
3182 if (!NT_STATUS_IS_OK(cli_unlink(cli1, fname, aSYSTEM | aHIDDEN))) {
3183 printf("unlink failed (%s)\n", cli_errstr(cli1));
3187 if (!torture_close_connection(cli1)) {
3191 if (!*shared_correct) {
3195 printf("finished oplock test 2\n");
3200 /* handler for oplock 3 tests */
3201 static NTSTATUS oplock3_handler(struct cli_state *cli, uint16_t fnum, unsigned char level)
3203 printf("got oplock break fnum=%d level=%d\n",
3205 return cli_oplock_ack(cli, fnum, level);
3208 static bool run_oplock3(int dummy)
3210 struct cli_state *cli;
3211 const char *fname = "\\oplockt3.dat";
3213 char buf[4] = "abcd";
3214 bool correct = True;
3215 volatile bool *shared_correct;
3217 shared_correct = (volatile bool *)shm_setup(sizeof(bool));
3218 *shared_correct = True;
3220 printf("starting oplock test 3\n");
3225 use_level_II_oplocks = True;
3226 if (!torture_open_connection(&cli, 0)) {
3227 *shared_correct = False;
3231 /* try to trigger a oplock break in parent */
3232 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3233 cli_write(cli, fnum, 0, buf, 0, 4);
3239 use_level_II_oplocks = True;
3240 if (!torture_open_connection(&cli, 1)) { /* other is forked */
3243 cli_oplock_handler(cli, oplock3_handler);
3244 cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum);
3245 cli_write(cli, fnum, 0, buf, 0, 4);
3246 cli_close(cli, fnum);
3247 cli_open(cli, fname, O_RDWR, DENY_NONE, &fnum);
3248 cli->timeout = 20000;
3249 cli_receive_smb(cli);
3250 printf("finished oplock test 3\n");
3252 return (correct && *shared_correct);
3254 /* What are we looking for here? What's sucess and what's FAILURE? */
3260 Test delete on close semantics.
3262 static bool run_deletetest(int dummy)
3264 struct cli_state *cli1 = NULL;
3265 struct cli_state *cli2 = NULL;
3266 const char *fname = "\\delete.file";
3267 uint16_t fnum1 = (uint16_t)-1;
3268 uint16_t fnum2 = (uint16_t)-1;
3269 bool correct = True;
3271 printf("starting delete test\n");
3273 if (!torture_open_connection(&cli1, 0)) {
3277 cli_sockopt(cli1, sockops);
3279 /* Test 1 - this should delete the file on close. */
3281 cli_setatr(cli1, fname, 0, 0);
3282 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3284 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3285 0, FILE_OVERWRITE_IF,
3286 FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3287 printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3294 uint32 *accinfo = NULL;
3296 cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
3298 printf("access mode = 0x%lx\n", *accinfo);
3303 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3304 printf("[1] close failed (%s)\n", cli_errstr(cli1));
3309 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR, DENY_NONE, &fnum1))) {
3310 printf("[1] open of %s succeeded (should fail)\n", fname);
3315 printf("first delete on close test succeeded.\n");
3317 /* Test 2 - this should delete the file on close. */
3319 cli_setatr(cli1, fname, 0, 0);
3320 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3322 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS,
3323 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE,
3324 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3325 printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3330 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3331 printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3336 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3337 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3342 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3343 printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
3344 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3345 printf("[2] close failed (%s)\n", cli_errstr(cli1));
3349 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3351 printf("second delete on close test succeeded.\n");
3354 cli_setatr(cli1, fname, 0, 0);
3355 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3357 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3358 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3359 printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3364 /* This should fail with a sharing violation - open for delete is only compatible
3365 with SHARE_DELETE. */
3367 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3368 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0, &fnum2))) {
3369 printf("[3] open - 2 of %s succeeded - should have failed.\n", fname);
3374 /* This should succeed. */
3376 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3377 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3378 printf("[3] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3383 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3384 printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3389 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3390 printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
3395 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3396 printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
3401 /* This should fail - file should no longer be there. */
3403 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3404 printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
3405 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3406 printf("[3] close failed (%s)\n", cli_errstr(cli1));
3408 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3412 printf("third delete on close test succeeded.\n");
3415 cli_setatr(cli1, fname, 0, 0);
3416 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3418 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3419 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3420 printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3425 /* This should succeed. */
3426 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3427 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2))) {
3428 printf("[4] open - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
3433 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3434 printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
3439 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3440 printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
3445 /* This should fail - no more opens once delete on close set. */
3446 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS,
3447 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3448 FILE_OPEN, 0, 0, &fnum2))) {
3449 printf("[4] open - 3 of %s succeeded ! Should have failed.\n", fname );
3453 printf("fourth delete on close test succeeded.\n");
3455 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3456 printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
3462 cli_setatr(cli1, fname, 0, 0);
3463 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3465 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum1))) {
3466 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3471 /* This should fail - only allowed on NT opens with DELETE access. */
3473 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3474 printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
3479 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3480 printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
3485 printf("fifth delete on close test succeeded.\n");
3488 cli_setatr(cli1, fname, 0, 0);
3489 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3491 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3492 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3493 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3494 printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3499 /* This should fail - only allowed on NT opens with DELETE access. */
3501 if (NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3502 printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
3507 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3508 printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
3513 printf("sixth delete on close test succeeded.\n");
3516 cli_setatr(cli1, fname, 0, 0);
3517 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3519 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3520 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3521 printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3526 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3527 printf("[7] setting delete_on_close on file failed !\n");
3532 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, false))) {
3533 printf("[7] unsetting delete_on_close on file failed !\n");
3538 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3539 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3544 /* This next open should succeed - we reset the flag. */
3546 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3547 printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3552 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3553 printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
3558 printf("seventh delete on close test succeeded.\n");
3561 cli_setatr(cli1, fname, 0, 0);
3562 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3564 if (!torture_open_connection(&cli2, 1)) {
3565 printf("[8] failed to open second connection.\n");
3570 cli_sockopt(cli1, sockops);
3572 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3573 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3574 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3575 printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
3580 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3581 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3582 FILE_OPEN, 0, 0, &fnum2))) {
3583 printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
3588 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum1, true))) {
3589 printf("[8] setting delete_on_close on file failed !\n");
3594 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3595 printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
3600 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
3601 printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
3606 /* This should fail.. */
3607 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3608 printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
3612 printf("eighth delete on close test succeeded.\n");
3614 /* This should fail - we need to set DELETE_ACCESS. */
3615 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
3616 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3617 printf("[9] open of %s succeeded should have failed!\n", fname);
3622 printf("ninth delete on close test succeeded.\n");
3624 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
3625 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0, &fnum1))) {
3626 printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3631 /* This should delete the file. */
3632 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3633 printf("[10] close failed (%s)\n", cli_errstr(cli1));
3638 /* This should fail.. */
3639 if (NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_NONE, &fnum1))) {
3640 printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
3644 printf("tenth delete on close test succeeded.\n");
3646 cli_setatr(cli1, fname, 0, 0);
3647 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3649 /* What error do we get when attempting to open a read-only file with
3652 /* Create a readonly file. */
3653 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
3654 FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3655 printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
3660 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3661 printf("[11] close failed (%s)\n", cli_errstr(cli1));
3666 /* Now try open for delete access. */
3667 if (NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
3668 0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
3669 FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3670 printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
3671 cli_close(cli1, fnum1);
3675 NTSTATUS nterr = cli_nt_error(cli1);
3676 if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
3677 printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
3681 printf("eleventh delete on close test succeeded.\n");
3685 printf("finished delete test\n");
3688 /* FIXME: This will crash if we aborted before cli2 got
3689 * intialized, because these functions don't handle
3690 * uninitialized connections. */
3692 if (fnum1 != (uint16_t)-1) cli_close(cli1, fnum1);
3693 if (fnum2 != (uint16_t)-1) cli_close(cli1, fnum2);
3694 cli_setatr(cli1, fname, 0, 0);
3695 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3697 if (cli1 && !torture_close_connection(cli1)) {
3700 if (cli2 && !torture_close_connection(cli2)) {
3708 print out server properties
3710 static bool run_properties(int dummy)
3712 struct cli_state *cli;
3713 bool correct = True;
3715 printf("starting properties test\n");
3719 if (!torture_open_connection(&cli, 0)) {
3723 cli_sockopt(cli, sockops);
3725 d_printf("Capabilities 0x%08x\n", cli->capabilities);
3727 if (!torture_close_connection(cli)) {
3736 /* FIRST_DESIRED_ACCESS 0xf019f */
3737 #define FIRST_DESIRED_ACCESS FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|\
3738 FILE_READ_EA| /* 0xf */ \
3739 FILE_WRITE_EA|FILE_READ_ATTRIBUTES| /* 0x90 */ \
3740 FILE_WRITE_ATTRIBUTES| /* 0x100 */ \
3741 DELETE_ACCESS|READ_CONTROL_ACCESS|\
3742 WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS /* 0xf0000 */
3743 /* SECOND_DESIRED_ACCESS 0xe0080 */
3744 #define SECOND_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3745 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3746 WRITE_OWNER_ACCESS /* 0xe0000 */
3749 #define THIRD_DESIRED_ACCESS FILE_READ_ATTRIBUTES| /* 0x80 */ \
3750 READ_CONTROL_ACCESS|WRITE_DAC_ACCESS|\
3752 WRITE_OWNER_ACCESS /* */
3756 Test ntcreate calls made by xcopy
3758 static bool run_xcopy(int dummy)
3760 static struct cli_state *cli1;
3761 const char *fname = "\\test.txt";
3762 bool correct = True;
3763 uint16_t fnum1, fnum2;
3765 printf("starting xcopy test\n");
3767 if (!torture_open_connection(&cli1, 0)) {
3771 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3772 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
3773 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
3774 0x4044, 0, &fnum1))) {
3775 printf("First open failed - %s\n", cli_errstr(cli1));
3779 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0,
3780 SECOND_DESIRED_ACCESS, 0,
3781 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN,
3782 0x200000, 0, &fnum2))) {
3783 printf("second open failed - %s\n", cli_errstr(cli1));
3787 if (!torture_close_connection(cli1)) {
3795 Test rename on files open with share delete and no share delete.
3797 static bool run_rename(int dummy)
3799 static struct cli_state *cli1;
3800 const char *fname = "\\test.txt";
3801 const char *fname1 = "\\test1.txt";
3802 bool correct = True;
3807 printf("starting rename test\n");
3809 if (!torture_open_connection(&cli1, 0)) {
3813 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3814 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3815 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3816 FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3817 printf("First open failed - %s\n", cli_errstr(cli1));
3821 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3822 printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
3824 printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
3828 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3829 printf("close - 1 failed (%s)\n", cli_errstr(cli1));
3833 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3834 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3835 status = cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3837 FILE_SHARE_DELETE|FILE_SHARE_NONE,
3839 FILE_SHARE_DELETE|FILE_SHARE_READ,
3841 FILE_OVERWRITE_IF, 0, 0, &fnum1);
3842 if (!NT_STATUS_IS_OK(status)) {
3843 printf("Second open failed - %s\n", cli_errstr(cli1));
3847 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3848 printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
3851 printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
3854 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3855 printf("close - 2 failed (%s)\n", cli_errstr(cli1));
3859 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3860 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3862 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
3863 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3864 printf("Third open failed - %s\n", cli_errstr(cli1));
3873 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
3874 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3875 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3878 if (!NT_STATUS_IS_OK(cli_nt_delete_on_close(cli1, fnum2, true))) {
3879 printf("[8] setting delete_on_close on file failed !\n");
3883 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum2))) {
3884 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3890 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3891 printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
3894 printf("Third rename succeeded (SHARE_NONE)\n");
3897 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3898 printf("close - 3 failed (%s)\n", cli_errstr(cli1));
3902 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3903 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3907 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3908 FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3909 printf("Fourth open failed - %s\n", cli_errstr(cli1));
3913 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3914 printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
3916 printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
3920 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3921 printf("close - 4 failed (%s)\n", cli_errstr(cli1));
3925 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3926 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3930 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3931 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
3932 printf("Fifth open failed - %s\n", cli_errstr(cli1));
3936 if (!NT_STATUS_IS_OK(cli_rename(cli1, fname, fname1))) {
3937 printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
3941 printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
3945 * Now check if the first name still exists ...
3948 /* if (!NT_STATUS_OP(cli_ntcreate(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
3949 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum2))) {
3950 printf("Opening original file after rename of open file fails: %s\n",
3954 printf("Opening original file after rename of open file works ...\n");
3955 (void)cli_close(cli1, fnum2);
3959 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
3960 printf("close - 5 failed (%s)\n", cli_errstr(cli1));
3964 /* Check that the renamed file has FILE_ATTRIBUTE_ARCHIVE. */
3965 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname1, &attr, NULL, NULL))) {
3966 printf("getatr on file %s failed - %s ! \n",
3971 if (attr != FILE_ATTRIBUTE_ARCHIVE) {
3972 printf("Renamed file %s has wrong attr 0x%x "
3973 "(should be 0x%x)\n",
3976 (unsigned int)FILE_ATTRIBUTE_ARCHIVE);
3979 printf("Renamed file %s has archive bit set\n", fname1);
3983 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
3984 cli_unlink(cli1, fname1, aSYSTEM | aHIDDEN);
3986 if (!torture_close_connection(cli1)) {
3993 static bool run_pipe_number(int dummy)
3995 struct cli_state *cli1;
3996 const char *pipe_name = "\\SPOOLSS";
4000 printf("starting pipenumber test\n");
4001 if (!torture_open_connection(&cli1, 0)) {
4005 cli_sockopt(cli1, sockops);
4007 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4008 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0, &fnum))) {
4009 printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
4013 printf("\r%6d", num_pipes);
4016 printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
4017 torture_close_connection(cli1);
4022 Test open mode returns on read-only files.
4024 static bool run_opentest(int dummy)
4026 static struct cli_state *cli1;
4027 static struct cli_state *cli2;
4028 const char *fname = "\\readonly.file";
4029 uint16_t fnum1, fnum2;
4032 bool correct = True;
4035 printf("starting open test\n");
4037 if (!torture_open_connection(&cli1, 0)) {
4041 cli_setatr(cli1, fname, 0, 0);
4042 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4044 cli_sockopt(cli1, sockops);
4046 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4047 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4051 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4052 printf("close2 failed (%s)\n", cli_errstr(cli1));
4056 if (!NT_STATUS_IS_OK(cli_setatr(cli1, fname, aRONLY, 0))) {
4057 printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
4061 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4062 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4066 /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
4067 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4069 if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess,
4070 NT_STATUS_ACCESS_DENIED)) {
4071 printf("correct error code ERRDOS/ERRnoaccess returned\n");
4074 printf("finished open test 1\n");
4076 cli_close(cli1, fnum1);
4078 /* Now try not readonly and ensure ERRbadshare is returned. */
4080 cli_setatr(cli1, fname, 0, 0);
4082 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY, DENY_WRITE, &fnum1))) {
4083 printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
4087 /* This will fail - but the error should be ERRshare. */
4088 cli_open(cli1, fname, O_RDWR, DENY_ALL, &fnum2);
4090 if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare,
4091 NT_STATUS_SHARING_VIOLATION)) {
4092 printf("correct error code ERRDOS/ERRbadshare returned\n");
4095 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4096 printf("close2 failed (%s)\n", cli_errstr(cli1));
4100 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4102 printf("finished open test 2\n");
4104 /* Test truncate open disposition on file opened for read. */
4106 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum1))) {
4107 printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
4111 /* write 20 bytes. */
4113 memset(buf, '\0', 20);
4115 if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
4116 printf("write failed (%s)\n", cli_errstr(cli1));
4120 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4121 printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
4125 /* Ensure size == 20. */
4126 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4127 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4132 printf("(3) file size != 20\n");
4136 /* Now test if we can truncate a file opened for readonly. */
4138 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE, &fnum1))) {
4139 printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
4143 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4144 printf("close2 failed (%s)\n", cli_errstr(cli1));
4148 /* Ensure size == 0. */
4149 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, NULL, &fsize, NULL))) {
4150 printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
4155 printf("(3) file size != 0\n");
4158 printf("finished open test 3\n");
4160 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4163 printf("testing ctemp\n");
4164 if (!NT_STATUS_IS_OK(cli_ctemp(cli1, talloc_tos(), "\\", &fnum1, &tmp_path))) {
4165 printf("ctemp failed (%s)\n", cli_errstr(cli1));
4168 printf("ctemp gave path %s\n", tmp_path);
4169 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4170 printf("close of temp failed (%s)\n", cli_errstr(cli1));
4172 if (!NT_STATUS_IS_OK(cli_unlink(cli1, tmp_path, aSYSTEM | aHIDDEN))) {
4173 printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
4176 /* Test the non-io opens... */
4178 if (!torture_open_connection(&cli2, 1)) {
4182 cli_setatr(cli2, fname, 0, 0);
4183 cli_unlink(cli2, fname, aSYSTEM | aHIDDEN);
4185 cli_sockopt(cli2, sockops);
4187 printf("TEST #1 testing 2 non-io opens (no delete)\n");
4189 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4190 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4191 printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4195 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4196 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4197 printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4201 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4202 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4205 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4206 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4210 printf("non-io open test #1 passed.\n");
4212 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4214 printf("TEST #2 testing 2 non-io opens (first with delete)\n");
4216 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4217 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4218 printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4222 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4223 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4224 printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4228 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4229 printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4232 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4233 printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
4237 printf("non-io open test #2 passed.\n");
4239 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4241 printf("TEST #3 testing 2 non-io opens (second with delete)\n");
4243 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4244 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4245 printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4249 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4250 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4251 printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4255 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4256 printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4259 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4260 printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4264 printf("non-io open test #3 passed.\n");
4266 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4268 printf("TEST #4 testing 2 non-io opens (both with delete)\n");
4270 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4271 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4272 printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4276 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4277 FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4278 printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4282 printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4284 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4285 printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4289 printf("non-io open test #4 passed.\n");
4291 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4293 printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
4295 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4296 FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4297 printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4301 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4302 FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4303 printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4307 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4308 printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4312 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4313 printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4317 printf("non-io open test #5 passed.\n");
4319 printf("TEST #6 testing 1 non-io open, one io open\n");
4321 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4323 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4324 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4325 printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4329 if (!NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4330 FILE_SHARE_READ, FILE_OPEN_IF, 0, 0, &fnum2))) {
4331 printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4335 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4336 printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4340 if (!NT_STATUS_IS_OK(cli_close(cli2, fnum2))) {
4341 printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
4345 printf("non-io open test #6 passed.\n");
4347 printf("TEST #7 testing 1 non-io open, one io open with delete\n");
4349 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4351 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
4352 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4353 printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4357 if (NT_STATUS_IS_OK(cli_ntcreate(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
4358 FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0, &fnum2))) {
4359 printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
4363 printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
4365 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4366 printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
4370 printf("non-io open test #7 passed.\n");
4372 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4374 if (!torture_close_connection(cli1)) {
4377 if (!torture_close_connection(cli2)) {
4384 NTSTATUS torture_setup_unix_extensions(struct cli_state *cli)
4386 uint16 major, minor;
4387 uint32 caplow, caphigh;
4390 if (!SERVER_HAS_UNIX_CIFS(cli)) {
4391 printf("Server doesn't support UNIX CIFS extensions.\n");
4392 return NT_STATUS_NOT_SUPPORTED;
4395 status = cli_unix_extensions_version(cli, &major, &minor, &caplow,
4397 if (!NT_STATUS_IS_OK(status)) {
4398 printf("Server didn't return UNIX CIFS extensions: %s\n",
4403 status = cli_set_unix_extensions_capabilities(cli, major, minor,
4405 if (!NT_STATUS_IS_OK(status)) {
4406 printf("Server doesn't support setting UNIX CIFS extensions: "
4407 "%s.\n", nt_errstr(status));
4411 return NT_STATUS_OK;
4415 Test POSIX open /mkdir calls.
4417 static bool run_simple_posix_open_test(int dummy)
4419 static struct cli_state *cli1;
4420 const char *fname = "posix:file";
4421 const char *hname = "posix:hlink";
4422 const char *sname = "posix:symlink";
4423 const char *dname = "posix:dir";
4426 uint16_t fnum1 = (uint16_t)-1;
4427 SMB_STRUCT_STAT sbuf;
4428 bool correct = false;
4431 printf("Starting simple POSIX open test\n");
4433 if (!torture_open_connection(&cli1, 0)) {
4437 cli_sockopt(cli1, sockops);
4439 status = torture_setup_unix_extensions(cli1);
4440 if (!NT_STATUS_IS_OK(status)) {
4444 cli_setatr(cli1, fname, 0, 0);
4445 cli_posix_unlink(cli1, fname);
4446 cli_setatr(cli1, dname, 0, 0);
4447 cli_posix_rmdir(cli1, dname);
4448 cli_setatr(cli1, hname, 0, 0);
4449 cli_posix_unlink(cli1, hname);
4450 cli_setatr(cli1, sname, 0, 0);
4451 cli_posix_unlink(cli1, sname);
4453 /* Create a directory. */
4454 if (!NT_STATUS_IS_OK(cli_posix_mkdir(cli1, dname, 0777))) {
4455 printf("POSIX mkdir of %s failed (%s)\n", dname, cli_errstr(cli1));
4459 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4460 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4464 /* Test ftruncate - set file size. */
4465 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 1000))) {
4466 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4470 /* Ensure st_size == 1000 */
4471 if (!NT_STATUS_IS_OK(cli_posix_stat(cli1, fname, &sbuf))) {
4472 printf("stat failed (%s)\n", cli_errstr(cli1));
4476 if (sbuf.st_ex_size != 1000) {
4477 printf("ftruncate - stat size (%u) != 1000\n", (unsigned int)sbuf.st_ex_size);
4481 /* Test ftruncate - set file size back to zero. */
4482 if (!NT_STATUS_IS_OK(cli_ftruncate(cli1, fnum1, 0))) {
4483 printf("ftruncate failed (%s)\n", cli_errstr(cli1));
4487 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4488 printf("close failed (%s)\n", cli_errstr(cli1));
4492 /* Now open the file again for read only. */
4493 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4494 printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
4498 /* Now unlink while open. */
4499 if (!NT_STATUS_IS_OK(cli_posix_unlink(cli1, fname))) {
4500 printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
4504 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4505 printf("close(2) failed (%s)\n", cli_errstr(cli1));
4509 /* Ensure the file has gone. */
4510 if (NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDONLY, 0, &fnum1))) {
4511 printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
4515 /* What happens when we try and POSIX open a directory ? */
4516 if (NT_STATUS_IS_OK(cli_posix_open(cli1, dname, O_RDONLY, 0, &fnum1))) {
4517 printf("POSIX open of directory %s succeeded, should have failed.\n", fname);
4520 if (!check_error(__LINE__, cli1, ERRDOS, EISDIR,
4521 NT_STATUS_FILE_IS_A_DIRECTORY)) {
4526 /* Create the file. */
4527 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600, &fnum1))) {
4528 printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
4532 /* Write some data into it. */
4533 if (cli_write(cli1, fnum1, 0, "TEST DATA\n", 0, 10) != 10) {
4534 printf("cli_write failed: %s\n", cli_errstr(cli1));
4538 cli_close(cli1, fnum1);
4540 /* Now create a hardlink. */
4541 if (!NT_STATUS_IS_OK(cli_posix_hardlink(cli1, fname, hname))) {
4542 printf("POSIX hardlink of %s failed (%s)\n", hname, cli_errstr(cli1));
4546 /* Now create a symlink. */
4547 if (!NT_STATUS_IS_OK(cli_posix_symlink(cli1, fname, sname))) {
4548 printf("POSIX symlink of %s failed (%s)\n", sname, cli_errstr(cli1));
4552 /* Open the hardlink for read. */
4553 if (!NT_STATUS_IS_OK(cli_posix_open(cli1, hname, O_RDONLY, 0, &fnum1))) {
4554 printf("POSIX open of %s failed (%s)\n", hname, cli_errstr(cli1));
4558 if (cli_read(cli1, fnum1, buf, 0, 10) != 10) {
4559 printf("POSIX read of %s failed (%s)\n", hname, cli_errstr(cli1));
4563 if (memcmp(buf, "TEST DATA\n", 10)) {
4564 printf("invalid data read from hardlink\n");
4568 /* Do a POSIX lock/unlock. */
4569 if (!NT_STATUS_IS_OK(cli_posix_lock(cli1, fnum1, 0, 100, true, READ_LOCK))) {
4570 printf("POSIX lock failed %s\n", cli_errstr(cli1));
4574 /* Punch a hole in the locked area. */
4575 if (!NT_STATUS_IS_OK(cli_posix_unlock(cli1, fnum1, 10, 80))) {
4576 printf("POSIX unlock failed %s\n", cli_errstr(cli1));
4580 cli_close(cli1, fnum1);
4582 /* Open the symlink for read - this should fail. A POSIX
4583 client should not be doing opens on a symlink. */
4584 if (NT_STATUS_IS_OK(cli_posix_open(cli1, sname, O_RDONLY, 0, &fnum1))) {
4585 printf("POSIX open of %s succeeded (should have failed)\n", sname);
4588 if (!check_error(__LINE__, cli1, ERRDOS, ERRbadpath,
4589 NT_STATUS_OBJECT_PATH_NOT_FOUND)) {
4590 printf("POSIX open of %s should have failed "
4591 "with NT_STATUS_OBJECT_PATH_NOT_FOUND, "
4592 "failed with %s instead.\n",
4593 sname, cli_errstr(cli1));
4598 if (!NT_STATUS_IS_OK(cli_posix_readlink(cli1, sname, namebuf, sizeof(namebuf)))) {
4599 printf("POSIX readlink on %s failed (%s)\n", sname, cli_errstr(cli1));
4603 if (strcmp(namebuf, fname) != 0) {
4604 printf("POSIX readlink on %s failed to match name %s (read %s)\n",
4605 sname, fname, namebuf);
4609 if (!NT_STATUS_IS_OK(cli_posix_rmdir(cli1, dname))) {
4610 printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
4614 printf("Simple POSIX open test passed\n");
4619 if (fnum1 != (uint16_t)-1) {
4620 cli_close(cli1, fnum1);
4621 fnum1 = (uint16_t)-1;
4624 cli_setatr(cli1, sname, 0, 0);
4625 cli_posix_unlink(cli1, sname);
4626 cli_setatr(cli1, hname, 0, 0);
4627 cli_posix_unlink(cli1, hname);
4628 cli_setatr(cli1, fname, 0, 0);
4629 cli_posix_unlink(cli1, fname);
4630 cli_setatr(cli1, dname, 0, 0);
4631 cli_posix_rmdir(cli1, dname);
4633 if (!torture_close_connection(cli1)) {
4641 static uint32 open_attrs_table[] = {
4642 FILE_ATTRIBUTE_NORMAL,
4643 FILE_ATTRIBUTE_ARCHIVE,
4644 FILE_ATTRIBUTE_READONLY,
4645 FILE_ATTRIBUTE_HIDDEN,
4646 FILE_ATTRIBUTE_SYSTEM,
4648 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY,
4649 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN,
4650 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM,
4651 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4652 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4653 FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4655 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN,
4656 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM,
4657 FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM,
4658 FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_SYSTEM,
4661 struct trunc_open_results {
4668 static struct trunc_open_results attr_results[] = {
4669 { 0, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4670 { 1, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4671 { 2, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4672 { 16, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_ARCHIVE },
4673 { 17, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_ARCHIVE },
4674 { 18, FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_READONLY, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY },
4675 { 51, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4676 { 54, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4677 { 56, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4678 { 68, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4679 { 71, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4680 { 73, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM },
4681 { 99, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN,FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4682 { 102, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4683 { 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 },
4684 { 116, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4685 { 119, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4686 { 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 },
4687 { 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 },
4688 { 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 },
4689 { 227, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4690 { 230, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_HIDDEN },
4691 { 232, FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN },
4692 { 244, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4693 { 247, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_SYSTEM },
4694 { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
4697 static bool run_openattrtest(int dummy)
4699 static struct cli_state *cli1;
4700 const char *fname = "\\openattr.file";
4702 bool correct = True;
4704 unsigned int i, j, k, l;
4706 printf("starting open attr test\n");
4708 if (!torture_open_connection(&cli1, 0)) {
4712 cli_sockopt(cli1, sockops);
4714 for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
4715 cli_setatr(cli1, fname, 0, 0);
4716 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4717 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
4718 FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0, &fnum1))) {
4719 printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4723 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4724 printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
4728 for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
4729 if (!NT_STATUS_IS_OK(cli_ntcreate(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
4730 FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0, &fnum1))) {
4731 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4732 if (attr_results[l].num == k) {
4733 printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
4734 k, open_attrs_table[i],
4735 open_attrs_table[j],
4736 fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
4740 if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
4741 printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
4742 k, open_attrs_table[i], open_attrs_table[j],
4747 printf("[%d] trunc open 0x%x -> 0x%x failed\n", k, open_attrs_table[i], open_attrs_table[j]);
4753 if (!NT_STATUS_IS_OK(cli_close(cli1, fnum1))) {
4754 printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
4758 if (!NT_STATUS_IS_OK(cli_getatr(cli1, fname, &attr, NULL, NULL))) {
4759 printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
4764 printf("[%d] getatr check [0x%x] trunc [0x%x] got attr 0x%x\n",
4765 k, open_attrs_table[i], open_attrs_table[j], attr );
4768 for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
4769 if (attr_results[l].num == k) {
4770 if (attr != attr_results[l].result_attr ||
4771 open_attrs_table[i] != attr_results[l].init_attr ||
4772 open_attrs_table[j] != attr_results[l].trunc_attr) {
4773 printf("getatr check failed. [0x%x] trunc [0x%x] got attr 0x%x, should be 0x%x\n",
4774 open_attrs_table[i],
4775 open_attrs_table[j],
4777 attr_results[l].result_attr);
4787 cli_setatr(cli1, fname, 0, 0);
4788 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
4790 printf("open attr test %s.\n", correct ? "passed" : "failed");
4792 if (!torture_close_connection(cli1)) {
4798 static void list_fn(const char *mnt, struct file_info *finfo,
4799 const char *name, void *state)
4801 int *matched = (int *)state;
4802 if (matched != NULL) {
4808 test directory listing speed
4810 static bool run_dirtest(int dummy)
4813 static struct cli_state *cli;
4815 struct timeval core_start;
4816 bool correct = True;
4819 printf("starting directory test\n");
4821 if (!torture_open_connection(&cli, 0)) {
4825 cli_sockopt(cli, sockops);
4828 for (i=0;i<torture_numops;i++) {
4830 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4831 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE, &fnum))) {
4832 fprintf(stderr,"Failed to open %s\n", fname);
4835 cli_close(cli, fnum);
4838 core_start = timeval_current();
4841 cli_list(cli, "a*.*", 0, list_fn, &matched);
4842 printf("Matched %d\n", matched);
4845 cli_list(cli, "b*.*", 0, list_fn, &matched);
4846 printf("Matched %d\n", matched);
4849 cli_list(cli, "xyzabc", 0, list_fn, &matched);
4850 printf("Matched %d\n", matched);
4852 printf("dirtest core %g seconds\n", timeval_elapsed(&core_start));
4855 for (i=0;i<torture_numops;i++) {
4857 slprintf(fname, sizeof(fname), "\\%x", (int)random());
4858 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4861 if (!torture_close_connection(cli)) {
4865 printf("finished dirtest\n");
4870 static void del_fn(const char *mnt, struct file_info *finfo, const char *mask,
4873 struct cli_state *pcli = (struct cli_state *)state;
4875 slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name);
4877 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
4880 if (finfo->mode & aDIR) {
4881 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
4882 printf("del_fn: failed to rmdir %s\n,", fname );
4884 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
4885 printf("del_fn: failed to unlink %s\n,", fname );
4891 sees what IOCTLs are supported
4893 bool torture_ioctl_test(int dummy)
4895 static struct cli_state *cli;
4896 uint16_t device, function;
4898 const char *fname = "\\ioctl.dat";
4902 if (!torture_open_connection(&cli, 0)) {
4906 printf("starting ioctl test\n");
4908 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
4910 if (!NT_STATUS_IS_OK(cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4911 printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
4915 status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
4916 printf("ioctl device info: %s\n", nt_errstr(status));
4918 status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
4919 printf("ioctl job info: %s\n", nt_errstr(status));
4921 for (device=0;device<0x100;device++) {
4922 printf("ioctl test with device = 0x%x\n", device);
4923 for (function=0;function<0x100;function++) {
4924 uint32 code = (device<<16) | function;
4926 status = cli_raw_ioctl(cli, fnum, code, &blob);
4928 if (NT_STATUS_IS_OK(status)) {
4929 printf("ioctl 0x%x OK : %d bytes\n", (int)code,
4931 data_blob_free(&blob);
4936 if (!torture_close_connection(cli)) {
4945 tries varients of chkpath
4947 bool torture_chkpath_test(int dummy)
4949 static struct cli_state *cli;
4953 if (!torture_open_connection(&cli, 0)) {
4957 printf("starting chkpath test\n");
4959 /* cleanup from an old run */
4960 cli_rmdir(cli, "\\chkpath.dir\\dir2");
4961 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
4962 cli_rmdir(cli, "\\chkpath.dir");
4964 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir"))) {
4965 printf("mkdir1 failed : %s\n", cli_errstr(cli));
4969 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\chkpath.dir\\dir2"))) {
4970 printf("mkdir2 failed : %s\n", cli_errstr(cli));
4974 if (!NT_STATUS_IS_OK(cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
4975 printf("open1 failed (%s)\n", cli_errstr(cli));
4978 cli_close(cli, fnum);
4980 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir"))) {
4981 printf("chkpath1 failed: %s\n", cli_errstr(cli));
4985 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dir2"))) {
4986 printf("chkpath2 failed: %s\n", cli_errstr(cli));
4990 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\foo.txt"))) {
4991 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
4992 NT_STATUS_NOT_A_DIRECTORY);
4994 printf("* chkpath on a file should fail\n");
4998 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\bar.txt"))) {
4999 ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile,
5000 NT_STATUS_OBJECT_NAME_NOT_FOUND);
5002 printf("* chkpath on a non existant file should fail\n");
5006 if (!NT_STATUS_IS_OK(cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt"))) {
5007 ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath,
5008 NT_STATUS_OBJECT_PATH_NOT_FOUND);
5010 printf("* chkpath on a non existent component should fail\n");
5014 cli_rmdir(cli, "\\chkpath.dir\\dir2");
5015 cli_unlink(cli, "\\chkpath.dir\\*", aSYSTEM | aHIDDEN);
5016 cli_rmdir(cli, "\\chkpath.dir");
5018 if (!torture_close_connection(cli)) {
5025 static bool run_eatest(int dummy)
5027 static struct cli_state *cli;
5028 const char *fname = "\\eatest.txt";
5029 bool correct = True;
5033 struct ea_struct *ea_list = NULL;
5034 TALLOC_CTX *mem_ctx = talloc_init("eatest");
5037 printf("starting eatest\n");
5039 if (!torture_open_connection(&cli, 0)) {
5040 talloc_destroy(mem_ctx);
5044 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
5045 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0,
5046 FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5047 FILE_SHARE_NONE, FILE_OVERWRITE_IF,
5048 0x4044, 0, &fnum))) {
5049 printf("open failed - %s\n", cli_errstr(cli));
5050 talloc_destroy(mem_ctx);
5054 for (i = 0; i < 10; i++) {
5055 fstring ea_name, ea_val;
5057 slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
5058 memset(ea_val, (char)i+1, i+1);
5059 if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
5060 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5061 talloc_destroy(mem_ctx);
5066 cli_close(cli, fnum);
5067 for (i = 0; i < 10; i++) {
5068 fstring ea_name, ea_val;
5070 slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
5071 memset(ea_val, (char)i+1, i+1);
5072 if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
5073 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5074 talloc_destroy(mem_ctx);
5079 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5080 if (!NT_STATUS_IS_OK(status)) {
5081 printf("ea_get list failed - %s\n", nt_errstr(status));
5085 printf("num_eas = %d\n", (int)num_eas);
5087 if (num_eas != 20) {
5088 printf("Should be 20 EA's stored... failing.\n");
5092 for (i = 0; i < num_eas; i++) {
5093 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5094 dump_data(0, ea_list[i].value.data,
5095 ea_list[i].value.length);
5098 /* Setting EA's to zero length deletes them. Test this */
5099 printf("Now deleting all EA's - case indepenent....\n");
5102 cli_set_ea_path(cli, fname, "", "", 0);
5104 for (i = 0; i < 20; i++) {
5106 slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
5107 if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
5108 printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
5109 talloc_destroy(mem_ctx);
5115 status = cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list);
5116 if (!NT_STATUS_IS_OK(status)) {
5117 printf("ea_get list failed - %s\n", nt_errstr(status));
5121 printf("num_eas = %d\n", (int)num_eas);
5122 for (i = 0; i < num_eas; i++) {
5123 printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
5124 dump_data(0, ea_list[i].value.data,
5125 ea_list[i].value.length);
5129 printf("deleting EA's failed.\n");
5133 /* Try and delete a non existant EA. */
5134 if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
5135 printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
5139 talloc_destroy(mem_ctx);
5140 if (!torture_close_connection(cli)) {
5147 static bool run_dirtest1(int dummy)
5150 static struct cli_state *cli;
5153 bool correct = True;
5155 printf("starting directory test\n");
5157 if (!torture_open_connection(&cli, 0)) {
5161 cli_sockopt(cli, sockops);
5163 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5164 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5165 cli_rmdir(cli, "\\LISTDIR");
5166 cli_mkdir(cli, "\\LISTDIR");
5168 /* Create 1000 files and 1000 directories. */
5169 for (i=0;i<1000;i++) {
5171 slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
5172 if (!NT_STATUS_IS_OK(cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
5173 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5174 fprintf(stderr,"Failed to open %s\n", fname);
5177 cli_close(cli, fnum);
5179 for (i=0;i<1000;i++) {
5181 slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
5182 if (!NT_STATUS_IS_OK(cli_mkdir(cli, fname))) {
5183 fprintf(stderr,"Failed to open %s\n", fname);
5188 /* Now ensure that doing an old list sees both files and directories. */
5190 cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, &num_seen);
5191 printf("num_seen = %d\n", num_seen );
5192 /* We should see 100 files + 1000 directories + . and .. */
5193 if (num_seen != 2002)
5196 /* Ensure if we have the "must have" bits we only see the
5200 cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, &num_seen);
5201 printf("num_seen = %d\n", num_seen );
5202 if (num_seen != 1002)
5206 cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, &num_seen);
5207 printf("num_seen = %d\n", num_seen );
5208 if (num_seen != 1000)
5211 /* Delete everything. */
5212 cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
5213 cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
5214 cli_rmdir(cli, "\\LISTDIR");
5217 printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
5218 printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
5219 printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
5222 if (!torture_close_connection(cli)) {
5226 printf("finished dirtest1\n");
5231 static bool run_error_map_extract(int dummy) {
5233 static struct cli_state *c_dos;
5234 static struct cli_state *c_nt;
5239 uint32 flgs2, errnum;
5246 /* NT-Error connection */
5248 if (!(c_nt = open_nbt_connection())) {
5252 c_nt->use_spnego = False;
5254 status = cli_negprot(c_nt);
5256 if (!NT_STATUS_IS_OK(status)) {
5257 printf("%s rejected the NT-error negprot (%s)\n", host,
5263 if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
5265 printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
5269 /* DOS-Error connection */
5271 if (!(c_dos = open_nbt_connection())) {
5275 c_dos->use_spnego = False;
5276 c_dos->force_dos_errors = True;
5278 status = cli_negprot(c_dos);
5279 if (!NT_STATUS_IS_OK(status)) {
5280 printf("%s rejected the DOS-error negprot (%s)\n", host,
5282 cli_shutdown(c_dos);
5286 if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
5288 printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
5292 for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
5293 fstr_sprintf(user, "%X", error);
5295 if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user,
5296 password, strlen(password),
5297 password, strlen(password),
5299 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5302 flgs2 = SVAL(c_nt->inbuf,smb_flg2);
5304 /* Case #1: 32-bit NT errors */
5305 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5306 nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
5308 printf("/** Dos error on NT connection! (%s) */\n",
5310 nt_status = NT_STATUS(0xc0000000);
5313 if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user,
5314 password, strlen(password),
5315 password, strlen(password),
5317 printf("/** Session setup succeeded. This shouldn't happen...*/\n");
5319 flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
5321 /* Case #1: 32-bit NT errors */
5322 if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
5323 printf("/** NT error on DOS connection! (%s) */\n",
5325 errnum = errclass = 0;
5327 cli_dos_error(c_dos, &errclass, &errnum);
5330 if (NT_STATUS_V(nt_status) != error) {
5331 printf("/*\t{ This NT error code was 'sqashed'\n\t from %s to %s \n\t during the session setup }\n*/\n",
5332 get_nt_error_c_code(NT_STATUS(error)),
5333 get_nt_error_c_code(nt_status));
5336 printf("\t{%s,\t%s,\t%s},\n",
5337 smb_dos_err_class(errclass),
5338 smb_dos_err_name(errclass, errnum),
5339 get_nt_error_c_code(NT_STATUS(error)));
5344 static bool run_sesssetup_bench(int dummy)
5346 static struct cli_state *c;
5347 const char *fname = "\\file.dat";
5352 if (!torture_open_connection(&c, 0)) {
5356 if (!NT_STATUS_IS_OK(cli_ntcreate(
5357 c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5358 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
5359 FILE_DELETE_ON_CLOSE, 0, &fnum))) {
5360 d_printf("open %s failed: %s\n", fname, cli_errstr(c));
5364 for (i=0; i<torture_numops; i++) {
5365 status = cli_session_setup(
5367 password, strlen(password),
5368 password, strlen(password),
5370 if (!NT_STATUS_IS_OK(status)) {
5371 d_printf("(%s) cli_session_setup failed: %s\n",
5372 __location__, nt_errstr(status));
5376 d_printf("\r%d ", (int)c->vuid);
5378 status = cli_ulogoff(c);
5379 if (!NT_STATUS_IS_OK(status)) {
5380 d_printf("(%s) cli_ulogoff failed: %s\n",
5381 __location__, nt_errstr(status));
5390 static bool subst_test(const char *str, const char *user, const char *domain,
5391 uid_t uid, gid_t gid, const char *expected)
5396 subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
5398 if (strcmp(subst, expected) != 0) {
5399 printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
5400 "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
5409 static void chain1_open_completion(struct tevent_req *req)
5413 status = cli_open_recv(req, &fnum);
5416 d_printf("cli_open_recv returned %s: %d\n",
5418 NT_STATUS_IS_OK(status) ? fnum : -1);
5421 static void chain1_write_completion(struct tevent_req *req)
5425 status = cli_write_andx_recv(req, &written);
5428 d_printf("cli_write_andx_recv returned %s: %d\n",
5430 NT_STATUS_IS_OK(status) ? (int)written : -1);
5433 static void chain1_close_completion(struct tevent_req *req)
5436 bool *done = (bool *)tevent_req_callback_data_void(req);
5438 status = cli_close_recv(req);
5443 d_printf("cli_close returned %s\n", nt_errstr(status));
5446 static bool run_chain1(int dummy)
5448 struct cli_state *cli1;
5449 struct event_context *evt = event_context_init(NULL);
5450 struct tevent_req *reqs[3], *smbreqs[3];
5452 const char *str = "foobar";
5455 printf("starting chain1 test\n");
5456 if (!torture_open_connection(&cli1, 0)) {
5460 cli_sockopt(cli1, sockops);
5462 reqs[0] = cli_open_create(talloc_tos(), evt, cli1, "\\test",
5463 O_CREAT|O_RDWR, 0, &smbreqs[0]);
5464 if (reqs[0] == NULL) return false;
5465 tevent_req_set_callback(reqs[0], chain1_open_completion, NULL);
5468 reqs[1] = cli_write_andx_create(talloc_tos(), evt, cli1, 0, 0,
5469 (uint8_t *)str, 0, strlen(str)+1,
5470 smbreqs, 1, &smbreqs[1]);
5471 if (reqs[1] == NULL) return false;
5472 tevent_req_set_callback(reqs[1], chain1_write_completion, NULL);
5474 reqs[2] = cli_close_create(talloc_tos(), evt, cli1, 0, &smbreqs[2]);
5475 if (reqs[2] == NULL) return false;
5476 tevent_req_set_callback(reqs[2], chain1_close_completion, &done);
5478 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5479 if (!NT_STATUS_IS_OK(status)) {
5484 event_loop_once(evt);
5487 torture_close_connection(cli1);
5491 static void chain2_sesssetup_completion(struct tevent_req *req)
5494 status = cli_session_setup_guest_recv(req);
5495 d_printf("sesssetup returned %s\n", nt_errstr(status));
5498 static void chain2_tcon_completion(struct tevent_req *req)
5500 bool *done = (bool *)tevent_req_callback_data_void(req);
5502 status = cli_tcon_andx_recv(req);
5503 d_printf("tcon_and_x returned %s\n", nt_errstr(status));
5507 static bool run_chain2(int dummy)
5509 struct cli_state *cli1;
5510 struct event_context *evt = event_context_init(NULL);
5511 struct tevent_req *reqs[2], *smbreqs[2];
5515 printf("starting chain2 test\n");
5516 status = cli_start_connection(&cli1, global_myname(), host, NULL,
5517 port_to_use, Undefined, 0, NULL);
5518 if (!NT_STATUS_IS_OK(status)) {
5522 cli_sockopt(cli1, sockops);
5524 reqs[0] = cli_session_setup_guest_create(talloc_tos(), evt, cli1,
5526 if (reqs[0] == NULL) return false;
5527 tevent_req_set_callback(reqs[0], chain2_sesssetup_completion, NULL);
5529 reqs[1] = cli_tcon_andx_create(talloc_tos(), evt, cli1, "IPC$",
5530 "?????", NULL, 0, &smbreqs[1]);
5531 if (reqs[1] == NULL) return false;
5532 tevent_req_set_callback(reqs[1], chain2_tcon_completion, &done);
5534 status = cli_smb_chain_send(smbreqs, ARRAY_SIZE(smbreqs));
5535 if (!NT_STATUS_IS_OK(status)) {
5540 event_loop_once(evt);
5543 torture_close_connection(cli1);
5548 struct torture_createdel_state {
5549 struct tevent_context *ev;
5550 struct cli_state *cli;
5553 static void torture_createdel_created(struct tevent_req *subreq);
5554 static void torture_createdel_closed(struct tevent_req *subreq);
5556 static struct tevent_req *torture_createdel_send(TALLOC_CTX *mem_ctx,
5557 struct tevent_context *ev,
5558 struct cli_state *cli,
5561 struct tevent_req *req, *subreq;
5562 struct torture_createdel_state *state;
5564 req = tevent_req_create(mem_ctx, &state,
5565 struct torture_createdel_state);
5572 subreq = cli_ntcreate_send(
5573 state, ev, cli, name, 0,
5574 FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
5575 FILE_ATTRIBUTE_NORMAL,
5576 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
5577 FILE_OPEN_IF, FILE_DELETE_ON_CLOSE, 0);
5579 if (tevent_req_nomem(subreq, req)) {
5580 return tevent_req_post(req, ev);
5582 tevent_req_set_callback(subreq, torture_createdel_created, req);
5586 static void torture_createdel_created(struct tevent_req *subreq)
5588 struct tevent_req *req = tevent_req_callback_data(
5589 subreq, struct tevent_req);
5590 struct torture_createdel_state *state = tevent_req_data(
5591 req, struct torture_createdel_state);
5595 status = cli_ntcreate_recv(subreq, &fnum);
5596 TALLOC_FREE(subreq);
5597 if (!NT_STATUS_IS_OK(status)) {
5598 DEBUG(10, ("cli_ntcreate_recv returned %s\n",
5599 nt_errstr(status)));
5600 tevent_req_nterror(req, status);
5604 subreq = cli_close_send(state, state->ev, state->cli, fnum);
5605 if (tevent_req_nomem(subreq, req)) {
5608 tevent_req_set_callback(subreq, torture_createdel_closed, req);
5611 static void torture_createdel_closed(struct tevent_req *subreq)
5613 struct tevent_req *req = tevent_req_callback_data(
5614 subreq, struct tevent_req);
5617 status = cli_close_recv(subreq);
5618 if (!NT_STATUS_IS_OK(status)) {
5619 DEBUG(10, ("cli_close_recv returned %s\n", nt_errstr(status)));
5620 tevent_req_nterror(req, status);
5623 tevent_req_done(req);
5626 static NTSTATUS torture_createdel_recv(struct tevent_req *req)
5628 return tevent_req_simple_recv_ntstatus(req);
5631 struct torture_createdels_state {
5632 struct tevent_context *ev;
5633 struct cli_state *cli;
5634 const char *base_name;
5638 struct tevent_req **reqs;
5641 static void torture_createdels_done(struct tevent_req *subreq);
5643 static struct tevent_req *torture_createdels_send(TALLOC_CTX *mem_ctx,
5644 struct tevent_context *ev,
5645 struct cli_state *cli,
5646 const char *base_name,
5650 struct tevent_req *req;
5651 struct torture_createdels_state *state;
5654 req = tevent_req_create(mem_ctx, &state,
5655 struct torture_createdels_state);
5661 state->base_name = talloc_strdup(state, base_name);
5662 if (tevent_req_nomem(state->base_name, req)) {
5663 return tevent_req_post(req, ev);
5665 state->num_files = MAX(num_parallel, num_files);
5667 state->received = 0;
5669 state->reqs = talloc_array(state, struct tevent_req *, num_parallel);
5670 if (tevent_req_nomem(state->reqs, req)) {
5671 return tevent_req_post(req, ev);
5674 for (i=0; i<num_parallel; i++) {
5677 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5679 if (tevent_req_nomem(name, req)) {
5680 return tevent_req_post(req, ev);
5682 state->reqs[i] = torture_createdel_send(
5683 state->reqs, state->ev, state->cli, name);
5684 if (tevent_req_nomem(state->reqs[i], req)) {
5685 return tevent_req_post(req, ev);
5687 name = talloc_move(state->reqs[i], &name);
5688 tevent_req_set_callback(state->reqs[i],
5689 torture_createdels_done, req);
5695 static void torture_createdels_done(struct tevent_req *subreq)
5697 struct tevent_req *req = tevent_req_callback_data(
5698 subreq, struct tevent_req);
5699 struct torture_createdels_state *state = tevent_req_data(
5700 req, struct torture_createdels_state);
5701 size_t num_parallel = talloc_array_length(state->reqs);
5706 status = torture_createdel_recv(subreq);
5707 if (!NT_STATUS_IS_OK(status)){
5708 DEBUG(10, ("torture_createdel_recv returned %s\n",
5709 nt_errstr(status)));
5710 TALLOC_FREE(subreq);
5711 tevent_req_nterror(req, status);
5715 for (i=0; i<num_parallel; i++) {
5716 if (subreq == state->reqs[i]) {
5720 if (i == num_parallel) {
5721 DEBUG(10, ("received something we did not send\n"));
5722 tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
5725 TALLOC_FREE(state->reqs[i]);
5727 if (state->sent >= state->num_files) {
5728 tevent_req_done(req);
5732 name = talloc_asprintf(state, "%s%8.8d", state->base_name,
5734 if (tevent_req_nomem(name, req)) {
5737 state->reqs[i] = torture_createdel_send(state->reqs, state->ev,
5739 if (tevent_req_nomem(state->reqs[i], req)) {
5742 name = talloc_move(state->reqs[i], &name);
5743 tevent_req_set_callback(state->reqs[i], torture_createdels_done, req);
5747 static NTSTATUS torture_createdels_recv(struct tevent_req *req)
5749 return tevent_req_simple_recv_ntstatus(req);
5752 struct swallow_notify_state {
5753 struct tevent_context *ev;
5754 struct cli_state *cli;
5756 uint32_t completion_filter;
5758 bool (*fn)(uint32_t action, const char *name, void *priv);
5762 static void swallow_notify_done(struct tevent_req *subreq);
5764 static struct tevent_req *swallow_notify_send(TALLOC_CTX *mem_ctx,
5765 struct tevent_context *ev,
5766 struct cli_state *cli,
5768 uint32_t completion_filter,
5770 bool (*fn)(uint32_t action,
5775 struct tevent_req *req, *subreq;
5776 struct swallow_notify_state *state;
5778 req = tevent_req_create(mem_ctx, &state,
5779 struct swallow_notify_state);
5786 state->completion_filter = completion_filter;
5787 state->recursive = recursive;
5791 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5792 0xffff, state->completion_filter,
5794 if (tevent_req_nomem(subreq, req)) {
5795 return tevent_req_post(req, ev);
5797 tevent_req_set_callback(subreq, swallow_notify_done, req);
5801 static void swallow_notify_done(struct tevent_req *subreq)
5803 struct tevent_req *req = tevent_req_callback_data(
5804 subreq, struct tevent_req);
5805 struct swallow_notify_state *state = tevent_req_data(
5806 req, struct swallow_notify_state);
5808 uint32_t i, num_changes;
5809 struct notify_change *changes;
5811 status = cli_notify_recv(subreq, state, &num_changes, &changes);
5812 TALLOC_FREE(subreq);
5813 if (!NT_STATUS_IS_OK(status)) {
5814 DEBUG(10, ("cli_notify_recv returned %s\n",
5815 nt_errstr(status)));
5816 tevent_req_nterror(req, status);
5820 for (i=0; i<num_changes; i++) {
5821 state->fn(changes[i].action, changes[i].name, state->priv);
5823 TALLOC_FREE(changes);
5825 subreq = cli_notify_send(state, state->ev, state->cli, state->fnum,
5826 0xffff, state->completion_filter,
5828 if (tevent_req_nomem(subreq, req)) {
5831 tevent_req_set_callback(subreq, swallow_notify_done, req);
5834 static bool print_notifies(uint32_t action, const char *name, void *priv)
5836 if (DEBUGLEVEL > 5) {
5837 d_printf("%d %s\n", (int)action, name);
5842 static void notify_bench_done(struct tevent_req *req)
5844 int *num_finished = (int *)tevent_req_callback_data_void(req);
5848 static bool run_notify_bench(int dummy)
5850 const char *dname = "\\notify-bench";
5851 struct tevent_context *ev;
5854 struct tevent_req *req1;
5855 struct tevent_req *req2 = NULL;
5856 int i, num_unc_names;
5857 int num_finished = 0;
5859 printf("starting notify-bench test\n");
5861 if (use_multishare_conn) {
5863 unc_list = file_lines_load(multishare_conn_fname,
5864 &num_unc_names, 0, NULL);
5865 if (!unc_list || num_unc_names <= 0) {
5866 d_printf("Failed to load unc names list from '%s'\n",
5867 multishare_conn_fname);
5870 TALLOC_FREE(unc_list);
5875 ev = tevent_context_init(talloc_tos());
5877 d_printf("tevent_context_init failed\n");
5881 for (i=0; i<num_unc_names; i++) {
5882 struct cli_state *cli;
5885 base_fname = talloc_asprintf(talloc_tos(), "%s\\file%3.3d.",
5887 if (base_fname == NULL) {
5891 if (!torture_open_connection(&cli, i)) {
5895 status = cli_ntcreate(cli, dname, 0,
5896 MAXIMUM_ALLOWED_ACCESS,
5897 0, FILE_SHARE_READ|FILE_SHARE_WRITE|
5899 FILE_OPEN_IF, FILE_DIRECTORY_FILE, 0,
5902 if (!NT_STATUS_IS_OK(status)) {
5903 d_printf("Could not create %s: %s\n", dname,
5908 req1 = swallow_notify_send(talloc_tos(), ev, cli, dnum,
5909 FILE_NOTIFY_CHANGE_FILE_NAME |
5910 FILE_NOTIFY_CHANGE_DIR_NAME |
5911 FILE_NOTIFY_CHANGE_ATTRIBUTES |
5912 FILE_NOTIFY_CHANGE_LAST_WRITE,
5913 false, print_notifies, NULL);
5915 d_printf("Could not create notify request\n");
5919 req2 = torture_createdels_send(talloc_tos(), ev, cli,
5920 base_fname, 10, torture_numops);
5922 d_printf("Could not create createdels request\n");
5925 TALLOC_FREE(base_fname);
5927 tevent_req_set_callback(req2, notify_bench_done,
5931 while (num_finished < num_unc_names) {
5933 ret = tevent_loop_once(ev);
5935 d_printf("tevent_loop_once failed\n");
5940 if (!tevent_req_poll(req2, ev)) {
5941 d_printf("tevent_req_poll failed\n");
5944 status = torture_createdels_recv(req2);
5945 d_printf("torture_createdels_recv returned %s\n", nt_errstr(status));
5950 static bool run_mangle1(int dummy)
5952 struct cli_state *cli;
5953 const char *fname = "this_is_a_long_fname_to_be_mangled.txt";
5957 time_t change_time, access_time, write_time;
5961 printf("starting mangle1 test\n");
5962 if (!torture_open_connection(&cli, 0)) {
5966 cli_sockopt(cli, sockops);
5968 if (!NT_STATUS_IS_OK(cli_ntcreate(
5969 cli, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
5970 FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0, &fnum))) {
5971 d_printf("open %s failed: %s\n", fname, cli_errstr(cli));
5974 cli_close(cli, fnum);
5976 status = cli_qpathinfo_alt_name(cli, fname, alt_name);
5977 if (!NT_STATUS_IS_OK(status)) {
5978 d_printf("cli_qpathinfo_alt_name failed: %s\n",
5982 d_printf("alt_name: %s\n", alt_name);
5984 if (!NT_STATUS_IS_OK(cli_open(cli, alt_name, O_RDONLY, DENY_NONE, &fnum))) {
5985 d_printf("cli_open(%s) failed: %s\n", alt_name,
5989 cli_close(cli, fnum);
5991 status = cli_qpathinfo1(cli, alt_name, &change_time, &access_time,
5992 &write_time, &size, &mode);
5993 if (!NT_STATUS_IS_OK(status)) {
5994 d_printf("cli_qpathinfo1(%s) failed: %s\n", alt_name,
6002 static size_t null_source(uint8_t *buf, size_t n, void *priv)
6004 size_t *to_pull = (size_t *)priv;
6005 size_t thistime = *to_pull;
6007 thistime = MIN(thistime, n);
6008 if (thistime == 0) {
6012 memset(buf, 0, thistime);
6013 *to_pull -= thistime;
6017 static bool run_windows_write(int dummy)
6019 struct cli_state *cli1;
6023 const char *fname = "\\writetest.txt";
6024 struct timeval start_time;
6028 printf("starting windows_write test\n");
6029 if (!torture_open_connection(&cli1, 0)) {
6033 if (!NT_STATUS_IS_OK(cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE, &fnum))) {
6034 printf("open failed (%s)\n", cli_errstr(cli1));
6038 cli_sockopt(cli1, sockops);
6040 start_time = timeval_current();
6042 for (i=0; i<torture_numops; i++) {
6044 off_t start = i * torture_blocksize;
6046 size_t to_pull = torture_blocksize - 1;
6048 if (cli_write(cli1, fnum, 0, &c,
6049 start + torture_blocksize - 1, 1) != 1) {
6050 printf("cli_write failed: %s\n", cli_errstr(cli1));
6054 status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
6055 null_source, &to_pull);
6056 if (!NT_STATUS_IS_OK(status)) {
6057 printf("cli_push returned: %s\n", nt_errstr(status));
6062 seconds = timeval_elapsed(&start_time);
6063 kbytes = (double)torture_blocksize * torture_numops;
6066 printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
6067 (double)seconds, (int)(kbytes/seconds));
6071 cli_close(cli1, fnum);
6072 cli_unlink(cli1, fname, aSYSTEM | aHIDDEN);
6073 torture_close_connection(cli1);
6077 static bool run_cli_echo(int dummy)
6079 struct cli_state *cli;
6082 printf("starting cli_echo test\n");
6083 if (!torture_open_connection(&cli, 0)) {
6086 cli_sockopt(cli, sockops);
6088 status = cli_echo(cli, 5, data_blob_const("hello", 5));
6090 d_printf("cli_echo returned %s\n", nt_errstr(status));
6092 torture_close_connection(cli);
6093 return NT_STATUS_IS_OK(status);
6096 static bool run_uid_regression_test(int dummy)
6098 static struct cli_state *cli;
6101 bool correct = True;
6104 printf("starting uid regression test\n");
6106 if (!torture_open_connection(&cli, 0)) {
6110 cli_sockopt(cli, sockops);
6112 /* Ok - now save then logoff our current user. */
6113 old_vuid = cli->vuid;
6115 status = cli_ulogoff(cli);
6116 if (!NT_STATUS_IS_OK(status)) {
6117 d_printf("(%s) cli_ulogoff failed: %s\n",
6118 __location__, nt_errstr(status));
6123 cli->vuid = old_vuid;
6125 /* Try an operation. */
6126 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\uid_reg_test"))) {
6127 /* We expect bad uid. */
6128 if (!check_error(__LINE__, cli, ERRSRV, ERRbaduid,
6129 NT_STATUS_NO_SUCH_USER)) {
6134 old_cnum = cli->cnum;
6136 /* Now try a SMBtdis with the invald vuid set to zero. */
6139 /* This should succeed. */
6140 status = cli_tdis(cli);
6142 if (NT_STATUS_IS_OK(status)) {
6143 printf("First tdis with invalid vuid should succeed.\n");
6145 printf("First tdis failed (%s)\n", nt_errstr(status));
6148 cli->vuid = old_vuid;
6149 cli->cnum = old_cnum;
6151 /* This should fail. */
6152 status = cli_tdis(cli);
6153 if (NT_STATUS_IS_OK(status)) {
6154 printf("Second tdis with invalid vuid should fail - succeeded instead !.\n");
6156 /* Should be bad tid. */
6157 if (!check_error(__LINE__, cli, ERRSRV, ERRinvnid,
6158 NT_STATUS_NETWORK_NAME_DELETED)) {
6163 cli_rmdir(cli, "\\uid_reg_test");
6172 static const char *illegal_chars = "*\\/?<>|\":";
6173 static char force_shortname_chars[] = " +,.[];=\177";
6175 static void shortname_del_fn(const char *mnt, struct file_info *finfo,
6176 const char *mask, void *state)
6178 struct cli_state *pcli = (struct cli_state *)state;
6180 slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name);
6182 if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0)
6185 if (finfo->mode & aDIR) {
6186 if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname)))
6187 printf("del_fn: failed to rmdir %s\n,", fname );
6189 if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN)))
6190 printf("del_fn: failed to unlink %s\n,", fname );
6200 static void shortname_list_fn(const char *mnt, struct file_info *finfo,
6201 const char *name, void *state)
6203 struct sn_state *s = (struct sn_state *)state;
6207 printf("shortname list: i = %d, name = |%s|, shortname = |%s|\n",
6208 i, finfo->name, finfo->short_name);
6211 if (strchr(force_shortname_chars, i)) {
6212 if (!finfo->short_name[0]) {
6213 /* Shortname not created when it should be. */
6214 d_printf("(%s) ERROR: Shortname was not created for file %s containing %d\n",
6215 __location__, finfo->name, i);
6218 } else if (finfo->short_name[0]){
6219 /* Shortname created when it should not be. */
6220 d_printf("(%s) ERROR: Shortname %s was created for file %s\n",
6221 __location__, finfo->short_name, finfo->name);
6227 static bool run_shortname_test(int dummy)
6229 static struct cli_state *cli;
6230 bool correct = True;
6235 printf("starting shortname test\n");
6237 if (!torture_open_connection(&cli, 0)) {
6241 cli_sockopt(cli, sockops);
6243 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6244 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6245 cli_rmdir(cli, "\\shortname");
6247 if (!NT_STATUS_IS_OK(cli_mkdir(cli, "\\shortname"))) {
6248 d_printf("(%s) cli_mkdir of \\shortname failed: %s\n",
6249 __location__, cli_errstr(cli));
6254 strlcpy(fname, "\\shortname\\", sizeof(fname));
6255 strlcat(fname, "test .txt", sizeof(fname));
6259 for (i = 32; i < 128; i++) {
6261 uint16_t fnum = (uint16_t)-1;
6265 if (strchr(illegal_chars, i)) {
6270 status = cli_ntcreate(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
6271 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0, &fnum);
6272 if (!NT_STATUS_IS_OK(status)) {
6273 d_printf("(%s) cli_nt_create of %s failed: %s\n",
6274 __location__, fname, cli_errstr(cli));
6278 cli_close(cli, fnum);
6281 cli_list(cli, "\\shortname\\test*.*", 0, shortname_list_fn,
6283 if (s.matched != 1) {
6284 d_printf("(%s) failed to list %s: %s\n",
6285 __location__, fname, cli_errstr(cli));
6289 if (!NT_STATUS_IS_OK(cli_unlink(cli, fname, aSYSTEM | aHIDDEN))) {
6290 d_printf("(%s) failed to delete %s: %s\n",
6291 __location__, fname, cli_errstr(cli));
6304 cli_list(cli, "\\shortname\\*", 0, shortname_del_fn, cli);
6305 cli_list(cli, "\\shortname\\*", aDIR, shortname_del_fn, cli);
6306 cli_rmdir(cli, "\\shortname");
6307 torture_close_connection(cli);
6311 static void pagedsearch_cb(struct tevent_req *req)
6314 struct tldap_message *msg;
6317 rc = tldap_search_paged_recv(req, talloc_tos(), &msg);
6318 if (rc != TLDAP_SUCCESS) {
6319 d_printf("tldap_search_paged_recv failed: %s\n",
6320 tldap_err2string(rc));
6323 if (tldap_msg_type(msg) != TLDAP_RES_SEARCH_ENTRY) {
6327 if (!tldap_entry_dn(msg, &dn)) {
6328 d_printf("tldap_entry_dn failed\n");
6331 d_printf("%s\n", dn);
6335 static bool run_tldap(int dummy)
6337 struct tldap_context *ld;
6340 struct sockaddr_storage addr;
6341 struct tevent_context *ev;
6342 struct tevent_req *req;
6346 if (!resolve_name(host, &addr, 0, false)) {
6347 d_printf("could not find host %s\n", host);
6350 status = open_socket_out(&addr, 389, 9999, &fd);
6351 if (!NT_STATUS_IS_OK(status)) {
6352 d_printf("open_socket_out failed: %s\n", nt_errstr(status));
6356 ld = tldap_context_create(talloc_tos(), fd);
6359 d_printf("tldap_context_create failed\n");
6363 rc = tldap_fetch_rootdse(ld);
6364 if (rc != TLDAP_SUCCESS) {
6365 d_printf("tldap_fetch_rootdse failed: %s\n",
6366 tldap_errstr(talloc_tos(), ld, rc));
6370 basedn = tldap_talloc_single_attribute(
6371 tldap_rootdse(ld), "defaultNamingContext", talloc_tos());
6372 if (basedn == NULL) {
6373 d_printf("no defaultNamingContext\n");
6376 d_printf("defaultNamingContext: %s\n", basedn);
6378 ev = tevent_context_init(talloc_tos());
6380 d_printf("tevent_context_init failed\n");
6384 req = tldap_search_paged_send(talloc_tos(), ev, ld, basedn,
6385 TLDAP_SCOPE_SUB, "(objectclass=*)",
6387 NULL, 0, NULL, 0, 0, 0, 0, 5);
6389 d_printf("tldap_search_paged_send failed\n");
6392 tevent_req_set_callback(req, pagedsearch_cb, NULL);
6394 tevent_req_poll(req, ev);
6398 /* test search filters against rootDSE */
6399 filter = "(&(|(name=samba)(nextRid<=10000000)(usnChanged>=10)(samba~=ambas)(!(name=s*m*a)))"
6400 "(|(name:=samba)(name:dn:2.5.13.5:=samba)(:dn:2.5.13.5:=samba)(!(name=*samba))))";
6402 rc = tldap_search(ld, "", TLDAP_SCOPE_BASE, filter,
6403 NULL, 0, 0, NULL, 0, NULL, 0, 0, 0, 0,
6404 talloc_tos(), NULL, NULL);
6405 if (rc != TLDAP_SUCCESS) {
6406 d_printf("tldap_search with complex filter failed: %s\n",
6407 tldap_errstr(talloc_tos(), ld, rc));
6415 /* Torture test to ensure no regression of :
6416 https://bugzilla.samba.org/show_bug.cgi?id=7084
6419 static bool run_dir_createtime(int dummy)
6421 struct cli_state *cli;
6422 const char *dname = "\\testdir";
6423 const char *fname = "\\testdir\\testfile";
6425 struct timespec create_time;
6426 struct timespec create_time1;
6430 if (!torture_open_connection(&cli, 0)) {
6434 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6435 cli_rmdir(cli, dname);
6437 status = cli_mkdir(cli, dname);
6438 if (!NT_STATUS_IS_OK(status)) {
6439 printf("mkdir failed: %s\n", nt_errstr(status));
6443 status = cli_qpathinfo2(cli, dname, &create_time, NULL, NULL, NULL,
6445 if (!NT_STATUS_IS_OK(status)) {
6446 printf("cli_qpathinfo2 returned %s\n",
6451 /* Sleep 3 seconds, then create a file. */
6454 status = cli_open(cli, fname, O_RDWR | O_CREAT | O_EXCL,
6456 if (!NT_STATUS_IS_OK(status)) {
6457 printf("cli_open failed: %s\n", nt_errstr(status));
6461 status = cli_qpathinfo2(cli, dname, &create_time1, NULL, NULL, NULL,
6463 if (!NT_STATUS_IS_OK(status)) {
6464 printf("cli_qpathinfo2 (2) returned %s\n",
6469 if (timespec_compare(&create_time1, &create_time)) {
6470 printf("run_dir_createtime: create time was updated (error)\n");
6472 printf("run_dir_createtime: create time was not updated (correct)\n");
6478 cli_unlink(cli, fname, aSYSTEM | aHIDDEN);
6479 cli_rmdir(cli, dname);
6480 if (!torture_close_connection(cli)) {
6487 static bool run_streamerror(int dummy)
6489 struct cli_state *cli;
6490 const char *dname = "\\testdir";
6491 const char *streamname =
6492 "testdir:{4c8cc155-6c1e-11d1-8e41-00c04fb9386d}:$DATA";
6494 time_t change_time, access_time, write_time;
6496 uint16_t mode, fnum;
6499 if (!torture_open_connection(&cli, 0)) {
6503 cli_unlink(cli, "\\testdir\\*", aSYSTEM | aHIDDEN);
6504 cli_rmdir(cli, dname);
6506 status = cli_mkdir(cli, dname);
6507 if (!NT_STATUS_IS_OK(status)) {
6508 printf("mkdir failed: %s\n", nt_errstr(status));
6512 cli_qpathinfo1(cli, streamname, &change_time, &access_time, &write_time,
6514 status = cli_nt_error(cli);
6516 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6517 printf("pathinfo returned %s, expected "
6518 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6523 status = cli_ntcreate(cli, streamname, 0x16,
6524 FILE_READ_DATA|FILE_READ_EA|
6525 FILE_READ_ATTRIBUTES|READ_CONTROL_ACCESS,
6526 FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
6527 FILE_OPEN, 0, 0, &fnum);
6529 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
6530 printf("ntcreate returned %s, expected "
6531 "NT_STATUS_OBJECT_NAME_NOT_FOUND\n",
6537 cli_rmdir(cli, dname);
6541 static bool run_local_substitute(int dummy)
6545 ok &= subst_test("%U", "bla", "", -1, -1, "bla");
6546 ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
6547 ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
6548 ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
6549 ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
6550 ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
6551 ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
6552 ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
6554 /* Different captialization rules in sub_basic... */
6556 ok &= (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
6562 static bool run_local_base64(int dummy)
6567 for (i=1; i<2000; i++) {
6568 DATA_BLOB blob1, blob2;
6571 blob1.data = talloc_array(talloc_tos(), uint8_t, i);
6573 generate_random_buffer(blob1.data, blob1.length);
6575 b64 = base64_encode_data_blob(talloc_tos(), blob1);
6577 d_fprintf(stderr, "base64_encode_data_blob failed "
6578 "for %d bytes\n", i);
6581 blob2 = base64_decode_data_blob(b64);
6584 if (data_blob_cmp(&blob1, &blob2)) {
6585 d_fprintf(stderr, "data_blob_cmp failed for %d "
6589 TALLOC_FREE(blob1.data);
6590 data_blob_free(&blob2);
6595 static bool run_local_gencache(int dummy)
6601 if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
6602 d_printf("%s: gencache_set() failed\n", __location__);
6606 if (!gencache_get("foo", NULL, NULL)) {
6607 d_printf("%s: gencache_get() failed\n", __location__);
6611 if (!gencache_get("foo", &val, &tm)) {
6612 d_printf("%s: gencache_get() failed\n", __location__);
6616 if (strcmp(val, "bar") != 0) {
6617 d_printf("%s: gencache_get() returned %s, expected %s\n",
6618 __location__, val, "bar");
6625 if (!gencache_del("foo")) {
6626 d_printf("%s: gencache_del() failed\n", __location__);
6629 if (gencache_del("foo")) {
6630 d_printf("%s: second gencache_del() succeeded\n",
6635 if (gencache_get("foo", &val, &tm)) {
6636 d_printf("%s: gencache_get() on deleted entry "
6637 "succeeded\n", __location__);
6641 blob = data_blob_string_const_null("bar");
6642 tm = time(NULL) + 60;
6644 if (!gencache_set_data_blob("foo", &blob, tm)) {
6645 d_printf("%s: gencache_set_data_blob() failed\n", __location__);
6649 if (!gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6650 d_printf("%s: gencache_get_data_blob() failed\n", __location__);
6654 if (strcmp((const char *)blob.data, "bar") != 0) {
6655 d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
6656 __location__, (const char *)blob.data, "bar");
6657 data_blob_free(&blob);
6661 data_blob_free(&blob);
6663 if (!gencache_del("foo")) {
6664 d_printf("%s: gencache_del() failed\n", __location__);
6667 if (gencache_del("foo")) {
6668 d_printf("%s: second gencache_del() succeeded\n",
6673 if (gencache_get_data_blob("foo", &blob, NULL, NULL)) {
6674 d_printf("%s: gencache_get_data_blob() on deleted entry "
6675 "succeeded\n", __location__);
6682 static bool rbt_testval(struct db_context *db, const char *key,
6685 struct db_record *rec;
6686 TDB_DATA data = string_tdb_data(value);
6690 rec = db->fetch_locked(db, db, string_tdb_data(key));
6692 d_fprintf(stderr, "fetch_locked failed\n");
6695 status = rec->store(rec, data, 0);
6696 if (!NT_STATUS_IS_OK(status)) {
6697 d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
6702 rec = db->fetch_locked(db, db, string_tdb_data(key));
6704 d_fprintf(stderr, "second fetch_locked failed\n");
6707 if ((rec->value.dsize != data.dsize)
6708 || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
6709 d_fprintf(stderr, "Got wrong data back\n");
6719 static bool run_local_rbtree(int dummy)
6721 struct db_context *db;
6725 db = db_open_rbt(NULL);
6728 d_fprintf(stderr, "db_open_rbt failed\n");
6732 for (i=0; i<1000; i++) {
6735 if (asprintf(&key, "key%ld", random()) == -1) {
6738 if (asprintf(&value, "value%ld", random()) == -1) {
6743 if (!rbt_testval(db, key, value)) {
6750 if (asprintf(&value, "value%ld", random()) == -1) {
6755 if (!rbt_testval(db, key, value)) {
6772 struct talloc_dict_test {
6776 static int talloc_dict_traverse_fn(DATA_BLOB key, void *data, void *priv)
6778 int *count = (int *)priv;
6783 static bool run_local_talloc_dict(int dummy)
6785 struct talloc_dict *dict;
6786 struct talloc_dict_test *t;
6789 dict = talloc_dict_init(talloc_tos());
6794 t = talloc(talloc_tos(), struct talloc_dict_test);
6801 if (!talloc_dict_set(dict, data_blob_const(&key, sizeof(key)), t)) {
6806 if (talloc_dict_traverse(dict, talloc_dict_traverse_fn, &count) != 0) {
6819 static bool run_local_string_to_sid(int dummy) {
6822 if (string_to_sid(&sid, "S--1-5-32-545")) {
6823 printf("allowing S--1-5-32-545\n");
6826 if (string_to_sid(&sid, "S-1-5-32-+545")) {
6827 printf("allowing S-1-5-32-+545\n");
6830 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")) {
6831 printf("allowing S-1-2-3-4-5-6-7-8-9-0-1-2-3-4-5-6-7-8-9-0\n");
6834 if (string_to_sid(&sid, "S-1-5-32-545-abc")) {
6835 printf("allowing S-1-5-32-545-abc\n");
6838 if (!string_to_sid(&sid, "S-1-5-32-545")) {
6839 printf("could not parse S-1-5-32-545\n");
6842 if (!sid_equal(&sid, &global_sid_Builtin_Users)) {
6843 printf("mis-parsed S-1-5-32-545 as %s\n",
6844 sid_string_tos(&sid));
6850 /* Split a path name into filename and stream name components. Canonicalise
6851 * such that an implicit $DATA token is always explicit.
6853 * The "specification" of this function can be found in the
6854 * run_local_stream_name() function in torture.c, I've tried those
6855 * combinations against a W2k3 server.
6858 static NTSTATUS split_ntfs_stream_name(TALLOC_CTX *mem_ctx, const char *fname,
6859 char **pbase, char **pstream)
6862 char *stream = NULL;
6863 char *sname; /* stream name */
6864 const char *stype; /* stream type */
6866 DEBUG(10, ("split_ntfs_stream_name called for [%s]\n", fname));
6868 sname = strchr_m(fname, ':');
6870 if (lp_posix_pathnames() || (sname == NULL)) {
6871 if (pbase != NULL) {
6872 base = talloc_strdup(mem_ctx, fname);
6873 NT_STATUS_HAVE_NO_MEMORY(base);
6878 if (pbase != NULL) {
6879 base = talloc_strndup(mem_ctx, fname, PTR_DIFF(sname, fname));
6880 NT_STATUS_HAVE_NO_MEMORY(base);
6885 stype = strchr_m(sname, ':');
6887 if (stype == NULL) {
6888 sname = talloc_strdup(mem_ctx, sname);
6892 if (StrCaseCmp(stype, ":$DATA") != 0) {
6894 * If there is an explicit stream type, so far we only
6895 * allow $DATA. Is there anything else allowed? -- vl
6897 DEBUG(10, ("[%s] is an invalid stream type\n", stype));
6899 return NT_STATUS_OBJECT_NAME_INVALID;
6901 sname = talloc_strndup(mem_ctx, sname, PTR_DIFF(stype, sname));
6905 if (sname == NULL) {
6907 return NT_STATUS_NO_MEMORY;
6910 if (sname[0] == '\0') {
6912 * no stream name, so no stream
6917 if (pstream != NULL) {
6918 stream = talloc_asprintf(mem_ctx, "%s:%s", sname, stype);
6919 if (stream == NULL) {
6922 return NT_STATUS_NO_MEMORY;
6925 * upper-case the type field
6927 strupper_m(strchr_m(stream, ':')+1);
6931 if (pbase != NULL) {
6934 if (pstream != NULL) {
6937 return NT_STATUS_OK;
6940 static bool test_stream_name(const char *fname, const char *expected_base,
6941 const char *expected_stream,
6942 NTSTATUS expected_status)
6946 char *stream = NULL;
6948 status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
6949 if (!NT_STATUS_EQUAL(status, expected_status)) {
6953 if (!NT_STATUS_IS_OK(status)) {
6957 if (base == NULL) goto error;
6959 if (strcmp(expected_base, base) != 0) goto error;
6961 if ((expected_stream != NULL) && (stream == NULL)) goto error;
6962 if ((expected_stream == NULL) && (stream != NULL)) goto error;
6964 if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
6968 TALLOC_FREE(stream);
6972 d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
6973 fname, expected_base ? expected_base : "<NULL>",
6974 expected_stream ? expected_stream : "<NULL>",
6975 nt_errstr(expected_status));
6976 d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
6977 base ? base : "<NULL>", stream ? stream : "<NULL>",
6980 TALLOC_FREE(stream);
6984 static bool run_local_stream_name(int dummy)
6988 ret &= test_stream_name(
6989 "bla", "bla", NULL, NT_STATUS_OK);
6990 ret &= test_stream_name(
6991 "bla::$DATA", "bla", NULL, NT_STATUS_OK);
6992 ret &= test_stream_name(
6993 "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6994 ret &= test_stream_name(
6995 "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
6996 ret &= test_stream_name(
6997 "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
6998 ret &= test_stream_name(
6999 "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
7000 ret &= test_stream_name(
7001 "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
7002 ret &= test_stream_name(
7003 "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
7008 static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
7010 if (a.length != b.length) {
7011 printf("a.length=%d != b.length=%d\n",
7012 (int)a.length, (int)b.length);
7015 if (memcmp(a.data, b.data, a.length) != 0) {
7016 printf("a.data and b.data differ\n");
7022 static bool run_local_memcache(int dummy)
7024 struct memcache *cache;
7026 DATA_BLOB d1, d2, d3;
7027 DATA_BLOB v1, v2, v3;
7029 TALLOC_CTX *mem_ctx;
7031 size_t size1, size2;
7034 cache = memcache_init(NULL, 100);
7036 if (cache == NULL) {
7037 printf("memcache_init failed\n");
7041 d1 = data_blob_const("d1", 2);
7042 d2 = data_blob_const("d2", 2);
7043 d3 = data_blob_const("d3", 2);
7045 k1 = data_blob_const("d1", 2);
7046 k2 = data_blob_const("d2", 2);
7048 memcache_add(cache, STAT_CACHE, k1, d1);
7049 memcache_add(cache, GETWD_CACHE, k2, d2);
7051 if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
7052 printf("could not find k1\n");
7055 if (!data_blob_equal(d1, v1)) {
7059 if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7060 printf("could not find k2\n");
7063 if (!data_blob_equal(d2, v2)) {
7067 memcache_add(cache, STAT_CACHE, k1, d3);
7069 if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
7070 printf("could not find replaced k1\n");
7073 if (!data_blob_equal(d3, v3)) {
7077 memcache_add(cache, GETWD_CACHE, k1, d1);
7079 if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
7080 printf("Did find k2, should have been purged\n");
7086 cache = memcache_init(NULL, 0);
7088 mem_ctx = talloc_init("foo");
7090 str1 = talloc_strdup(mem_ctx, "string1");
7091 str2 = talloc_strdup(mem_ctx, "string2");
7093 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7094 data_blob_string_const("torture"), &str1);
7095 size1 = talloc_total_size(cache);
7097 memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
7098 data_blob_string_const("torture"), &str2);
7099 size2 = talloc_total_size(cache);
7101 printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
7103 if (size2 > size1) {
7104 printf("memcache leaks memory!\n");
7114 static void wbclient_done(struct tevent_req *req)
7117 struct winbindd_response *wb_resp;
7118 int *i = (int *)tevent_req_callback_data_void(req);
7120 wbc_err = wb_trans_recv(req, req, &wb_resp);
7123 d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
7126 static bool run_local_wbclient(int dummy)
7128 struct event_context *ev;
7129 struct wb_context **wb_ctx;
7130 struct winbindd_request wb_req;
7131 bool result = false;
7134 BlockSignals(True, SIGPIPE);
7136 ev = tevent_context_init_byname(talloc_tos(), "epoll");
7141 wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, nprocs);
7142 if (wb_ctx == NULL) {
7146 ZERO_STRUCT(wb_req);
7147 wb_req.cmd = WINBINDD_PING;
7149 d_printf("nprocs=%d, numops=%d\n", (int)nprocs, (int)torture_numops);
7151 for (i=0; i<nprocs; i++) {
7152 wb_ctx[i] = wb_context_init(ev, NULL);
7153 if (wb_ctx[i] == NULL) {
7156 for (j=0; j<torture_numops; j++) {
7157 struct tevent_req *req;
7158 req = wb_trans_send(ev, ev, wb_ctx[i],
7159 (j % 2) == 0, &wb_req);
7163 tevent_req_set_callback(req, wbclient_done, &i);
7169 while (i < nprocs * torture_numops) {
7170 event_loop_once(ev);
7179 static void getaddrinfo_finished(struct tevent_req *req)
7181 char *name = (char *)tevent_req_callback_data_void(req);
7182 struct addrinfo *ainfo;
7185 res = getaddrinfo_recv(req, &ainfo);
7187 d_printf("gai(%s) returned %s\n", name, gai_strerror(res));
7190 d_printf("gai(%s) succeeded\n", name);
7191 freeaddrinfo(ainfo);
7194 static bool run_getaddrinfo_send(int dummy)
7196 TALLOC_CTX *frame = talloc_stackframe();
7197 struct fncall_context *ctx;
7198 struct tevent_context *ev;
7199 bool result = false;
7200 const char *names[4] = { "www.samba.org", "notfound.samba.org",
7201 "www.slashdot.org", "heise.de" };
7202 struct tevent_req *reqs[4];
7205 ev = event_context_init(frame);
7210 ctx = fncall_context_init(frame, 4);
7212 for (i=0; i<ARRAY_SIZE(names); i++) {
7213 reqs[i] = getaddrinfo_send(frame, ev, ctx, names[i], NULL,
7215 if (reqs[i] == NULL) {
7218 tevent_req_set_callback(reqs[i], getaddrinfo_finished,
7222 for (i=0; i<ARRAY_SIZE(reqs); i++) {
7223 tevent_loop_once(ev);
7232 static bool dbtrans_inc(struct db_context *db)
7234 struct db_record *rec;
7239 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7241 printf(__location__ "fetch_lock failed\n");
7245 if (rec->value.dsize != sizeof(uint32_t)) {
7246 printf(__location__ "value.dsize = %d\n",
7247 (int)rec->value.dsize);
7251 val = (uint32_t *)rec->value.dptr;
7254 status = rec->store(rec, make_tdb_data((uint8_t *)val,
7257 if (!NT_STATUS_IS_OK(status)) {
7258 printf(__location__ "store failed: %s\n",
7269 static bool run_local_dbtrans(int dummy)
7271 struct db_context *db;
7272 struct db_record *rec;
7277 db = db_open(talloc_tos(), "transtest.tdb", 0, TDB_DEFAULT,
7278 O_RDWR|O_CREAT, 0600);
7280 printf("Could not open transtest.db\n");
7284 res = db->transaction_start(db);
7286 printf(__location__ "transaction_start failed\n");
7290 rec = db->fetch_locked(db, db, string_term_tdb_data("transtest"));
7292 printf(__location__ "fetch_lock failed\n");
7296 if (rec->value.dptr == NULL) {
7298 status = rec->store(
7299 rec, make_tdb_data((uint8_t *)&initial,
7302 if (!NT_STATUS_IS_OK(status)) {
7303 printf(__location__ "store returned %s\n",
7311 res = db->transaction_commit(db);
7313 printf(__location__ "transaction_commit failed\n");
7321 res = db->transaction_start(db);
7323 printf(__location__ "transaction_start failed\n");
7327 if (!dbwrap_fetch_uint32(db, "transtest", &val)) {
7328 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7332 for (i=0; i<10; i++) {
7333 if (!dbtrans_inc(db)) {
7338 if (!dbwrap_fetch_uint32(db, "transtest", &val2)) {
7339 printf(__location__ "dbwrap_fetch_uint32 failed\n");
7343 if (val2 != val + 10) {
7344 printf(__location__ "val=%d, val2=%d\n",
7345 (int)val, (int)val2);
7349 printf("val2=%d\r", val2);
7351 res = db->transaction_commit(db);
7353 printf(__location__ "transaction_commit failed\n");
7363 * Just a dummy test to be run under a debugger. There's no real way
7364 * to inspect the tevent_select specific function from outside of
7368 static bool run_local_tevent_select(int dummy)
7370 struct tevent_context *ev;
7371 struct tevent_fd *fd1, *fd2;
7372 bool result = false;
7374 ev = tevent_context_init_byname(NULL, "select");
7376 d_fprintf(stderr, "tevent_context_init_byname failed\n");
7380 fd1 = tevent_add_fd(ev, ev, 2, 0, NULL, NULL);
7382 d_fprintf(stderr, "tevent_add_fd failed\n");
7385 fd2 = tevent_add_fd(ev, ev, 3, 0, NULL, NULL);
7387 d_fprintf(stderr, "tevent_add_fd failed\n");
7392 fd2 = tevent_add_fd(ev, ev, 1, 0, NULL, NULL);
7394 d_fprintf(stderr, "tevent_add_fd failed\n");
7404 static double create_procs(bool (*fn)(int), bool *result)
7407 volatile pid_t *child_status;
7408 volatile bool *child_status_out;
7411 struct timeval start;
7415 child_status = (volatile pid_t *)shm_setup(sizeof(pid_t)*nprocs);
7416 if (!child_status) {
7417 printf("Failed to setup shared memory\n");
7421 child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
7422 if (!child_status_out) {
7423 printf("Failed to setup result status shared memory\n");
7427 for (i = 0; i < nprocs; i++) {
7428 child_status[i] = 0;
7429 child_status_out[i] = True;
7432 start = timeval_current();
7434 for (i=0;i<nprocs;i++) {
7437 pid_t mypid = getpid();
7438 sys_srandom(((int)mypid) ^ ((int)time(NULL)));
7440 slprintf(myname,sizeof(myname),"CLIENT%d", i);
7443 if (torture_open_connection(¤t_cli, i)) break;
7445 printf("pid %d failed to start\n", (int)getpid());
7451 child_status[i] = getpid();
7453 while (child_status[i] && timeval_elapsed(&start) < 5) smb_msleep(2);
7455 child_status_out[i] = fn(i);
7462 for (i=0;i<nprocs;i++) {
7463 if (child_status[i]) synccount++;
7465 if (synccount == nprocs) break;
7467 } while (timeval_elapsed(&start) < 30);
7469 if (synccount != nprocs) {
7470 printf("FAILED TO START %d CLIENTS (started %d)\n", nprocs, synccount);
7472 return timeval_elapsed(&start);
7475 /* start the client load */
7476 start = timeval_current();
7478 for (i=0;i<nprocs;i++) {
7479 child_status[i] = 0;
7482 printf("%d clients started\n", nprocs);
7484 for (i=0;i<nprocs;i++) {
7485 while (waitpid(0, &status, 0) == -1 && errno == EINTR) /* noop */ ;
7490 for (i=0;i<nprocs;i++) {
7491 if (!child_status_out[i]) {
7495 return timeval_elapsed(&start);
7498 #define FLAG_MULTIPROC 1
7505 {"FDPASS", run_fdpasstest, 0},
7506 {"LOCK1", run_locktest1, 0},
7507 {"LOCK2", run_locktest2, 0},
7508 {"LOCK3", run_locktest3, 0},
7509 {"LOCK4", run_locktest4, 0},
7510 {"LOCK5", run_locktest5, 0},
7511 {"LOCK6", run_locktest6, 0},
7512 {"LOCK7", run_locktest7, 0},
7513 {"LOCK8", run_locktest8, 0},
7514 {"LOCK9", run_locktest9, 0},
7515 {"UNLINK", run_unlinktest, 0},
7516 {"BROWSE", run_browsetest, 0},
7517 {"ATTR", run_attrtest, 0},
7518 {"TRANS2", run_trans2test, 0},
7519 {"MAXFID", run_maxfidtest, FLAG_MULTIPROC},
7520 {"TORTURE",run_torture, FLAG_MULTIPROC},
7521 {"RANDOMIPC", run_randomipc, 0},
7522 {"NEGNOWAIT", run_negprot_nowait, 0},
7523 {"NBENCH", run_nbench, 0},
7524 {"NBENCH2", run_nbench2, 0},
7525 {"OPLOCK1", run_oplock1, 0},
7526 {"OPLOCK2", run_oplock2, 0},
7527 {"OPLOCK3", run_oplock3, 0},
7528 {"DIR", run_dirtest, 0},
7529 {"DIR1", run_dirtest1, 0},
7530 {"DIR-CREATETIME", run_dir_createtime, 0},
7531 {"DENY1", torture_denytest1, 0},
7532 {"DENY2", torture_denytest2, 0},
7533 {"TCON", run_tcon_test, 0},
7534 {"TCONDEV", run_tcon_devtype_test, 0},
7535 {"RW1", run_readwritetest, 0},
7536 {"RW2", run_readwritemulti, FLAG_MULTIPROC},
7537 {"RW3", run_readwritelarge, 0},
7538 {"OPEN", run_opentest, 0},
7539 {"POSIX", run_simple_posix_open_test, 0},
7540 {"POSIX-APPEND", run_posix_append, 0},
7541 { "UID-REGRESSION-TEST", run_uid_regression_test, 0},
7542 { "SHORTNAME-TEST", run_shortname_test, 0},
7544 {"OPENATTR", run_openattrtest, 0},
7546 {"XCOPY", run_xcopy, 0},
7547 {"RENAME", run_rename, 0},
7548 {"DELETE", run_deletetest, 0},
7549 {"PROPERTIES", run_properties, 0},
7550 {"MANGLE", torture_mangle, 0},
7551 {"MANGLE1", run_mangle1, 0},
7552 {"W2K", run_w2ktest, 0},
7553 {"TRANS2SCAN", torture_trans2_scan, 0},
7554 {"NTTRANSSCAN", torture_nttrans_scan, 0},
7555 {"UTABLE", torture_utable, 0},
7556 {"CASETABLE", torture_casetable, 0},
7557 {"ERRMAPEXTRACT", run_error_map_extract, 0},
7558 {"PIPE_NUMBER", run_pipe_number, 0},
7559 {"TCON2", run_tcon2_test, 0},
7560 {"IOCTL", torture_ioctl_test, 0},
7561 {"CHKPATH", torture_chkpath_test, 0},
7562 {"FDSESS", run_fdsesstest, 0},
7563 { "EATEST", run_eatest, 0},
7564 { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
7565 { "CHAIN1", run_chain1, 0},
7566 { "CHAIN2", run_chain2, 0},
7567 { "WINDOWS-WRITE", run_windows_write, 0},
7568 { "CLI_ECHO", run_cli_echo, 0},
7569 { "GETADDRINFO", run_getaddrinfo_send, 0},
7570 { "TLDAP", run_tldap },
7571 { "STREAMERROR", run_streamerror },
7572 { "NOTIFY-BENCH", run_notify_bench },
7573 { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
7574 { "LOCAL-GENCACHE", run_local_gencache, 0},
7575 { "LOCAL-TALLOC-DICT", run_local_talloc_dict, 0},
7576 { "LOCAL-BASE64", run_local_base64, 0},
7577 { "LOCAL-RBTREE", run_local_rbtree, 0},
7578 { "LOCAL-MEMCACHE", run_local_memcache, 0},
7579 { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
7580 { "LOCAL-WBCLIENT", run_local_wbclient, 0},
7581 { "LOCAL-string_to_sid", run_local_string_to_sid, 0},
7582 { "LOCAL-DBTRANS", run_local_dbtrans, 0},
7583 { "LOCAL-TEVENT-SELECT", run_local_tevent_select, 0},
7588 /****************************************************************************
7589 run a specified test or "ALL"
7590 ****************************************************************************/
7591 static bool run_test(const char *name)
7598 if (strequal(name,"ALL")) {
7599 for (i=0;torture_ops[i].name;i++) {
7600 run_test(torture_ops[i].name);
7605 for (i=0;torture_ops[i].name;i++) {
7606 fstr_sprintf(randomfname, "\\XX%x",
7607 (unsigned)random());
7609 if (strequal(name, torture_ops[i].name)) {
7611 printf("Running %s\n", name);
7612 if (torture_ops[i].flags & FLAG_MULTIPROC) {
7613 t = create_procs(torture_ops[i].fn, &result);
7616 printf("TEST %s FAILED!\n", name);
7619 struct timeval start;
7620 start = timeval_current();
7621 if (!torture_ops[i].fn(0)) {
7623 printf("TEST %s FAILED!\n", name);
7625 t = timeval_elapsed(&start);
7627 printf("%s took %g secs\n\n", name, t);
7632 printf("Did not find a test named %s\n", name);
7640 static void usage(void)
7644 printf("WARNING samba4 test suite is much more complete nowadays.\n");
7645 printf("Please use samba4 torture.\n\n");
7647 printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
7649 printf("\t-d debuglevel\n");
7650 printf("\t-U user%%pass\n");
7651 printf("\t-k use kerberos\n");
7652 printf("\t-N numprocs\n");
7653 printf("\t-n my_netbios_name\n");
7654 printf("\t-W workgroup\n");
7655 printf("\t-o num_operations\n");
7656 printf("\t-O socket_options\n");
7657 printf("\t-m maximum protocol\n");
7658 printf("\t-L use oplocks\n");
7659 printf("\t-c CLIENT.TXT specify client load file for NBENCH\n");
7660 printf("\t-A showall\n");
7661 printf("\t-p port\n");
7662 printf("\t-s seed\n");
7663 printf("\t-b unclist_filename specify multiple shares for multiple connections\n");
7666 printf("tests are:");
7667 for (i=0;torture_ops[i].name;i++) {
7668 printf(" %s", torture_ops[i].name);
7672 printf("default test is ALL\n");
7677 /****************************************************************************
7679 ****************************************************************************/
7680 int main(int argc,char *argv[])
7686 bool correct = True;
7687 TALLOC_CTX *frame = talloc_stackframe();
7688 int seed = time(NULL);
7692 #ifdef HAVE_SETBUFFER
7693 setbuffer(stdout, NULL, 0);
7698 setup_logging("smbtorture", true);
7700 if (is_default_dyn_CONFIGFILE()) {
7701 if(getenv("SMB_CONF_PATH")) {
7702 set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
7705 lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
7712 for(p = argv[1]; *p; p++)
7716 if (strncmp(argv[1], "//", 2)) {
7720 fstrcpy(host, &argv[1][2]);
7721 p = strchr_m(&host[2],'/');
7726 fstrcpy(share, p+1);
7728 fstrcpy(myname, get_myname(talloc_tos()));
7730 fprintf(stderr, "Failed to get my hostname.\n");
7734 if (*username == 0 && getenv("LOGNAME")) {
7735 fstrcpy(username,getenv("LOGNAME"));
7741 fstrcpy(workgroup, lp_workgroup());
7743 while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ll:d:Aec:ks:b:B:")) != EOF) {
7746 port_to_use = atoi(optarg);
7749 seed = atoi(optarg);
7752 fstrcpy(workgroup,optarg);
7755 max_protocol = interpret_protocol(optarg, max_protocol);
7758 nprocs = atoi(optarg);
7761 torture_numops = atoi(optarg);
7764 DEBUGLEVEL = atoi(optarg);
7773 local_path = optarg;
7776 torture_showall = True;
7779 fstrcpy(myname, optarg);
7782 client_txt = optarg;
7789 use_kerberos = True;
7791 d_printf("No kerberos support compiled in\n");
7797 fstrcpy(username,optarg);
7798 p = strchr_m(username,'%');
7801 fstrcpy(password, p+1);
7806 fstrcpy(multishare_conn_fname, optarg);
7807 use_multishare_conn = True;
7810 torture_blocksize = atoi(optarg);
7813 printf("Unknown option %c (%d)\n", (char)opt, opt);
7818 d_printf("using seed %d\n", seed);
7822 if(use_kerberos && !gotuser) gotpass = True;
7825 p = getpass("Password:");
7827 fstrcpy(password, p);
7832 printf("host=%s share=%s user=%s myname=%s\n",
7833 host, share, username, myname);
7835 if (argc == optind) {
7836 correct = run_test("ALL");
7838 for (i=optind;i<argc;i++) {
7839 if (!run_test(argv[i])) {