Fix RAW-OPEN against Samba3
[kai/samba.git] / source / torture / raw / open.c
index 94b28f6379265cc6ec0cc8d98051c01898c58542..b6979fa0d9868d6320abbe6c34ab00b11902e5a5 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/>.
 */
 
 #include "includes.h"
 #include "torture/torture.h"
 #include "libcli/raw/libcliraw.h"
+#include "libcli/raw/raw_proto.h"
 #include "system/time.h"
 #include "system/filesys.h"
 #include "librpc/gen_ndr/security.h"
 #include "lib/events/events.h"
 #include "libcli/libcli.h"
+#include "torture/util.h"
+#include "auth/credentials/credentials.h"
+#include "lib/cmdline/popt_common.h"
+#include "param/param.h"
 
 /* enum for whether reads/writes are possible on a file */
 enum rdwr_mode {RDWR_NONE, RDWR_RDONLY, RDWR_WRONLY, RDWR_RDWR};
@@ -38,8 +42,8 @@ enum rdwr_mode {RDWR_NONE, RDWR_RDONLY, RDWR_WRONLY, RDWR_RDWR};
 static enum rdwr_mode check_rdwr(struct smbcli_tree *tree, int fnum)
 {
        uint8_t c = 1;
-       BOOL can_read  = (smbcli_read(tree, fnum, &c, 0, 1) == 1);
-       BOOL can_write = (smbcli_write(tree, fnum, 0, &c, 0, 1) == 1);
+       bool can_read  = (smbcli_read(tree, fnum, &c, 0, 1) == 1);
+       bool can_write = (smbcli_write(tree, fnum, 0, &c, 0, 1) == 1);
        if ( can_read &&  can_write) return RDWR_RDWR;
        if ( can_read && !can_write) return RDWR_RDONLY;
        if (!can_read &&  can_write) return RDWR_WRONLY;
@@ -64,15 +68,15 @@ static const char *rdwr_string(enum rdwr_mode m)
        if (!NT_STATUS_EQUAL(status, correct)) { \
                printf("(%s) Incorrect status %s - should be %s\n", \
                       __location__, nt_errstr(status), nt_errstr(correct)); \
-               ret = False; \
+               ret = false; \
                goto done; \
        }} while (0)
 
 #define CREATE_FILE do { \
-       fnum = create_complex_file(cli, mem_ctx, fname); \
+       fnum = create_complex_file(cli, tctx, fname); \
        if (fnum == -1) { \
                printf("(%s) Failed to create %s - %s\n", __location__, fname, smbcli_errstr(cli->tree)); \
-               ret = False; \
+               ret = false; \
                goto done; \
        }} while (0)
 
@@ -81,59 +85,59 @@ static const char *rdwr_string(enum rdwr_mode m)
        if (m != correct) { \
                printf("(%s) Incorrect readwrite mode %s - expected %s\n", \
                       __location__, rdwr_string(m), rdwr_string(correct)); \
-               ret = False; \
+               ret = false; \
        }} while (0)
 
 #define CHECK_TIME(t, field) do { \
        time_t t1, t2; \
        finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
        finfo.all_info.in.file.path = fname; \
-       status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
+       status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
        CHECK_STATUS(status, NT_STATUS_OK); \
        t1 = t & ~1; \
        t2 = nt_time_to_unix(finfo.all_info.out.field) & ~1; \
-       if (ABS(t1-t2) > 2) { \
+       if (abs(t1-t2) > 2) { \
                printf("(%s) wrong time for field %s  %s - %s\n", \
                       __location__, #field, \
-                      timestring(mem_ctx, t1), \
-                      timestring(mem_ctx, t2)); \
-               dump_all_info(mem_ctx, &finfo); \
-               ret = False; \
+                      timestring(tctx, t1), \
+                      timestring(tctx, t2)); \
+               dump_all_info(tctx, &finfo); \
+               ret = false; \
        }} while (0)
 
 #define CHECK_NTTIME(t, field) do { \
        NTTIME t2; \
        finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
        finfo.all_info.in.file.path = fname; \
-       status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
+       status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
        CHECK_STATUS(status, NT_STATUS_OK); \
        t2 = finfo.all_info.out.field; \
        if (t != t2) { \
                printf("(%s) wrong time for field %s  %s - %s\n", \
                       __location__, #field, \
-                      nt_time_string(mem_ctx, t), \
-                      nt_time_string(mem_ctx, t2)); \
-               dump_all_info(mem_ctx, &finfo); \
-               ret = False; \
+                      nt_time_string(tctx, t), \
+                      nt_time_string(tctx, t2)); \
+               dump_all_info(tctx, &finfo); \
+               ret = false; \
        }} while (0)
 
 #define CHECK_ALL_INFO(v, field) do { \
        finfo.all_info.level = RAW_FILEINFO_ALL_INFO; \
        finfo.all_info.in.file.path = fname; \
-       status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo); \
+       status = smb_raw_pathinfo(cli->tree, tctx, &finfo); \
        CHECK_STATUS(status, NT_STATUS_OK); \
        if ((v) != (finfo.all_info.out.field)) { \
                printf("(%s) wrong value for field %s  0x%x - 0x%x\n", \
                       __location__, #field, (int)v, (int)(finfo.all_info.out.field)); \
-               dump_all_info(mem_ctx, &finfo); \
-               ret = False; \
+               dump_all_info(tctx, &finfo); \
+               ret = false; \
        }} while (0)
 
 #define CHECK_VAL(v, correct) do { \
        if ((v) != (correct)) { \
                printf("(%s) wrong value for %s  0x%x - should be 0x%x\n", \
                       __location__, #v, (int)(v), (int)correct); \
-               ret = False; \
+               ret = false; \
        }} while (0)
 
 #define SET_ATTRIB(sattrib) do { \
