Merge branch 'checktalloc' of /home/jelmer/samba4
[amitay/samba.git] / source3 / torture / torture.c
index fe53baae7e197ff93268351c9737f8d6c19f442a..e2d1497b280b589d9727d17188d2b896817216e9 100644 (file)
@@ -5,7 +5,7 @@
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#define NO_SYSLOG
-
 #include "includes.h"
+#include "wbc_async.h"
+
+extern char *optarg;
+extern int optind;
 
 static fstring host, workgroup, share, password, username, myname;
 static int max_protocol = PROTOCOL_NT1;
 static const char *sockops="TCP_NODELAY";
 static int nprocs=1;
+static int port_to_use=0;
 int torture_numops=100;
+int torture_blocksize=1024*1024;
 static int procnum; /* records process count number when forking */
-static struct cli_state current_cli;
+static struct cli_state *current_cli;
 static fstring randomfname;
-static BOOL use_oplocks;
-static BOOL use_level_II_oplocks;
+static bool use_oplocks;
+static bool use_level_II_oplocks;
 static const char *client_txt = "client_oplocks.txt";
-static BOOL use_kerberos;
+static bool use_kerberos;
+static fstring multishare_conn_fname;
+static bool use_multishare_conn = False;
+static bool do_encrypt;
 
-BOOL torture_showall = False;
+bool torture_showall = False;
 
-static double create_procs(BOOL (*fn)(int), BOOL *result);
+static double create_procs(bool (*fn)(int), bool *result);
 
 
 static struct timeval tp1,tp2;
 
+
 void start_timer(void)
 {
-       gettimeofday(&tp1,NULL);
+       GetTimeOfDay(&tp1);
 }
 
 double end_timer(void)
 {
-       gettimeofday(&tp2,NULL);
+       GetTimeOfDay(&tp2);
        return((tp2.tv_sec - tp1.tv_sec) + 
               (tp2.tv_usec - tp1.tv_usec)*1.0e-6);
 }
@@ -69,7 +76,7 @@ void *shm_setup(int size)
        int shmid;
        void *ret;
 
-       shmid = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
+       shmid = shmget(IPC_PRIVATE, size, S_IRUSR | S_IWUSR);
        if (shmid == -1) {
                printf("can't get shared memory\n");
                exit(1);
@@ -91,22 +98,81 @@ void *shm_setup(int size)
        return ret;
 }
 
+/********************************************************************
+ Ensure a connection is encrypted.
+********************************************************************/
 
-static BOOL open_nbt_connection(struct cli_state *c)
+static bool force_cli_encryption(struct cli_state *c,
+                       const char *sharename)
 {
-       struct nmb_name called, calling;
-       struct in_addr ip;
+       uint16 major, minor;
+       uint32 caplow, caphigh;
+       NTSTATUS status;
+
+       if (!SERVER_HAS_UNIX_CIFS(c)) {
+               d_printf("Encryption required and "
+                       "server that doesn't support "
+                       "UNIX extensions - failing connect\n");
+                       return false;
+       }
+
+       if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) {
+               d_printf("Encryption required and "
+                       "can't get UNIX CIFS extensions "
+                       "version from server.\n");
+               return false;
+       }
+
+       if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) {
+               d_printf("Encryption required and "
+                       "share %s doesn't support "
+                       "encryption.\n", sharename);
+               return false;
+       }
+
+       if (c->use_kerberos) {
+               status = cli_gss_smb_encryption_start(c);
+       } else {
+               status = cli_raw_ntlm_smb_encryption_start(c,
+                                               username,
+                                               password,
+                                               workgroup);
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               d_printf("Encryption required and "
+                       "setup failed with error %s.\n",
+                       nt_errstr(status));
+               return false;
+       }
 
-       ZERO_STRUCTP(c);
+       return true;
+}
+
+
+static struct cli_state *open_nbt_connection(void)
+{
+       struct nmb_name called, calling;
+       struct sockaddr_storage ss;
+       struct cli_state *c;
+       NTSTATUS status;
 
        make_nmb_name(&calling, myname, 0x0);
        make_nmb_name(&called , host, 0x20);
 
-        zero_ip(&ip);
+        zero_sockaddr(&ss);
 
-       if (!cli_initialise(c) || !cli_connect(c, host, &ip)) {
-               printf("Failed to connect with %s\n", host);
-               return False;
+       if (!(c = cli_initialise())) {
+               printf("Failed initialize cli_struct to connect with %s\n", host);
+               return NULL;
+       }
+
+       c->port = port_to_use;
+
+       status = cli_connect(c, host, &ss);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
+               return NULL;
        }
 
        c->use_kerberos = use_kerberos;
@@ -116,51 +182,179 @@ static BOOL open_nbt_connection(struct cli_state *c)
        if (use_level_II_oplocks) c->use_level_II_oplocks = True;
 
        if (!cli_session_request(c, &calling, &called)) {
-               printf("%s rejected the session\n",host);
-               cli_shutdown(c);
-               return False;
+               /*
+                * Well, that failed, try *SMBSERVER ...
+                * However, we must reconnect as well ...
+                */
+               status = cli_connect(c, host, &ss);
+               if (!NT_STATUS_IS_OK(status)) {
+                       printf("Failed to connect with %s. Error %s\n", host, nt_errstr(status) );
+                       return NULL;
+               }
+
+               make_nmb_name(&called, "*SMBSERVER", 0x20);
+               if (!cli_session_request(c, &calling, &called)) {
+                       printf("%s rejected the session\n",host);
+                       printf("We tried with a called name of %s & %s\n",
+                               host, "*SMBSERVER");
+                       cli_shutdown(c);
+                       return NULL;
+               }
        }
 
-       return True;
+       return c;
 }
 