@@ -151,14 +155,14 @@ static const char *rdwr_string(enum rdwr_mode m)
 /*
   test RAW_OPEN_OPEN
 */
-static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_open(struct smbcli_state *cli, struct torture_context *tctx)
 {
        union smb_open io;
        union smb_fileinfo finfo;
        const char *fname = BASEDIR "\\torture_open.txt";
        NTSTATUS status;
        int fnum = -1, fnum2;
-       BOOL ret = True;
+       bool ret = true;
 
        printf("Checking RAW_OPEN_OPEN\n");
 
@@ -166,7 +170,7 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openold.in.fname = fname;
        io.openold.in.open_mode = OPEN_FLAGS_FCB;
        io.openold.in.search_attrs = 0;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
        fnum = io.openold.out.file.fnum;
 
@@ -174,12 +178,12 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CREATE_FILE;
        smbcli_close(cli->tree, fnum);
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.file.fnum;
        CHECK_RDWR(fnum, RDWR_RDWR);
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum2 = io.openold.out.file.fnum;
        CHECK_RDWR(fnum2, RDWR_RDWR);
@@ -192,21 +196,21 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openold.in.search_attrs = 0;
 
        io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.file.fnum;
        CHECK_RDWR(fnum, RDWR_RDONLY);
        smbcli_close(cli->tree, fnum);
 
        io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.file.fnum;
        CHECK_RDWR(fnum, RDWR_WRONLY);
        smbcli_close(cli->tree, fnum);
 
        io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.file.fnum;
        CHECK_RDWR(fnum, RDWR_RDWR);
@@ -214,7 +218,7 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* check the share modes roughly - not a complete matrix */
        io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.file.fnum;
        CHECK_RDWR(fnum, RDWR_RDWR);
@@ -225,11 +229,11 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        }
 
        io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
 
        io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum2 = io.openold.out.file.fnum;
        CHECK_RDWR(fnum2, RDWR_RDONLY);
@@ -242,7 +246,7 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openold.in.fname = fname;
        io.openold.in.search_attrs = 0;
        io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.file.fnum;
 
@@ -262,7 +266,7 @@ done:
 /*
   test RAW_OPEN_OPENX
 */