-BOOL torture_open_connection(struct cli_state *c)
+/* Insert a NULL at the first separator of the given path and return a pointer
+ * to the remainder of the string.
+ */
+static char *
+terminate_path_at_separator(char * path)
 {
-       ZERO_STRUCTP(c);
+       char * p;
 
-       if (!open_nbt_connection(c)) {
-               return False;
+       if (!path) {
+               return NULL;
        }
 
-       if (!cli_negprot(c)) {
-               printf("%s rejected the negprot (%s)\n",host, cli_errstr(c));
-               cli_shutdown(c);
-               return False;
+       if ((p = strchr_m(path, '/'))) {
+               *p = '\0';
+               return p + 1;
+       }
+
+       if ((p = strchr_m(path, '\\'))) {
+               *p = '\0';
+               return p + 1;
        }
+       
+       /* No separator. */
+       return NULL;
+}
+
+/*
+  parse a //server/share type UNC name
+*/
+bool smbcli_parse_unc(const char *unc_name, TALLOC_CTX *mem_ctx,
+                     char **hostname, char **sharename)
+{
+       char *p;
 
-       if (!cli_session_setup(c, username, 
-                              password, strlen(password),
-                              password, strlen(password),
-                              workgroup)) {
-               printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(c));
-               cli_shutdown(c);
+       *hostname = *sharename = NULL;
+
+       if (strncmp(unc_name, "\\\\", 2) &&
+           strncmp(unc_name, "//", 2)) {
                return False;
        }
 
-       if (!cli_send_tconX(c, share, "?????",
-                           password, strlen(password)+1)) {
-               printf("%s refused tree connect (%s)\n", host, cli_errstr(c));
-               cli_shutdown(c);
+       *hostname = talloc_strdup(mem_ctx, &unc_name[2]);
+       p = terminate_path_at_separator(*hostname);
+
+       if (p && *p) {
+               *sharename = talloc_strdup(mem_ctx, p);
+               terminate_path_at_separator(*sharename);
+       }
+
+       if (*hostname && *sharename) {
+               return True;
+       }
+
+       TALLOC_FREE(*hostname);
+       TALLOC_FREE(*sharename);
+       return False;
+}
+
+static bool torture_open_connection_share(struct cli_state **c,
+                                  const char *hostname, 
+                                  const char *sharename)
+{
+       bool retry;
+       int flags = 0;
+       NTSTATUS status;
+
+       if (use_kerberos)
+               flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
+
+       status = cli_full_connection(c, myname,
+                                    hostname, NULL, port_to_use, 
+                                    sharename, "?????", 
+                                    username, workgroup, 
+                                    password, flags, Undefined, &retry);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("failed to open share connection: //%s/%s port:%d - %s\n",
+                       hostname, sharename, port_to_use, nt_errstr(status));
                return False;
        }
 
+       if (use_oplocks) (*c)->use_oplocks = True;
+       if (use_level_II_oplocks) (*c)->use_level_II_oplocks = True;
+       (*c)->timeout = 120000; /* set a really long timeout (2 minutes) */
+
+       if (do_encrypt) {
+               return force_cli_encryption(*c,
+                                       sharename);
+       }
        return True;
 }
 
+bool torture_open_connection(struct cli_state **c, int conn_index)
+{
+       char **unc_list = NULL;
+       int num_unc_names = 0;
+       bool result;
+
+       if (use_multishare_conn==True) {
+               char *h, *s;
+               unc_list = file_lines_load(multishare_conn_fname, &num_unc_names, 0, NULL);
+               if (!unc_list || num_unc_names <= 0) {
+                       printf("Failed to load unc names list from '%s'\n", multishare_conn_fname);
+                       exit(1);
+               }
+
+               if (!smbcli_parse_unc(unc_list[conn_index % num_unc_names],
+                                     NULL, &h, &s)) {
+                       printf("Failed to parse UNC name %s\n",
+                              unc_list[conn_index % num_unc_names]);
+                       TALLOC_FREE(unc_list);
+                       exit(1);
+               }
+
+               result = torture_open_connection_share(c, h, s);
+
+               /* h, s were copied earlier */
+               TALLOC_FREE(unc_list);
+               return result;
+       }
+
+       return torture_open_connection_share(c, host, share);
+}
+
+bool torture_cli_session_setup2(struct cli_state *cli, uint16 *new_vuid)
+{
+       uint16 old_vuid = cli->vuid;
+       fstring old_user_name;
+       size_t passlen = strlen(password);
+       NTSTATUS status;
+       bool ret;
+
+       fstrcpy(old_user_name, cli->user_name);
+       cli->vuid = 0;
+       ret = NT_STATUS_IS_OK(cli_session_setup(cli, username,
+                                               password, passlen,
+                                               password, passlen,
+                                               workgroup));
+       *new_vuid = cli->vuid;
+       cli->vuid = old_vuid;
+       status = cli_set_username(cli, old_user_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return false;
+       }
+       return ret;
+}
+
 
-BOOL torture_close_connection(struct cli_state *c)
+bool torture_close_connection(struct cli_state *c)
 {
-       BOOL ret = True;
+       bool ret = True;
        if (!cli_tdis(c)) {
                printf("tdis failed (%s)\n", cli_errstr(c));
                ret = False;
@@ -173,20 +367,20 @@ BOOL torture_close_connection(struct cli_state *c)
 
 
 /* check if the server produced the expected error code */
-static BOOL check_error(int line, struct cli_state *c, 
+static bool check_error(int line, struct cli_state *c, 
                        uint8 eclass, uint32 ecode, NTSTATUS nterr)
 {
         if (cli_is_dos_error(c)) {
-                uint8 class;
+                uint8 cclass;
                 uint32 num;
 
                 /* Check DOS error */
 
-                cli_dos_error(c, &class, &num);
+                cli_dos_error(c, &cclass, &num);
 
-                if (eclass != class || ecode != num) {
+                if (eclass != cclass || ecode != num) {
                         printf("unexpected error code class=%d code=%d\n", 
-                               (int)class, (int)num);
+                               (int)cclass, (int)num);
                         printf(" expected %d/%d %s (line=%d)\n", 
                                (int)eclass, (int)ecode, nt_errstr(nterr), line);
                         return False;
@@ -210,7 +404,7 @@ static BOOL check_error(int line, struct cli_state *c,
 }
 
 
-static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
+static bool wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
 {
        while (!cli_lock(c, fnum, offset, len, -1, WRITE_LOCK)) {
                if (!check_error(__LINE__, c, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
@@ -219,7 +413,7 @@ static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len)
 }
 
 
-static BOOL rw_torture(struct cli_state *c)
+static bool rw_torture(struct cli_state *c)
 {
        const char *lockfname = "\\torture.lck";
        fstring fname;
@@ -228,7 +422,9 @@ static BOOL rw_torture(struct cli_state *c)
        pid_t pid2, pid = getpid();
        int i, j;
        char buf[1024];
-       BOOL correct = True;
+       bool correct = True;
+
+       memset(buf, '\0', sizeof(buf));
 
        fnum2 = cli_open(c, lockfname, O_RDWR | O_CREAT | O_EXCL, 
                         DENY_NONE);
@@ -308,34 +504,34 @@ static BOOL rw_torture(struct cli_state *c)
        return correct;
 }
 
-static BOOL run_torture(int dummy)
+static bool run_torture(int dummy)
 {
-       struct cli_state cli;
-        BOOL ret;
+       struct cli_state *cli;
+        bool ret;
 
        cli = current_cli;
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
-       ret = rw_torture(&cli);
+       ret = rw_torture(cli);
        
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                ret = False;
        }
 
        return ret;
 }
 
-static BOOL rw_torture3(struct cli_state *c, char *lockfname)
+static bool rw_torture3(struct cli_state *c, char *lockfname)
 {
        int fnum = -1;
-       int i = 0;
+       unsigned int i = 0;
        char buf[131072];
        char buf_rd[131072];
        unsigned count;
        unsigned countprev = 0;
        ssize_t sent = 0;
-       BOOL correct = True;
+       bool correct = True;
 
        srandom(1);
        for (i = 0; i < sizeof(buf); i += sizeof(uint32))
@@ -359,7 +555,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
                {
                        fnum = cli_open(c, lockfname, O_RDONLY, 
                                         DENY_NONE);
-                       msleep(10);
+                       smb_msleep(10);
                }
                if (fnum == -1) {
                        printf("second open read-only of %s failed (%s)\n",
@@ -397,9 +593,9 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
                                                  sizeof(buf)-count);
                        if (sent < 0)
                        {
-                               printf("read failed offset:%d size:%d (%s)\n",
-                                               count, sizeof(buf)-count,
-                                               cli_errstr(c));
+                               printf("read failed offset:%d size:%ld (%s)\n",
+                                      count, (unsigned long)sizeof(buf)-count,
+                                      cli_errstr(c));
                                correct = False;
                                sent = 0;
                        }
@@ -408,8 +604,7 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
                                if (memcmp(buf_rd+count, buf+count, sent) != 0)
                                {
                                        printf("read/write compare failed\n");
-                                       printf("offset: %d req %d recvd %d\n",
-                                               count, sizeof(buf)-count, sent);
+                                       printf("offset: %d req %ld recvd %ld\n", count, (unsigned long)sizeof(buf)-count, (unsigned long)sent);
                                        correct = False;
                                        break;
                                }
@@ -426,15 +621,15 @@ static BOOL rw_torture3(struct cli_state *c, char *lockfname)
        return correct;
 }
 
-static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
+static bool rw_torture2(struct cli_state *c1, struct cli_state *c2)
 {
        const char *lockfname = "\\torture2.lck";
        int fnum1;
        int fnum2;
        int i;
-       uchar buf[131072];
-       uchar buf_rd[131072];
-       BOOL correct = True;
+       char buf[131072];
+       char buf_rd[131072];
+       bool correct = True;
        ssize_t bytes_read;
 
        if (!cli_unlink(c1, lockfname)) {
@@ -464,23 +659,27 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
                        printf("%d\r", i); fflush(stdout);
                }
 
-               generate_random_buffer(buf, buf_size, False);
+               generate_random_buffer((unsigned char *)buf, buf_size);
 
                if (cli_write(c1, fnum1, 0, buf, 0, buf_size) != buf_size) {
                        printf("write failed (%s)\n", cli_errstr(c1));
                        correct = False;
+                       break;
                }
 
                if ((bytes_read = cli_read(c2, fnum2, buf_rd, 0, buf_size)) != buf_size) {
                        printf("read failed (%s)\n", cli_errstr(c2));
-                       printf("read %d, expected %d\n", bytes_read, buf_size); 
+                       printf("read %d, expected %ld\n", (int)bytes_read, 
+                              (unsigned long)buf_size); 
                        correct = False;
+                       break;
                }
 
                if (memcmp(buf_rd, buf, buf_size) != 0)
                {
                        printf("read/write compare failed\n");
                        correct = False;
+                       break;
                }
        }
 
@@ -501,152 +700,158 @@ static BOOL rw_torture2(struct cli_state *c1, struct cli_state *c2)
        return correct;
 }
 
-static BOOL run_readwritetest(int dummy)
+static bool run_readwritetest(int dummy)
 {
-       static struct cli_state cli1, cli2;
-       BOOL test1, test2;
+       static struct cli_state *cli1, *cli2;
+       bool test1, test2 = False;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
-       cli_sockopt(&cli1, sockops);
-       cli_sockopt(&cli2, sockops);
+       cli_sockopt(cli1, sockops);
+       cli_sockopt(cli2, sockops);
 
        printf("starting readwritetest\n");
 
-       test1 = rw_torture2(&cli1, &cli2);
+       test1 = rw_torture2(cli1, cli2);
        printf("Passed readwritetest v1: %s\n", BOOLSTR(test1));
 
-       test2 = rw_torture2(&cli1, &cli1);
-       printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
+       if (test1) {
+               test2 = rw_torture2(cli1, cli1);
+               printf("Passed readwritetest v2: %s\n", BOOLSTR(test2));
+       }
 
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                test1 = False;
        }
 
-       if (!torture_close_connection(&cli2)) {
+       if (!torture_close_connection(cli2)) {
                test2 = False;
        }
 
        return (test1 && test2);
 }
 
-static BOOL run_readwritemulti(int dummy)
+static bool run_readwritemulti(int dummy)
 {
-       static struct cli_state cli;
-       BOOL test;
+       struct cli_state *cli;
+       bool test;
 
        cli = current_cli;
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
        printf("run_readwritemulti: fname %s\n", randomfname);
-       test = rw_torture3(&cli, randomfname);
+       test = rw_torture3(cli, randomfname);
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                test = False;
        }
        
        return test;
 }
 
-static BOOL run_readwritelarge(int dummy)
+static bool run_readwritelarge(int dummy)
 {
-       static struct cli_state cli1;
+       static struct cli_state *cli1;
        int fnum1;
        const char *lockfname = "\\large.dat";
-       size_t fsize;
+       SMB_OFF_T fsize;
        char buf[126*1024];
-       BOOL correct = True;
+       bool correct = True;
  
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli1, sockops);
        memset(buf,'\0',sizeof(buf));
        
-       cli1.max_xmit = 128*1024;
+       cli1->max_xmit = 128*1024;
        
        printf("starting readwritelarge\n");
  
-       cli_unlink(&cli1, lockfname);
+       cli_unlink(cli1, lockfname);
 
-       fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
+               printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
                return False;
        }
    
-       cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf));
+       cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf));
 
-       if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
-               printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
+               printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
        if (fsize == sizeof(buf))
-               printf("readwritelarge test 1 succeeded (size = %x)\n", fsize);
+               printf("readwritelarge test 1 succeeded (size = %lx)\n", 
+                      (unsigned long)fsize);
        else {
-               printf("readwritelarge test 1 failed (size = %x)\n", fsize);
+               printf("readwritelarge test 1 failed (size = %lx)\n", 
+                      (unsigned long)fsize);
                correct = False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
-       if (!cli_unlink(&cli1, lockfname)) {
-               printf("unlink failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_unlink(cli1, lockfname)) {
+               printf("unlink failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
-       fnum1 = cli_open(&cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, lockfname, O_RDWR | O_CREAT | O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(&cli1));
+               printf("open read/write of %s failed (%s)\n", lockfname, cli_errstr(cli1));
                return False;
        }
        
-       cli1.max_xmit = 4*1024;
+       cli1->max_xmit = 4*1024;
        
-       cli_smbwrite(&cli1, fnum1, buf, 0, sizeof(buf));
+       cli_smbwrite(cli1, fnum1, buf, 0, sizeof(buf));
        
-       if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
-               printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
+               printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
        if (fsize == sizeof(buf))
-               printf("readwritelarge test 2 succeeded (size = %x)\n", fsize);
+               printf("readwritelarge test 2 succeeded (size = %lx)\n", 
+                      (unsigned long)fsize);
        else {
-               printf("readwritelarge test 2 failed (size = %x)\n", fsize);
+               printf("readwritelarge test 2 failed (size = %lx)\n", 
+                      (unsigned long)fsize);
                correct = False;
        }
 
 #if 0
        /* ToDo - set allocation. JRA */
-       if(!cli_set_allocation_size(&cli1, fnum1, 0)) {
+       if(!cli_set_allocation_size(cli1, fnum1, 0)) {
                printf("set allocation size to zero failed (%s)\n", cli_errstr(&cli1));
                return False;
        }
-       if (!cli_qfileinfo(&cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
-               printf("qfileinfo failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_qfileinfo(cli1, fnum1, NULL, &fsize, NULL, NULL, NULL, NULL, NULL)) {
+               printf("qfileinfo failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
        if (fsize != 0)
                printf("readwritelarge test 3 (truncate test) succeeded (size = %x)\n", fsize);
 #endif
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
        
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
        return correct;
-       }
+}
 
 int line_count = 0;
 int nbio_id;
@@ -654,26 +859,25 @@ int nbio_id;
 #define ival(s) strtol(s, NULL, 0)
 
 /* run a test that simulates an approximate netbench client load */
-static BOOL run_netbench(int client)
+static bool run_netbench(int client)
 {
-       struct cli_state cli;
+       struct cli_state *cli;
        int i;
-       fstring fname;
-       pstring line;
+       char line[1024];
        char cname[20];
        FILE *f;
-       char *params[20];
-       BOOL correct = True;
+       const char *params[20];
+       bool correct = True;
 
        cli = current_cli;
 
        nbio_id = client;
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
-       nb_setup(&cli);
+       nb_setup(cli);
 
-       slprintf(cname,sizeof(fname), "client%d", client);
+       slprintf(cname,sizeof(cname)-1, "client%d", client);
 
        f = fopen(client_txt, "r");
 
@@ -683,6 +887,7 @@ static BOOL run_netbench(int client)
        }
 
        while (fgets(line, sizeof(line)-1, f)) {
+               char *saveptr;
                line_count++;
 
                line[strlen(line)-1] = 0;
@@ -690,11 +895,11 @@ static BOOL run_netbench(int client)
                /* printf("[%d] %s\n", line_count, line); */
 
                all_string_sub(line,"client1", cname, sizeof(line));
-               
+
                /* parse the command parameters */
-               params[0] = strtok(line," ");
+               params[0] = strtok_r(line, " ", &saveptr);
                i = 0;
-               while (params[i]) params[++i] = strtok(NULL," ");
+               while (params[i]) params[++i] = strtok_r(NULL, " ", &saveptr);
 
                params[i] = "";
 
@@ -743,7 +948,7 @@ static BOOL run_netbench(int client)
 
        nb_cleanup();
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
        
@@ -752,10 +957,10 @@ static BOOL run_netbench(int client)
 
 
 /* run a test that simulates an approximate netbench client load */
-static BOOL run_nbench(int dummy)
+static bool run_nbench(int dummy)
 {
        double t;
-       BOOL correct = True;
+       bool correct = True;
 
        nbio_shmem(nprocs);
 
@@ -779,51 +984,51 @@ static BOOL run_nbench(int dummy)
      must not use posix semantics)
   2) support for lock timeouts
  */
-static BOOL run_locktest1(int dummy)
+static bool run_locktest1(int dummy)
 {
-       static struct cli_state cli1, cli2;
+       struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt1.lck";
        int fnum1, fnum2, fnum3;
        time_t t1, t2;
        unsigned lock_timeout;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
-       cli_sockopt(&cli1, sockops);
-       cli_sockopt(&cli2, sockops);
+       cli_sockopt(cli1, sockops);
+       cli_sockopt(cli2, sockops);
 
        printf("starting locktest1\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
-       fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+       fnum2 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
        if (fnum2 == -1) {
-               printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
-       fnum3 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+       fnum3 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
        if (fnum3 == -1) {
-               printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
-       if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
-               printf("lock1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
+               printf("lock1 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
 
-       if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
+       if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
                printf("lock2 succeeded! This is a locking bug\n");
                return False;
        } else {
-               if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
+               if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
                                 NT_STATUS_LOCK_NOT_GRANTED)) return False;
        }
 
@@ -831,55 +1036,56 @@ static BOOL run_locktest1(int dummy)
        lock_timeout = (1 + (random() % 20));
        printf("Testing lock timeout with timeout=%u\n", lock_timeout);
        t1 = time(NULL);
-       if (cli_lock(&cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
+       if (cli_lock(cli2, fnum3, 0, 4, lock_timeout * 1000, WRITE_LOCK)) {
                printf("lock3 succeeded! This is a locking bug\n");
                return False;
        } else {
-               if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
+               if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
                                 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
        }
        t2 = time(NULL);
 
-       if (t2 - t1 < 5) {
+       if (ABS(t2 - t1) < lock_timeout-1) {
                printf("error: This server appears not to support timed lock requests\n");
        }
+
        printf("server slept for %u seconds for a %u second timeout\n",
               (unsigned int)(t2-t1), lock_timeout);
 
-       if (!cli_close(&cli1, fnum2)) {
-               printf("close1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum2)) {
+               printf("close1 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       if (cli_lock(&cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
+       if (cli_lock(cli2, fnum3, 0, 4, 0, WRITE_LOCK)) {
                printf("lock4 succeeded! This is a locking bug\n");
                return False;
        } else {
-               if (!check_error(__LINE__, &cli2, ERRDOS, ERRlock, 
+               if (!check_error(__LINE__, cli2, ERRDOS, ERRlock, 
                                 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close2 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       if (!cli_close(&cli2, fnum3)) {
-               printf("close3 failed (%s)\n", cli_errstr(&cli2));
+       if (!cli_close(cli2, fnum3)) {
+               printf("close3 failed (%s)\n", cli_errstr(cli2));
                return False;
        }
 
-       if (!cli_unlink(&cli1, fname)) {
-               printf("unlink failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_unlink(cli1, fname)) {
+               printf("unlink failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
 
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                return False;
        }
 
-       if (!torture_close_connection(&cli2)) {
+       if (!torture_close_connection(cli2)) {
                return False;
        }
 
@@ -888,79 +1094,261 @@ static BOOL run_locktest1(int dummy)
 }
 
 /*
- checks for correct tconX support
+  this checks to see if a secondary tconx can use open files from an
+  earlier tconx
  */
-static BOOL run_tcon_test(int dummy)
+static bool run_tcon_test(int dummy)
 {
-       static struct cli_state cli1;
+       static struct cli_state *cli;
        const char *fname = "\\tcontest.tmp";
        int fnum1;
-       uint16 cnum;
+       uint16 cnum1, cnum2, cnum3;
+       uint16 vuid1, vuid2;
        char buf[4];
+       bool ret = True;
+       NTSTATUS status;
+
+       memset(buf, '\0', sizeof(buf));
 
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli, sockops);
 
        printf("starting tcontest\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli, fname);
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
-       if (fnum1 == -1)
-       {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       if (fnum1 == -1) {
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
                return False;
        }
 
-       cnum = cli1.cnum;
+       cnum1 = cli->cnum;
+       vuid1 = cli->vuid;
 
-       if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4)
-       {
-               printf("write failed (%s)", cli_errstr(&cli1));
+       if (cli_write(cli, fnum1, 0, buf, 130, 4) != 4) {
+               printf("initial write failed (%s)", cli_errstr(cli));
                return False;
        }
 
-       if (!cli_send_tconX(&cli1, share, "?????",
-                           password, strlen(password)+1)) {
+       status = cli_tcon_andx(cli, share, "?????",
+                              password, strlen(password)+1);
+       if (!NT_STATUS_IS_OK(status)) {
                printf("%s refused 2nd tree connect (%s)\n", host,
-                          cli_errstr(&cli1));
-               cli_shutdown(&cli1);
+                      nt_errstr(status));
+               cli_shutdown(cli);
                return False;
        }
 
-       if (cli_write(&cli1, fnum1, 0, buf, 130, 4) == 4)
-       {
-               printf("write succeeded (%s)", cli_errstr(&cli1));
+       cnum2 = cli->cnum;
+       cnum3 = MAX(cnum1, cnum2) + 1; /* any invalid number */
+       vuid2 = cli->vuid + 1;
+
+       /* try a write with the wrong tid */
+       cli->cnum = cnum2;
+
+       if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
+               printf("* server allows write with wrong TID\n");
+               ret = False;
+       } else {
+               printf("server fails write with wrong TID : %s\n", cli_errstr(cli));
+       }
+
+
+       /* try a write with an invalid tid */
+       cli->cnum = cnum3;
+
+       if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
+               printf("* server allows write with invalid TID\n");
+               ret = False;
+       } else {
+               printf("server fails write with invalid TID : %s\n", cli_errstr(cli));
+       }
+
+       /* try a write with an invalid vuid */
+       cli->vuid = vuid2;
+       cli->cnum = cnum1;
+
+       if (cli_write(cli, fnum1, 0, buf, 130, 4) == 4) {
+               printf("* server allows write with invalid VUID\n");
+               ret = False;
+       } else {
+               printf("server fails write with invalid VUID : %s\n", cli_errstr(cli));
+       }
+
+       cli->cnum = cnum1;
+       cli->vuid = vuid1;
+
+       if (!cli_close(cli, fnum1)) {
+               printf("close failed (%s)\n", cli_errstr(cli));
                return False;
        }
 
-       if (cli_close(&cli1, fnum1)) {
-               printf("close2 succeeded (%s)\n", cli_errstr(&cli1));
+       cli->cnum = cnum2;
+
+       if (!cli_tdis(cli)) {
+               printf("secondary tdis failed (%s)\n", cli_errstr(cli));
                return False;
        }
 
-       if (!cli_tdis(&cli1)) {
-               printf("tdis failed (%s)\n", cli_errstr(&cli1));
+       cli->cnum = cnum1;
+
+       if (!torture_close_connection(cli)) {
                return False;
        }
 
-       cli1.cnum = cnum;
+       return ret;
+}
+
+
+/*
+ checks for old style tcon support
+ */
+static bool run_tcon2_test(int dummy)
+{
+       static struct cli_state *cli;
+       uint16 cnum, max_xmit;
+       char *service;
+       NTSTATUS status;
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close2 failed (%s)\n", cli_errstr(&cli1));
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
+       cli_sockopt(cli, sockops);
+
+       printf("starting tcon2 test\n");
+
+       if (asprintf(&service, "\\\\%s\\%s", host, share) == -1) {
+               return false;
+       }
+
+       status = cli_raw_tcon(cli, service, password, "?????", &max_xmit, &cnum);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("tcon2 failed : %s\n", cli_errstr(cli));
+       } else {
+               printf("tcon OK : max_xmit=%d cnum=%d tid=%d\n", 
+                      (int)max_xmit, (int)cnum, SVAL(cli->inbuf, smb_tid));
+       }
 
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli)) {
                return False;
        }
 
-       printf("Passed tcontest\n");
+       printf("Passed tcontest\n");
        return True;
 }
 
+static bool tcon_devtest(struct cli_state *cli,
+                        const char *myshare, const char *devtype,
+                        const char *return_devtype,
+                        NTSTATUS expected_error)
+{
+       NTSTATUS status;
+       bool ret;
+
+       status = cli_tcon_andx(cli, myshare, devtype,
+                              password, strlen(password)+1);
+
+       if (NT_STATUS_IS_OK(expected_error)) {
+               if (NT_STATUS_IS_OK(status)) {
+                       if (strcmp(cli->dev, return_devtype) == 0) {
+                               ret = True;
+                       } else { 
+                               printf("tconX to share %s with type %s "
+                                      "succeeded but returned the wrong "
+                                      "device type (got [%s] but should have got [%s])\n",
+                                      myshare, devtype, cli->dev, return_devtype);
+                               ret = False;
+                       }
+               } else {
+                       printf("tconX to share %s with type %s "
+                              "should have succeeded but failed\n",
+                              myshare, devtype);
+                       ret = False;
+               }
+               cli_tdis(cli);
+       } else {
+               if (NT_STATUS_IS_OK(status)) {
+                       printf("tconx to share %s with type %s "
+                              "should have failed but succeeded\n",
+                              myshare, devtype);
+                       ret = False;
+               } else {
+                       if (NT_STATUS_EQUAL(cli_nt_error(cli),
+                                           expected_error)) {
+                               ret = True;
+                       } else {
+                               printf("Returned unexpected error\n");
+                               ret = False;
+                       }
+               }
+       }
+       return ret;
+}
+
+/*
+ checks for correct tconX support
+ */
+static bool run_tcon_devtype_test(int dummy)
+{
+       static struct cli_state *cli1 = NULL;
+       bool retry;
+       int flags = 0;
+       NTSTATUS status;
+       bool ret = True;
+
+       status = cli_full_connection(&cli1, myname,
+                                    host, NULL, port_to_use,
+                                    NULL, NULL,
+                                    username, workgroup,
+                                    password, flags, Undefined, &retry);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("could not open connection\n");
+               return False;
+       }
+
+       if (!tcon_devtest(cli1, "IPC$", "A:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
+               ret = False;
+
+       if (!tcon_devtest(cli1, "IPC$", "?????", "IPC", NT_STATUS_OK))
+               ret = False;
+
+       if (!tcon_devtest(cli1, "IPC$", "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
+               ret = False;
+
+       if (!tcon_devtest(cli1, "IPC$", "IPC", "IPC", NT_STATUS_OK))
+               ret = False;
+                       
+       if (!tcon_devtest(cli1, "IPC$", "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
+               ret = False;
+
+       if (!tcon_devtest(cli1, share, "A:", "A:", NT_STATUS_OK))
+               ret = False;
+
+       if (!tcon_devtest(cli1, share, "?????", "A:", NT_STATUS_OK))
+               ret = False;
+
+       if (!tcon_devtest(cli1, share, "LPT:", NULL, NT_STATUS_BAD_DEVICE_TYPE))
+               ret = False;
+
+       if (!tcon_devtest(cli1, share, "IPC", NULL, NT_STATUS_BAD_DEVICE_TYPE))
+               ret = False;
+                       
+       if (!tcon_devtest(cli1, share, "FOOBA", NULL, NT_STATUS_BAD_DEVICE_TYPE))
+               ret = False;
+
+       cli_shutdown(cli1);
+
+       if (ret)
+               printf("Passed tcondevtest\n");
+
+       return ret;
+}
+
 
 /*
   This test checks that 
@@ -973,128 +1361,128 @@ static BOOL run_tcon_test(int dummy)
 
   3) the server denies unlock requests by an incorrect client PID
 */
-static BOOL run_locktest2(int dummy)
+static bool run_locktest2(int dummy)
 {
-       static struct cli_state cli;
+       static struct cli_state *cli;
        const char *fname = "\\lockt2.lck";
        int fnum1, fnum2, fnum3;
-       BOOL correct = True;
+       bool correct = True;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
        printf("starting locktest2\n");
 
-       cli_unlink(&cli, fname);
+       cli_unlink(cli, fname);
 
-       cli_setpid(&cli, 1);
+       cli_setpid(cli, 1);
 
-       fnum1 = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
                return False;
        }
 
-       fnum2 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
+       fnum2 = cli_open(cli, fname, O_RDWR, DENY_NONE);
        if (fnum2 == -1) {
-               printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli));
+               printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli));
                return False;
        }
 
-       cli_setpid(&cli, 2);
+       cli_setpid(cli, 2);
 
-       fnum3 = cli_open(&cli, fname, O_RDWR, DENY_NONE);
+       fnum3 = cli_open(cli, fname, O_RDWR, DENY_NONE);
        if (fnum3 == -1) {
-               printf("open3 of %s failed (%s)\n", fname, cli_errstr(&cli));
+               printf("open3 of %s failed (%s)\n", fname, cli_errstr(cli));
                return False;
        }
 
-       cli_setpid(&cli, 1);
+       cli_setpid(cli, 1);
 
-       if (!cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
-               printf("lock1 failed (%s)\n", cli_errstr(&cli));
+       if (!cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
+               printf("lock1 failed (%s)\n", cli_errstr(cli));
                return False;
        }
 
-       if (cli_lock(&cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
+       if (cli_lock(cli, fnum1, 0, 4, 0, WRITE_LOCK)) {
                printf("WRITE lock1 succeeded! This is a locking bug\n");
                correct = False;
        } else {
-               if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
+               if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
                                 NT_STATUS_LOCK_NOT_GRANTED)) return False;
        }
 
-       if (cli_lock(&cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
+       if (cli_lock(cli, fnum2, 0, 4, 0, WRITE_LOCK)) {
                printf("WRITE lock2 succeeded! This is a locking bug\n");
                correct = False;
        } else {
-               if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
+               if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
                                 NT_STATUS_LOCK_NOT_GRANTED)) return False;
        }
 
-       if (cli_lock(&cli, fnum2, 0, 4, 0, READ_LOCK)) {
+       if (cli_lock(cli, fnum2, 0, 4, 0, READ_LOCK)) {
                printf("READ lock2 succeeded! This is a locking bug\n");
                correct = False;
        } else {
-               if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, 
+               if (!check_error(__LINE__, cli, ERRDOS, ERRlock, 
                                 NT_STATUS_FILE_LOCK_CONFLICT)) return False;
        }
 
-       if (!cli_lock(&cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
-               printf("lock at 100 failed (%s)\n", cli_errstr(&cli));
+       if (!cli_lock(cli, fnum1, 100, 4, 0, WRITE_LOCK)) {
+               printf("lock at 100 failed (%s)\n", cli_errstr(cli));
        }
-       cli_setpid(&cli, 2);
-       if (cli_unlock(&cli, fnum1, 100, 4)) {
+       cli_setpid(cli, 2);
+       if (cli_unlock(cli, fnum1, 100, 4)) {
                printf("unlock at 100 succeeded! This is a locking bug\n");
                correct = False;
        }
 
-       if (cli_unlock(&cli, fnum1, 0, 4)) {
+       if (cli_unlock(cli, fnum1, 0, 4)) {
                printf("unlock1 succeeded! This is a locking bug\n");
                correct = False;
        } else {
-               if (!check_error(__LINE__, &cli, 
+               if (!check_error(__LINE__, cli, 
                                 ERRDOS, ERRlock, 
                                 NT_STATUS_RANGE_NOT_LOCKED)) return False;
        }
 
-       if (cli_unlock(&cli, fnum1, 0, 8)) {
+       if (cli_unlock(cli, fnum1, 0, 8)) {
                printf("unlock2 succeeded! This is a locking bug\n");
                correct = False;
        } else {
-               if (!check_error(__LINE__, &cli, 
+               if (!check_error(__LINE__, cli, 
                                 ERRDOS, ERRlock, 
                                 NT_STATUS_RANGE_NOT_LOCKED)) return False;
        }
 
-       if (cli_lock(&cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
+       if (cli_lock(cli, fnum3, 0, 4, 0, WRITE_LOCK)) {
                printf("lock3 succeeded! This is a locking bug\n");
                correct = False;
        } else {
-               if (!check_error(__LINE__, &cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
+               if (!check_error(__LINE__, cli, ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED)) return False;
        }
 
-       cli_setpid(&cli, 1);
+       cli_setpid(cli, 1);
 
-       if (!cli_close(&cli, fnum1)) {
-               printf("close1 failed (%s)\n", cli_errstr(&cli));
+       if (!cli_close(cli, fnum1)) {
+               printf("close1 failed (%s)\n", cli_errstr(cli));
                return False;
        }
 
-       if (!cli_close(&cli, fnum2)) {
-               printf("close2 failed (%s)\n", cli_errstr(&cli));
+       if (!cli_close(cli, fnum2)) {
+               printf("close2 failed (%s)\n", cli_errstr(cli));
                return False;
        }
 
-       if (!cli_close(&cli, fnum3)) {
-               printf("close3 failed (%s)\n", cli_errstr(&cli));
+       if (!cli_close(cli, fnum3)) {
+               printf("close3 failed (%s)\n", cli_errstr(cli));
                return False;
        }
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -1109,50 +1497,50 @@ static BOOL run_locktest2(int dummy)
 
   1) the server supports the full offset range in lock requests
 */
-static BOOL run_locktest3(int dummy)
+static bool run_locktest3(int dummy)
 {
-       static struct cli_state cli1, cli2;
+       static struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt3.lck";
        int fnum1, fnum2, i;
        uint32 offset;
-       BOOL correct = True;
+       bool correct = True;
 
 #define NEXT_OFFSET offset += (~(uint32)0) / torture_numops
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
-       cli_sockopt(&cli1, sockops);
-       cli_sockopt(&cli2, sockops);
+       cli_sockopt(cli1, sockops);
+       cli_sockopt(cli2, sockops);
 
        printf("starting locktest3\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
-       fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+       fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
        if (fnum2 == -1) {
-               printf("open2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("open2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
        for (offset=i=0;i<torture_numops;i++) {
                NEXT_OFFSET;
-               if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
+               if (!cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
                        printf("lock1 %d failed (%s)\n", 
                               i,
-                              cli_errstr(&cli1));
+                              cli_errstr(cli1));
                        return False;
                }
 
-               if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
+               if (!cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
                        printf("lock2 %d failed (%s)\n", 
                               i,
-                              cli_errstr(&cli1));
+                              cli_errstr(cli1));
                        return False;
                }
        }
@@ -1160,22 +1548,22 @@ static BOOL run_locktest3(int dummy)
        for (offset=i=0;i<torture_numops;i++) {
                NEXT_OFFSET;
 
-               if (cli_lock(&cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
+               if (cli_lock(cli1, fnum1, offset-2, 1, 0, WRITE_LOCK)) {
                        printf("error: lock1 %d succeeded!\n", i);
                        return False;
                }
 
-               if (cli_lock(&cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
+               if (cli_lock(cli2, fnum2, offset-1, 1, 0, WRITE_LOCK)) {
                        printf("error: lock2 %d succeeded!\n", i);
                        return False;
                }
 
-               if (cli_lock(&cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
+               if (cli_lock(cli1, fnum1, offset-1, 1, 0, WRITE_LOCK)) {
                        printf("error: lock3 %d succeeded!\n", i);
                        return False;
                }
 
-               if (cli_lock(&cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
+               if (cli_lock(cli2, fnum2, offset-2, 1, 0, WRITE_LOCK)) {
                        printf("error: lock4 %d succeeded!\n", i);
                        return False;
                }
@@ -1184,41 +1572,41 @@ static BOOL run_locktest3(int dummy)
        for (offset=i=0;i<torture_numops;i++) {
                NEXT_OFFSET;
 
-               if (!cli_unlock(&cli1, fnum1, offset-1, 1)) {
+               if (!cli_unlock(cli1, fnum1, offset-1, 1)) {
                        printf("unlock1 %d failed (%s)\n", 
                               i,
-                              cli_errstr(&cli1));
+                              cli_errstr(cli1));
                        return False;
                }
 
-               if (!cli_unlock(&cli2, fnum2, offset-2, 1)) {
+               if (!cli_unlock(cli2, fnum2, offset-2, 1)) {
                        printf("unlock2 %d failed (%s)\n", 
                               i,
-                              cli_errstr(&cli1));
+                              cli_errstr(cli1));
                        return False;
                }
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close1 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       if (!cli_close(&cli2, fnum2)) {
-               printf("close2 failed (%s)\n", cli_errstr(&cli2));
+       if (!cli_close(cli2, fnum2)) {
+               printf("close2 failed (%s)\n", cli_errstr(cli2));
                return False;
        }
 
-       if (!cli_unlink(&cli1, fname)) {
-               printf("unlink failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_unlink(cli1, fname)) {
+               printf("unlink failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
        
-       if (!torture_close_connection(&cli2)) {
+       if (!torture_close_connection(cli2)) {
                correct = False;
        }
 
@@ -1234,169 +1622,169 @@ static BOOL run_locktest3(int dummy)
 /*
   looks at overlapping locks
 */
-static BOOL run_locktest4(int dummy)
+static bool run_locktest4(int dummy)
 {
-       static struct cli_state cli1, cli2;
+       static struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt4.lck";
        int fnum1, fnum2, f;
-       BOOL ret;
+       bool ret;
        char buf[1000];
-       BOOL correct = True;
+       bool correct = True;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
 
-       cli_sockopt(&cli1, sockops);
-       cli_sockopt(&cli2, sockops);
+       cli_sockopt(cli1, sockops);
+       cli_sockopt(cli2, sockops);
 
        printf("starting locktest4\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
-       fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
 
        memset(buf, 0, sizeof(buf));
 
-       if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
+       if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
                printf("Failed to create file\n");
                correct = False;
                goto fail;
        }
 
-       ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
-             cli_lock(&cli1, fnum1, 2, 4, 0, WRITE_LOCK);
+       ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
+             cli_lock(cli1, fnum1, 2, 4, 0, WRITE_LOCK);
        EXPECTED(ret, False);
        printf("the same process %s set overlapping write locks\n", ret?"can":"cannot");
            
-       ret = cli_lock(&cli1, fnum1, 10, 4, 0, READ_LOCK) &&
-             cli_lock(&cli1, fnum1, 12, 4, 0, READ_LOCK);
+       ret = cli_lock(cli1, fnum1, 10, 4, 0, READ_LOCK) &&
+             cli_lock(cli1, fnum1, 12, 4, 0, READ_LOCK);
        EXPECTED(ret, True);
        printf("the same process %s set overlapping read locks\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
-             cli_lock(&cli2, fnum2, 22, 4, 0, WRITE_LOCK);
+       ret = cli_lock(cli1, fnum1, 20, 4, 0, WRITE_LOCK) &&
+             cli_lock(cli2, fnum2, 22, 4, 0, WRITE_LOCK);
        EXPECTED(ret, False);
        printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot");
            
-       ret = cli_lock(&cli1, fnum1, 30, 4, 0, READ_LOCK) &&
-             cli_lock(&cli2, fnum2, 32, 4, 0, READ_LOCK);
+       ret = cli_lock(cli1, fnum1, 30, 4, 0, READ_LOCK) &&
+             cli_lock(cli2, fnum2, 32, 4, 0, READ_LOCK);
        EXPECTED(ret, True);
        printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot");
        
-       ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
-             (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 42, 4, 0, WRITE_LOCK));
+       ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 40, 4, 0, WRITE_LOCK)) &&
+             (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 42, 4, 0, WRITE_LOCK));
        EXPECTED(ret, False);
        printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot");
            
-       ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
-             (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 52, 4, 0, READ_LOCK));
+       ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 50, 4, 0, READ_LOCK)) &&
+             (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 52, 4, 0, READ_LOCK));
        EXPECTED(ret, True);
        printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK) &&
-             cli_lock(&cli1, fnum1, 60, 4, 0, READ_LOCK);
+       ret = cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK) &&
+             cli_lock(cli1, fnum1, 60, 4, 0, READ_LOCK);
        EXPECTED(ret, True);
        printf("the same process %s set the same read lock twice\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
-             cli_lock(&cli1, fnum1, 70, 4, 0, WRITE_LOCK);
+       ret = cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK) &&
+             cli_lock(cli1, fnum1, 70, 4, 0, WRITE_LOCK);
        EXPECTED(ret, False);
        printf("the same process %s set the same write lock twice\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli1, fnum1, 80, 4, 0, READ_LOCK) &&
-             cli_lock(&cli1, fnum1, 80, 4, 0, WRITE_LOCK);
+       ret = cli_lock(cli1, fnum1, 80, 4, 0, READ_LOCK) &&
+             cli_lock(cli1, fnum1, 80, 4, 0, WRITE_LOCK);
        EXPECTED(ret, False);
        printf("the same process %s overlay a read lock with a write lock\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
-             cli_lock(&cli1, fnum1, 90, 4, 0, READ_LOCK);
+       ret = cli_lock(cli1, fnum1, 90, 4, 0, WRITE_LOCK) &&
+             cli_lock(cli1, fnum1, 90, 4, 0, READ_LOCK);
        EXPECTED(ret, True);
        printf("the same process %s overlay a write lock with a read lock\n", ret?"can":"cannot");
 
-       ret = (cli_setpid(&cli1, 1), cli_lock(&cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
-             (cli_setpid(&cli1, 2), cli_lock(&cli1, fnum1, 100, 4, 0, READ_LOCK));
+       ret = (cli_setpid(cli1, 1), cli_lock(cli1, fnum1, 100, 4, 0, WRITE_LOCK)) &&
+             (cli_setpid(cli1, 2), cli_lock(cli1, fnum1, 100, 4, 0, READ_LOCK));
        EXPECTED(ret, False);
        printf("a different pid %s overlay a write lock with a read lock\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli1, fnum1, 110, 4, 0, READ_LOCK) &&
-             cli_lock(&cli1, fnum1, 112, 4, 0, READ_LOCK) &&
-             cli_unlock(&cli1, fnum1, 110, 6);
+       ret = cli_lock(cli1, fnum1, 110, 4, 0, READ_LOCK) &&
+             cli_lock(cli1, fnum1, 112, 4, 0, READ_LOCK) &&
+             cli_unlock(cli1, fnum1, 110, 6);
        EXPECTED(ret, False);
        printf("the same process %s coalesce read locks\n", ret?"can":"cannot");
 
 
-       ret = cli_lock(&cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
-             (cli_read(&cli2, fnum2, buf, 120, 4) == 4);
+       ret = cli_lock(cli1, fnum1, 120, 4, 0, WRITE_LOCK) &&
+             (cli_read(cli2, fnum2, buf, 120, 4) == 4);
        EXPECTED(ret, False);
        printf("this server %s strict write locking\n", ret?"doesn't do":"does");
 
-       ret = cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK) &&
-             (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4);
+       ret = cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK) &&
+             (cli_write(cli2, fnum2, 0, buf, 130, 4) == 4);
        EXPECTED(ret, False);
        printf("this server %s strict read locking\n", ret?"doesn't do":"does");
 
 
-       ret = cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
-             cli_lock(&cli1, fnum1, 140, 4, 0, READ_LOCK) &&
-             cli_unlock(&cli1, fnum1, 140, 4) &&
-             cli_unlock(&cli1, fnum1, 140, 4);
+       ret = cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
+             cli_lock(cli1, fnum1, 140, 4, 0, READ_LOCK) &&
+             cli_unlock(cli1, fnum1, 140, 4) &&
+             cli_unlock(cli1, fnum1, 140, 4);
        EXPECTED(ret, True);
        printf("this server %s do recursive read locking\n", ret?"does":"doesn't");
 
 
-       ret = cli_lock(&cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
-             cli_lock(&cli1, fnum1, 150, 4, 0, READ_LOCK) &&
-             cli_unlock(&cli1, fnum1, 150, 4) &&
-             (cli_read(&cli2, fnum2, buf, 150, 4) == 4) &&
-             !(cli_write(&cli2, fnum2, 0, buf, 150, 4) == 4) &&
-             cli_unlock(&cli1, fnum1, 150, 4);
+       ret = cli_lock(cli1, fnum1, 150, 4, 0, WRITE_LOCK) &&
+             cli_lock(cli1, fnum1, 150, 4, 0, READ_LOCK) &&
+             cli_unlock(cli1, fnum1, 150, 4) &&
+             (cli_read(cli2, fnum2, buf, 150, 4) == 4) &&
+             !(cli_write(cli2, fnum2, 0, buf, 150, 4) == 4) &&
+             cli_unlock(cli1, fnum1, 150, 4);
        EXPECTED(ret, True);
        printf("this server %s do recursive lock overlays\n", ret?"does":"doesn't");
 
-       ret = cli_lock(&cli1, fnum1, 160, 4, 0, READ_LOCK) &&
-             cli_unlock(&cli1, fnum1, 160, 4) &&
-             (cli_write(&cli2, fnum2, 0, buf, 160, 4) == 4) &&         
-             (cli_read(&cli2, fnum2, buf, 160, 4) == 4);               
+       ret = cli_lock(cli1, fnum1, 160, 4, 0, READ_LOCK) &&
+             cli_unlock(cli1, fnum1, 160, 4) &&
+             (cli_write(cli2, fnum2, 0, buf, 160, 4) == 4) &&          
+             (cli_read(cli2, fnum2, buf, 160, 4) == 4);                
        EXPECTED(ret, True);
        printf("the same process %s remove a read lock using write locking\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
-             cli_unlock(&cli1, fnum1, 170, 4) &&
-             (cli_write(&cli2, fnum2, 0, buf, 170, 4) == 4) &&         
-             (cli_read(&cli2, fnum2, buf, 170, 4) == 4);               
+       ret = cli_lock(cli1, fnum1, 170, 4, 0, WRITE_LOCK) &&
+             cli_unlock(cli1, fnum1, 170, 4) &&
+             (cli_write(cli2, fnum2, 0, buf, 170, 4) == 4) &&          
+             (cli_read(cli2, fnum2, buf, 170, 4) == 4);                
        EXPECTED(ret, True);
        printf("the same process %s remove a write lock using read locking\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
-             cli_lock(&cli1, fnum1, 190, 4, 0, READ_LOCK) &&
-             cli_unlock(&cli1, fnum1, 190, 4) &&
-             !(cli_write(&cli2, fnum2, 0, buf, 190, 4) == 4) &&                
-             (cli_read(&cli2, fnum2, buf, 190, 4) == 4);               
+       ret = cli_lock(cli1, fnum1, 190, 4, 0, WRITE_LOCK) &&
+             cli_lock(cli1, fnum1, 190, 4, 0, READ_LOCK) &&
+             cli_unlock(cli1, fnum1, 190, 4) &&
+             !(cli_write(cli2, fnum2, 0, buf, 190, 4) == 4) &&         
+             (cli_read(cli2, fnum2, buf, 190, 4) == 4);                
        EXPECTED(ret, True);
        printf("the same process %s remove the first lock first\n", ret?"does":"doesn't");
 
-       cli_close(&cli1, fnum1);
-       cli_close(&cli2, fnum2);
-       fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
-       f = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
-       ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
-             cli_lock(&cli1, f, 0, 1, 0, READ_LOCK) &&
-             cli_close(&cli1, fnum1) &&
-             ((fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
-             cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
-        cli_close(&cli1, f);
-       cli_close(&cli1, fnum1);
+       cli_close(cli1, fnum1);
+       cli_close(cli2, fnum2);
+       fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
+       f = cli_open(cli1, fname, O_RDWR, DENY_NONE);
+       ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
+             cli_lock(cli1, f, 0, 1, 0, READ_LOCK) &&
+             cli_close(cli1, fnum1) &&
+             ((fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE)) != -1) &&
+             cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
+        cli_close(cli1, f);
+       cli_close(cli1, fnum1);
        EXPECTED(ret, True);
        printf("the server %s have the NT byte range lock bug\n", !ret?"does":"doesn't");
 
  fail:
-       cli_close(&cli1, fnum1);
-       cli_close(&cli2, fnum2);
-       cli_unlink(&cli1, fname);
-       torture_close_connection(&cli1);
-       torture_close_connection(&cli2);
+       cli_close(cli1, fnum1);
+       cli_close(cli2, fnum2);
+       cli_unlink(cli1, fname);
+       torture_close_connection(cli1);
+       torture_close_connection(cli2);
 
        printf("finished locktest4\n");
        return correct;
@@ -1405,74 +1793,74 @@ static BOOL run_locktest4(int dummy)
 /*
   looks at lock upgrade/downgrade.
 */
-static BOOL run_locktest5(int dummy)
+static bool run_locktest5(int dummy)
 {
-       static struct cli_state cli1, cli2;
+       static struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt5.lck";
        int fnum1, fnum2, fnum3;
-       BOOL ret;
+       bool ret;
        char buf[1000];
-       BOOL correct = True;
+       bool correct = True;
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
 
-       cli_sockopt(&cli1, sockops);
-       cli_sockopt(&cli2, sockops);
+       cli_sockopt(cli1, sockops);
+       cli_sockopt(cli2, sockops);
 
        printf("starting locktest5\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
-       fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
-       fnum3 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
+       fnum3 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
 
        memset(buf, 0, sizeof(buf));
 
-       if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
+       if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
                printf("Failed to create file\n");
                correct = False;
                goto fail;
        }
 
        /* Check for NT bug... */
-       ret = cli_lock(&cli1, fnum1, 0, 8, 0, READ_LOCK) &&
-                 cli_lock(&cli1, fnum3, 0, 1, 0, READ_LOCK);
-       cli_close(&cli1, fnum1);
-       fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
-       ret = cli_lock(&cli1, fnum1, 7, 1, 0, WRITE_LOCK);
+       ret = cli_lock(cli1, fnum1, 0, 8, 0, READ_LOCK) &&
+                 cli_lock(cli1, fnum3, 0, 1, 0, READ_LOCK);
+       cli_close(cli1, fnum1);
+       fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
+       ret = cli_lock(cli1, fnum1, 7, 1, 0, WRITE_LOCK);
        EXPECTED(ret, True);
        printf("this server %s the NT locking bug\n", ret ? "doesn't have" : "has");
-       cli_close(&cli1, fnum1);
-       fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
-       cli_unlock(&cli1, fnum3, 0, 1);
+       cli_close(cli1, fnum1);
+       fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
+       cli_unlock(cli1, fnum3, 0, 1);
 
-       ret = cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
-             cli_lock(&cli1, fnum1, 1, 1, 0, READ_LOCK);
+       ret = cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK) &&
+             cli_lock(cli1, fnum1, 1, 1, 0, READ_LOCK);
        EXPECTED(ret, True);
        printf("the same process %s overlay a write with a read lock\n", ret?"can":"cannot");
 
-       ret = cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
+       ret = cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
        EXPECTED(ret, False);
 
        printf("a different processs %s get a read lock on the first process lock stack\n", ret?"can":"cannot");
 
        /* Unlock the process 2 lock. */
-       cli_unlock(&cli2, fnum2, 0, 4);
+       cli_unlock(cli2, fnum2, 0, 4);
 
-       ret = cli_lock(&cli1, fnum3, 0, 4, 0, READ_LOCK);
+       ret = cli_lock(cli1, fnum3, 0, 4, 0, READ_LOCK);
        EXPECTED(ret, False);
 
        printf("the same processs on a different fnum %s get a read lock\n", ret?"can":"cannot");
 
        /* Unlock the process 1 fnum3 lock. */
-       cli_unlock(&cli1, fnum3, 0, 4);
+       cli_unlock(cli1, fnum3, 0, 4);
 
        /* Stack 2 more locks here. */
-       ret = cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK) &&
-                 cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK);
+       ret = cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK) &&
+                 cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK);
 
        EXPECTED(ret, True);
        printf("the same process %s stack read locks\n", ret?"can":"cannot");
@@ -1480,44 +1868,44 @@ static BOOL run_locktest5(int dummy)
        /* Unlock the first process lock, then check this was the WRITE lock that was
                removed. */
 
-       ret = cli_unlock(&cli1, fnum1, 0, 4) &&
-                       cli_lock(&cli2, fnum2, 0, 4, 0, READ_LOCK);
+       ret = cli_unlock(cli1, fnum1, 0, 4) &&
+                       cli_lock(cli2, fnum2, 0, 4, 0, READ_LOCK);
 
        EXPECTED(ret, True);
        printf("the first unlock removes the %s lock\n", ret?"WRITE":"READ");
 
        /* Unlock the process 2 lock. */
-       cli_unlock(&cli2, fnum2, 0, 4);
+       cli_unlock(cli2, fnum2, 0, 4);
 
        /* We should have 3 stacked locks here. Ensure we need to do 3 unlocks. */
 
-       ret = cli_unlock(&cli1, fnum1, 1, 1) &&
-                 cli_unlock(&cli1, fnum1, 0, 4) &&
-                 cli_unlock(&cli1, fnum1, 0, 4);
+       ret = cli_unlock(cli1, fnum1, 1, 1) &&
+                 cli_unlock(cli1, fnum1, 0, 4) &&
+                 cli_unlock(cli1, fnum1, 0, 4);
 
        EXPECTED(ret, True);
        printf("the same process %s unlock the stack of 4 locks\n", ret?"can":"cannot"); 
 
        /* Ensure the next unlock fails. */
-       ret = cli_unlock(&cli1, fnum1, 0, 4);
+       ret = cli_unlock(cli1, fnum1, 0, 4);
        EXPECTED(ret, False);
        printf("the same process %s count the lock stack\n", !ret?"can":"cannot"); 
 
        /* Ensure connection 2 can get a write lock. */
-       ret = cli_lock(&cli2, fnum2, 0, 4, 0, WRITE_LOCK);
+       ret = cli_lock(cli2, fnum2, 0, 4, 0, WRITE_LOCK);
        EXPECTED(ret, True);
 
        printf("a different processs %s get a write lock on the unlocked stack\n", ret?"can":"cannot");
 
 
  fail:
-       cli_close(&cli1, fnum1);
-       cli_close(&cli2, fnum2);
-       cli_unlink(&cli1, fname);
-       if (!torture_close_connection(&cli1)) {
+       cli_close(cli1, fnum1);
+       cli_close(cli2, fnum2);
+       cli_unlink(cli1, fname);
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
-       if (!torture_close_connection(&cli2)) {
+       if (!torture_close_connection(cli2)) {
                correct = False;
        }
 
@@ -1529,92 +1917,92 @@ static BOOL run_locktest5(int dummy)
 /*
   tries the unusual lockingX locktype bits
 */
-static BOOL run_locktest6(int dummy)
+static bool run_locktest6(int dummy)
 {
-       static struct cli_state cli;
+       static struct cli_state *cli;
        const char *fname[1] = { "\\lock6.txt" };
        int i;
        int fnum;
        NTSTATUS status;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
        printf("starting locktest6\n");
 
        for (i=0;i<1;i++) {
                printf("Testing %s\n", fname[i]);
 
-               cli_unlink(&cli, fname[i]);
+               cli_unlink(cli, fname[i]);
 
-               fnum = cli_open(&cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
-               status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
-               cli_close(&cli, fnum);
+               fnum = cli_open(cli, fname[i], O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+               status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CHANGE_LOCKTYPE);
+               cli_close(cli, fnum);
                printf("CHANGE_LOCKTYPE gave %s\n", nt_errstr(status));
 
-               fnum = cli_open(&cli, fname[i], O_RDWR, DENY_NONE);
-               status = cli_locktype(&cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
-               cli_close(&cli, fnum);
+               fnum = cli_open(cli, fname[i], O_RDWR, DENY_NONE);
+               status = cli_locktype(cli, fnum, 0, 8, 0, LOCKING_ANDX_CANCEL_LOCK);
+               cli_close(cli, fnum);
                printf("CANCEL_LOCK gave %s\n", nt_errstr(status));
 
-               cli_unlink(&cli, fname[i]);
+               cli_unlink(cli, fname[i]);
        }
 
-       torture_close_connection(&cli);
+       torture_close_connection(cli);
 
        printf("finished locktest6\n");
        return True;
 }
 
-static BOOL run_locktest7(int dummy)
+static bool run_locktest7(int dummy)
 {
-       static struct cli_state cli1;
+       struct cli_state *cli1;
        const char *fname = "\\lockt7.lck";
        int fnum1;
        char buf[200];
-       BOOL correct = False;
+       bool correct = False;
 
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
 
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli1, sockops);
 
        printf("starting locktest7\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
 
        memset(buf, 0, sizeof(buf));
 
-       if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
+       if (cli_write(cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) {
                printf("Failed to create file\n");
                goto fail;
        }
 
-       cli_setpid(&cli1, 1);
+       cli_setpid(cli1, 1);
 
-       if (!cli_lock(&cli1, fnum1, 130, 4, 0, READ_LOCK)) {
-               printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(&cli1));
+       if (!cli_lock(cli1, fnum1, 130, 4, 0, READ_LOCK)) {
+               printf("Unable to apply read lock on range 130:4, error was %s\n", cli_errstr(cli1));
                goto fail;
        } else {
                printf("pid1 successfully locked range 130:4 for READ\n");
        }
 
-       if (cli_read(&cli1, fnum1, buf, 130, 4) != 4) {
-               printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(&cli1));
+       if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
+               printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
                goto fail;
        } else {
                printf("pid1 successfully read the range 130:4\n");
        }
 
-       if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) {
-               printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(&cli1));
-               if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
+       if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
+               printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
+               if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
                        printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
                        goto fail;
                }
@@ -1623,17 +2011,17 @@ static BOOL run_locktest7(int dummy)
                goto fail;
        }
 
-       cli_setpid(&cli1, 2);
+       cli_setpid(cli1, 2);
 
-       if (cli_read(&cli1, fnum1, buf, 130, 4) != 4) {
-               printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(&cli1));
+       if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
+               printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
        } else {
                printf("pid2 successfully read the range 130:4\n");
        }
 
-       if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) {
-               printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(&cli1));
-               if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
+       if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
+               printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
+               if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
                        printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
                        goto fail;
                }
@@ -1642,35 +2030,35 @@ static BOOL run_locktest7(int dummy)
                goto fail;
        }
 
-       cli_setpid(&cli1, 1);
-       cli_unlock(&cli1, fnum1, 130, 4);
+       cli_setpid(cli1, 1);
+       cli_unlock(cli1, fnum1, 130, 4);
 
-       if (!cli_lock(&cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
-               printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(&cli1));
+       if (!cli_lock(cli1, fnum1, 130, 4, 0, WRITE_LOCK)) {
+               printf("Unable to apply write lock on range 130:4, error was %s\n", cli_errstr(cli1));
                goto fail;
        } else {
                printf("pid1 successfully locked range 130:4 for WRITE\n");
        }
 
-       if (cli_read(&cli1, fnum1, buf, 130, 4) != 4) {
-               printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(&cli1));
+       if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
+               printf("pid1 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
                goto fail;
        } else {
                printf("pid1 successfully read the range 130:4\n");
        }
 
-       if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) {
-               printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(&cli1));
+       if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
+               printf("pid1 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
                goto fail;
        } else {
                printf("pid1 successfully wrote to the range 130:4\n");
        }
 
-       cli_setpid(&cli1, 2);
+       cli_setpid(cli1, 2);
 
-       if (cli_read(&cli1, fnum1, buf, 130, 4) != 4) {
-               printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(&cli1));
-               if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
+       if (cli_read(cli1, fnum1, buf, 130, 4) != 4) {
+               printf("pid2 unable to read the range 130:4, error was %s\n", cli_errstr(cli1));
+               if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
                        printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
                        goto fail;
                }
@@ -1679,9 +2067,9 @@ static BOOL run_locktest7(int dummy)
                goto fail;
        }
 
-       if (cli_write(&cli1, fnum1, 0, buf, 130, 4) != 4) {
-               printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(&cli1));
-               if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
+       if (cli_write(cli1, fnum1, 0, buf, 130, 4) != 4) {
+               printf("pid2 unable to write to the range 130:4, error was %s\n", cli_errstr(cli1));
+               if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_FILE_LOCK_CONFLICT)) {
                        printf("Incorrect error (should be NT_STATUS_FILE_LOCK_CONFLICT)\n");
                        goto fail;
                }
@@ -1690,13 +2078,13 @@ static BOOL run_locktest7(int dummy)
                goto fail;
        }
 
-       cli_unlock(&cli1, fnum1, 130, 0);
+       cli_unlock(cli1, fnum1, 130, 0);
        correct = True;
 
 fail:
-       cli_close(&cli1, fnum1);
-       cli_unlink(&cli1, fname);
-       torture_close_connection(&cli1);
+       cli_close(cli1, fnum1);
+       cli_unlink(cli1, fname);
+       torture_close_connection(cli1);
 
        printf("finished locktest7\n");
        return correct;
@@ -1706,98 +2094,180 @@ fail:
 test whether fnums and tids open on one VC are available on another (a major
 security hole)
 */
-static BOOL run_fdpasstest(int dummy)
+static bool run_fdpasstest(int dummy)
 {
-       static struct cli_state cli1, cli2, cli3;
+       struct cli_state *cli1, *cli2;
        const char *fname = "\\fdpass.tst";
        int fnum1;
-       pstring buf;
+       char buf[1024];
 
-       if (!torture_open_connection(&cli1) || !torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli1, 0) || !torture_open_connection(&cli2, 1)) {
                return False;
        }
-       cli_sockopt(&cli1, sockops);
-       cli_sockopt(&cli2, sockops);
+       cli_sockopt(cli1, sockops);
+       cli_sockopt(cli2, sockops);
 
        printf("starting fdpasstest\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       if (cli_write(&cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
-               printf("write failed (%s)\n", cli_errstr(&cli1));
+       if (cli_write(cli1, fnum1, 0, "hello world\n", 0, 13) != 13) {
+               printf("write failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       cli3 = cli2;
-       cli3.vuid = cli1.vuid;
-       cli3.cnum = cli1.cnum;
-       cli3.pid = cli1.pid;
+       cli2->vuid = cli1->vuid;
+       cli2->cnum = cli1->cnum;
+       cli2->pid = cli1->pid;
 
-       if (cli_read(&cli3, fnum1, buf, 0, 13) == 13) {
+       if (cli_read(cli2, fnum1, buf, 0, 13) == 13) {
                printf("read succeeded! nasty security hole [%s]\n",
                       buf);
                return False;
        }
 
-       cli_close(&cli1, fnum1);
-       cli_unlink(&cli1, fname);
+       cli_close(cli1, fnum1);
+       cli_unlink(cli1, fname);
 
-       torture_close_connection(&cli1);
-       torture_close_connection(&cli2);
+       torture_close_connection(cli1);
+       torture_close_connection(cli2);
 
        printf("finished fdpasstest\n");
        return True;
 }
 
+static bool run_fdsesstest(int dummy)
+{
+       struct cli_state *cli;
+       uint16 new_vuid;
+       uint16 saved_vuid;
+       uint16 new_cnum;
+       uint16 saved_cnum;
+       const char *fname = "\\fdsess.tst";
+       const char *fname1 = "\\fdsess1.tst";
+       int fnum1;
+       int fnum2;
+       char buf[1024];
+       bool ret = True;
+
+       if (!torture_open_connection(&cli, 0))
+               return False;
+       cli_sockopt(cli, sockops);
+
+       if (!torture_cli_session_setup2(cli, &new_vuid))
+               return False;
+
+       saved_cnum = cli->cnum;
+       if (!NT_STATUS_IS_OK(cli_tcon_andx(cli, share, "?????", "", 1)))
+               return False;
+       new_cnum = cli->cnum;
+       cli->cnum = saved_cnum;
+
+       printf("starting fdsesstest\n");
+
+       cli_unlink(cli, fname);
+       cli_unlink(cli, fname1);
+
+       fnum1 = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       if (fnum1 == -1) {
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
+               return False;
+       }
+
+       if (cli_write(cli, fnum1, 0, "hello world\n", 0, 13) != 13) {
+               printf("write failed (%s)\n", cli_errstr(cli));
+               return False;
+       }
+
+       saved_vuid = cli->vuid;
+       cli->vuid = new_vuid;
+
+       if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
+               printf("read succeeded with different vuid! nasty security hole [%s]\n",
+                      buf);
+               ret = False;
+       }
+       /* Try to open a file with different vuid, samba cnum. */
+       fnum2 = cli_open(cli, fname1, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       if (fnum2 != -1) {
+               printf("create with different vuid, same cnum succeeded.\n");
+               cli_close(cli, fnum2);
+               cli_unlink(cli, fname1);
+       } else {
+               printf("create with different vuid, same cnum failed.\n");
+               printf("This will cause problems with service clients.\n");
+               ret = False;
+       }
+
+       cli->vuid = saved_vuid;
+
+       /* Try with same vuid, different cnum. */
+       cli->cnum = new_cnum;
+
+       if (cli_read(cli, fnum1, buf, 0, 13) == 13) {
+               printf("read succeeded with different cnum![%s]\n",
+                      buf);
+               ret = False;
+       }
+
+       cli->cnum = saved_cnum;
+       cli_close(cli, fnum1);
+       cli_unlink(cli, fname);
+
+       torture_close_connection(cli);
+
+       printf("finished fdsesstest\n");
+       return ret;
+}
 
 /*
   This test checks that 
 
   1) the server does not allow an unlink on a file that is open
 */
-static BOOL run_unlinktest(int dummy)
+static bool run_unlinktest(int dummy)
 {
-       static struct cli_state cli;
+       struct cli_state *cli;
        const char *fname = "\\unlink.tst";
        int fnum;
-       BOOL correct = True;
+       bool correct = True;
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
        printf("starting unlink test\n");
 
-       cli_unlink(&cli, fname);
+       cli_unlink(cli, fname);
 
-       cli_setpid(&cli, 1);
+       cli_setpid(cli, 1);
 
-       fnum = cli_open(&cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
                return False;
        }
 
-       if (cli_unlink(&cli, fname)) {
+       if (cli_unlink(cli, fname)) {
                printf("error: server allowed unlink on an open file\n");
                correct = False;
        } else {
-               correct = check_error(__LINE__, &cli, ERRDOS, ERRbadshare, 
+               correct = check_error(__LINE__, cli, ERRDOS, ERRbadshare, 
                                      NT_STATUS_SHARING_VIOLATION);
        }
 
-       cli_close(&cli, fnum);
-       cli_unlink(&cli, fname);
+       cli_close(cli, fnum);
+       cli_unlink(cli, fname);
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -1810,14 +2280,14 @@ static BOOL run_unlinktest(int dummy)
 /*
 test how many open files this server supports on the one socket
 */
-static BOOL run_maxfidtest(int dummy)
+static bool run_maxfidtest(int dummy)
 {
-       static struct cli_state cli;
-       const char *template = "\\maxfid.%d.%d";
+       struct cli_state *cli;
+       const char *ftemplate = "\\maxfid.%d.%d";
        fstring fname;
        int fnums[0x11000], i;
        int retries=4;
-       BOOL correct = True;
+       bool correct = True;
 
        cli = current_cli;
 
@@ -1826,15 +2296,15 @@ static BOOL run_maxfidtest(int dummy)
                return False;
        }
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
        for (i=0; i<0x11000; i++) {
-               slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
-               if ((fnums[i] = cli_open(&cli, fname, 
+               slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
+               if ((fnums[i] = cli_open(cli, fname, 
                                        O_RDWR|O_CREAT|O_TRUNC, DENY_NONE)) ==
                    -1) {
                        printf("open of %s failed (%s)\n", 
-                              fname, cli_errstr(&cli));
+                              fname, cli_errstr(cli));
                        printf("maximum fnum is %d\n", i);
                        break;
                }
@@ -1845,11 +2315,11 @@ static BOOL run_maxfidtest(int dummy)
 
        printf("cleaning up\n");
        for (;i>=0;i--) {
-               slprintf(fname,sizeof(fname)-1,template, i,(int)getpid());
-               cli_close(&cli, fnums[i]);
-               if (!cli_unlink(&cli, fname)) {
+               slprintf(fname,sizeof(fname)-1,ftemplate, i,(int)getpid());
+               cli_close(cli, fnums[i]);
+               if (!cli_unlink(cli, fname)) {
                        printf("unlink of %s failed (%s)\n", 
-                              fname, cli_errstr(&cli));
+                              fname, cli_errstr(cli));
                        correct = False;
                }
                printf("%6d\r", i);
@@ -1857,7 +2327,7 @@ static BOOL run_maxfidtest(int dummy)
        printf("%6d\n", 0);
 
        printf("maxfid test finished\n");
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
        return correct;
@@ -1873,23 +2343,23 @@ static void rand_buf(char *buf, int len)
 }
 
 /* send smb negprot commands, not reading the response */
-static BOOL run_negprot_nowait(int dummy)
+static bool run_negprot_nowait(int dummy)
 {
        int i;
-       static struct cli_state cli;
-       BOOL correct = True;
+       static struct cli_state *cli;
+       bool correct = True;
 
        printf("starting negprot nowait test\n");
 
-       if (!open_nbt_connection(&cli)) {
+       if (!(cli = open_nbt_connection())) {
                return False;
        }
 
        for (i=0;i<50000;i++) {
-               cli_negprot_send(&cli);
+               cli_negprot_sendsync(cli);
        }
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -1900,20 +2370,20 @@ static BOOL run_negprot_nowait(int dummy)
 
 
 /* send random IPC commands */
-static BOOL run_randomipc(int dummy)
+static bool run_randomipc(int dummy)
 {
        char *rparam = NULL;
        char *rdata = NULL;
-       int rdrcnt,rprcnt;
-       pstring param;
+       unsigned int rdrcnt,rprcnt;
+       char param[1024];
        int api, param_len, i;
-       static struct cli_state cli;
-       BOOL correct = True;
+       struct cli_state *cli;
+       bool correct = True;
        int count = 50000;
 
        printf("starting random ipc test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
@@ -1925,7 +2395,7 @@ static BOOL run_randomipc(int dummy)
   
                SSVAL(param,0,api); 
 
-               cli_api(&cli, 
+               cli_api(cli, 
                        param, param_len, 8,  
                        NULL, 0, BUFFER_SIZE, 
                        &rparam, &rprcnt,     
@@ -1936,7 +2406,7 @@ static BOOL run_randomipc(int dummy)
        }
        printf("%d/%d\n", i, count);
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -1959,28 +2429,28 @@ static void browse_callback(const char *sname, uint32 stype,
   This test checks the browse list code
 
 */
-static BOOL run_browsetest(int dummy)
+static bool run_browsetest(int dummy)
 {
-       static struct cli_state cli;
-       BOOL correct = True;
+       static struct cli_state *cli;
+       bool correct = True;
 
        printf("starting browse test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
        printf("domain list:\n");
-       cli_NetServerEnum(&cli, cli.server_domain, 
+       cli_NetServerEnum(cli, cli->server_domain, 
                          SV_TYPE_DOMAIN_ENUM,
                          browse_callback, NULL);
 
        printf("machine list:\n");
-       cli_NetServerEnum(&cli, cli.server_domain, 
+       cli_NetServerEnum(cli, cli->server_domain, 
                          SV_TYPE_ALL,
                          browse_callback, NULL);
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -1994,26 +2464,26 @@ static BOOL run_browsetest(int dummy)
 /*
   This checks how the getatr calls works
 */
-static BOOL run_attrtest(int dummy)
+static bool run_attrtest(int dummy)
 {
-       static struct cli_state cli;
+       struct cli_state *cli;
        int fnum;
        time_t t, t2;
-       const char *fname = "\\attrib.tst";
-       BOOL correct = True;
+       const char *fname = "\\attrib123456789.tst";
+       bool correct = True;
 
        printf("starting attrib test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       cli_unlink(&cli, fname);
-       fnum = cli_open(&cli, fname, 
+       cli_unlink(cli, fname);
+       fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
-       cli_close(&cli, fnum);
-       if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
-               printf("getatr failed (%s)\n", cli_errstr(&cli));
+       cli_close(cli, fnum);
+       if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
+               printf("getatr failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
 
@@ -2026,13 +2496,13 @@ static BOOL run_attrtest(int dummy)
 
        t2 = t-60*60*24; /* 1 day ago */
 
-       if (!cli_setatr(&cli, fname, 0, t2)) {
-               printf("setatr failed (%s)\n", cli_errstr(&cli));
+       if (!cli_setatr(cli, fname, 0, t2)) {
+               printf("setatr failed (%s)\n", cli_errstr(cli));
                correct = True;
        }
 
-       if (!cli_getatr(&cli, fname, NULL, NULL, &t)) {
-               printf("getatr failed (%s)\n", cli_errstr(&cli));
+       if (!cli_getatr(cli, fname, NULL, NULL, &t)) {
+               printf("getatr failed (%s)\n", cli_errstr(cli));
                correct = True;
        }
 
@@ -2043,9 +2513,9 @@ static BOOL run_attrtest(int dummy)
                correct = True;
        }
 
-       cli_unlink(&cli, fname);
+       cli_unlink(cli, fname);
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -2058,35 +2528,36 @@ static BOOL run_attrtest(int dummy)
 /*
   This checks a couple of trans2 calls
 */
-static BOOL run_trans2test(int dummy)
+static bool run_trans2test(int dummy)
 {
-       static struct cli_state cli;
+       struct cli_state *cli;
        int fnum;
-       size_t size;
-       time_t c_time, a_time, m_time, w_time, m_time2;
+       SMB_OFF_T size;
+       time_t c_time, a_time, m_time;
+       struct timespec c_time_ts, a_time_ts, m_time_ts, w_time_ts, m_time2_ts;
        const char *fname = "\\trans2.tst";
        const char *dname = "\\trans2";
        const char *fname2 = "\\trans2\\trans2.tst";
-       pstring pname;
-       BOOL correct = True;
+       char pname[1024];
+       bool correct = True;
 
        printf("starting trans2 test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       cli_unlink(&cli, fname);
-       fnum = cli_open(&cli, fname, 
+       cli_unlink(cli, fname);
+       fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
-       if (!cli_qfileinfo(&cli, fnum, NULL, &size, &c_time, &a_time, &m_time,
-                          NULL, NULL)) {
-               printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(&cli));
+       if (!cli_qfileinfo(cli, fnum, NULL, &size, &c_time_ts, &a_time_ts, &w_time_ts,
+                          &m_time_ts, NULL)) {
+               printf("ERROR: qfileinfo failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
 
-       if (!cli_qfilename(&cli, fnum, pname)) {
-               printf("ERROR: qfilename failed (%s)\n", cli_errstr(&cli));
+       if (!cli_qfilename(cli, fnum, pname, sizeof(pname))) {
+               printf("ERROR: qfilename failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
 
@@ -2096,28 +2567,27 @@ static BOOL run_trans2test(int dummy)
                correct = False;
        }
 
-       cli_close(&cli, fnum);
+       cli_close(cli, fnum);
 
        sleep(2);
 
-       cli_unlink(&cli, fname);
-       fnum = cli_open(&cli, fname, 
+       cli_unlink(cli, fname);
+       fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
        if (fnum == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
                return False;
        }
-       cli_close(&cli, fnum);
+       cli_close(cli, fnum);
 
-       if (!cli_qpathinfo(&cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
-               printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(&cli));
+       if (!cli_qpathinfo(cli, fname, &c_time, &a_time, &m_time, &size, NULL)) {
+               printf("ERROR: qpathinfo failed (%s)\n", cli_errstr(cli));
                correct = False;
        } else {
                if (c_time != m_time) {
                        printf("create time=%s", ctime(&c_time));
                        printf("modify time=%s", ctime(&m_time));
                        printf("This system appears to have sticky create times\n");
-                       correct = False;
                }
                if (a_time % (60*60) == 0) {
                        printf("access time=%s", ctime(&a_time));
@@ -2132,56 +2602,57 @@ static BOOL run_trans2test(int dummy)
        }
 
 
-       cli_unlink(&cli, fname);
-       fnum = cli_open(&cli, fname, 
+       cli_unlink(cli, fname);
+       fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
-       cli_close(&cli, fnum);
-       if (!cli_qpathinfo2(&cli, fname, &c_time, &a_time, &m_time
-                           &w_time, &size, NULL, NULL)) {
-               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       cli_close(cli, fnum);
+       if (!cli_qpathinfo2(cli, fname, &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time_ts, &size, NULL, NULL)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        } else {
-               if (w_time < 60*60*24*2) {
-                       printf("write time=%s", ctime(&w_time));
+               if (w_time_ts.tv_sec < 60*60*24*2) {
+                       printf("write time=%s", ctime(&w_time_ts.tv_sec));
                        printf("This system appears to set a initial 0 write time\n");
                        correct = False;
                }
        }
 
-       cli_unlink(&cli, fname);
+       cli_unlink(cli, fname);
 
 
        /* check if the server updates the directory modification time
            when creating a new file */
-       if (!cli_mkdir(&cli, dname)) {
-               printf("ERROR: mkdir failed (%s)\n", cli_errstr(&cli));
+       if (!cli_mkdir(cli, dname)) {
+               printf("ERROR: mkdir failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
        sleep(3);
-       if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time
-                           &w_time, &size, NULL, NULL)) {
-               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time_ts, &size, NULL, NULL)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        }
 
-       fnum = cli_open(&cli, fname2, 
+       fnum = cli_open(cli, fname2, 
                        O_RDWR | O_CREAT | O_TRUNC, DENY_NONE);
-       cli_write(&cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
-       cli_close(&cli, fnum);
-       if (!cli_qpathinfo2(&cli, "\\trans2\\", &c_time, &a_time, &m_time2
-                           &w_time, &size, NULL, NULL)) {
-               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(&cli));
+       cli_write(cli, fnum,  0, (char *)&fnum, 0, sizeof(fnum));
+       cli_close(cli, fnum);
+       if (!cli_qpathinfo2(cli, "\\trans2\\", &c_time_ts, &a_time_ts, &w_time_ts
+                           &m_time2_ts, &size, NULL, NULL)) {
+               printf("ERROR: qpathinfo2 failed (%s)\n", cli_errstr(cli));
                correct = False;
        } else {
-               if (m_time2 == m_time) {
+               if (memcmp(&m_time_ts, &m_time2_ts, sizeof(struct timespec))
+                   == 0) {
                        printf("This system does not update directory modification times\n");
                        correct = False;
                }
        }
-       cli_unlink(&cli, fname2);
-       cli_rmdir(&cli, dname);
+       cli_unlink(cli, fname2);
+       cli_rmdir(cli, dname);
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -2194,48 +2665,48 @@ static BOOL run_trans2test(int dummy)
   This checks new W2K calls.
 */
 
-static BOOL new_trans(struct cli_state *pcli, int fnum, int level)
+static bool new_trans(struct cli_state *pcli, int fnum, int level)
 {
-       char buf[4096];
-       BOOL correct = True;
-
-       memset(buf, 0xff, sizeof(buf));
+       char *buf = NULL;
+       uint32 len;
+       bool correct = True;
 
-       if (!cli_qfileinfo_test(pcli, fnum, level, buf)) {
+       if (!cli_qfileinfo_test(pcli, fnum, level, &buf, &len)) {
                printf("ERROR: qfileinfo (%d) failed (%s)\n", level, cli_errstr(pcli));
                correct = False;
        } else {
-               printf("qfileinfo: level %d\n", level);
-               dump_data(0, buf, 256);
+               printf("qfileinfo: level %d, len = %u\n", level, len);
+               dump_data(0, (uint8 *)buf, len);
                printf("\n");
        }
+       SAFE_FREE(buf);
        return correct;
 }
 
-static BOOL run_w2ktest(int dummy)
+static bool run_w2ktest(int dummy)
 {
-       static struct cli_state cli;
+       struct cli_state *cli;
        int fnum;
        const char *fname = "\\w2ktest\\w2k.tst";
        int level;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting w2k test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       fnum = cli_open(&cli, fname, 
+       fnum = cli_open(cli, fname, 
                        O_RDWR | O_CREAT , DENY_NONE);
 
        for (level = 1004; level < 1040; level++) {
-               new_trans(&cli, fnum, level);
+               new_trans(cli, fnum, level);
        }
 
-       cli_close(&cli, fnum);
+       cli_close(cli, fnum);
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -2248,47 +2719,47 @@ static BOOL run_w2ktest(int dummy)
 /*
   this is a harness for some oplock tests
  */
-static BOOL run_oplock1(int dummy)
+static bool run_oplock1(int dummy)
 {
-       static struct cli_state cli1;
+       struct cli_state *cli1;
        const char *fname = "\\lockt1.lck";
        int fnum1;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting oplock test 1\n");
 
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli1, sockops);
 
-       cli1.use_oplocks = True;
+       cli1->use_oplocks = True;
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       cli1.use_oplocks = False;
+       cli1->use_oplocks = False;
 
-       cli_unlink(&cli1, fname);
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname);
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close2 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       if (!cli_unlink(&cli1, fname)) {
-               printf("unlink failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_unlink(cli1, fname)) {
+               printf("unlink failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
 
@@ -2297,17 +2768,17 @@ static BOOL run_oplock1(int dummy)
        return correct;
 }
 
-static BOOL run_oplock2(int dummy)
+static bool run_oplock2(int dummy)
 {
-       static struct cli_state cli1, cli2;
+       struct cli_state *cli1, *cli2;
        const char *fname = "\\lockt2.lck";
        int fnum1, fnum2;
        int saved_use_oplocks = use_oplocks;
        char buf[4];
-       BOOL correct = True;
-       volatile BOOL *shared_correct;
+       bool correct = True;
+       volatile bool *shared_correct;
 
-       shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
+       shared_correct = (volatile bool *)shm_setup(sizeof(bool));
        *shared_correct = True;
 
        use_level_II_oplocks = True;
@@ -2315,32 +2786,32 @@ static BOOL run_oplock2(int dummy)
 
        printf("starting oplock test 2\n");
 
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                use_level_II_oplocks = False;
                use_oplocks = saved_use_oplocks;
                return False;
        }
 
-       cli1.use_oplocks = True;
-       cli1.use_level_II_oplocks = True;
+       cli1->use_oplocks = True;
+       cli1->use_level_II_oplocks = True;
 
-       if (!torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli2, 1)) {
                use_level_II_oplocks = False;
                use_oplocks = saved_use_oplocks;
                return False;
        }
 
-       cli2.use_oplocks = True;
-       cli2.use_level_II_oplocks = True;
+       cli2->use_oplocks = True;
+       cli2->use_level_II_oplocks = True;
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       cli_sockopt(&cli1, sockops);
-       cli_sockopt(&cli2, sockops);
+       cli_sockopt(cli1, sockops);
+       cli_sockopt(cli2, sockops);
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
@@ -2350,17 +2821,17 @@ static BOOL run_oplock2(int dummy)
 
        if (fork() == 0) {
                /* Child code */
-               fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE);
+               fnum2 = cli_open(cli2, fname, O_RDWR, DENY_NONE);
                if (fnum2 == -1) {
-                       printf("second open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+                       printf("second open of %s failed (%s)\n", fname, cli_errstr(cli1));
                        *shared_correct = False;
                        exit(0);
                }
 
                sleep(2);
 
-               if (!cli_close(&cli2, fnum2)) {
-                       printf("close2 failed (%s)\n", cli_errstr(&cli1));
+               if (!cli_close(cli2, fnum2)) {
+                       printf("close2 failed (%s)\n", cli_errstr(cli1));
                        *shared_correct = False;
                }
 
@@ -2369,56 +2840,57 @@ static BOOL run_oplock2(int dummy)
 
        sleep(2);
 
-       /* Ensure cli1 processes the break. */
+       /* Ensure cli1 processes the break. Empty file should always return 0
+        * bytes.  */
 
-       if (cli_read(&cli1, fnum1, buf, 0, 4) != 4) {
-               printf("read on fnum1 failed (%s)\n", cli_errstr(&cli1));
+       if (cli_read(cli1, fnum1, buf, 0, 4) != 0) {
+               printf("read on fnum1 failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
        /* Should now be at level II. */
        /* Test if sending a write locks causes a break to none. */
 
-       if (!cli_lock(&cli1, fnum1, 0, 4, 0, READ_LOCK)) {
-               printf("lock failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_lock(cli1, fnum1, 0, 4, 0, READ_LOCK)) {
+               printf("lock failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
-       cli_unlock(&cli1, fnum1, 0, 4);
+       cli_unlock(cli1, fnum1, 0, 4);
 
        sleep(2);
 
-       if (!cli_lock(&cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
-               printf("lock failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_lock(cli1, fnum1, 0, 4, 0, WRITE_LOCK)) {
+               printf("lock failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
-       cli_unlock(&cli1, fnum1, 0, 4);
+       cli_unlock(cli1, fnum1, 0, 4);
 
        sleep(2);
 
-       cli_read(&cli1, fnum1, buf, 0, 4);
+       cli_read(cli1, fnum1, buf, 0, 4);
 
 #if 0
-       if (cli_write(&cli1, fnum1, 0, buf, 0, 4) != 4) {
-               printf("write on fnum1 failed (%s)\n", cli_errstr(&cli1));
+       if (cli_write(cli1, fnum1, 0, buf, 0, 4) != 4) {
+               printf("write on fnum1 failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 #endif
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close1 failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
        sleep(4);
 
-       if (!cli_unlink(&cli1, fname)) {
-               printf("unlink failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_unlink(cli1, fname)) {
+               printf("unlink failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
 
@@ -2432,23 +2904,23 @@ static BOOL run_oplock2(int dummy)
 }
 
 /* handler for oplock 3 tests */
-static BOOL oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
+static bool oplock3_handler(struct cli_state *cli, int fnum, unsigned char level)
 {
        printf("got oplock break fnum=%d level=%d\n",
               fnum, level);
        return cli_oplock_ack(cli, fnum, level);
 }
 
-static BOOL run_oplock3(int dummy)
+static bool run_oplock3(int dummy)
 {
-       static struct cli_state cli;
+       struct cli_state *cli;
        const char *fname = "\\oplockt3.dat";
        int fnum;
        char buf[4] = "abcd";
-       BOOL correct = True;
-       volatile BOOL *shared_correct;
+       bool correct = True;
+       volatile bool *shared_correct;
 
-       shared_correct = (volatile BOOL *)shm_setup(sizeof(BOOL));
+       shared_correct = (volatile bool *)shm_setup(sizeof(bool));
        *shared_correct = True;
 
        printf("starting oplock test 3\n");
@@ -2457,30 +2929,30 @@ static BOOL run_oplock3(int dummy)
                /* Child code */
                use_oplocks = True;
                use_level_II_oplocks = True;
-               if (!torture_open_connection(&cli)) {
+               if (!torture_open_connection(&cli, 0)) {
                        *shared_correct = False;
                        exit(0);
                } 
                sleep(2);
                /* try to trigger a oplock break in parent */
-               fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
-               cli_write(&cli, fnum, 0, buf, 0, 4);
+               fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
+               cli_write(cli, fnum, 0, buf, 0, 4);
                exit(0);
        }
 
        /* parent code */
        use_oplocks = True;
        use_level_II_oplocks = True;
-       if (!torture_open_connection(&cli)) { 
+       if (!torture_open_connection(&cli, 1)) { /* other is forked */
                return False;
        }
-       cli_oplock_handler(&cli, oplock3_handler);
-       fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
-       cli_write(&cli, fnum, 0, buf, 0, 4);
-       cli_close(&cli, fnum);
-       fnum = cli_open(&cli, fname, O_RDWR, DENY_NONE);
-       cli.timeout = 20000;
-       cli_receive_smb(&cli);
+       cli_oplock_handler(cli, oplock3_handler);
+       fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
+       cli_write(cli, fnum, 0, buf, 0, 4);
+       cli_close(cli, fnum);
+       fnum = cli_open(cli, fname, O_RDWR, DENY_NONE);
+       cli->timeout = 20000;
+       cli_receive_smb(cli);
        printf("finished oplock test 3\n");
 
        return (correct && *shared_correct);
@@ -2493,48 +2965,56 @@ static BOOL run_oplock3(int dummy)
 /*
   Test delete on close semantics.
  */
-static BOOL run_deletetest(int dummy)
+static bool run_deletetest(int dummy)
 {
-       static struct cli_state cli1;
-       static struct cli_state cli2;
+       struct cli_state *cli1 = NULL;
+       struct cli_state *cli2 = NULL;
        const char *fname = "\\delete.file";
        int fnum1 = -1;
        int fnum2 = -1;
-       BOOL correct = True;
+       bool correct = True;
        
        printf("starting delete test\n");
        
-       ZERO_STRUCT(cli1);
-       ZERO_STRUCT(cli2);
-
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli1, sockops);
 
        /* Test 1 - this should delete the file on close. */
        
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
        
-       fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 
-                                  FILE_DELETE_ON_CLOSE);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  0, FILE_OVERWRITE_IF, 
+                                  FILE_DELETE_ON_CLOSE, 0);
        
        if (fnum1 == -1) {
-               printf("[1] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[1] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
-       
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[1] close failed (%s)\n", cli_errstr(&cli1));
+
+#if 0 /* JRATEST */
+        {
+                uint32 *accinfo = NULL;
+                uint32 len;
+                cli_qfileinfo_test(cli1, fnum1, SMB_FILE_ACCESS_INFORMATION, (char **)&accinfo, &len);
+               if (accinfo)
+                       printf("access mode = 0x%lx\n", *accinfo);
+                SAFE_FREE(accinfo);
+        }
+#endif
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("[1] close failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
-       fnum1 = cli_open(&cli1, fname, O_RDWR, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR, DENY_NONE);
        if (fnum1 != -1) {
                printf("[1] open of %s succeeded (should fail)\n", fname);
                correct = False;
@@ -2545,52 +3025,52 @@ static BOOL run_deletetest(int dummy)
        
        /* Test 2 - this should delete the file on close. */
        
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
        
-       fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS,
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS,
                                   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, 
-                                  FILE_OVERWRITE_IF, 0);
+                                  FILE_OVERWRITE_IF, 0, 0);
        
        if (fnum1 == -1) {
-               printf("[2] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[2] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
-       if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
-               printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+               printf("[2] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[2] close failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[2] close failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
-       fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
        if (fnum1 != -1) {
                printf("[2] open of %s succeeded should have been deleted on close !\n", fname);
-               if (!cli_close(&cli1, fnum1)) {
-                       printf("[2] close failed (%s)\n", cli_errstr(&cli1));
+               if (!cli_close(cli1, fnum1)) {
+                       printf("[2] close failed (%s)\n", cli_errstr(cli1));
                        correct = False;
                        goto fail;
                }
-               cli_unlink(&cli1, fname);
+               cli_unlink(cli1, fname);
        } else
                printf("second delete on close test succeeded.\n");
        
        /* Test 3 - ... */
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[3] open - 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
@@ -2598,8 +3078,8 @@ static BOOL run_deletetest(int dummy)
        /* This should fail with a sharing violation - open for delete is only compatible
           with SHARE_DELETE. */
 
-       fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                       FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0);
+       fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                       FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0, 0);
 
        if (fnum2 != -1) {
                printf("[3] open  - 2 of %s succeeded - should have failed.\n", fname);
@@ -2609,84 +3089,85 @@ static BOOL run_deletetest(int dummy)
 
        /* This should succeed. */
 
-       fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                       FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
+       fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                       FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
 
        if (fnum2 == -1) {
-               printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[3] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
-       if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
-               printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+               printf("[3] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[3] close 1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[3] close 1 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
-       if (!cli_close(&cli1, fnum2)) {
-               printf("[3] close 2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum2)) {
+               printf("[3] close 2 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
        /* This should fail - file should no longer be there. */
 
-       fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
        if (fnum1 != -1) {
                printf("[3] open of %s succeeded should have been deleted on close !\n", fname);
-               if (!cli_close(&cli1, fnum1)) {
-                       printf("[3] close failed (%s)\n", cli_errstr(&cli1));
+               if (!cli_close(cli1, fnum1)) {
+                       printf("[3] close failed (%s)\n", cli_errstr(cli1));
                }
-               cli_unlink(&cli1, fname);
+               cli_unlink(cli1, fname);
                correct = False;
                goto fail;
        } else
                printf("third delete on close test succeeded.\n");
 
        /* Test 4 ... */
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
-                       FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+                       FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
                                                                
        if (fnum1 == -1) {
-               printf("[4] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[4] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
        /* This should succeed. */
-       fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
-                       FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
+       fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
+                       FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0);
        if (fnum2 == -1) {
-               printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[4] open  - 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
-       if (!cli_close(&cli1, fnum2)) {
-               printf("[4] close - 1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum2)) {
+               printf("[4] close - 1 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
-       if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
-               printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
+               printf("[4] setting delete_on_close failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
        /* This should fail - no more opens once delete on close set. */
-       fnum2 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS,
-                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
+       fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS,
+                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+                                  FILE_OPEN, 0, 0);
        if (fnum2 != -1) {
                printf("[4] open  - 3 of %s succeeded ! Should have failed.\n", fname );
                correct = False;
@@ -2694,33 +3175,33 @@ static BOOL run_deletetest(int dummy)
        } else
                printf("fourth delete on close test succeeded.\n");
        
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[4] close - 2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[4] close - 2 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
        /* Test 5 ... */
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
        
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT, DENY_NONE);
        if (fnum1 == -1) {
-               printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
        /* This should fail - only allowed on NT opens with DELETE access. */
 
-       if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
+       if (cli_nt_delete_on_close(cli1, fnum1, True)) {
                printf("[5] setting delete_on_close on OpenX file succeeded - should fail !\n");
                correct = False;
                goto fail;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[5] close - 2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[5] close - 2 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
@@ -2728,29 +3209,29 @@ static BOOL run_deletetest(int dummy)
        printf("fifth delete on close test succeeded.\n");
        
        /* Test 6 ... */
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
        
-       fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
                                   FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
-                                  FILE_OVERWRITE_IF, 0);
+                                  FILE_OVERWRITE_IF, 0, 0);
        
        if (fnum1 == -1) {
-               printf("[6] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[6] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
        /* This should fail - only allowed on NT opens with DELETE access. */
        
-       if (cli_nt_delete_on_close(&cli1, fnum1, True)) {
+       if (cli_nt_delete_on_close(cli1, fnum1, True)) {
                printf("[6] setting delete_on_close on file with no delete access succeeded - should fail !\n");
                correct = False;
                goto fail;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[6] close - 2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[6] close - 2 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
@@ -2758,47 +3239,47 @@ static BOOL run_deletetest(int dummy)
        printf("sixth delete on close test succeeded.\n");
        
        /* Test 7 ... */
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
        
-       fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
-                                  FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+                                  FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF, 0, 0);
                                                                
        if (fnum1 == -1) {
-               printf("[7] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[7] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
-       if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
+       if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
                printf("[7] setting delete_on_close on file failed !\n");
                correct = False;
                goto fail;
        }
        
-       if (!cli_nt_delete_on_close(&cli1, fnum1, False)) {
+       if (!cli_nt_delete_on_close(cli1, fnum1, False)) {
                printf("[7] unsetting delete_on_close on file failed !\n");
                correct = False;
                goto fail;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
        
        /* This next open should succeed - we reset the flag. */
        
-       fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
        if (fnum1 == -1) {
-               printf("[5] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[5] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[7] close - 2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[7] close - 2 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
@@ -2806,55 +3287,57 @@ static BOOL run_deletetest(int dummy)
        printf("seventh delete on close test succeeded.\n");
        
        /* Test 7 ... */
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
        
-       if (!torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli2, 1)) {
                printf("[8] failed to open second connection.\n");
                correct = False;
                goto fail;
        }
 
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli1, sockops);
        
-       fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
-                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+                                  FILE_OVERWRITE_IF, 0, 0);
        
        if (fnum1 == -1) {
-               printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[8] open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
-       fnum2 = cli_nt_create_full(&cli2, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
-                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0);
+       fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+                                  FILE_OPEN, 0, 0);
        
        if (fnum2 == -1) {
-               printf("[8] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[8] open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                correct = False;
                goto fail;
        }
 
-       if (!cli_nt_delete_on_close(&cli1, fnum1, True)) {
+       if (!cli_nt_delete_on_close(cli1, fnum1, True)) {
                printf("[8] setting delete_on_close on file failed !\n");
                correct = False;
                goto fail;
        }
        
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[8] close - 1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[8] close - 1 failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
-       if (!cli_close(&cli2, fnum2)) {
-               printf("[8] close - 2 failed (%s)\n", cli_errstr(&cli2));
+       if (!cli_close(cli2, fnum2)) {
+               printf("[8] close - 2 failed (%s)\n", cli_errstr(cli2));
                correct = False;
                goto fail;
        }
 
        /* This should fail.. */
-       fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
        if (fnum1 != -1) {
                printf("[8] open of %s succeeded should have been deleted on close !\n", fname);
                goto fail;
@@ -2863,8 +3346,8 @@ static BOOL run_deletetest(int dummy)
                printf("eighth delete on close test succeeded.\n");
 
        /* This should fail - we need to set DELETE_ACCESS. */
-       fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA,
-                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
+       fnum1 = cli_nt_create_full(cli1, fname, 0,FILE_READ_DATA|FILE_WRITE_DATA,
+                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
        
        if (fnum1 != -1) {
                printf("[9] open of %s succeeded should have failed!\n", fname);
@@ -2874,69 +3357,115 @@ static BOOL run_deletetest(int dummy)
 
        printf("ninth delete on close test succeeded.\n");
 
-       fnum1 = cli_nt_create_full(&cli1, fname, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
-                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA|DELETE_ACCESS,
+                                  FILE_ATTRIBUTE_NORMAL, FILE_SHARE_NONE, FILE_OVERWRITE_IF, FILE_DELETE_ON_CLOSE, 0);
        if (fnum1 == -1) {
-               printf("[10] open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("[10] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
        /* This should delete the file. */
-       if (!cli_close(&cli1, fnum1)) {
-               printf("[10] close failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("[10] close failed (%s)\n", cli_errstr(cli1));
                correct = False;
                goto fail;
        }
 
        /* This should fail.. */
-       fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_NONE);
        if (fnum1 != -1) {
                printf("[10] open of %s succeeded should have been deleted on close !\n", fname);
                goto fail;
                correct = False;
        } else
                printf("tenth delete on close test succeeded.\n");
-       printf("finished delete test\n");
 
-  fail:
-       
-       cli_close(&cli1, fnum1);
-       cli_close(&cli1, fnum2);
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
-       
-       if (!torture_close_connection(&cli1)) {
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
+
+       /* What error do we get when attempting to open a read-only file with
+          delete access ? */
+
+       /* Create a readonly file. */
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA,
+                                  FILE_ATTRIBUTE_READONLY, FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
+       if (fnum1 == -1) {
+               printf("[11] open of %s failed (%s)\n", fname, cli_errstr(cli1));
                correct = False;
+               goto fail;
        }
-       if (!torture_close_connection(&cli2)) {
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("[11] close failed (%s)\n", cli_errstr(cli1));
                correct = False;
+               goto fail;
        }
-       return correct;
-}
-
-
-/*
-  print out server properties
- */
-static BOOL run_properties(int dummy)
-{
-       static struct cli_state cli;
-       BOOL correct = True;
-       
-       printf("starting properties test\n");
-       
-       ZERO_STRUCT(cli);
 
-       if (!torture_open_connection(&cli)) {
-               return False;
-       }
+       /* Now try open for delete access. */
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES|DELETE_ACCESS,
+                                  0, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
+                                  FILE_OVERWRITE_IF, 0, 0);
        
-       cli_sockopt(&cli, sockops);
-
-       d_printf("Capabilities 0x%08x\n", cli.capabilities);
+       if (fnum1 != -1) {
+               printf("[11] open of %s succeeded should have been denied with ACCESS_DENIED!\n", fname);
+               cli_close(cli1, fnum1);
+               goto fail;
+               correct = False;
+       } else {
+               NTSTATUS nterr = cli_nt_error(cli1);
+               if (!NT_STATUS_EQUAL(nterr,NT_STATUS_ACCESS_DENIED)) {
+                       printf("[11] open of %s should have been denied with ACCESS_DENIED! Got error %s\n", fname, nt_errstr(nterr));
+                       goto fail;
+                       correct = False;
+               } else {
+                       printf("eleventh delete on close test succeeded.\n");
+               }
+       }
+       
+       printf("finished delete test\n");
+
+  fail:
+       /* FIXME: This will crash if we aborted before cli2 got
+        * intialized, because these functions don't handle
+        * uninitialized connections. */
+               
+       if (fnum1 != -1) cli_close(cli1, fnum1);
+       if (fnum2 != -1) cli_close(cli1, fnum2);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
+
+       if (cli1 && !torture_close_connection(cli1)) {
+               correct = False;
+       }
+       if (cli2 && !torture_close_connection(cli2)) {
+               correct = False;
+       }
+       return correct;
+}
+
+
+/*
+  print out server properties
+ */
+static bool run_properties(int dummy)
+{
+       static struct cli_state *cli;
+       bool correct = True;
+       
+       printf("starting properties test\n");
+       
+       ZERO_STRUCT(cli);
+
+       if (!torture_open_connection(&cli, 0)) {
+               return False;
+       }
+       
+       cli_sockopt(cli, sockops);
+
+       d_printf("Capabilities 0x%08x\n", cli->capabilities);
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -2967,39 +3496,39 @@ static BOOL run_properties(int dummy)
 /*
   Test ntcreate calls made by xcopy
  */
-static BOOL run_xcopy(int dummy)
+static bool run_xcopy(int dummy)
 {
-       static struct cli_state cli1;
+       static struct cli_state *cli1;
        const char *fname = "\\test.txt";
-       BOOL correct = True;
+       bool correct = True;
        int fnum1, fnum2;
 
        printf("starting xcopy test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
-       fnum1 = cli_nt_create_full(&cli1, fname, 
+       fnum1 = cli_nt_create_full(cli1, fname, 0,
                                   FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
                                   FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
-                                  0x4044);
+                                  0x4044, 0);
 
        if (fnum1 == -1) {
-               printf("First open failed - %s\n", cli_errstr(&cli1));
+               printf("First open failed - %s\n", cli_errstr(cli1));
                return False;
        }
 
-       fnum2 = cli_nt_create_full(&cli1, fname, 
+       fnum2 = cli_nt_create_full(cli1, fname, 0,
                                   SECOND_DESIRED_ACCESS, 0,
                                   FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 
-                                  0x200000);
+                                  0x200000, 0);
        if (fnum2 == -1) {
-               printf("second open failed - %s\n", cli_errstr(&cli1));
+               printf("second open failed - %s\n", cli_errstr(cli1));
                return False;
        }
        
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
        
@@ -3009,76 +3538,76 @@ static BOOL run_xcopy(int dummy)
 /*
   Test rename on files open with share delete and no share delete.
  */
-static BOOL run_rename(int dummy)
+static bool run_rename(int dummy)
 {
-       static struct cli_state cli1;
+       static struct cli_state *cli1;
        const char *fname = "\\test.txt";
        const char *fname1 = "\\test1.txt";
-       BOOL correct = True;
+       bool correct = True;
        int fnum1;
 
        printf("starting rename test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
-       cli_unlink(&cli1, fname);
-       cli_unlink(&cli1, fname1);
-       fnum1 = cli_nt_create_full(&cli1, fname, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname1);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("First open failed - %s\n", cli_errstr(&cli1));
+               printf("First open failed - %s\n", cli_errstr(cli1));
                return False;
        }
 
-       if (!cli_rename(&cli1, fname, fname1)) {
-               printf("First rename failed (this is correct) - %s\n", cli_errstr(&cli1));
+       if (!cli_rename(cli1, fname, fname1)) {
+               printf("First rename failed (SHARE_READ) (this is correct) - %s\n", cli_errstr(cli1));
        } else {
-               printf("First rename succeeded - this should have failed !\n");
+               printf("First rename succeeded (SHARE_READ) - this should have failed !\n");
                correct = False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close - 1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close - 1 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       cli_unlink(&cli1, fname);
-       cli_unlink(&cli1, fname1);
-       fnum1 = cli_nt_create_full(&cli1, fname,GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname1);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
 #if 0
-                                  FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+                                  FILE_SHARE_DELETE|FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 #else
-                                  FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0);
+                                  FILE_SHARE_DELETE|FILE_SHARE_READ, FILE_OVERWRITE_IF, 0, 0);
 #endif
 
        if (fnum1 == -1) {
-               printf("Second open failed - %s\n", cli_errstr(&cli1));
+               printf("Second open failed - %s\n", cli_errstr(cli1));
                return False;
        }
 
-       if (!cli_rename(&cli1, fname, fname1)) {
-               printf("Second rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
+       if (!cli_rename(cli1, fname, fname1)) {
+               printf("Second rename failed (SHARE_DELETE | SHARE_READ) - this should have succeeded - %s\n", cli_errstr(cli1));
                correct = False;
        } else {
-               printf("Second rename succeeded\n");
+               printf("Second rename succeeded (SHARE_DELETE | SHARE_READ)\n");
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close - 2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close - 2 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
-       cli_unlink(&cli1, fname);
-       cli_unlink(&cli1, fname1);
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname1);
 
-       fnum1 = cli_nt_create_full(&cli1, fname,READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, READ_CONTROL_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("Third open failed - %s\n", cli_errstr(&cli1));
+               printf("Third open failed - %s\n", cli_errstr(cli1));
                return False;
        }
 
@@ -3087,167 +3616,238 @@ static BOOL run_rename(int dummy)
   {
   int fnum2;
 
-       fnum2 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+       fnum2 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum2 == -1) {
-               printf("Fourth open failed - %s\n", cli_errstr(&cli1));
+               printf("Fourth open failed - %s\n", cli_errstr(cli1));
                return False;
        }
-       if (!cli_nt_delete_on_close(&cli1, fnum2, True)) {
+       if (!cli_nt_delete_on_close(cli1, fnum2, True)) {
                printf("[8] setting delete_on_close on file failed !\n");
                return False;
        }
        
-       if (!cli_close(&cli1, fnum2)) {
-               printf("close - 4 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum2)) {
+               printf("close - 4 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
   }
 #endif
 
-       if (!cli_rename(&cli1, fname, fname1)) {
-               printf("Third rename failed - this should have succeeded - %s\n", cli_errstr(&cli1));
+       if (!cli_rename(cli1, fname, fname1)) {
+               printf("Third rename failed (SHARE_NONE) - this should have succeeded - %s\n", cli_errstr(cli1));
                correct = False;
        } else {
-               printf("Third rename succeeded\n");
+               printf("Third rename succeeded (SHARE_NONE)\n");
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close - 3 failed (%s)\n", cli_errstr(cli1));
+               return False;
+       }
+
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname1);
+
+        /*----*/
+
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
+
+       if (fnum1 == -1) {
+               printf("Fourth open failed - %s\n", cli_errstr(cli1));
+               return False;
+       }
+
+       if (!cli_rename(cli1, fname, fname1)) {
+               printf("Fourth rename failed (SHARE_READ | SHARE_WRITE) (this is correct) - %s\n", cli_errstr(cli1));
+       } else {
+               printf("Fourth rename succeeded (SHARE_READ | SHARE_WRITE) - this should have failed !\n");
+               correct = False;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close - 4 failed (%s)\n", cli_errstr(cli1));
+               return False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close - 3 failed (%s)\n", cli_errstr(&cli1));
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname1);
+
+        /*--*/
+
+       fnum1 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
+
+       if (fnum1 == -1) {
+               printf("Fifth open failed - %s\n", cli_errstr(cli1));
                return False;
        }
 
-       cli_unlink(&cli1, fname);
-       cli_unlink(&cli1, fname1);
+       if (!cli_rename(cli1, fname, fname1)) {
+               printf("Fifth rename failed (SHARE_READ | SHARE_WRITE | SHARE_DELETE) - this should have succeeded - %s ! \n",
+                       cli_errstr(cli1));
+               correct = False;
+       } else {
+               printf("Fifth rename succeeded (SHARE_READ | SHARE_WRITE | SHARE_DELETE) (this is correct) - %s\n", cli_errstr(cli1));
+       }
+
+        /*
+         * Now check if the first name still exists ...
+         */
+
+        /*fnum2 = cli_nt_create_full(cli1, fname, 0, GENERIC_READ_ACCESS, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
+
+        if (fnum2 == -1) {
+          printf("Opening original file after rename of open file fails: %s\n",
+              cli_errstr(cli1));
+        }
+        else {
+          printf("Opening original file after rename of open file works ...\n");
+          (void)cli_close(cli1, fnum2);
+          } */
+
+        /*--*/
+
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close - 5 failed (%s)\n", cli_errstr(cli1));
+               return False;
+       }
 
-       if (!torture_close_connection(&cli1)) {
+       cli_unlink(cli1, fname);
+       cli_unlink(cli1, fname1);
+        
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
        
        return correct;
 }
 
-static BOOL run_pipe_number(int dummy)
+static bool run_pipe_number(int dummy)
 {
-       static struct cli_state cli1;
+       struct cli_state *cli1;
        const char *pipe_name = "\\SPOOLSS";
        int fnum;
        int num_pipes = 0;
 
        printf("starting pipenumber test\n");
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
 
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli1, sockops);
        while(1) {
-               fnum = cli_nt_create_full(&cli1, pipe_name,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0);
+               fnum = cli_nt_create_full(cli1, pipe_name, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN_IF, 0, 0);
 
                if (fnum == -1) {
-                       printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(&cli1));
+                       printf("Open of pipe %s failed with error (%s)\n", pipe_name, cli_errstr(cli1));
                        break;
                }
                num_pipes++;
+               printf("\r%6d", num_pipes);
        }
 
        printf("pipe_number test - we can open %d %s pipes.\n", num_pipes, pipe_name );
-       torture_close_connection(&cli1);
+       torture_close_connection(cli1);
        return True;
 }
 
 /*
   Test open mode returns on read-only files.
  */
-static BOOL run_opentest(int dummy)
+static bool run_opentest(int dummy)
 {
-       static struct cli_state cli1;
-       static struct cli_state cli2;
+       static struct cli_state *cli1;
+       static struct cli_state *cli2;
        const char *fname = "\\readonly.file";
        int fnum1, fnum2;
        char buf[20];
-       size_t fsize;
-       BOOL correct = True;
+       SMB_OFF_T fsize;
+       bool correct = True;
        char *tmp_path;
 
        printf("starting open test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
        
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli1, sockops);
        
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close2 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
        
-       if (!cli_setatr(&cli1, fname, aRONLY, 0)) {
-               printf("cli_setatr failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_setatr(cli1, fname, aRONLY, 0)) {
+               printf("cli_setatr failed (%s)\n", cli_errstr(cli1));
                return False;
        }
        
-       fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
+       fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
        
        /* This will fail - but the error should be ERRnoaccess, not ERRbadshare. */
-       fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
+       fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
        
-        if (check_error(__LINE__, &cli1, ERRDOS, ERRnoaccess, 
+        if (check_error(__LINE__, cli1, ERRDOS, ERRnoaccess, 
                        NT_STATUS_ACCESS_DENIED)) {
                printf("correct error code ERRDOS/ERRnoaccess returned\n");
        }
        
        printf("finished open test 1\n");
        
-       cli_close(&cli1, fnum1);
+       cli_close(cli1, fnum1);
        
        /* Now try not readonly and ensure ERRbadshare is returned. */
        
-       cli_setatr(&cli1, fname, 0, 0);
+       cli_setatr(cli1, fname, 0, 0);
        
-       fnum1 = cli_open(&cli1, fname, O_RDONLY, DENY_WRITE);
+       fnum1 = cli_open(cli1, fname, O_RDONLY, DENY_WRITE);
        if (fnum1 == -1) {
-               printf("open of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
        
        /* This will fail - but the error should be ERRshare. */
-       fnum2 = cli_open(&cli1, fname, O_RDWR, DENY_ALL);
+       fnum2 = cli_open(cli1, fname, O_RDWR, DENY_ALL);
        
-       if (check_error(__LINE__, &cli1, ERRDOS, ERRbadshare, 
+       if (check_error(__LINE__, cli1, ERRDOS, ERRbadshare, 
                        NT_STATUS_SHARING_VIOLATION)) {
                printf("correct error code ERRDOS/ERRbadshare returned\n");
        }
        
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close2 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
        
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
        
        printf("finished open test 2\n");
        
        /* Test truncate open disposition on file opened for read. */
        
-       fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
        if (fnum1 == -1) {
-               printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("(3) open (1) of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
        
@@ -3255,19 +3855,19 @@ static BOOL run_opentest(int dummy)
        
        memset(buf, '\0', 20);
 
-       if (cli_write(&cli1, fnum1, 0, buf, 0, 20) != 20) {
-               printf("write failed (%s)\n", cli_errstr(&cli1));
+       if (cli_write(cli1, fnum1, 0, buf, 0, 20) != 20) {
+               printf("write failed (%s)\n", cli_errstr(cli1));
                correct = False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("(3) close1 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("(3) close1 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
        
        /* Ensure size == 20. */
-       if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
-               printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
+               printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
                return False;
        }
        
@@ -3278,20 +3878,20 @@ static BOOL run_opentest(int dummy)
 
        /* Now test if we can truncate a file opened for readonly. */
        
-       fnum1 = cli_open(&cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
+       fnum1 = cli_open(cli1, fname, O_RDONLY|O_TRUNC, DENY_NONE);
        if (fnum1 == -1) {
-               printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("(3) open (2) of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
        
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close2 failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close2 failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
        /* Ensure size == 0. */
-       if (!cli_getatr(&cli1, fname, NULL, &fsize, NULL)) {
-               printf("(3) getatr failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_getatr(cli1, fname, NULL, &fsize, NULL)) {
+               printf("(3) getatr failed (%s)\n", cli_errstr(cli1));
                return False;
        }
 
@@ -3301,181 +3901,181 @@ static BOOL run_opentest(int dummy)
        }
        printf("finished open test 3\n");
        
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
 
        printf("testing ctemp\n");
-       fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
+       fnum1 = cli_ctemp(cli1, "\\", &tmp_path);
        if (fnum1 == -1) {
-               printf("ctemp failed (%s)\n", cli_errstr(&cli1));
+               printf("ctemp failed (%s)\n", cli_errstr(cli1));
                return False;
        }
        printf("ctemp gave path %s\n", tmp_path);
-       if (!cli_close(&cli1, fnum1)) {
-               printf("close of temp failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("close of temp failed (%s)\n", cli_errstr(cli1));
        }
-       if (!cli_unlink(&cli1, tmp_path)) {
-               printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
+       if (!cli_unlink(cli1, tmp_path)) {
+               printf("unlink of temp failed (%s)\n", cli_errstr(cli1));
        }
        
        /* Test the non-io opens... */
 
-       if (!torture_open_connection(&cli2)) {
+       if (!torture_open_connection(&cli2, 1)) {
                return False;
        }
        
-       cli_setatr(&cli2, fname, 0, 0);
-       cli_unlink(&cli2, fname);
+       cli_setatr(cli2, fname, 0, 0);
+       cli_unlink(cli2, fname);
        
-       cli_sockopt(&cli2, sockops);
+       cli_sockopt(cli2, sockops);
 
        printf("TEST #1 testing 2 non-io opens (no delete)\n");
        
-       fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("test 1 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OPEN_IF, 0);
+       fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
 
        if (fnum2 == -1) {
-               printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("test 1 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
-       if (!cli_close(&cli2, fnum2)) {
-               printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+       if (!cli_close(cli2, fnum2)) {
+               printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
        printf("non-io open test #1 passed.\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
        printf("TEST #2 testing 2 non-io opens (first with delete)\n");
        
-       fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("test 2 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OPEN_IF, 0);
+       fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
 
        if (fnum2 == -1) {
-               printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("test 2 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("test 1 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
-       if (!cli_close(&cli2, fnum2)) {
-               printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       if (!cli_close(cli2, fnum2)) {
+               printf("test 1 close 2 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
        printf("non-io open test #2 passed.\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
        printf("TEST #3 testing 2 non-io opens (second with delete)\n");
        
-       fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("test 3 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OPEN_IF, 0);
+       fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
 
        if (fnum2 == -1) {
-               printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("test 3 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("test 3 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
-       if (!cli_close(&cli2, fnum2)) {
-               printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+       if (!cli_close(cli2, fnum2)) {
+               printf("test 3 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
        printf("non-io open test #3 passed.\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
        printf("TEST #4 testing 2 non-io opens (both with delete)\n");
        
-       fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("test 4 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OPEN_IF, 0);
+       fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OPEN_IF, 0, 0);
 
        if (fnum2 != -1) {
-               printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("test 4 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
-       printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
+       printf("test 3 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("test 4 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
        printf("non-io open test #4 passed.\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
        printf("TEST #5 testing 2 non-io opens (both with delete - both with file share delete)\n");
        
-       fnum1 = cli_nt_create_full(&cli1, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("test 5 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
+       fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
 
        if (fnum2 == -1) {
-               printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("test 5 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("test 5 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       if (!cli_close(&cli2, fnum2)) {
-               printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+       if (!cli_close(cli2, fnum2)) {
+               printf("test 5 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
@@ -3483,31 +4083,31 @@ static BOOL run_opentest(int dummy)
 
        printf("TEST #6 testing 1 non-io open, one io open\n");
        
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("test 6 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       fnum2 = cli_nt_create_full(&cli2, fname,FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_READ, FILE_OPEN_IF, 0);
+       fnum2 = cli_nt_create_full(cli2, fname, 0, FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ, FILE_OPEN_IF, 0, 0);
 
        if (fnum2 == -1) {
-               printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("test 6 open 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("test 6 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       if (!cli_close(&cli2, fnum2)) {
-               printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(&cli2));
+       if (!cli_close(cli2, fnum2)) {
+               printf("test 6 close 2 of %s failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
@@ -3515,45 +4115,158 @@ static BOOL run_opentest(int dummy)
 
        printf("TEST #7 testing 1 non-io open, one io open with delete\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
        if (fnum1 == -1) {
-               printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+               printf("test 7 open 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
-       fnum2 = cli_nt_create_full(&cli2, fname,DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
-                                  FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0);
+       fnum2 = cli_nt_create_full(cli2, fname, 0, DELETE_ACCESS|FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
+                                  FILE_SHARE_READ|FILE_SHARE_DELETE, FILE_OPEN_IF, 0, 0);
 
        if (fnum2 != -1) {
-               printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(&cli2));
+               printf("test 7 open 2 of %s SUCCEEDED - should have failed (%s)\n", fname, cli_errstr(cli2));
                return False;
        }
 
-       printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(&cli2), "sharing violation");
+       printf("test 7 open 2 of %s gave %s (correct error should be %s)\n", fname, cli_errstr(cli2), "sharing violation");
 
-       if (!cli_close(&cli1, fnum1)) {
-               printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(&cli1));
+       if (!cli_close(cli1, fnum1)) {
+               printf("test 7 close 1 of %s failed (%s)\n", fname, cli_errstr(cli1));
                return False;
        }
 
        printf("non-io open test #7 passed.\n");
 
-       cli_unlink(&cli1, fname);
+       cli_unlink(cli1, fname);
 
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
-       if (!torture_close_connection(&cli2)) {
+       if (!torture_close_connection(cli2)) {
                correct = False;
        }
        
        return correct;
 }
 
+/*
+  Test POSIX open /mkdir calls.
+ */
+static bool run_simple_posix_open_test(int dummy)
+{
+       static struct cli_state *cli1;
+       const char *fname = "\\posix.file";
+       const char *dname = "\\posix.dir";
+       uint16 major, minor;
+       uint32 caplow, caphigh;
+       int fnum1 = -1;
+       bool correct = false;
+
+       printf("Starting simple POSIX open test\n");
+
+       if (!torture_open_connection(&cli1, 0)) {
+               return false;
+       }
+
+       cli_sockopt(cli1, sockops);
+
+       if (!SERVER_HAS_UNIX_CIFS(cli1)) {
+               printf("Server doesn't support UNIX CIFS extensions.\n");
+               return false;
+       }
+
+       if (!cli_unix_extensions_version(cli1, &major,
+                       &minor, &caplow, &caphigh)) {
+               printf("Server didn't return UNIX CIFS extensions.\n");
+               return false;
+       }
+
+       if (!cli_set_unix_extensions_capabilities(cli1,
+                       major, minor, caplow, caphigh)) {
+               printf("Server doesn't support setting UNIX CIFS extensions.\n");
+               return false;
+        }
+
+       cli_setatr(cli1, fname, 0, 0);
+       cli_posix_unlink(cli1, fname);
+       cli_setatr(cli1, dname, 0, 0);
+       cli_posix_rmdir(cli1, dname);
+
+       /* Create a directory. */
+       if (cli_posix_mkdir(cli1, dname, 0777) == -1) {
+               printf("Server doesn't support setting UNIX CIFS extensions.\n");
+               goto out;
+       }
+
+       fnum1 = cli_posix_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, 0600);
+       if (fnum1 == -1) {
+               printf("POSIX create of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Now open the file again for read only. */
+       fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
+       if (fnum1 == -1) {
+               printf("POSIX open of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Now unlink while open. */
+       if (!cli_posix_unlink(cli1, fname)) {
+               printf("POSIX unlink of %s failed (%s)\n", fname, cli_errstr(cli1));
+               goto out;
+       }
+
+       if (!cli_close(cli1, fnum1)) {
+               printf("close(2) failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       /* Ensure the file has gone. */
+       fnum1 = cli_posix_open(cli1, fname, O_RDONLY, 0);
+       if (fnum1 != -1) {
+               printf("POSIX open of %s succeeded, should have been deleted.\n", fname);
+               goto out;
+       }
+
+       if (!cli_posix_rmdir(cli1, dname)) {
+               printf("POSIX rmdir failed (%s)\n", cli_errstr(cli1));
+               goto out;
+       }
+
+       printf("Simple POSIX open test passed\n");
+       correct = true;
+
+  out:
+
+       if (fnum1 != -1) {
+               cli_close(cli1, fnum1);
+               fnum1 = -1;
+       }
+
+       cli_setatr(cli1, fname, 0, 0);
+       cli_posix_unlink(cli1, fname);
+       cli_setatr(cli1, dname, 0, 0);
+       cli_posix_rmdir(cli1, dname);
+
+       if (!torture_close_connection(cli1)) {
+               correct = false;
+       }
+
+       return correct;
+}
+
+
 static uint32 open_attrs_table[] = {
                FILE_ATTRIBUTE_NORMAL,
                FILE_ATTRIBUTE_ARCHIVE,
@@ -3575,7 +4288,7 @@ static uint32 open_attrs_table[] = {
 };
 
 struct trunc_open_results {
-       int num;
+       unsigned int num;
        uint32 init_attr;
        uint32 trunc_attr;
        uint32 result_attr;
@@ -3610,42 +4323,42 @@ static struct trunc_open_results attr_results[] = {
        { 249, FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM, FILE_ATTRIBUTE_ARCHIVE|FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_SYSTEM }
 };
 
-static BOOL run_openattrtest(int dummy)
+static bool run_openattrtest(int dummy)
 {
-       static struct cli_state cli1;
+       static struct cli_state *cli1;
        const char *fname = "\\openattr.file";
        int fnum1;
-       BOOL correct = True;
+       bool correct = True;
        uint16 attr;
-       int i, j, k, l;
+       unsigned int i, j, k, l;
 
        printf("starting open attr test\n");
        
-       if (!torture_open_connection(&cli1)) {
+       if (!torture_open_connection(&cli1, 0)) {
                return False;
        }
        
-       cli_sockopt(&cli1, sockops);
+       cli_sockopt(cli1, sockops);
 
        for (k = 0, i = 0; i < sizeof(open_attrs_table)/sizeof(uint32); i++) {
-               cli_setatr(&cli1, fname, 0, 0);
-               cli_unlink(&cli1, fname);
-               fnum1 = cli_nt_create_full(&cli1, fname,FILE_WRITE_DATA, open_attrs_table[i],
-                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0);
+               cli_setatr(cli1, fname, 0, 0);
+               cli_unlink(cli1, fname);
+               fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_WRITE_DATA, open_attrs_table[i],
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 0, 0);
 
                if (fnum1 == -1) {
-                       printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(&cli1));
+                       printf("open %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
                        return False;
                }
 
-               if (!cli_close(&cli1, fnum1)) {
-                       printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(&cli1));
+               if (!cli_close(cli1, fnum1)) {
+                       printf("close %d (1) of %s failed (%s)\n", i, fname, cli_errstr(cli1));
                        return False;
                }
 
                for (j = 0; j < sizeof(open_attrs_table)/sizeof(uint32); j++) {
-                       fnum1 = cli_nt_create_full(&cli1, fname,FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
-                                          FILE_SHARE_NONE, FILE_OVERWRITE, 0);
+                       fnum1 = cli_nt_create_full(cli1, fname, 0, FILE_READ_DATA|FILE_WRITE_DATA, open_attrs_table[j],
+                                          FILE_SHARE_NONE, FILE_OVERWRITE, 0, 0);
 
                        if (fnum1 == -1) {
                                for (l = 0; l < sizeof(attr_results)/sizeof(struct trunc_open_results); l++) {
@@ -3653,14 +4366,14 @@ static BOOL run_openattrtest(int dummy)
                                                printf("[%d] trunc open 0x%x -> 0x%x of %s failed - should have succeeded !(0x%x:%s)\n",
                                                                k, open_attrs_table[i],
                                                                open_attrs_table[j],
-                                                               fname, NT_STATUS_V(cli_nt_error(&cli1)), cli_errstr(&cli1));
+                                                               fname, NT_STATUS_V(cli_nt_error(cli1)), cli_errstr(cli1));
                                                correct = False;
                                        }
                                }
-                               if (NT_STATUS_V(cli_nt_error(&cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
+                               if (NT_STATUS_V(cli_nt_error(cli1)) != NT_STATUS_V(NT_STATUS_ACCESS_DENIED)) {
                                        printf("[%d] trunc open 0x%x -> 0x%x failed with wrong error code %s\n",
                                                        k, open_attrs_table[i], open_attrs_table[j],
-                                                       cli_errstr(&cli1));
+                                                       cli_errstr(cli1));
                                        correct = False;
                                }
 #if 0
@@ -3670,13 +4383,13 @@ static BOOL run_openattrtest(int dummy)
                                continue;
                        }
 
-                       if (!cli_close(&cli1, fnum1)) {
-                               printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(&cli1));
+                       if (!cli_close(cli1, fnum1)) {
+                               printf("close %d (2) of %s failed (%s)\n", j, fname, cli_errstr(cli1));
                                return False;
                        }
 
-                       if (!cli_getatr(&cli1, fname, &attr, NULL, NULL)) {
-                               printf("getatr(2) failed (%s)\n", cli_errstr(&cli1));
+                       if (!cli_getatr(cli1, fname, &attr, NULL, NULL)) {
+                               printf("getatr(2) failed (%s)\n", cli_errstr(cli1));
                                return False;
                        }
 
@@ -3704,18 +4417,18 @@ static BOOL run_openattrtest(int dummy)
                }
        }
 
-       cli_setatr(&cli1, fname, 0, 0);
-       cli_unlink(&cli1, fname);
+       cli_setatr(cli1, fname, 0, 0);
+       cli_unlink(cli1, fname);
 
        printf("open attr test %s.\n", correct ? "passed" : "failed");
 
-       if (!torture_close_connection(&cli1)) {
+       if (!torture_close_connection(cli1)) {
                correct = False;
        }
        return correct;
 }
 
-static void list_fn(file_info *finfo, const char *name, void *state)
+static void list_fn(const char *mnt, file_info *finfo, const char *name, void *state)
 {
        
 }
@@ -3723,39 +4436,39 @@ static void list_fn(file_info *finfo, const char *name, void *state)
 /*
   test directory listing speed
  */
-static BOOL run_dirtest(int dummy)
+static bool run_dirtest(int dummy)
 {
        int i;
-       static struct cli_state cli;
+       static struct cli_state *cli;
        int fnum;
        double t1;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting directory test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
        srandom(0);
        for (i=0;i<torture_numops;i++) {
                fstring fname;
                slprintf(fname, sizeof(fname), "\\%x", (int)random());
-               fnum = cli_open(&cli, fname, O_RDWR|O_CREAT, DENY_NONE);
+               fnum = cli_open(cli, fname, O_RDWR|O_CREAT, DENY_NONE);
                if (fnum == -1) {
                        fprintf(stderr,"Failed to open %s\n", fname);
                        return False;
                }
-               cli_close(&cli, fnum);
+               cli_close(cli, fnum);
        }
 
        t1 = end_timer();
 
-       printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
-       printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
-       printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
+       printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
+       printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
+       printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
 
        printf("dirtest core %g seconds\n", end_timer() - t1);
 
@@ -3763,10 +4476,10 @@ static BOOL run_dirtest(int dummy)
        for (i=0;i<torture_numops;i++) {
                fstring fname;
                slprintf(fname, sizeof(fname), "\\%x", (int)random());
-               cli_unlink(&cli, fname);
+               cli_unlink(cli, fname);
        }
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -3775,7 +4488,7 @@ static BOOL run_dirtest(int dummy)
        return correct;
 }
 
-static void del_fn(file_info *finfo, const char *mask, void *state)
+static void del_fn(const char *mnt, file_info *finfo, const char *mask, void *state)
 {
        struct cli_state *pcli = (struct cli_state *)state;
        fstring fname;
@@ -3793,49 +4506,307 @@ static void del_fn(file_info *finfo, const char *mask, void *state)
        }
 }
 
-static BOOL run_dirtest1(int dummy)
+
+/*
+  sees what IOCTLs are supported
+ */
+bool torture_ioctl_test(int dummy)
+{
+       static struct cli_state *cli;
+       uint16 device, function;
+       int fnum;
+       const char *fname = "\\ioctl.dat";
+       DATA_BLOB blob;
+       NTSTATUS status;
+
+       if (!torture_open_connection(&cli, 0)) {
+               return False;
+       }
+
+       printf("starting ioctl test\n");
+
+       cli_unlink(cli, fname);
+
+       fnum = cli_open(cli, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       if (fnum == -1) {
+               printf("open of %s failed (%s)\n", fname, cli_errstr(cli));
+               return False;
+       }
+
+       status = cli_raw_ioctl(cli, fnum, 0x2d0000 | (0x0420<<2), &blob);
+       printf("ioctl device info: %s\n", cli_errstr(cli));
+
+       status = cli_raw_ioctl(cli, fnum, IOCTL_QUERY_JOB_INFO, &blob);
+       printf("ioctl job info: %s\n", cli_errstr(cli));
+
+       for (device=0;device<0x100;device++) {
+               printf("testing device=0x%x\n", device);
+               for (function=0;function<0x100;function++) {
+                       uint32 code = (device<<16) | function;
+
+                       status = cli_raw_ioctl(cli, fnum, code, &blob);
+
+                       if (NT_STATUS_IS_OK(status)) {
+                               printf("ioctl 0x%x OK : %d bytes\n", (int)code,
+                                      (int)blob.length);
+                               data_blob_free(&blob);
+                       }
+               }
+       }
+
+       if (!torture_close_connection(cli)) {
+               return False;
+       }
+
+       return True;
+}
+
+
+/*
+  tries varients of chkpath
+ */
+bool torture_chkpath_test(int dummy)
+{
+       static struct cli_state *cli;
+       int fnum;
+       bool ret;
+
+       if (!torture_open_connection(&cli, 0)) {
+               return False;
+       }
+
+       printf("starting chkpath test\n");
+
+       /* cleanup from an old run */
+       cli_rmdir(cli, "\\chkpath.dir\\dir2");
+       cli_unlink(cli, "\\chkpath.dir\\*");
+       cli_rmdir(cli, "\\chkpath.dir");
+
+       if (!cli_mkdir(cli, "\\chkpath.dir")) {
+               printf("mkdir1 failed : %s\n", cli_errstr(cli));
+               return False;
+       }
+
+       if (!cli_mkdir(cli, "\\chkpath.dir\\dir2")) {
+               printf("mkdir2 failed : %s\n", cli_errstr(cli));
+               return False;
+       }
+
+       fnum = cli_open(cli, "\\chkpath.dir\\foo.txt", O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       if (fnum == -1) {
+               printf("open1 failed (%s)\n", cli_errstr(cli));
+               return False;
+       }
+       cli_close(cli, fnum);
+
+       if (!cli_chkpath(cli, "\\chkpath.dir")) {
+               printf("chkpath1 failed: %s\n", cli_errstr(cli));
+               ret = False;
+       }
+
+       if (!cli_chkpath(cli, "\\chkpath.dir\\dir2")) {
+               printf("chkpath2 failed: %s\n", cli_errstr(cli));
+               ret = False;
+       }
+
+       if (!cli_chkpath(cli, "\\chkpath.dir\\foo.txt")) {
+               ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
+                                 NT_STATUS_NOT_A_DIRECTORY);
+       } else {
+               printf("* chkpath on a file should fail\n");
+               ret = False;
+       }
+
+       if (!cli_chkpath(cli, "\\chkpath.dir\\bar.txt")) {
+               ret = check_error(__LINE__, cli, ERRDOS, ERRbadfile, 
+                                 NT_STATUS_OBJECT_NAME_NOT_FOUND);
+       } else {
+               printf("* chkpath on a non existant file should fail\n");
+               ret = False;
+       }
+
+       if (!cli_chkpath(cli, "\\chkpath.dir\\dirxx\\bar.txt")) {
+               ret = check_error(__LINE__, cli, ERRDOS, ERRbadpath, 
+                                 NT_STATUS_OBJECT_PATH_NOT_FOUND);
+       } else {
+               printf("* chkpath on a non existent component should fail\n");
+               ret = False;
+       }
+
+       cli_rmdir(cli, "\\chkpath.dir\\dir2");
+       cli_unlink(cli, "\\chkpath.dir\\*");
+       cli_rmdir(cli, "\\chkpath.dir");
+
+       if (!torture_close_connection(cli)) {
+               return False;
+       }
+
+       return ret;
+}
+
+static bool run_eatest(int dummy)
+{
+       static struct cli_state *cli;
+       const char *fname = "\\eatest.txt";
+       bool correct = True;
+       int fnum, i;
+       size_t num_eas;
+       struct ea_struct *ea_list = NULL;
+       TALLOC_CTX *mem_ctx = talloc_init("eatest");
+
+       printf("starting eatest\n");
+       
+       if (!torture_open_connection(&cli, 0)) {
+               talloc_destroy(mem_ctx);
+               return False;
+       }
+       
+       cli_unlink(cli, fname);
+       fnum = cli_nt_create_full(cli, fname, 0,
+                                  FIRST_DESIRED_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
+                                  FILE_SHARE_NONE, FILE_OVERWRITE_IF, 
+                                  0x4044, 0);
+
+       if (fnum == -1) {
+               printf("open failed - %s\n", cli_errstr(cli));
+               talloc_destroy(mem_ctx);
+               return False;
+       }
+
+       for (i = 0; i < 10; i++) {
+               fstring ea_name, ea_val;
+
+               slprintf(ea_name, sizeof(ea_name), "EA_%d", i);
+               memset(ea_val, (char)i+1, i+1);
+               if (!cli_set_ea_fnum(cli, fnum, ea_name, ea_val, i+1)) {
+                       printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
+                       talloc_destroy(mem_ctx);
+                       return False;
+               }
+       }
+       
+       cli_close(cli, fnum);
+       for (i = 0; i < 10; i++) {
+               fstring ea_name, ea_val;
+
+               slprintf(ea_name, sizeof(ea_name), "EA_%d", i+10);
+               memset(ea_val, (char)i+1, i+1);
+               if (!cli_set_ea_path(cli, fname, ea_name, ea_val, i+1)) {
+                       printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
+                       talloc_destroy(mem_ctx);
+                       return False;
+               }
+       }
+       
+       if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
+               printf("ea_get list failed - %s\n", cli_errstr(cli));
+               correct = False;
+       }
+
+       printf("num_eas = %d\n", (int)num_eas);
+
+       if (num_eas != 20) {
+               printf("Should be 20 EA's stored... failing.\n");
+               correct = False;
+       }
+
+       for (i = 0; i < num_eas; i++) {
+               printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
+               dump_data(0, ea_list[i].value.data,
+                         ea_list[i].value.length);
+       }
+
+       /* Setting EA's to zero length deletes them. Test this */
+       printf("Now deleting all EA's - case indepenent....\n");
+
+#if 1
+       cli_set_ea_path(cli, fname, "", "", 0);
+#else
+       for (i = 0; i < 20; i++) {
+               fstring ea_name;
+               slprintf(ea_name, sizeof(ea_name), "ea_%d", i);
+               if (!cli_set_ea_path(cli, fname, ea_name, "", 0)) {
+                       printf("ea_set of name %s failed - %s\n", ea_name, cli_errstr(cli));
+                       talloc_destroy(mem_ctx);
+                       return False;
+               }
+       }
+#endif
+
+       if (!cli_get_ea_list_path(cli, fname, mem_ctx, &num_eas, &ea_list)) {
+               printf("ea_get list failed - %s\n", cli_errstr(cli));
+               correct = False;
+       }
+
+       printf("num_eas = %d\n", (int)num_eas);
+       for (i = 0; i < num_eas; i++) {
+               printf("%d: ea_name = %s. Val = ", i, ea_list[i].name);
+               dump_data(0, ea_list[i].value.data,
+                         ea_list[i].value.length);
+       }
+
+       if (num_eas != 0) {
+               printf("deleting EA's failed.\n");
+               correct = False;
+       }
+
+       /* Try and delete a non existant EA. */
+       if (!cli_set_ea_path(cli, fname, "foo", "", 0)) {
+               printf("deleting non-existant EA 'foo' should succeed. %s\n", cli_errstr(cli));
+               correct = False;
+       }
+
+       talloc_destroy(mem_ctx);
+       if (!torture_close_connection(cli)) {
+               correct = False;
+       }
+       
+       return correct;
+}
+
+static bool run_dirtest1(int dummy)
 {
        int i;
-       static struct cli_state cli;
+       static struct cli_state *cli;
        int fnum, num_seen;
-       BOOL correct = True;
+       bool correct = True;
 
        printf("starting directory test\n");
 
-       if (!torture_open_connection(&cli)) {
+       if (!torture_open_connection(&cli, 0)) {
                return False;
        }
 
-       cli_sockopt(&cli, sockops);
+       cli_sockopt(cli, sockops);
 
-       cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
-       cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
-       cli_rmdir(&cli, "\\LISTDIR");
-       cli_mkdir(&cli, "\\LISTDIR");
+       cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
+       cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
+       cli_rmdir(cli, "\\LISTDIR");
+       cli_mkdir(cli, "\\LISTDIR");
 
        /* Create 1000 files and 1000 directories. */
        for (i=0;i<1000;i++) {
                fstring fname;
                slprintf(fname, sizeof(fname), "\\LISTDIR\\f%d", i);
-               fnum = cli_nt_create_full(&cli, fname, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
-                                  FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0);
+               fnum = cli_nt_create_full(cli, fname, 0, GENERIC_ALL_ACCESS, FILE_ATTRIBUTE_ARCHIVE,
+                                  FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OVERWRITE_IF, 0, 0);
                if (fnum == -1) {
                        fprintf(stderr,"Failed to open %s\n", fname);
                        return False;
                }
-               cli_close(&cli, fnum);
+               cli_close(cli, fnum);
        }
        for (i=0;i<1000;i++) {
                fstring fname;
                slprintf(fname, sizeof(fname), "\\LISTDIR\\d%d", i);
-               if (!cli_mkdir(&cli, fname)) {
+               if (!cli_mkdir(cli, fname)) {
                        fprintf(stderr,"Failed to open %s\n", fname);
                        return False;
                }
        }
 
        /* Now ensure that doing an old list sees both files and directories. */
-       num_seen = cli_list_old(&cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
+       num_seen = cli_list_old(cli, "\\LISTDIR\\*", aDIR, list_fn, NULL);
        printf("num_seen = %d\n", num_seen );
        /* We should see 100 files + 1000 directories + . and .. */
        if (num_seen != 2002)
@@ -3844,28 +4815,28 @@ static BOOL run_dirtest1(int dummy)
        /* Ensure if we have the "must have" bits we only see the
         * relevent entries.
         */
-       num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
+       num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aDIR<<8)|aDIR, list_fn, NULL);
        printf("num_seen = %d\n", num_seen );
        if (num_seen != 1002)
                correct = False;
 
-       num_seen = cli_list_old(&cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
+       num_seen = cli_list_old(cli, "\\LISTDIR\\*", (aARCH<<8)|aDIR, list_fn, NULL);
        printf("num_seen = %d\n", num_seen );
        if (num_seen != 1000)
                correct = False;
 
        /* Delete everything. */
-       cli_list(&cli, "\\LISTDIR\\*", 0, del_fn, &cli);
-       cli_list(&cli, "\\LISTDIR\\*", aDIR, del_fn, &cli);
-       cli_rmdir(&cli, "\\LISTDIR");
+       cli_list(cli, "\\LISTDIR\\*", 0, del_fn, cli);
+       cli_list(cli, "\\LISTDIR\\*", aDIR, del_fn, cli);
+       cli_rmdir(cli, "\\LISTDIR");
 
 #if 0
-       printf("Matched %d\n", cli_list(&cli, "a*.*", 0, list_fn, NULL));
-       printf("Matched %d\n", cli_list(&cli, "b*.*", 0, list_fn, NULL));
-       printf("Matched %d\n", cli_list(&cli, "xyzabc", 0, list_fn, NULL));
+       printf("Matched %d\n", cli_list(cli, "a*.*", 0, list_fn, NULL));
+       printf("Matched %d\n", cli_list(cli, "b*.*", 0, list_fn, NULL));
+       printf("Matched %d\n", cli_list(cli, "xyzabc", 0, list_fn, NULL));
 #endif
 
-       if (!torture_close_connection(&cli)) {
+       if (!torture_close_connection(cli)) {
                correct = False;
        }
 
@@ -3874,10 +4845,11 @@ static BOOL run_dirtest1(int dummy)
        return correct;
 }
 
-static BOOL run_error_map_extract(int dummy) {
+static bool run_error_map_extract(int dummy) {
        
-       static struct cli_state c_dos;
-       static struct cli_state c_nt;
+       static struct cli_state *c_dos;
+       static struct cli_state *c_nt;
+       NTSTATUS status;
 
        uint32 error;
 
@@ -3890,81 +4862,86 @@ static BOOL run_error_map_extract(int dummy) {
 
        /* NT-Error connection */
 
-       if (!open_nbt_connection(&c_nt)) {
+       if (!(c_nt = open_nbt_connection())) {
                return False;
        }
 
-       c_nt.use_spnego = False;
+       c_nt->use_spnego = False;
 
-       if (!cli_negprot(&c_nt)) {
-               printf("%s rejected the NT-error negprot (%s)\n",host, cli_errstr(&c_nt));
-               cli_shutdown(&c_nt);
+       status = cli_negprot(c_nt);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("%s rejected the NT-error negprot (%s)\n", host,
+                      nt_errstr(status));
+               cli_shutdown(c_nt);
                return False;
        }
 
-       if (!cli_session_setup(&c_nt, "", "", 0, "", 0,
-                              workgroup)) {
-               printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(&c_nt));
+       if (!NT_STATUS_IS_OK(cli_session_setup(c_nt, "", "", 0, "", 0,
+                                              workgroup))) {
+               printf("%s rejected the NT-error initial session setup (%s)\n",host, cli_errstr(c_nt));
                return False;
        }
 
        /* DOS-Error connection */
 
-       if (!open_nbt_connection(&c_dos)) {
+       if (!(c_dos = open_nbt_connection())) {
                return False;
        }
 
-       c_dos.use_spnego = False;
-       c_dos.force_dos_errors = True;
+       c_dos->use_spnego = False;
+       c_dos->force_dos_errors = True;
 
-       if (!cli_negprot(&c_dos)) {
-               printf("%s rejected the DOS-error negprot (%s)\n",host, cli_errstr(&c_dos));
-               cli_shutdown(&c_dos);
+       status = cli_negprot(c_dos);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("%s rejected the DOS-error negprot (%s)\n", host,
+                      nt_errstr(status));
+               cli_shutdown(c_dos);
                return False;
        }
 
-       if (!cli_session_setup(&c_dos, "", "", 0, "", 0,
-                              workgroup)) {
-               printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(&c_dos));
+       if (!NT_STATUS_IS_OK(cli_session_setup(c_dos, "", "", 0, "", 0,
+                                              workgroup))) {
+               printf("%s rejected the DOS-error initial session setup (%s)\n",host, cli_errstr(c_dos));
                return False;
        }
 
        for (error=(0xc0000000 | 0x1); error < (0xc0000000| 0xFFF); error++) {
-               snprintf(user, sizeof(user), "%X", error);
+               fstr_sprintf(user, "%X", error);
 
-               if (cli_session_setup(&c_nt, user, 
-                                      password, strlen(password),
-                                      password, strlen(password),
-                                     workgroup)) {
+               if (NT_STATUS_IS_OK(cli_session_setup(c_nt, user, 
+                                                     password, strlen(password),
+                                                     password, strlen(password),
+                                                     workgroup))) {
                        printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
                }
                
-               flgs2 = SVAL(c_nt.inbuf,smb_flg2);
+               flgs2 = SVAL(c_nt->inbuf,smb_flg2);
                
                /* Case #1: 32-bit NT errors */
                if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
-                       nt_status = NT_STATUS(IVAL(c_nt.inbuf,smb_rcls));
+                       nt_status = NT_STATUS(IVAL(c_nt->inbuf,smb_rcls));
                } else {
                        printf("/** Dos error on NT connection! (%s) */\n", 
-                              cli_errstr(&c_nt));
+                              cli_errstr(c_nt));
                        nt_status = NT_STATUS(0xc0000000);
                }
 
-               if (cli_session_setup(&c_dos, user, 
-                                      password, strlen(password),
-                                      password, strlen(password),
-                                      workgroup)) {
+               if (NT_STATUS_IS_OK(cli_session_setup(c_dos, user, 
+                                                     password, strlen(password),
+                                                     password, strlen(password),
+                                                     workgroup))) {
                        printf("/** Session setup succeeded.  This shouldn't happen...*/\n");
                }
-               flgs2 = SVAL(c_dos.inbuf,smb_flg2), errnum;
+               flgs2 = SVAL(c_dos->inbuf,smb_flg2), errnum;
                
                /* Case #1: 32-bit NT errors */
                if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
                        printf("/** NT error on DOS connection! (%s) */\n", 
-                              cli_errstr(&c_nt));
+                              cli_errstr(c_nt));
                        errnum = errclass = 0;
                } else {
-                       cli_dos_error(&c_dos, &errclass, &errnum);
+                       cli_dos_error(c_dos, &errclass, &errnum);
                }
 
                if (NT_STATUS_V(nt_status) != error) { 
@@ -3981,13 +4958,732 @@ static BOOL run_error_map_extract(int dummy) {
        return True;
 }
 
-static double create_procs(BOOL (*fn)(int), BOOL *result)
+static bool run_sesssetup_bench(int dummy)
 {
-       int i, status;
-       volatile pid_t *child_status;
-       volatile BOOL *child_status_out;
-       int synccount;
-       int tries = 8;
+       static struct cli_state *c;
+       const char *fname = "\\file.dat";
+       int fnum;
+       NTSTATUS status;
+       int i;
+
+       if (!torture_open_connection(&c, 0)) {
+               return false;
+       }
+
+       fnum = cli_nt_create_full(
+               c, fname, 0, GENERIC_ALL_ACCESS|DELETE_ACCESS,
+               FILE_ATTRIBUTE_NORMAL, 0, FILE_OVERWRITE_IF,
+               FILE_DELETE_ON_CLOSE, 0);
+       if (fnum == -1) {
+               d_printf("open %s failed: %s\n", fname, cli_errstr(c));
+               return false;
+       }
+
+       for (i=0; i<torture_numops; i++) {
+               status = cli_session_setup(
+                       c, username,
+                       password, strlen(password),
+                       password, strlen(password),
+                       workgroup);
+               if (!NT_STATUS_IS_OK(status)) {
+                       d_printf("(%s) cli_session_setup failed: %s\n",
+                                __location__, nt_errstr(status));
+                       return false;
+               }
+
+               d_printf("\r%d   ", (int)c->vuid);
+
+               if (!cli_ulogoff(c)) {
+                       d_printf("(%s) cli_ulogoff failed: %s\n",
+                                __location__, cli_errstr(c));
+                       return false;
+               }
+               c->vuid = 0;
+       }
+
+       return true;
+}
+
+static bool subst_test(const char *str, const char *user, const char *domain,
+                      uid_t uid, gid_t gid, const char *expected)
+{
+       char *subst;
+       bool result = true;
+
+       subst = talloc_sub_specified(talloc_tos(), str, user, domain, uid, gid);
+
+       if (strcmp(subst, expected) != 0) {
+               printf("sub_specified(%s, %s, %s, %d, %d) returned [%s], expected "
+                      "[%s]\n", str, user, domain, (int)uid, (int)gid, subst,
+                      expected);
+               result = false;
+       }
+
+       TALLOC_FREE(subst);
+       return result;
+}
+
+static void chain1_open_completion(struct async_req *req)
+{
+       int fnum;
+       NTSTATUS status;
+
+       status = cli_open_recv(req, &fnum);
+       TALLOC_FREE(req);
+
+       d_printf("cli_open_recv returned %s: %d\n",
+                nt_errstr(status),
+                NT_STATUS_IS_OK(status) ? fnum : -1);
+}
+
+static void chain1_read_completion(struct async_req *req)
+{
+       NTSTATUS status;
+       ssize_t received;
+       uint8_t *rcvbuf;
+
+       status = cli_read_andx_recv(req, &received, &rcvbuf);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(req);
+               d_printf("cli_read_andx_recv returned %s\n",
+                        nt_errstr(status));
+               return;
+       }
+
+       d_printf("got %d bytes: %.*s\n", (int)received, (int)received,
+                (char *)rcvbuf);
+       TALLOC_FREE(req);
+}
+
+static void chain1_write_completion(struct async_req *req)
+{
+       NTSTATUS status;
+       size_t written;
+
+       status = cli_write_andx_recv(req, &written);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(req);
+               d_printf("cli_write_andx_recv returned %s\n",
+                        nt_errstr(status));
+               return;
+       }
+
+       d_printf("wrote %d bytes\n", (int)written);
+       TALLOC_FREE(req);
+}
+
+static void chain1_close_completion(struct async_req *req)
+{
+       NTSTATUS status;
+
+       status = cli_close_recv(req);
+       *((bool *)(req->async.priv)) = true;
+
+       TALLOC_FREE(req);
+
+       d_printf("cli_close returned %s\n", nt_errstr(status));
+}
+
+static bool run_chain1(int dummy)
+{
+       struct cli_state *cli1;
+       struct event_context *evt = event_context_init(NULL);
+       struct async_req *reqs[4];
+       bool done = false;
+       const char *text = "hallo";
+
+       printf("starting chain1 test\n");
+       if (!torture_open_connection(&cli1, 0)) {
+               return False;
+       }
+
+       cli_sockopt(cli1, sockops);
+
+       cli_chain_cork(cli1, evt, 0);
+       reqs[0] = cli_open_send(talloc_tos(), evt, cli1, "\\test",
+                               O_CREAT|O_RDWR, 0);
+       reqs[0]->async.fn = chain1_open_completion;
+       reqs[1] = cli_write_andx_send(talloc_tos(), evt, cli1, 0, 0,
+                                     (uint8_t *)text, 0, strlen(text));
+       reqs[1]->async.fn = chain1_write_completion;
+       reqs[2] = cli_read_andx_send(talloc_tos(), evt, cli1, 0, 1, 10);
+       reqs[2]->async.fn = chain1_read_completion;
+       reqs[3] = cli_close_send(talloc_tos(), evt, cli1, 0);
+       reqs[3]->async.fn = chain1_close_completion;
+       reqs[3]->async.priv = (void *)&done;
+       cli_chain_uncork(cli1);
+
+       while (!done) {
+               event_loop_once(evt);
+       }
+
+       torture_close_connection(cli1);
+       return True;
+}
+
+static size_t null_source(uint8_t *buf, size_t n, void *priv)
+{
+       size_t *to_pull = (size_t *)priv;
+       size_t thistime = *to_pull;
+
+       thistime = MIN(thistime, n);
+       if (thistime == 0) {
+               return 0;
+       }
+
+       memset(buf, 0, thistime);
+       *to_pull -= thistime;
+       return thistime;
+}
+
+static bool run_windows_write(int dummy)
+{
+       struct cli_state *cli1;
+       int fnum;
+       int i;
+       bool ret = false;
+       const char *fname = "\\writetest.txt";
+       double seconds;
+       double kbytes;
+
+       printf("starting windows_write test\n");
+       if (!torture_open_connection(&cli1, 0)) {
+               return False;
+       }
+
+       fnum = cli_open(cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE);
+       if (fnum == -1) {
+               printf("open failed (%s)\n", cli_errstr(cli1));
+               return False;
+       }
+
+       cli_sockopt(cli1, sockops);
+
+       start_timer();
+
+       for (i=0; i<torture_numops; i++) {
+               char c = 0;
+               off_t start = i * torture_blocksize;
+               NTSTATUS status;
+               size_t to_pull = torture_blocksize - 1;
+
+               if (cli_write(cli1, fnum, 0, &c,
+                             start + torture_blocksize - 1, 1) != 1) {
+                       printf("cli_write failed: %s\n", cli_errstr(cli1));
+                       goto fail;
+               }
+
+               status = cli_push(cli1, fnum, 0, i * torture_blocksize, torture_blocksize,
+                                 null_source, &to_pull);
+               if (!NT_STATUS_IS_OK(status)) {
+                       printf("cli_push returned: %s\n", nt_errstr(status));
+                       goto fail;
+               }
+       }
+
+       seconds = end_timer();
+       kbytes = (double)torture_blocksize * torture_numops;
+       kbytes /= 1024;
+
+       printf("Wrote %d kbytes in %.2f seconds: %d kb/sec\n", (int)kbytes,
+              (double)seconds, (int)(kbytes/seconds));
+
+       ret = true;
+ fail:
+       cli_close(cli1, fnum);
+       cli_unlink(cli1, fname);
+       torture_close_connection(cli1);
+       return ret;
+}
+
+static bool run_cli_echo(int dummy)
+{
+       struct cli_state *cli;
+       struct event_context *ev = event_context_init(NULL);
+       struct async_req *req;
+       NTSTATUS status;
+
+       printf("starting chain1 test\n");
+       if (!torture_open_connection(&cli, 0)) {
+               return false;
+       }
+       cli_sockopt(cli, sockops);
+
+       req = cli_echo_send(ev, ev, cli, 5, data_blob_const("hello", 5));
+       if (req == NULL) {
+               d_printf("cli_echo_send failed\n");
+               return false;
+       }
+
+       while (req->state < ASYNC_REQ_DONE) {
+               event_loop_once(ev);
+       }
+
+       status = cli_echo_recv(req);
+       d_printf("cli_echo returned %s\n", nt_errstr(status));
+
+       TALLOC_FREE(req);
+
+       torture_close_connection(cli);
+       return NT_STATUS_IS_OK(status);
+}
+
+static bool run_local_substitute(int dummy)
+{
+       bool ok = true;
+
+       ok &= subst_test("%U", "bla", "", -1, -1, "bla");
+       ok &= subst_test("%u%U", "bla", "", -1, -1, "blabla");
+       ok &= subst_test("%g", "", "", -1, -1, "NO_GROUP");
+       ok &= subst_test("%G", "", "", -1, -1, "NO_GROUP");
+       ok &= subst_test("%g", "", "", -1, 0, gidtoname(0));
+       ok &= subst_test("%G", "", "", -1, 0, gidtoname(0));
+       ok &= subst_test("%D%u", "u", "dom", -1, 0, "domu");
+       ok &= subst_test("%i %I", "", "", -1, -1, "0.0.0.0 0.0.0.0");
+
+       /* Different captialization rules in sub_basic... */
+
+       ok &=  (strcmp(talloc_sub_basic(talloc_tos(), "BLA", "dom", "%U%D"),
+                      "blaDOM") == 0);
+
+       return ok;
+}
+
+static bool run_local_gencache(int dummy)
+{
+       char *val;
+       time_t tm;
+       DATA_BLOB blob;
+
+       if (!gencache_init()) {
+               d_printf("%s: gencache_init() failed\n", __location__);
+               return False;
+       }
+
+       if (!gencache_set("foo", "bar", time(NULL) + 1000)) {
+               d_printf("%s: gencache_set() failed\n", __location__);
+               return False;
+       }
+
+       if (!gencache_get("foo", &val, &tm)) {
+               d_printf("%s: gencache_get() failed\n", __location__);
+               return False;
+       }
+
+       if (strcmp(val, "bar") != 0) {
+               d_printf("%s: gencache_get() returned %s, expected %s\n",
+                        __location__, val, "bar");
+               SAFE_FREE(val);
+               return False;
+       }
+
+       SAFE_FREE(val);
+
+       if (!gencache_del("foo")) {
+               d_printf("%s: gencache_del() failed\n", __location__);
+               return False;
+       }
+       if (gencache_del("foo")) {
+               d_printf("%s: second gencache_del() succeeded\n",
+                        __location__);
+               return False;
+       }
+                       
+       if (gencache_get("foo", &val, &tm)) {
+               d_printf("%s: gencache_get() on deleted entry "
+                        "succeeded\n", __location__);
+               return False;
+       }
+
+       blob = data_blob_string_const_null("bar");
+       tm = time(NULL);
+
+       if (!gencache_set_data_blob("foo", &blob, tm)) {
+               d_printf("%s: gencache_set_data_blob() failed\n", __location__);
+               return False;
+       }
+
+       data_blob_free(&blob);
+
+       if (!gencache_get_data_blob("foo", &blob, NULL)) {
+               d_printf("%s: gencache_get_data_blob() failed\n", __location__);
+               return False;
+       }
+
+       if (strcmp((const char *)blob.data, "bar") != 0) {
+               d_printf("%s: gencache_get_data_blob() returned %s, expected %s\n",
+                        __location__, (const char *)blob.data, "bar");
+               data_blob_free(&blob);
+               return False;
+       }
+
+       data_blob_free(&blob);
+
+       if (!gencache_del("foo")) {
+               d_printf("%s: gencache_del() failed\n", __location__);
+               return False;
+       }
+       if (gencache_del("foo")) {
+               d_printf("%s: second gencache_del() succeeded\n",
+                        __location__);
+               return False;
+       }
+
+       if (gencache_get_data_blob("foo", &blob, NULL)) {
+               d_printf("%s: gencache_get_data_blob() on deleted entry "
+                        "succeeded\n", __location__);
+               return False;
+       }
+
+       if (!gencache_shutdown()) {
+               d_printf("%s: gencache_shutdown() failed\n", __location__);
+               return False;
+       }
+
+       if (gencache_shutdown()) {
+               d_printf("%s: second gencache_shutdown() succeeded\n",
+                        __location__);
+               return False;
+       }
+
+       return True;
+}
+
+static bool rbt_testval(struct db_context *db, const char *key,
+                       const char *value)
+{
+       struct db_record *rec;
+       TDB_DATA data = string_tdb_data(value);
+       bool ret = false;
+       NTSTATUS status;
+
+       rec = db->fetch_locked(db, db, string_tdb_data(key));
+       if (rec == NULL) {
+               d_fprintf(stderr, "fetch_locked failed\n");
+               goto done;
+       }
+       status = rec->store(rec, data, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               d_fprintf(stderr, "store failed: %s\n", nt_errstr(status));
+               goto done;
+       }
+       TALLOC_FREE(rec);
+
+       rec = db->fetch_locked(db, db, string_tdb_data(key));
+       if (rec == NULL) {
+               d_fprintf(stderr, "second fetch_locked failed\n");
+               goto done;
+       }
+       if ((rec->value.dsize != data.dsize)
+           || (memcmp(rec->value.dptr, data.dptr, data.dsize) != 0)) {
+               d_fprintf(stderr, "Got wrong data back\n");
+               goto done;
+       }
+
+       ret = true;
+ done:
+       TALLOC_FREE(rec);
+       return ret;
+}
+
+static bool run_local_rbtree(int dummy)
+{
+       struct db_context *db;
+       bool ret = false;
+       int i;
+
+       db = db_open_rbt(NULL);
+
+       if (db == NULL) {
+               d_fprintf(stderr, "db_open_rbt failed\n");
+               return false;
+       }
+
+       for (i=0; i<1000; i++) {
+               char *key, *value;
+
+               if (asprintf(&key, "key%ld", random()) == -1) {
+                       goto done;
+               }
+               if (asprintf(&value, "value%ld", random()) == -1) {
+                       SAFE_FREE(key);
+                       goto done;
+               }
+
+               if (!rbt_testval(db, key, value)) {
+                       SAFE_FREE(key);
+                       SAFE_FREE(value);
+                       goto done;
+               }
+
+               SAFE_FREE(value);
+               if (asprintf(&value, "value%ld", random()) == -1) {
+                       SAFE_FREE(key);
+                       goto done;
+               }
+
+               if (!rbt_testval(db, key, value)) {
+                       SAFE_FREE(key);
+                       SAFE_FREE(value);
+                       goto done;
+               }
+
+               SAFE_FREE(key);
+               SAFE_FREE(value);
+       }
+
+       ret = true;
+
+ done:
+       TALLOC_FREE(db);
+       return ret;
+}
+
+static bool test_stream_name(const char *fname, const char *expected_base,
+                            const char *expected_stream,
+                            NTSTATUS expected_status)
+{
+       NTSTATUS status;
+       char *base = NULL;
+       char *stream = NULL;
+
+       status = split_ntfs_stream_name(talloc_tos(), fname, &base, &stream);
+       if (!NT_STATUS_EQUAL(status, expected_status)) {
+               goto error;
+       }
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return true;
+       }
+
+       if (base == NULL) goto error;
+
+       if (strcmp(expected_base, base) != 0) goto error;
+
+       if ((expected_stream != NULL) && (stream == NULL)) goto error;
+       if ((expected_stream == NULL) && (stream != NULL)) goto error;
+
+       if ((stream != NULL) && (strcmp(expected_stream, stream) != 0))
+               goto error;
+
+       TALLOC_FREE(base);
+       TALLOC_FREE(stream);
+       return true;
+
+ error:
+       d_fprintf(stderr, "test_stream(%s, %s, %s, %s)\n",
+                 fname, expected_base ? expected_base : "<NULL>",
+                 expected_stream ? expected_stream : "<NULL>",
+                 nt_errstr(expected_status));
+       d_fprintf(stderr, "-> base=%s, stream=%s, status=%s\n",
+                 base ? base : "<NULL>", stream ? stream : "<NULL>",
+                 nt_errstr(status));
+       TALLOC_FREE(base);
+       TALLOC_FREE(stream);
+       return false;
+}
+
+static bool run_local_stream_name(int dummy)
+{
+       bool ret = true;
+
+       ret &= test_stream_name(
+               "bla", "bla", NULL, NT_STATUS_OK);
+       ret &= test_stream_name(
+               "bla::$DATA", "bla", NULL, NT_STATUS_OK);
+       ret &= test_stream_name(
+               "bla:blub:", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_stream_name(
+               "bla::", NULL, NULL, NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_stream_name(
+               "bla::123", "bla", NULL, NT_STATUS_OBJECT_NAME_INVALID);
+       ret &= test_stream_name(
+               "bla:$DATA", "bla", "$DATA:$DATA", NT_STATUS_OK);
+       ret &= test_stream_name(
+               "bla:x:$DATA", "bla", "x:$DATA", NT_STATUS_OK);
+       ret &= test_stream_name(
+               "bla:x", "bla", "x:$DATA", NT_STATUS_OK);
+
+       return ret;
+}
+
+static bool data_blob_equal(DATA_BLOB a, DATA_BLOB b)
+{
+       if (a.length != b.length) {
+               printf("a.length=%d != b.length=%d\n",
+                      (int)a.length, (int)b.length);
+               return false;
+       }
+       if (memcmp(a.data, b.data, a.length) != 0) {
+               printf("a.data and b.data differ\n");
+               return false;
+       }
+       return true;
+}
+
+static bool run_local_memcache(int dummy)
+{
+       struct memcache *cache;
+       DATA_BLOB k1, k2;
+       DATA_BLOB d1, d2, d3;
+       DATA_BLOB v1, v2, v3;
+
+       TALLOC_CTX *mem_ctx;
+       char *str1, *str2;
+       size_t size1, size2;
+       bool ret = false;
+
+       cache = memcache_init(NULL, 100);
+
+       if (cache == NULL) {
+               printf("memcache_init failed\n");
+               return false;
+       }
+
+       d1 = data_blob_const("d1", 2);
+       d2 = data_blob_const("d2", 2);
+       d3 = data_blob_const("d3", 2);
+
+       k1 = data_blob_const("d1", 2);
+       k2 = data_blob_const("d2", 2);
+
+       memcache_add(cache, STAT_CACHE, k1, d1);
+       memcache_add(cache, GETWD_CACHE, k2, d2);
+
+       if (!memcache_lookup(cache, STAT_CACHE, k1, &v1)) {
+               printf("could not find k1\n");
+               return false;
+       }
+       if (!data_blob_equal(d1, v1)) {
+               return false;
+       }
+
+       if (!memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
+               printf("could not find k2\n");
+               return false;
+       }
+       if (!data_blob_equal(d2, v2)) {
+               return false;
+       }
+
+       memcache_add(cache, STAT_CACHE, k1, d3);
+
+       if (!memcache_lookup(cache, STAT_CACHE, k1, &v3)) {
+               printf("could not find replaced k1\n");
+               return false;
+       }
+       if (!data_blob_equal(d3, v3)) {
+               return false;
+       }
+
+       memcache_add(cache, GETWD_CACHE, k1, d1);
+
+       if (memcache_lookup(cache, GETWD_CACHE, k2, &v2)) {
+               printf("Did find k2, should have been purged\n");
+               return false;
+       }
+
+       TALLOC_FREE(cache);
+
+       cache = memcache_init(NULL, 0);
+
+       mem_ctx = talloc_init("foo");
+
+       str1 = talloc_strdup(mem_ctx, "string1");
+       str2 = talloc_strdup(mem_ctx, "string2");
+
+       memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
+                           data_blob_string_const("torture"), &str1);
+       size1 = talloc_total_size(cache);
+
+       memcache_add_talloc(cache, SINGLETON_CACHE_TALLOC,
+                           data_blob_string_const("torture"), &str2);
+       size2 = talloc_total_size(cache);
+
+       printf("size1=%d, size2=%d\n", (int)size1, (int)size2);
+
+       if (size2 > size1) {
+               printf("memcache leaks memory!\n");
+               goto fail;
+       }
+
+       ret = true;
+ fail:
+       TALLOC_FREE(cache);
+       return ret;
+}
+
+static void wbclient_done(struct async_req *req)
+{
+       wbcErr wbc_err;
+       struct winbindd_response *wb_resp;
+       int *i = (int *)req->async.priv;
+
+       wbc_err = wb_trans_recv(req, req, &wb_resp);
+       TALLOC_FREE(req);
+       *i += 1;
+       d_printf("wb_trans_recv %d returned %s\n", *i, wbcErrorString(wbc_err));
+}
+
+static bool run_local_wbclient(int dummy)
+{
+       struct event_context *ev;
+       struct wb_context **wb_ctx;
+       struct winbindd_request wb_req;
+       bool result = false;
+       int i, j;
+
+       BlockSignals(True, SIGPIPE);
+
+       ev = event_context_init(talloc_tos());
+       if (ev == NULL) {
+               goto fail;
+       }
+
+       wb_ctx = TALLOC_ARRAY(ev, struct wb_context *, torture_numops);
+       if (wb_ctx == NULL) {
+               goto fail;
+       }
+
+       ZERO_STRUCT(wb_req);
+       wb_req.cmd = WINBINDD_PING;
+
+       for (i=0; i<torture_numops; i++) {
+               wb_ctx[i] = wb_context_init(ev);
+               if (wb_ctx[i] == NULL) {
+                       goto fail;
+               }
+               for (j=0; j<5; j++) {
+                       struct async_req *req;
+                       req = wb_trans_send(ev, ev, wb_ctx[i],
+                                           (j % 2) == 0, &wb_req);
+                       if (req == NULL) {
+                               goto fail;
+                       }
+                       req->async.fn = wbclient_done;
+                       req->async.priv = &i;
+               }
+       }
+
+       i = 0;
+
+       while (i < 5 * torture_numops) {
+               event_loop_once(ev);
+       }
+
+       result = true;
+ fail:
+       TALLOC_FREE(ev);
+       return result;
+}
+
+static double create_procs(bool (*fn)(int), bool *result)
+{
+       int i, status;
+       volatile pid_t *child_status;
+       volatile bool *child_status_out;
+       int synccount;
+       int tries = 8;
 
        synccount = 0;
 
@@ -3997,7 +5693,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                return -1;
        }
 
-       child_status_out = (volatile BOOL *)shm_setup(sizeof(BOOL)*nprocs);
+       child_status_out = (volatile bool *)shm_setup(sizeof(bool)*nprocs);
        if (!child_status_out) {
                printf("Failed to setup result status shared memory\n");
                return -1;
@@ -4019,18 +5715,17 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                        slprintf(myname,sizeof(myname),"CLIENT%d", i);
 
                        while (1) {
-                               memset(&current_cli, 0, sizeof(current_cli));
-                               if (torture_open_connection(&current_cli)) break;
+                               if (torture_open_connection(&current_cli, i)) break;
                                if (tries-- == 0) {
                                        printf("pid %d failed to start\n", (int)getpid());
                                        _exit(1);
                                }
-                               msleep(10);     
+                               smb_msleep(10); 
                        }
 
                        child_status[i] = getpid();
 
-                       while (child_status[i] && end_timer() < 5) msleep(2);
+                       while (child_status[i] && end_timer() < 5) smb_msleep(2);
 
                        child_status_out[i] = fn(i);
                        _exit(0);
@@ -4043,7 +5738,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
                        if (child_status[i]) synccount++;
                }
                if (synccount == nprocs) break;
-               msleep(10);
+               smb_msleep(10);
        } while (end_timer() < 30);
 
        if (synccount != nprocs) {
@@ -4079,7 +5774,7 @@ static double create_procs(BOOL (*fn)(int), BOOL *result)
 
 static struct {
        const char *name;
-       BOOL (*fn)(int);
+       bool (*fn)(int);
        unsigned flags;
 } torture_ops[] = {
        {"FDPASS", run_fdpasstest, 0},
@@ -4107,10 +5802,12 @@ static struct {
        {"DENY1",  torture_denytest1, 0},
        {"DENY2",  torture_denytest2, 0},
        {"TCON",  run_tcon_test, 0},
+       {"TCONDEV",  run_tcon_devtype_test, 0},
        {"RW1",  run_readwritetest, 0},
        {"RW2",  run_readwritemulti, FLAG_MULTIPROC},
        {"RW3",  run_readwritelarge, 0},
        {"OPEN", run_opentest, 0},
+       {"POSIX", run_simple_posix_open_test, 0},
 #if 1
        {"OPENATTR", run_openattrtest, 0},
 #endif
@@ -4126,6 +5823,21 @@ static struct {
        {"CASETABLE", torture_casetable, 0},
        {"ERRMAPEXTRACT", run_error_map_extract, 0},
        {"PIPE_NUMBER", run_pipe_number, 0},
+       {"TCON2",  run_tcon2_test, 0},
+       {"IOCTL",  torture_ioctl_test, 0},
+       {"CHKPATH",  torture_chkpath_test, 0},
+       {"FDSESS", run_fdsesstest, 0},
+       { "EATEST", run_eatest, 0},
+       { "SESSSETUP_BENCH", run_sesssetup_bench, 0},
+       { "CHAIN1", run_chain1, 0},
+       { "WINDOWS-WRITE", run_windows_write, 0},
+       { "CLI_ECHO", run_cli_echo, 0},
+       { "LOCAL-SUBSTITUTE", run_local_substitute, 0},
+       { "LOCAL-GENCACHE", run_local_gencache, 0},
+       { "LOCAL-RBTREE", run_local_rbtree, 0},
+       { "LOCAL-MEMCACHE", run_local_memcache, 0},
+       { "LOCAL-STREAM-NAME", run_local_stream_name, 0},
+       { "LOCAL-WBCLIENT", run_local_wbclient, 0},
        {NULL, NULL, 0}};
 
 
@@ -4133,23 +5845,26 @@ static struct {
 /****************************************************************************
 run a specified test or "ALL"
 ****************************************************************************/
-static BOOL run_test(const char *name)
+static bool run_test(const char *name)
 {
-       BOOL ret = True;
-       BOOL result = True;
+       bool ret = True;
+       bool result = True;
+       bool found = False;
        int i;
        double t;
        if (strequal(name,"ALL")) {
                for (i=0;torture_ops[i].name;i++) {
                        run_test(torture_ops[i].name);
                }
+               found = True;
        }
        
        for (i=0;torture_ops[i].name;i++) {
-               snprintf(randomfname, sizeof(randomfname), "\\XX%x", 
+               fstr_sprintf(randomfname, "\\XX%x", 
                         (unsigned)random());
 
                if (strequal(name, torture_ops[i].name)) {
+                       found = True;
                        printf("Running %s\n", name);
                        if (torture_ops[i].flags & FLAG_MULTIPROC) {
                                t = create_procs(torture_ops[i].fn, &result);
@@ -4169,6 +5884,12 @@ static BOOL run_test(const char *name)
                        printf("%s took %g secs\n\n", name, t);
                }
        }
+
+       if (!found) {
+               printf("Did not find a test named %s\n", name);
+               ret = False;
+       }
+
        return ret;
 }
 
@@ -4177,6 +5898,9 @@ static void usage(void)
 {
        int i;
 
+       printf("WARNING samba4 test suite is much more complete nowadays.\n");
+       printf("Please use samba4 torture.\n\n");
+
        printf("Usage: smbtorture //server/share <options> TEST1 TEST2 ...\n");
 
        printf("\t-d debuglevel\n");
@@ -4191,7 +5915,9 @@ static void usage(void)
        printf("\t-L use oplocks\n");
        printf("\t-c CLIENT.TXT   specify client load file for NBENCH\n");
        printf("\t-A showall\n");
+       printf("\t-p port\n");
        printf("\t-s seed\n");
+       printf("\t-b unclist_filename   specify multiple shares for multiple connections\n");
        printf("\n\n");
 
        printf("tests are:");
@@ -4205,10 +5931,6 @@ static void usage(void)
        exit(1);
 }
 
-
-
-
-
 /****************************************************************************
   main program
 ****************************************************************************/
@@ -4218,9 +5940,9 @@ static void usage(void)
        char *p;
        int gotuser = 0;
        int gotpass = 0;
-       extern char *optarg;
-       extern int optind;
-       BOOL correct = True;
+       bool correct = True;
+       TALLOC_CTX *frame = talloc_stackframe();
+       int seed = time(NULL);
 
        dbf = x_stdout;
 
@@ -4228,7 +5950,14 @@ static void usage(void)
        setbuffer(stdout, NULL, 0);
 #endif
 
-       lp_load(dyn_CONFIGFILE,True,False,False);
+       load_case_tables();
+
+       if (is_default_dyn_CONFIGFILE()) {
+               if(getenv("SMB_CONF_PATH")) {
+                       set_dyn_CONFIGFILE(getenv("SMB_CONF_PATH"));
+               }
+       }
+       lp_load(get_dyn_CONFIGFILE(),True,False,False,True);
        load_interfaces();
 
        if (argc < 2) {
@@ -4251,7 +5980,11 @@ static void usage(void)
        *p = 0;
        fstrcpy(share, p+1);
 
-       get_myname(myname);
+       fstrcpy(myname, get_myname(talloc_tos()));
+       if (!*myname) {
+               fprintf(stderr, "Failed to get my hostname.\n");
+               return 1;
+       }
 
        if (*username == 0 && getenv("LOGNAME")) {
          fstrcpy(username,getenv("LOGNAME"));
@@ -4260,14 +5993,15 @@ static void usage(void)
        argc--;
        argv++;
 
-       srandom(time(NULL));
-
        fstrcpy(workgroup, lp_workgroup());
 
-       while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:Ld:Ac:ks:")) != EOF) {
+       while ((opt = getopt(argc, argv, "p:hW:U:n:N:O:o:m:Ld:Aec:ks:b:B:")) != EOF) {
                switch (opt) {
+               case 'p':
+                       port_to_use = atoi(optarg);
+                       break;
                case 's':
-                       srandom(atoi(optarg));
+                       seed = atoi(optarg);
                        break;
                case 'W':
                        fstrcpy(workgroup,optarg);
@@ -4299,6 +6033,9 @@ static void usage(void)
                case 'c':
                        client_txt = optarg;
                        break;
+               case 'e':
+                       do_encrypt = true;
+                       break;
                case 'k':
 #ifdef HAVE_KRB5
                        use_kerberos = True;
@@ -4317,12 +6054,23 @@ static void usage(void)
                                gotpass = 1;
                        }
                        break;
+               case 'b':
+                       fstrcpy(multishare_conn_fname, optarg);
+                       use_multishare_conn = True;
+                       break;
+               case 'B':
+                       torture_blocksize = atoi(optarg);
+                       break;
                default:
                        printf("Unknown option %c (%d)\n", (char)opt, opt);
                        usage();
                }
        }
 
+       d_printf("using seed %d\n", seed);
+
+       srandom(seed);
+
        if(use_kerberos && !gotuser) gotpass = True;
 
        while (!gotpass) {
@@ -4336,16 +6084,18 @@ static void usage(void)
        printf("host=%s share=%s user=%s myname=%s\n", 
               host, share, username, myname);
 
-       if (argc == 1) {
+       if (argc == optind) {
                correct = run_test("ALL");
        } else {
-               for (i=1;i<argc;i++) {
+               for (i=optind;i<argc;i++) {
                        if (!run_test(argv[i])) {
                                correct = False;
                        }
                }
        }
 
+       TALLOC_FREE(frame);
+
        if (correct) {
                return(0);
        } else {