-static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_openx(struct smbcli_state *cli, struct torture_context *tctx)
 {
        union smb_open io;
        union smb_fileinfo finfo;
@@ -270,26 +274,26 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        const char *fname_exe = BASEDIR "\\torture_openx.exe";
        NTSTATUS status;
        int fnum = -1, fnum2;
-       BOOL ret = True;
+       bool ret = true;
        int i;
        struct timeval tv;
        struct {
                uint16_t open_func;
-               BOOL with_file;
+               bool with_file;
                NTSTATUS correct_status;
        } open_funcs[] = {
-               { OPENX_OPEN_FUNC_OPEN,                           True,  NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_OPEN,                           False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
-               { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, True,  NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_FAIL,                           True,  NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
-               { OPENX_OPEN_FUNC_FAIL,                           False, NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
-               { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, True,  NT_STATUS_OBJECT_NAME_COLLISION },
-               { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_TRUNC,                          True,  NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_TRUNC,                          False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
-               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, True,  NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_OPEN,                           true,  NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_OPEN,                           false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+               { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_FAIL,                           true,  NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
+               { OPENX_OPEN_FUNC_FAIL,                           false, NT_STATUS_DOS(ERRDOS, ERRbadaccess) },
+               { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OBJECT_NAME_COLLISION },
+               { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_TRUNC,                          true,  NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_TRUNC,                          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
        };
 
        printf("Checking RAW_OPEN_OPENX\n");
@@ -308,21 +312,21 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        /* check all combinations of open_func */
        for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
                if (open_funcs[i].with_file) {
-                       fnum = create_complex_file(cli, mem_ctx, fname);
+                       fnum = create_complex_file(cli, tctx, fname);
                        if (fnum == -1) {
                                d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
-                               ret = False;
+                               ret = false;
                                goto done;
                        }
                        smbcli_close(cli->tree, fnum);
                }
                io.openx.in.open_func = open_funcs[i].open_func;
-               status = smb_raw_open(cli->tree, mem_ctx, &io);
+               status = smb_raw_open(cli->tree, tctx, &io);
                if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
                        printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_func=0x%x)\n", 
                               __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
                               i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_func);
-                       ret = False;
+                       ret = false;
                }
                if (NT_STATUS_IS_OK(status)) {
                        smbcli_close(cli->tree, io.openx.out.file.fnum);
@@ -336,7 +340,7 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* check the basic return fields */
        io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openx.out.file.fnum;
 
@@ -353,15 +357,15 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        smbcli_unlink(cli->tree, fname);
 
        /* check the fields when the file already existed */
-       fnum2 = create_complex_file(cli, mem_ctx, fname);
+       fnum2 = create_complex_file(cli, tctx, fname);
        if (fnum2 == -1) {
-               ret = False;
+               ret = false;
                goto done;
        }
        smbcli_close(cli->tree, fnum2);
 
        io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openx.out.file.fnum;
 
@@ -377,12 +381,12 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
 
        io.openx.in.search_attrs = FILE_ATTRIBUTE_HIDDEN;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        smbcli_close(cli->tree, io.openx.out.file.fnum);
 
        io.openx.in.search_attrs = 0;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        smbcli_close(cli->tree, io.openx.out.file.fnum);
 
@@ -393,10 +397,17 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openx.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
        io.openx.in.search_attrs = 0;
        io.openx.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
-       CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
-                      attrib & ~FILE_ATTRIBUTE_NONINDEXED);
+       if (torture_setting_bool(tctx, "samba3", false)) {
+               CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
+                              attrib & ~(FILE_ATTRIBUTE_NONINDEXED|
+                                         FILE_ATTRIBUTE_SPARSE));
+       }
+       else {
+               CHECK_ALL_INFO(FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_ARCHIVE, 
+                              attrib & ~(FILE_ATTRIBUTE_NONINDEXED));
+       }
        smbcli_close(cli->tree, io.openx.out.file.fnum);
        smbcli_unlink(cli->tree, fname);
 
@@ -404,19 +415,19 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
        io.openx.in.file_attrs = 0;
        io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openx.out.file.fnum;
 
        io.openx.in.timeout = 20000;
        tv = timeval_current();
        io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_NONE;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
        if (timeval_elapsed(&tv) > 3.0) {
                printf("(%s) Incorrect timing in openx with timeout - waited %.2f seconds\n",
                       __location__, timeval_elapsed(&tv));
-               ret = False;
+               ret = false;
        }
        smbcli_close(cli->tree, fnum);
        smbcli_unlink(cli->tree, fname);
@@ -431,27 +442,27 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openx.in.write_time = 0;
        io.openx.in.size = 0;
        io.openx.in.timeout = 0;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        smbcli_close(cli->tree, io.openx.out.file.fnum);
 
        /* check the extended return flag */
        io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | OPENX_FLAGS_EXTENDED_RETURN;
        io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
        smbcli_close(cli->tree, io.openx.out.file.fnum);
 
        io.openx.in.fname = "\\A.+,;=[].B";
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
 
        /* Check the mapping for open exec. */
 
        /* First create an .exe file. */
        smbcli_unlink(cli->tree, fname_exe);
-       fnum = create_complex_file(cli, mem_ctx, fname_exe);
+       fnum = create_complex_file(cli, tctx, fname_exe);
        smbcli_close(cli->tree, fnum);
 
        io.openx.level = RAW_OPEN_OPENX;
@@ -463,7 +474,7 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openx.in.write_time = 0;
        io.openx.in.size = 0;
        io.openx.in.timeout = 0;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        /* Can we read and write ? */
@@ -485,7 +496,7 @@ done:
 
   many thanks to kukks for a sniff showing how this works with os2->w2k
 */
-static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_t2open(struct smbcli_state *cli, struct torture_context *tctx)
 {
        union smb_open io;
        union smb_fileinfo finfo;
@@ -494,31 +505,31 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        const char *fname = BASEDIR "\\torture_t2open_3.txt";
        NTSTATUS status;
        int fnum;
-       BOOL ret = True;
+       bool ret = true;
        int i;
        struct {
                uint16_t open_func;
-               BOOL with_file;
+               bool with_file;
                NTSTATUS correct_status;
        } open_funcs[] = {
-               { OPENX_OPEN_FUNC_OPEN,                           True,  NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_OPEN,                           False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
-               { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, True,  NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_FAIL,                           True,  NT_STATUS_OBJECT_NAME_COLLISION },
-               { OPENX_OPEN_FUNC_FAIL,                           False, NT_STATUS_OBJECT_NAME_COLLISION },
-               { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, True,  NT_STATUS_OBJECT_NAME_COLLISION },
-               { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OBJECT_NAME_COLLISION },
-               { OPENX_OPEN_FUNC_TRUNC,                          True,  NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_TRUNC,                          False, NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, True,  NT_STATUS_OK },
-               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_OPEN,                           true,  NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_OPEN,                           false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+               { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_OPEN  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_FAIL,                           true,  NT_STATUS_OBJECT_NAME_COLLISION },
+               { OPENX_OPEN_FUNC_FAIL,                           false, NT_STATUS_OBJECT_NAME_COLLISION },
+               { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OBJECT_NAME_COLLISION },
+               { OPENX_OPEN_FUNC_FAIL  | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OBJECT_NAME_COLLISION },
+               { OPENX_OPEN_FUNC_TRUNC,                          true,  NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_TRUNC,                          false, NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, true,  NT_STATUS_OK },
+               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, false, NT_STATUS_OK },
        };
 
-       fnum = create_complex_file(cli, mem_ctx, fname1);
+       fnum = create_complex_file(cli, tctx, fname1);
        if (fnum == -1) {
                d_printf("Failed to create file %s - %s\n", fname1, smbcli_errstr(cli->tree));
-               ret = False;
+               ret = false;
                goto done;
        }
        smbcli_close(cli->tree, fnum);
@@ -536,31 +547,41 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.t2open.in.timeout = 0;
 
        io.t2open.in.num_eas = 3;
-       io.t2open.in.eas = talloc_array(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
+       io.t2open.in.eas = talloc_array(tctx, struct ea_struct, io.t2open.in.num_eas);
        io.t2open.in.eas[0].flags = 0;
        io.t2open.in.eas[0].name.s = ".CLASSINFO";
-       io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "first value", 11);
+       io.t2open.in.eas[0].value = data_blob_talloc(tctx, "first value", 11);
        io.t2open.in.eas[1].flags = 0;
        io.t2open.in.eas[1].name.s = "EA TWO";
-       io.t2open.in.eas[1].value = data_blob_talloc(mem_ctx, "foo", 3);
+       io.t2open.in.eas[1].value = data_blob_talloc(tctx, "foo", 3);
        io.t2open.in.eas[2].flags = 0;
        io.t2open.in.eas[2].name.s = "X THIRD";
-       io.t2open.in.eas[2].value = data_blob_talloc(mem_ctx, "xy", 2);
+       io.t2open.in.eas[2].value = data_blob_talloc(tctx, "xy", 2);
 
        /* check all combinations of open_func */
        for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
+       again:
                if (open_funcs[i].with_file) {
                        io.t2open.in.fname = fname1;
                } else {
                        io.t2open.in.fname = fname2;
                }
                io.t2open.in.open_func = open_funcs[i].open_func;
-               status = smb_raw_open(cli->tree, mem_ctx, &io);
+               status = smb_raw_open(cli->tree, tctx, &io);
+               if ((io.t2open.in.num_eas != 0)
+                   && NT_STATUS_EQUAL(status, NT_STATUS_EAS_NOT_SUPPORTED)
+                   && torture_setting_bool(tctx, "samba3", false)) {
+                       printf("(%s) EAs not supported, not treating as fatal "
+                              "in Samba3 test\n", __location__);
+                       io.t2open.in.num_eas = 0;
+                       goto again;
+               }
+
                if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
                        printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_func=0x%x)\n", 
                               __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
                               i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_func);
-                       ret = False;
+                       ret = false;
                }
                if (NT_STATUS_IS_OK(status)) {
                        smbcli_close(cli->tree, io.t2open.out.file.fnum);
@@ -574,7 +595,7 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
        io.t2open.in.write_time = 0;
        io.t2open.in.fname = fname;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.t2open.out.file.fnum;
 
@@ -591,21 +612,24 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        smbcli_close(cli->tree, fnum);
 
        status = torture_check_ea(cli, fname, ".CLASSINFO", "first value");
-       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_STATUS(status, io.t2open.in.num_eas
+                    ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
        status = torture_check_ea(cli, fname, "EA TWO", "foo");
-       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_STATUS(status, io.t2open.in.num_eas
+                    ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
        status = torture_check_ea(cli, fname, "X THIRD", "xy");
-       CHECK_STATUS(status, NT_STATUS_OK);
+       CHECK_STATUS(status, io.t2open.in.num_eas
+                    ? NT_STATUS_OK : NT_STATUS_EAS_NOT_SUPPORTED);
 
        /* now check the search attrib for hidden files - win2003 ignores this? */
        SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
        CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        smbcli_close(cli->tree, io.t2open.out.file.fnum);
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        smbcli_close(cli->tree, io.t2open.out.file.fnum);
 
@@ -615,7 +639,7 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        /* and check attrib on create */
        io.t2open.in.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
        io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        /* check timeout on create - win2003 ignores the timeout! */
@@ -623,7 +647,7 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.t2open.in.file_attrs = 0;
        io.t2open.in.timeout = 20000;
        io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
 
 done:
@@ -637,7 +661,7 @@ done:
 /*
   test RAW_OPEN_NTCREATEX
 */
-static BOOL test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_ntcreatex(struct smbcli_state *cli, struct torture_context *tctx)
 {
        union smb_open io;
        union smb_fileinfo finfo;
@@ -645,27 +669,27 @@ static BOOL test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        const char *dname = BASEDIR "\\torture_ntcreatex.dir";
        NTSTATUS status;
        int fnum = -1;
-       BOOL ret = True;
+       bool ret = true;
        int i;
        struct {
                uint32_t open_disp;
-               BOOL with_file;
+               bool with_file;
                NTSTATUS correct_status;
        } open_funcs[] = {
-               { NTCREATEX_DISP_SUPERSEDE,     True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_SUPERSEDE,     False, NT_STATUS_OK },
-               { NTCREATEX_DISP_OPEN,          True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_OPEN,          False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
-               { NTCREATEX_DISP_CREATE,        True,  NT_STATUS_OBJECT_NAME_COLLISION },
-               { NTCREATEX_DISP_CREATE,        False, NT_STATUS_OK },
-               { NTCREATEX_DISP_OPEN_IF,       True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_OPEN_IF,       False, NT_STATUS_OK },
-               { NTCREATEX_DISP_OVERWRITE,     True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_OVERWRITE,     False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
-               { NTCREATEX_DISP_OVERWRITE_IF,  True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_OVERWRITE_IF,  False, NT_STATUS_OK },
-               { 6,                            True,  NT_STATUS_INVALID_PARAMETER },
-               { 6,                            False, NT_STATUS_INVALID_PARAMETER },
+               { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
+               { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+               { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
+               { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
+               { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
+               { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+               { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
+               { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
+               { 6,                            false, NT_STATUS_INVALID_PARAMETER },
        };
 
        printf("Checking RAW_OPEN_NTCREATEX\n");
@@ -690,18 +714,18 @@ static BOOL test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                        fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
                        if (fnum == -1) {
                                d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
-                               ret = False;
+                               ret = false;
                                goto done;
                        }
                        smbcli_close(cli->tree, fnum);
                }
                io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
-               status = smb_raw_open(cli->tree, mem_ctx, &io);
+               status = smb_raw_open(cli->tree, tctx, &io);
                if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
                        printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n", 
                               __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
                               i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_disp);
-                       ret = False;
+                       ret = false;
                }
                if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
                        smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
@@ -712,7 +736,7 @@ static BOOL test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        /* basic field testing */
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.file.fnum;
 
@@ -731,15 +755,15 @@ static BOOL test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        /* check fields when the file already existed */
        smbcli_close(cli->tree, fnum);
        smbcli_unlink(cli->tree, fname);
-       fnum = create_complex_file(cli, mem_ctx, fname);
+       fnum = create_complex_file(cli, tctx, fname);
        if (fnum == -1) {
-               ret = False;
+               ret = false;
                goto done;
        }
        smbcli_close(cli->tree, fnum);
 
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.file.fnum;
 
@@ -776,7 +800,7 @@ static BOOL test_ntcreatex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.file.fnum;
 
@@ -810,7 +834,7 @@ done:
 /*
   test RAW_OPEN_NTTRANS_CREATE
 */
-static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_nttrans_create(struct smbcli_state *cli, struct torture_context *tctx)
 {
        union smb_open io;
        union smb_fileinfo finfo;
@@ -818,27 +842,27 @@ static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        const char *dname = BASEDIR "\\torture_ntcreatex.dir";
        NTSTATUS status;
        int fnum = -1;
-       BOOL ret = True;
+       bool ret = true;
        int i;
        struct {
                uint32_t open_disp;
-               BOOL with_file;
+               bool with_file;
                NTSTATUS correct_status;
        } open_funcs[] = {
-               { NTCREATEX_DISP_SUPERSEDE,     True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_SUPERSEDE,     False, NT_STATUS_OK },
-               { NTCREATEX_DISP_OPEN,          True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_OPEN,          False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
-               { NTCREATEX_DISP_CREATE,        True,  NT_STATUS_OBJECT_NAME_COLLISION },
-               { NTCREATEX_DISP_CREATE,        False, NT_STATUS_OK },
-               { NTCREATEX_DISP_OPEN_IF,       True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_OPEN_IF,       False, NT_STATUS_OK },
-               { NTCREATEX_DISP_OVERWRITE,     True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_OVERWRITE,     False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
-               { NTCREATEX_DISP_OVERWRITE_IF,  True,  NT_STATUS_OK },
-               { NTCREATEX_DISP_OVERWRITE_IF,  False, NT_STATUS_OK },
-               { 6,                            True,  NT_STATUS_INVALID_PARAMETER },
-               { 6,                            False, NT_STATUS_INVALID_PARAMETER },
+               { NTCREATEX_DISP_SUPERSEDE,     true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_SUPERSEDE,     false, NT_STATUS_OK },
+               { NTCREATEX_DISP_OPEN,          true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_OPEN,          false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+               { NTCREATEX_DISP_CREATE,        true,  NT_STATUS_OBJECT_NAME_COLLISION },
+               { NTCREATEX_DISP_CREATE,        false, NT_STATUS_OK },
+               { NTCREATEX_DISP_OPEN_IF,       true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_OPEN_IF,       false, NT_STATUS_OK },
+               { NTCREATEX_DISP_OVERWRITE,     true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_OVERWRITE,     false, NT_STATUS_OBJECT_NAME_NOT_FOUND },
+               { NTCREATEX_DISP_OVERWRITE_IF,  true,  NT_STATUS_OK },
+               { NTCREATEX_DISP_OVERWRITE_IF,  false, NT_STATUS_OK },
+               { 6,                            true,  NT_STATUS_INVALID_PARAMETER },
+               { 6,                            false, NT_STATUS_INVALID_PARAMETER },
        };
 
        printf("Checking RAW_OPEN_NTTRANS_CREATE\n");
@@ -865,18 +889,18 @@ static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                        fnum = smbcli_open(cli->tree, fname, O_CREAT|O_RDWR|O_TRUNC, DENY_NONE);
                        if (fnum == -1) {
                                d_printf("Failed to create file %s - %s\n", fname, smbcli_errstr(cli->tree));
-                               ret = False;
+                               ret = false;
                                goto done;
                        }
                        smbcli_close(cli->tree, fnum);
                }
                io.ntcreatex.in.open_disposition = open_funcs[i].open_disp;
-               status = smb_raw_open(cli->tree, mem_ctx, &io);
+               status = smb_raw_open(cli->tree, tctx, &io);
                if (!NT_STATUS_EQUAL(status, open_funcs[i].correct_status)) {
                        printf("(%s) incorrect status %s should be %s (i=%d with_file=%d open_disp=%d)\n", 
                               __location__, nt_errstr(status), nt_errstr(open_funcs[i].correct_status),
                               i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_disp);
-                       ret = False;
+                       ret = false;
                }
                if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
                        smbcli_close(cli->tree, io.ntcreatex.out.file.fnum);
@@ -887,7 +911,7 @@ static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        /* basic field testing */
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.file.fnum;
 
@@ -906,15 +930,15 @@ static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        /* check fields when the file already existed */
        smbcli_close(cli->tree, fnum);
        smbcli_unlink(cli->tree, fname);
-       fnum = create_complex_file(cli, mem_ctx, fname);
+       fnum = create_complex_file(cli, tctx, fname);
        if (fnum == -1) {
-               ret = False;
+               ret = false;
                goto done;
        }
        smbcli_close(cli->tree, fnum);
 
        io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.file.fnum;
 
@@ -930,6 +954,51 @@ static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
        CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
        smbcli_close(cli->tree, fnum);
+
+       /* check no-recall - don't pull a file from tape on a HSM */
+       io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_NO_RECALL;
+       status = smb_raw_open(cli->tree, tctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       fnum = io.ntcreatex.out.file.fnum;
+
+       CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+       CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
+       CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
+       CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
+       CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
+       CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
+       CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+       CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
+       CHECK_ALL_INFO(io.ntcreatex.out.size, size);
+       CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
+       CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
+       smbcli_close(cli->tree, fnum);
+
+       /* Check some create options (these all should be ignored) */
+       for (i=0; i < 32; i++) {
+               uint32_t create_option = (1 << i) & NTCREATEX_OPTIONS_MUST_IGNORE_MASK;
+               if (create_option == 0) {
+                       continue;
+               }
+               io.ntcreatex.in.create_options = create_option;
+               status = smb_raw_open(cli->tree, tctx, &io);
+               CHECK_STATUS(status, NT_STATUS_OK);
+               fnum = io.ntcreatex.out.file.fnum;
+
+               CHECK_VAL(io.ntcreatex.out.oplock_level, 0);
+               CHECK_VAL(io.ntcreatex.out.create_action, NTCREATEX_ACTION_EXISTED);
+               CHECK_NTTIME(io.ntcreatex.out.create_time, create_time);
+               CHECK_NTTIME(io.ntcreatex.out.access_time, access_time);
+               CHECK_NTTIME(io.ntcreatex.out.write_time, write_time);
+               CHECK_NTTIME(io.ntcreatex.out.change_time, change_time);
+               CHECK_ALL_INFO(io.ntcreatex.out.attrib, attrib);
+               CHECK_ALL_INFO(io.ntcreatex.out.alloc_size, alloc_size);
+               CHECK_ALL_INFO(io.ntcreatex.out.size, size);
+               CHECK_ALL_INFO(io.ntcreatex.out.is_directory, directory);
+               CHECK_VAL(io.ntcreatex.out.file_type, FILE_TYPE_DISK);
+               smbcli_close(cli->tree, fnum);
+       }
+
        smbcli_unlink(cli->tree, fname);
 
 
@@ -951,7 +1020,7 @@ static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
        io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
        io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.file.fnum;
 
@@ -989,14 +1058,14 @@ done:
   open_disposition==NTCREATEX_DISP_OVERWRITE_IF. Windows 2003 allows the
   second open.
 */
-static BOOL test_ntcreatex_brlocked(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_ntcreatex_brlocked(struct smbcli_state *cli, struct torture_context *tctx)
 {
        union smb_open io, io1;
        union smb_lock io2;
        struct smb_lock_entry lock[1];
        const char *fname = BASEDIR "\\torture_ntcreatex.txt";
        NTSTATUS status;
-       BOOL ret = True;
+       bool ret = true;
 
        printf("Testing ntcreatex with a byte range locked file\n");
 
@@ -1015,7 +1084,7 @@ static BOOL test_ntcreatex_brlocked(struct smbcli_state *cli, TALLOC_CTX *mem_ct
                NTCREATEX_SECURITY_ALL;
        io.ntcreatex.in.fname = fname;
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        io2.lockx.level = RAW_LOCK_LOCKX;
@@ -1046,7 +1115,7 @@ static BOOL test_ntcreatex_brlocked(struct smbcli_state *cli, TALLOC_CTX *mem_ct
                NTCREATEX_SECURITY_ALL;
        io1.ntcreatex.in.fname = fname;
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io1);
+       status = smb_raw_open(cli->tree, tctx, &io1);
        CHECK_STATUS(status, NT_STATUS_OK);
 
  done:
@@ -1059,13 +1128,13 @@ static BOOL test_ntcreatex_brlocked(struct smbcli_state *cli, TALLOC_CTX *mem_ct
 /*
   test RAW_OPEN_MKNEW
 */
-static BOOL test_mknew(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_mknew(struct smbcli_state *cli, struct torture_context *tctx)
 {
        union smb_open io;
        const char *fname = BASEDIR "\\torture_mknew.txt";
        NTSTATUS status;
        int fnum = -1;
-       BOOL ret = True;
+       bool ret = true;
        time_t basetime = (time(NULL) + 3600*24*3) & ~1;
        union smb_fileinfo finfo;
 
@@ -1075,11 +1144,11 @@ static BOOL test_mknew(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.mknew.in.attrib = 0;
        io.mknew.in.write_time = 0;
        io.mknew.in.fname = fname;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.mknew.out.file.fnum;
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
 
        smbcli_close(cli->tree, fnum);
@@ -1087,7 +1156,7 @@ static BOOL test_mknew(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* make sure write_time works */
        io.mknew.in.write_time = basetime;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.mknew.out.file.fnum;
        CHECK_TIME(basetime, write_time);
@@ -1097,7 +1166,7 @@ static BOOL test_mknew(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* make sure file_attrs works */
        io.mknew.in.attrib = FILE_ATTRIBUTE_HIDDEN;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.mknew.out.file.fnum;
        CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
@@ -1114,13 +1183,13 @@ done:
 /*
   test RAW_OPEN_CREATE
 */
-static BOOL test_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_create(struct smbcli_state *cli, struct torture_context *tctx)
 {
        union smb_open io;
        const char *fname = BASEDIR "\\torture_create.txt";
        NTSTATUS status;
        int fnum = -1;
-       BOOL ret = True;
+       bool ret = true;
        time_t basetime = (time(NULL) + 3600*24*3) & ~1;
        union smb_fileinfo finfo;
 
@@ -1130,11 +1199,11 @@ static BOOL test_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.create.in.attrib = 0;
        io.create.in.write_time = 0;
        io.create.in.fname = fname;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.create.out.file.fnum;
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        smbcli_close(cli->tree, io.create.out.file.fnum);
@@ -1143,7 +1212,7 @@ static BOOL test_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* make sure write_time works */
        io.create.in.write_time = basetime;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.create.out.file.fnum;
        CHECK_TIME(basetime, write_time);
@@ -1153,7 +1222,7 @@ static BOOL test_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        /* make sure file_attrs works */
        io.create.in.attrib = FILE_ATTRIBUTE_HIDDEN;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.create.out.file.fnum;
        CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_ARCHIVE, 
@@ -1170,12 +1239,12 @@ done:
 /*
   test RAW_OPEN_CTEMP
 */
-static BOOL test_ctemp(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_ctemp(struct smbcli_state *cli, TALLOC_CTX *tctx)
 {
        union smb_open io;
        NTSTATUS status;
        int fnum = -1;
-       BOOL ret = True;
+       bool ret = true;
        time_t basetime = (time(NULL) + 3600*24*3) & ~1;
        union smb_fileinfo finfo;
        const char *name, *fname = NULL;
@@ -1186,7 +1255,7 @@ static BOOL test_ctemp(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.ctemp.in.attrib = FILE_ATTRIBUTE_HIDDEN;
        io.ctemp.in.write_time = basetime;
        io.ctemp.in.directory = BASEDIR;
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ctemp.out.file.fnum;
 
@@ -1194,7 +1263,7 @@ static BOOL test_ctemp(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        finfo.generic.level = RAW_FILEINFO_NAME_INFO;
        finfo.generic.in.file.fnum = fnum;
-       status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
+       status = smb_raw_fileinfo(cli->tree, tctx, &finfo);
        CHECK_STATUS(status, NT_STATUS_OK);
 
        fname = finfo.name_info.out.fname.s;
@@ -1213,20 +1282,20 @@ done:
 /*
   test chained RAW_OPEN_OPENX_READX
 */
-static BOOL test_chained(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
+static bool test_chained(struct smbcli_state *cli, TALLOC_CTX *tctx)
 {
        union smb_open io;
        const char *fname = BASEDIR "\\torture_chained.txt";
        NTSTATUS status;
        int fnum = -1;
-       BOOL ret = True;
+       bool ret = true;
        const char *buf = "test";
        char buf2[4];
 
        printf("Checking RAW_OPEN_OPENX chained with READX\n");
        smbcli_unlink(cli->tree, fname);
 
-       fnum = create_complex_file(cli, mem_ctx, fname);
+       fnum = create_complex_file(cli, tctx, fname);
 
        smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
 
@@ -1249,13 +1318,13 @@ static BOOL test_chained(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openxreadx.in.remaining = 0;
        io.openxreadx.out.data = (uint8_t *)buf2;
 
-       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       status = smb_raw_open(cli->tree, tctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openxreadx.out.file.fnum;
 
        if (memcmp(buf, buf2, sizeof(buf)) != 0) {
                d_printf("wrong data in reply buffer\n");
-               ret = False;
+               ret = false;
        }
 
 done:
@@ -1265,50 +1334,92 @@ done:
        return ret;
 }
 
+/*
+  test RAW_OPEN_OPENX without a leading slash on the path.
+  NetApp filers are known to fail on this.
+  
+*/
+static bool test_no_leading_slash(struct smbcli_state *cli, TALLOC_CTX *tctx)
+{
+       union smb_open io;
+       const char *fname = BASEDIR "\\torture_no_leading_slash.txt";
+       NTSTATUS status;
+       int fnum = -1;
+       bool ret = true;
+       const char *buf = "test";
+
+       printf("Checking RAW_OPEN_OPENX without leading slash on path\n");
+       smbcli_unlink(cli->tree, fname);
+
+        /* Create the file */
+       fnum = create_complex_file(cli, tctx, fname);
+       smbcli_write(cli->tree, fnum, 0, buf, 0, sizeof(buf));
+       smbcli_close(cli->tree, fnum);  
+
+        /* Prepare to open the file using path without leading slash */
+       io.openx.level = RAW_OPEN_OPENX;
+       io.openx.in.fname = fname + 1;
+       io.openx.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
+       io.openx.in.open_mode = OPENX_MODE_ACCESS_RDWR;
+       io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN;
+       io.openx.in.search_attrs = 0;
+       io.openx.in.file_attrs = 0;
+       io.openx.in.write_time = 0;
+       io.openx.in.size = 1024*1024;
+       io.openx.in.timeout = 0;
+
+       status = smb_raw_open(cli->tree, tctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OK);
+       fnum = io.openx.out.file.fnum;
+
+done:
+       smbcli_close(cli->tree, fnum);
+       smbcli_unlink(cli->tree, fname);
+
+       return ret;
+}
+
 /* A little torture test to expose a race condition in Samba 3.0.20 ... :-) */
 
-static BOOL test_raw_open_multi(void)
+static bool test_raw_open_multi(struct torture_context *tctx)
 {
        struct smbcli_state *cli;
        TALLOC_CTX *mem_ctx = talloc_init("torture_test_oplock_multi");
        const char *fname = "\\test_oplock.dat";
        NTSTATUS status;
-       BOOL ret = True;
+       bool ret = true;
        union smb_open io;
        struct smbcli_state **clients;
        struct smbcli_request **requests;
        union smb_open *ios;
-       const char *host = lp_parm_string(-1, "torture", "host");
-       const char *share = lp_parm_string(-1, "torture", "share");
+       const char *host = torture_setting_string(tctx, "host", NULL);
+       const char *share = torture_setting_string(tctx, "share", NULL);
        int i, num_files = 3;
-       struct event_context *ev;
        int num_ok = 0;
        int num_collision = 0;
        
-       ev = event_context_init(mem_ctx);
        clients = talloc_array(mem_ctx, struct smbcli_state *, num_files);
        requests = talloc_array(mem_ctx, struct smbcli_request *, num_files);
        ios = talloc_array(mem_ctx, union smb_open, num_files);
-       if ((ev == NULL) || (clients == NULL) || (requests == NULL) ||
+       if ((tctx->ev == NULL) || (clients == NULL) || (requests == NULL) ||
            (ios == NULL)) {
                DEBUG(0, ("talloc failed\n"));
-               return False;
+               return false;
        }
 
-       if (!torture_open_connection_share(mem_ctx, &cli, host, share, ev)) {
-               return False;
+       if (!torture_open_connection_share(mem_ctx, &cli, tctx, host, share, tctx->ev)) {
+               return false;
        }
 
-       cli->tree->session->transport->options.request_timeout = 60000;
+       cli->tree->session->transport->options.request_timeout = 60;
 
        for (i=0; i<num_files; i++) {
                if (!torture_open_connection_share(mem_ctx, &(clients[i]),
-                                                  host, share, ev)) {
+                                                  tctx, host, share, tctx->ev)) {
                        DEBUG(0, ("Could not open %d'th connection\n", i));
-                       return False;
+                       return false;
                }
-               clients[i]->tree->session->transport->
-                       options.request_timeout = 60000;
+               clients[i]->tree->session->transport->options.request_timeout = 60;
        }
 
        /* cleanup */
@@ -1337,19 +1448,19 @@ static BOOL test_raw_open_multi(void)
                requests[i] = smb_raw_open_send(clients[i]->tree, &ios[i]);
                if (requests[i] == NULL) {
                        DEBUG(0, ("could not send %d'th request\n", i));
-                       return False;
+                       return false;
                }
        }
 
        DEBUG(10, ("waiting for replies\n"));
        while (1) {
-               BOOL unreplied = False;
+               bool unreplied = false;
                for (i=0; i<num_files; i++) {
                        if (requests[i] == NULL) {
                                continue;
                        }
                        if (requests[i]->state < SMBCLI_REQUEST_DONE) {
-                               unreplied = True;
+                               unreplied = true;
                                break;
                        }
                        status = smb_raw_open_recv(requests[i], mem_ctx,
@@ -1373,14 +1484,14 @@ static BOOL test_raw_open_multi(void)
                        break;
                }
 
-               if (event_loop_once(ev) != 0) {
+               if (event_loop_once(tctx->ev) != 0) {
                        DEBUG(0, ("event_loop_once failed\n"));
-                       return False;
+                       return false;
                }
        }
 
        if ((num_ok != 1) || (num_ok + num_collision != num_files)) {
-               ret = False;
+               ret = false;
        }
 
        for (i=0; i<num_files; i++) {
@@ -1392,38 +1503,29 @@ static BOOL test_raw_open_multi(void)
 
 /* basic testing of all RAW_OPEN_* calls 
 */
-BOOL torture_raw_open(void)
+bool torture_raw_open(struct torture_context *torture, struct smbcli_state *cli)
 {
-       struct smbcli_state *cli;
-       BOOL ret = True;
-       TALLOC_CTX *mem_ctx;
-
-       if (!torture_open_connection(&cli)) {
-               return False;
-       }
-
-       mem_ctx = talloc_init("torture_raw_open");
+       bool ret = true;
 
        if (!torture_setup_dir(cli, BASEDIR)) {
-               return False;
+               return false;
        }
 
-       ret &= test_ntcreatex_brlocked(cli, mem_ctx);
-       ret &= test_open(cli, mem_ctx);
-       ret &= test_raw_open_multi();
-       ret &= test_openx(cli, mem_ctx);
-       ret &= test_ntcreatex(cli, mem_ctx);
-       ret &= test_nttrans_create(cli, mem_ctx);
-       ret &= test_t2open(cli, mem_ctx);
-       ret &= test_mknew(cli, mem_ctx);
-       ret &= test_create(cli, mem_ctx);
-       ret &= test_ctemp(cli, mem_ctx);
-       ret &= test_chained(cli, mem_ctx);
+       ret &= test_ntcreatex_brlocked(cli, torture);
+       ret &= test_open(cli, torture);
+       ret &= test_raw_open_multi(torture);
+       ret &= test_openx(cli, torture);
+       ret &= test_ntcreatex(cli, torture);
+       ret &= test_nttrans_create(cli, torture);
+       ret &= test_t2open(cli, torture);
+       ret &= test_mknew(cli, torture);
+       ret &= test_create(cli, torture);
+       ret &= test_ctemp(cli, torture);
+       ret &= test_chained(cli, torture);
+       ret &= test_no_leading_slash(cli, torture);
 
        smb_raw_exit(cli->session);
        smbcli_deltree(cli->tree, BASEDIR);
 
-       torture_close_connection(cli);
-       talloc_free(mem_ctx);
        return ret;
 }