r4173: - new t2open code, that can cope with "create with EAs". Many thanks
authorAndrew Tridgell <tridge@samba.org>
Mon, 13 Dec 2004 10:48:21 +0000 (10:48 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:07:22 +0000 (13:07 -0500)
  to kukks on #samba-technical for the sniffs that allowed me to work
  this out

- much simpler ntvfs open generic mapping code

- added t2open create with EA torture test to RAW-OPEN test

source/include/smb_interfaces.h
source/libcli/raw/clisession.c
source/libcli/raw/rawfile.c
source/ntvfs/ntvfs_generic.c
source/ntvfs/posix/pvfs_open.c
source/smb_server/reply.c
source/torture/gentest.c
source/torture/raw/eas.c
source/torture/raw/open.c
source/torture/raw/search.c
source/torture/torture_util.c

index 4b767c8d70be7aff74c609744dea730ffa64ca95..4ba8ea3442954cb3312d59fad6ac51b158624d2f 100644 (file)
@@ -1133,6 +1133,7 @@ union smb_open {
                struct {
                        uint16_t flags;
                        uint16_t open_mode;
+                       uint16_t search_attrs;
                        uint16_t file_attrs;
                        time_t write_time;
                        uint16_t open_func;
@@ -1152,7 +1153,7 @@ union smb_open {
                        uint16_t ftype;
                        uint16_t devstate;
                        uint16_t action;
-                       uint32_t unknown;
+                       uint32_t file_id;
                } out;
        } t2open;
 
@@ -1161,7 +1162,7 @@ union smb_open {
                enum smb_open_level level;
 
                struct {
-                       uint16_t flags;
+                       uint16_t open_mode;
                        uint16_t search_attrs;
                        const char *fname;
                } in;
index 4f77145d4d73bf93a95589c68119cc66c647130c..519f112cebda8656980b01db2c2b7ce1a5a2dc4d 100644 (file)
@@ -51,7 +51,7 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport)
        
        capabilities = transport->negotiate.capabilities;
 
-       flags2 = FLAGS2_LONG_PATH_COMPONENTS;
+       flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES;
 
        if (capabilities & CAP_UNICODE) {
                flags2 |= FLAGS2_UNICODE_STRINGS;
index 028d8734e1970528a53d8f58b953b68a878079c5..bfd96bd36070a4f6ef16f3c6e6dd2dc041902f1e 100644 (file)
@@ -366,10 +366,10 @@ static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree,
 
        SSVAL(t2.in.params.data, VWV(0), parms->t2open.in.flags);
        SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode);
-       SSVAL(t2.in.params.data, VWV(2), 0); /* reserved */
+       SSVAL(t2.in.params.data, VWV(2), parms->t2open.in.search_attrs);
        SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs);
        raw_push_dos_date(tree->session->transport, 
-                        t2.in.params.data, VWV(4), parms->t2open.in.write_time);
+                         t2.in.params.data, VWV(4), parms->t2open.in.write_time);
        SSVAL(t2.in.params.data, VWV(6), parms->t2open.in.open_func);
        SIVAL(t2.in.params.data, VWV(7), parms->t2open.in.size);
        SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout);
@@ -377,8 +377,8 @@ static struct smbcli_request *smb_raw_t2open_send(struct smbcli_tree *tree,
        SSVAL(t2.in.params.data, VWV(13), 0);
 
        smbcli_blob_append_string(tree->session, mem_ctx, 
-                              &t2.in.params, parms->t2open.in.fname, 
-                              STR_TERMINATE);
+                                 &t2.in.params, parms->t2open.in.fname, 
+                                 STR_TERMINATE);
 
        ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas);
 
@@ -414,7 +414,7 @@ static NTSTATUS smb_raw_t2open_recv(struct smbcli_request *req, TALLOC_CTX *mem_
        parms->t2open.out.ftype =       SVAL(t2.out.params.data, VWV(7));
        parms->t2open.out.devstate =    SVAL(t2.out.params.data, VWV(8));
        parms->t2open.out.action =      SVAL(t2.out.params.data, VWV(9));
-       parms->t2open.out.unknown =     SVAL(t2.out.params.data, VWV(10));
+       parms->t2open.out.file_id =     SVAL(t2.out.params.data, VWV(10));
 
        return NT_STATUS_OK;
 }
@@ -433,7 +433,7 @@ struct smbcli_request *smb_raw_open_send(struct smbcli_tree *tree, union smb_ope
 
        case RAW_OPEN_OPEN:
                SETUP_REQUEST(SMBopen, 2, 0);
-               SSVAL(req->out.vwv, VWV(0), parms->openold.in.flags);
+               SSVAL(req->out.vwv, VWV(0), parms->openold.in.open_mode);
                SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs);
                smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE);
                break;
index 49de8944ffea49825872226d6e6173ca0fd55f5e..407bd38f7453555d50b4b13459d1bb5359e0cc43 100644 (file)
@@ -150,13 +150,6 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req,
        union smb_setfileinfo *sf;
        uint_t state;
 
-       /* this is really strange, but matches w2k3 */
-       if (io->generic.level == RAW_OPEN_T2OPEN &&
-           io->t2open.in.open_func != OPENX_OPEN_FUNC_OPEN &&
-           NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-               return NT_STATUS_ACCESS_DENIED;
-       }
-
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -167,7 +160,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req,
                io->openold.out.attrib     = io2->generic.out.attrib;
                io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time);
                io->openold.out.size       = io2->generic.out.size;
-               io->openold.out.rmode      = io->openold.in.flags;
+               io->openold.out.rmode      = io->openold.in.open_mode;
                break;
 
        case RAW_OPEN_OPENX:
@@ -175,6 +168,7 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req,
                io->openx.out.attrib      = io2->generic.out.attrib;
                io->openx.out.write_time  = nt_time_to_unix(io2->generic.out.write_time);
                io->openx.out.size        = io2->generic.out.size;
+               io->openx.out.access      = (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK);
                io->openx.out.ftype       = 0;
                io->openx.out.devstate    = 0;
                io->openx.out.action      = io2->generic.out.create_action;
@@ -190,15 +184,15 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req,
                break;
 
        case RAW_OPEN_T2OPEN:
-               io->t2open.out.fnum       = io2->openx.out.fnum;
-               io->t2open.out.attrib     = io2->openx.out.attrib;
-               io->t2open.out.write_time = 0;
-               io->t2open.out.size       = io2->openx.out.size;
-               io->t2open.out.access     = io->t2open.in.open_mode;
-               io->t2open.out.ftype      = io2->openx.out.ftype;
-               io->t2open.out.devstate   = io2->openx.out.devstate;
-               io->t2open.out.action     = io2->openx.out.action;
-               io->t2open.out.unknown    = 0;
+               io->t2open.out.fnum        = io2->generic.out.fnum;
+               io->t2open.out.attrib      = io2->generic.out.attrib;
+               io->t2open.out.write_time  = nt_time_to_unix(io2->generic.out.write_time);
+               io->t2open.out.size        = io2->generic.out.size;
+               io->t2open.out.access      = io->t2open.in.open_mode;
+               io->t2open.out.ftype       = 0;
+               io->t2open.out.devstate    = 0;
+               io->t2open.out.action      = io2->generic.out.create_action;
+               io->t2open.out.file_id      = 0;
                break;
 
        case RAW_OPEN_MKNEW:
@@ -248,6 +242,106 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req,
        return NT_STATUS_OK;
 }
 
+/*
+  the core of the mapping between openx style parameters and ntcreatex 
+  parameters
+*/
+static NTSTATUS map_openx_open(uint16_t flags, uint16_t open_mode, 
+                              uint16_t open_func, const char *fname,
+                              union smb_open *io2)
+{
+       if (flags & OPENX_FLAGS_REQUEST_OPLOCK) {
+               io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK;
+       }
+       if (flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) {
+               io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
+       }
+
+       switch (open_mode & OPENX_MODE_ACCESS_MASK) {
+       case OPENX_MODE_ACCESS_READ:
+               io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ;
+               break;
+       case OPENX_MODE_ACCESS_WRITE:
+               io2->generic.in.access_mask = SEC_RIGHTS_FILE_WRITE;
+               break;
+       case OPENX_MODE_ACCESS_RDWR:
+       case OPENX_MODE_ACCESS_FCB:
+       case OPENX_MODE_ACCESS_EXEC:
+               io2->generic.in.access_mask = 
+                       SEC_RIGHTS_FILE_READ | 
+                       SEC_RIGHTS_FILE_WRITE;
+               break;
+       default:
+               return NT_STATUS_INVALID_LOCK_SEQUENCE;
+       }
+
+       switch (open_mode & OPENX_MODE_DENY_MASK) {
+       case OPENX_MODE_DENY_READ:
+               io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
+               break;
+       case OPENX_MODE_DENY_WRITE:
+               io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ;
+               break;
+       case OPENX_MODE_DENY_ALL:
+               io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+               break;
+       case OPENX_MODE_DENY_NONE:
+               io2->generic.in.share_access = 
+                       NTCREATEX_SHARE_ACCESS_READ | 
+                       NTCREATEX_SHARE_ACCESS_WRITE;
+               break;
+       case OPENX_MODE_DENY_DOS:
+               /* DENY_DOS is quite strange - it depends on the filename! */
+               io2->generic.in.create_options |= 
+                       NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
+               if (is_exe_filename(fname)) {
+                       io2->generic.in.share_access = 
+                               NTCREATEX_SHARE_ACCESS_READ | 
+                               NTCREATEX_SHARE_ACCESS_WRITE;
+               } else {
+                       if ((open_mode & OPENX_MODE_ACCESS_MASK) == OPENX_MODE_ACCESS_READ) {
+                               io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ;
+                       } else {
+                               io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+                       }
+               }
+               break;
+       case OPENX_MODE_DENY_FCB:
+               io2->generic.in.create_options |= NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
+               io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
+               break;
+       default:
+               return NT_STATUS_INVALID_LOCK_SEQUENCE;
+       }
+
+       switch (open_func) {
+       case (OPENX_OPEN_FUNC_OPEN):
+               io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN;
+               break;
+       case (OPENX_OPEN_FUNC_TRUNC):
+               io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
+               break;
+       case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE):
+               io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE;
+               break;
+       case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE):
+               io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
+               break;
+       case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE):
+               io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
+               break;                  
+       default:
+               /* this one is very strange */
+               if ((open_mode & OPENX_MODE_ACCESS_MASK) == OPENX_MODE_ACCESS_EXEC) {
+                       io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE;
+                       break;
+               }
+               return NT_STATUS_INVALID_LOCK_SEQUENCE;
+       }
+
+       return NT_STATUS_OK;
+}
+
 /* 
    NTVFS open generic to any mapper
 */
@@ -272,105 +366,15 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
                
        switch (io->generic.level) {
        case RAW_OPEN_OPENX:
-               if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) {
-                       io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK;
-               }
-               if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) {
-                       io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
-               }
-       
-               switch (io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) {
-               case OPENX_MODE_ACCESS_READ:
-                       io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ;
-                       io->openx.out.access = OPENX_MODE_ACCESS_READ;
-                       break;
-               case OPENX_MODE_ACCESS_WRITE:
-                       io2->generic.in.access_mask = SEC_RIGHTS_FILE_WRITE;
-                       io->openx.out.access = OPENX_MODE_ACCESS_WRITE;
-                       break;
-               case OPENX_MODE_ACCESS_RDWR:
-               case OPENX_MODE_ACCESS_FCB:
-               case OPENX_MODE_ACCESS_EXEC:
-                       io2->generic.in.access_mask = 
-                               SEC_RIGHTS_FILE_READ | 
-                               SEC_RIGHTS_FILE_WRITE;
-                       io->openx.out.access = OPENX_MODE_ACCESS_RDWR;
-                       break;
-               default:
-                       status = NT_STATUS_INVALID_LOCK_SEQUENCE;
-                       goto done;
-               }
-               
-               switch (io->openx.in.open_mode & OPENX_MODE_DENY_MASK) {
-               case OPENX_MODE_DENY_READ:
-                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
-                       break;
-               case OPENX_MODE_DENY_WRITE:
-                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ;
-                       break;
-               case OPENX_MODE_DENY_ALL:
-                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
-                       break;
-               case OPENX_MODE_DENY_NONE:
-                       io2->generic.in.share_access = 
-                               NTCREATEX_SHARE_ACCESS_READ | 
-                               NTCREATEX_SHARE_ACCESS_WRITE;
-                       break;
-               case OPENX_MODE_DENY_DOS:
-                       /* DENY_DOS is quite strange - it depends on the filename! */
-                       io2->generic.in.create_options |= 
-                               NTCREATEX_OPTIONS_PRIVATE_DENY_DOS;
-                       if (is_exe_filename(io->openx.in.fname)) {
-                               io2->generic.in.share_access = 
-                                       NTCREATEX_SHARE_ACCESS_READ | 
-                                       NTCREATEX_SHARE_ACCESS_WRITE;
-                       } else {
-                               if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) == 
-                                   OPENX_MODE_ACCESS_READ) {
-                                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ;
-                               } else {
-                                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
-                               }
-                       }
-                       break;
-               case OPENX_MODE_DENY_FCB:
-                       io2->generic.in.create_options |= 
-                               NTCREATEX_OPTIONS_PRIVATE_DENY_FCB;
-                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
-                       break;
-               default:
-                       status = NT_STATUS_INVALID_LOCK_SEQUENCE;
-                       goto done;
-               }
-       
-               switch (io->openx.in.open_func) {
-               case (OPENX_OPEN_FUNC_OPEN):
-                       io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN;
-                       break;
-               case (OPENX_OPEN_FUNC_TRUNC):
-                       io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE;
-                       break;
-               case (OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE):
-                       io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE;
-                       break;
-               case (OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE):
-                       io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
-                       break;
-               case (OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE):
-                       io2->generic.in.open_disposition = NTCREATEX_DISP_OVERWRITE_IF;
-                       break;                  
-               default:
-                       /* this one is very strange */
-                       if ((io->openx.in.open_mode & OPENX_MODE_ACCESS_MASK) ==
-                           OPENX_MODE_ACCESS_EXEC) {
-                               io2->generic.in.open_disposition = NTCREATEX_DISP_CREATE;
-                               break;
-                       }
-                       status = NT_STATUS_INVALID_LOCK_SEQUENCE;
+               status = map_openx_open(io->openx.in.flags,
+                                       io->openx.in.open_mode, 
+                                       io->openx.in.open_func, 
+                                       io->openx.in.fname,
+                                       io2);
+               if (!NT_STATUS_IS_OK(status)) {
                        goto done;
                }
                
-               io2->generic.in.alloc_size = 0;
                io2->generic.in.file_attr = io->openx.in.file_attrs;
                io2->generic.in.fname = io->openx.in.fname;
                
@@ -379,85 +383,44 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
                
                
        case RAW_OPEN_OPEN:
+               status = map_openx_open(0,
+                                       io->openold.in.open_mode, 
+                                       OPENX_OPEN_FUNC_OPEN, 
+                                       io->openold.in.fname,
+                                       io2);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto done;
+               }
+
                io2->generic.in.file_attr = io->openold.in.search_attrs;
                io2->generic.in.fname = io->openold.in.fname;
-               io2->generic.in.open_disposition = NTCREATEX_DISP_OPEN;
-               switch (io->openold.in.flags & OPEN_FLAGS_MODE_MASK) {
-               case OPEN_FLAGS_OPEN_READ:
-                       io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ;
-                       io->openold.out.rmode = DOS_OPEN_RDONLY;
-                       break;
-               case OPEN_FLAGS_OPEN_WRITE:
-                       io2->generic.in.access_mask = SEC_RIGHTS_FILE_WRITE;
-                       io->openold.out.rmode = DOS_OPEN_WRONLY;
-                       break;
-               case OPEN_FLAGS_OPEN_RDWR:
-               case 0xf: /* FCB mode */
-                       io2->generic.in.access_mask = SEC_RIGHTS_FILE_READ |
-                               SEC_RIGHTS_FILE_WRITE;
-                       io->openold.out.rmode = DOS_OPEN_RDWR; /* assume we got r/w */
-                       break;
-               default:
-                       DEBUG(2,("ntvfs_map_open(OPEN): invalid mode 0x%x\n",
-                                io->openold.in.flags & OPEN_FLAGS_MODE_MASK));
-                       status = NT_STATUS_INVALID_PARAMETER;
+
+               status = ntvfs->ops->openfile(ntvfs, req, io2);
+               break;
+
+       case RAW_OPEN_T2OPEN:
+               io2->generic.level         = RAW_OPEN_NTTRANS_CREATE;
+
+               if (io->t2open.in.open_func == 0) {
+                       status = NT_STATUS_OBJECT_NAME_COLLISION;
                        goto done;
                }
-               
-               switch (io->openold.in.flags & OPEN_FLAGS_DENY_MASK) {
-               case OPEN_FLAGS_DENY_DOS:
-                               /* DENY_DOS is quite strange - it depends on the filename! */
-                               if (is_exe_filename(io->openold.in.fname)) {
-                                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ | NTCREATEX_SHARE_ACCESS_WRITE;
-                               } else {
-                                       if ((io->openold.in.flags & OPEN_FLAGS_MODE_MASK) == 
-                                           OPEN_FLAGS_OPEN_READ) {
-                                               io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ;
-                                       } else {
-                                               io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
-                                       }
-                               }
-                               break;
-               case OPEN_FLAGS_DENY_ALL:
-                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_NONE;
-                       break;
-               case OPEN_FLAGS_DENY_WRITE:
-                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_READ;
-                       break;
-               case OPEN_FLAGS_DENY_READ:
-                       io2->generic.in.share_access = NTCREATEX_SHARE_ACCESS_WRITE;
-                       break;
-               case OPEN_FLAGS_DENY_NONE:
-                       io2->generic.in.share_access = 
-                               NTCREATEX_SHARE_ACCESS_WRITE |
-                               NTCREATEX_SHARE_ACCESS_READ;
-                       break;
-               case OPEN_FLAGS_DENY_MASK:
-                       io2->generic.in.share_access = 
-                               NTCREATEX_SHARE_ACCESS_READ|
-                               NTCREATEX_SHARE_ACCESS_WRITE;
-                       break;
-               default:
-                       DEBUG(2,("ntvfs_map_open(OPEN): invalid DENY 0x%x\n",
-                                io->openold.in.flags & OPEN_FLAGS_DENY_MASK));
-                       status = NT_STATUS_INVALID_PARAMETER;
+
+               status = map_openx_open(io->t2open.in.flags,
+                                       io->t2open.in.open_mode, 
+                                       io->t2open.in.open_func, 
+                                       io->t2open.in.fname,
+                                       io2);
+               if (!NT_STATUS_IS_OK(status)) {
                        goto done;
                }
 
-               status = ntvfs->ops->openfile(ntvfs, req, io2);
-               break;
+               io2->generic.in.file_attr        = io->t2open.in.file_attrs;
+               io2->generic.in.fname            = io->t2open.in.fname;
+               io2->generic.in.ea_list          = talloc_p(io2, struct smb_ea_list);
+               io2->generic.in.ea_list->num_eas = io->t2open.in.num_eas;
+               io2->generic.in.ea_list->eas     = io->t2open.in.eas;
 
-       case RAW_OPEN_T2OPEN:
-               io2->generic.level         = RAW_OPEN_OPENX;
-               io2->openx.in.flags        = io->t2open.in.flags;
-               io2->openx.in.open_mode    = io->t2open.in.open_mode;
-               io2->openx.in.search_attrs = 0;
-               io2->openx.in.file_attrs   = io->t2open.in.file_attrs;
-               io2->openx.in.write_time   = io->t2open.in.write_time;
-               io2->openx.in.open_func    = OPENX_OPEN_FUNC_OPEN;
-               io2->openx.in.size         = io->t2open.in.size;
-               io2->openx.in.timeout      = io->t2open.in.timeout;
-               io2->openx.in.fname        = io->t2open.in.fname;
                status = ntvfs->ops->openfile(ntvfs, req, io2);
                break;
 
@@ -508,7 +471,6 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
                status = NT_STATUS_INVALID_LEVEL;
                break;
        }
-
 done:
        return ntvfs_map_async_finish(req, status);
 }
index a53deda270ae76880a3c7efdc1f9a6eaed0e09cc..af0858f6399326332a522f28aba9b5111c939bed 100644 (file)
@@ -794,38 +794,6 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
        return NT_STATUS_OK;
 }
 
-/*
-  special handling for t2open
-*/
-static NTSTATUS pvfs_open_t2open(struct ntvfs_module_context *ntvfs,
-                                struct smbsrv_request *req, union smb_open *io)
-{
-       struct pvfs_state *pvfs = ntvfs->private_data;
-       struct pvfs_filename *name;
-       NTSTATUS status;
-
-       status = pvfs_resolve_name(pvfs, req, io->t2open.in.fname, 0, &name);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       if (io->t2open.in.open_func & OPENX_OPEN_FUNC_CREATE) {
-               if (!name->stream_exists) return NT_STATUS_ACCESS_DENIED;
-       }
-       if (io->t2open.in.open_func & OPENX_OPEN_FUNC_TRUNC) {
-               if (name->stream_exists) return NT_STATUS_ACCESS_DENIED;
-               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-       if ((io->t2open.in.open_func & 0xF) == OPENX_OPEN_FUNC_FAIL) {
-               if (!name->stream_exists) return NT_STATUS_ACCESS_DENIED;
-               return NT_STATUS_OBJECT_NAME_COLLISION;
-       }
-
-       talloc_free(name);
-
-       return ntvfs_map_open(req, io, ntvfs);
-}
-
 /*
   open a file
 */
@@ -844,10 +812,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
        uint32_t access_mask;
        BOOL stream_existed;
 
-       if (io->generic.level == RAW_OPEN_T2OPEN) {
-               return pvfs_open_t2open(ntvfs, req, io);
-       }
-
        /* use the generic mapping code to avoid implementing all the
           different open calls. */
        if (io->generic.level != RAW_OPEN_GENERIC &&
index 9fba5063b89355c539f773ca62b3b743957daa08..91423b05f843146fc4a7819a7399c4ed0dce6a7f 100644 (file)
@@ -430,7 +430,7 @@ void reply_open(struct smbsrv_request *req)
        REQ_TALLOC(oi, sizeof(*oi));
 
        oi->openold.level = RAW_OPEN_OPEN;
-       oi->openold.in.flags = SVAL(req->in.vwv, VWV(0));
+       oi->openold.in.open_mode = SVAL(req->in.vwv, VWV(0));
        oi->openold.in.search_attrs = SVAL(req->in.vwv, VWV(1));
 
        req_pull_ascii4(req, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
index e49267e16252ce9e7dc5049e4e46892cc689d9d6..6c2f9d37fa6f029beb39faf927f44da876e11d36 100644 (file)
@@ -1089,14 +1089,14 @@ static BOOL handler_open(int instance)
        NTSTATUS status[NSERVERS];
 
        parm[0].openold.level = RAW_OPEN_OPEN;
-       parm[0].openold.in.flags = gen_bits_mask2(0xF, 0xFFFF);
+       parm[0].openold.in.open_mode = gen_bits_mask2(0xF, 0xFFFF);
        parm[0].openold.in.search_attrs = gen_attrib();
        parm[0].openold.in.fname = gen_fname_open(instance);
 
        if (!options.use_oplocks) {
                /* mask out oplocks */
-               parm[0].openold.in.flags &= ~(OPENX_FLAGS_REQUEST_OPLOCK|
-                                          OPENX_FLAGS_REQUEST_BATCH_OPLOCK);
+               parm[0].openold.in.open_mode &= ~(OPENX_FLAGS_REQUEST_OPLOCK|
+                                                 OPENX_FLAGS_REQUEST_BATCH_OPLOCK);
        }
        
        GEN_COPY_PARM;
index 044fe9ebb4f492f949b42db77f7757856aedb3a3..00c2fac74aa6d93a0ee8d195dd865dcd98fe2e21 100644 (file)
                goto done; \
        }} while (0)
 
-/*
-  check that an EA has the right value 
-*/
-static BOOL check_ea(struct smbcli_state *cli, TALLOC_CTX *mem_ctx,
-                    const char *fname, const char *eaname, const char *value)
-{
-       union smb_fileinfo info;
-       NTSTATUS status;
-       BOOL ret = True;
-       int i;
-
-       info.all_eas.level = RAW_FILEINFO_ALL_EAS;
-       info.all_eas.in.fname = fname;
-
-       status = smb_raw_pathinfo(cli->tree, mem_ctx, &info);
-       CHECK_STATUS(status, NT_STATUS_OK);
-
-       for (i=0;i<info.all_eas.out.num_eas;i++) {
-               if (StrCaseCmp(eaname, info.all_eas.out.eas[i].name.s) == 0) {
-                       if (value == NULL) {
-                               printf("attr '%s' should not be present\n", eaname);
-                               return False;
-                       }
-                       if (strlen(value) == info.all_eas.out.eas[i].value.length &&
-                           memcmp(value, 
-                                  info.all_eas.out.eas[i].value.data,
-                                  info.all_eas.out.eas[i].value.length) == 0) {
-                               return True;
-                       } else {
-                               printf("attr '%s' has wrong value '%*.*s'\n", 
-                                      eaname, 
-                                      info.all_eas.out.eas[i].value.length,
-                                      info.all_eas.out.eas[i].value.length,
-                                      info.all_eas.out.eas[i].value.data);
-                               ret = False;
-                               goto done;
-                       }
-               }
-       }
-
-       if (value != NULL) {
-               printf("attr '%s' not found\n", eaname);
-               ret = False;
-       }
-
-done:
-       return ret;
-}
-
 static DATA_BLOB data_blob_string_const(const char *str)
 {
        DATA_BLOB blob;
@@ -91,6 +42,12 @@ static DATA_BLOB data_blob_string_const(const char *str)
        return blob;
 }
 
+static BOOL check_ea(struct smbcli_state *cli, 
+                    const char *fname, const char *eaname, const char *value)
+{
+       NTSTATUS status = torture_check_ea(cli, fname, eaname, value);
+       return NT_STATUS_IS_OK(status);
+}
 
 static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 {
@@ -121,7 +78,7 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.fnum;
        
-       ret &= check_ea(cli, mem_ctx, fname, "EAONE", NULL);
+       ret &= check_ea(cli, fname, "EAONE", NULL);
 
        printf("Adding first EA\n");
        setfile.generic.level = RAW_SFILEINFO_EA_SET;
@@ -133,7 +90,7 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_setfileinfo(cli->tree, &setfile);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       ret &= check_ea(cli, mem_ctx, fname, "EAONE", "VALUE1");
+       ret &= check_ea(cli, fname, "EAONE", "VALUE1");
 
        setfile.ea_set.in.ea.name.s = "SECONDEA";
        setfile.ea_set.in.ea.value = data_blob_string_const("ValueTwo");
@@ -142,16 +99,16 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_setfileinfo(cli->tree, &setfile);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       ret &= check_ea(cli, mem_ctx, fname, "EAONE", "VALUE1");
-       ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", "ValueTwo");
+       ret &= check_ea(cli, fname, "EAONE", "VALUE1");
+       ret &= check_ea(cli, fname, "SECONDEA", "ValueTwo");
 
        printf("Modifying 2nd EA\n");
        setfile.ea_set.in.ea.value = data_blob_string_const(" Changed Value");
        status = smb_raw_setfileinfo(cli->tree, &setfile);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       ret &= check_ea(cli, mem_ctx, fname, "EAONE", "VALUE1");
-       ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", " Changed Value");
+       ret &= check_ea(cli, fname, "EAONE", "VALUE1");
+       ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
 
        printf("Setting a NULL EA\n");
        setfile.ea_set.in.ea.value = data_blob(NULL, 0);
@@ -159,9 +116,9 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_setfileinfo(cli->tree, &setfile);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       ret &= check_ea(cli, mem_ctx, fname, "EAONE", "VALUE1");
-       ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", " Changed Value");
-       ret &= check_ea(cli, mem_ctx, fname, "NULLEA", NULL);
+       ret &= check_ea(cli, fname, "EAONE", "VALUE1");
+       ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
+       ret &= check_ea(cli, fname, "NULLEA", NULL);
 
        printf("Deleting first EA\n");
        setfile.ea_set.in.ea.flags = 0;
@@ -170,8 +127,8 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_setfileinfo(cli->tree, &setfile);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       ret &= check_ea(cli, mem_ctx, fname, "EAONE", NULL);
-       ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", " Changed Value");
+       ret &= check_ea(cli, fname, "EAONE", NULL);
+       ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
 
        printf("Deleting second EA\n");
        setfile.ea_set.in.ea.flags = 0;
@@ -180,8 +137,8 @@ static BOOL test_eas(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        status = smb_raw_setfileinfo(cli->tree, &setfile);
        CHECK_STATUS(status, NT_STATUS_OK);
 
-       ret &= check_ea(cli, mem_ctx, fname, "EAONE", NULL);
-       ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", NULL);
+       ret &= check_ea(cli, fname, "EAONE", NULL);
+       ret &= check_ea(cli, fname, "SECONDEA", NULL);
 
 done:
        smbcli_close(cli->tree, fnum);
@@ -241,10 +198,10 @@ static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.fnum;
        
-       ret &= check_ea(cli, mem_ctx, fname, "EAONE", NULL);
-       ret &= check_ea(cli, mem_ctx, fname, "1st EA", "Value One");
-       ret &= check_ea(cli, mem_ctx, fname, "2nd EA", "Second Value");
-       ret &= check_ea(cli, mem_ctx, fname, "and 3rd", "final value");
+       ret &= check_ea(cli, fname, "EAONE", NULL);
+       ret &= check_ea(cli, fname, "1st EA", "Value One");
+       ret &= check_ea(cli, fname, "2nd EA", "Second Value");
+       ret &= check_ea(cli, fname, "and 3rd", "final value");
 
        smbcli_close(cli->tree, fnum);
 
@@ -261,10 +218,10 @@ static BOOL test_nttrans_create(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.ntcreatex.out.fnum;
        
-       ret &= check_ea(cli, mem_ctx, fname, "1st EA", "Value One");
-       ret &= check_ea(cli, mem_ctx, fname, "2nd EA", "Second Value");
-       ret &= check_ea(cli, mem_ctx, fname, "and 3rd", "final value");
-       ret &= check_ea(cli, mem_ctx, fname, "Fourth EA", NULL);
+       ret &= check_ea(cli, fname, "1st EA", "Value One");
+       ret &= check_ea(cli, fname, "2nd EA", "Second Value");
+       ret &= check_ea(cli, fname, "and 3rd", "final value");
+       ret &= check_ea(cli, fname, "Fourth EA", NULL);
 
 done:
        smbcli_close(cli->tree, fnum);
index a1cc76ebd8b4be13b033f4c09ec982169af14a2f..f3d5daeadeb9b71ac2bf2c0b7fdf3f4f85fdef20 100644 (file)
@@ -160,7 +160,7 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
 
        io.openold.level = RAW_OPEN_OPEN;
        io.openold.in.fname = fname;
-       io.openold.in.flags = OPEN_FLAGS_FCB;
+       io.openold.in.open_mode = OPEN_FLAGS_FCB;
        io.openold.in.search_attrs = 0;
        status = smb_raw_open(cli->tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
@@ -187,21 +187,21 @@ 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.flags = OPEN_FLAGS_OPEN_READ;
+       io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
        status = smb_raw_open(cli->tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.fnum;
        CHECK_RDWR(fnum, RDWR_RDONLY);
        smbcli_close(cli->tree, fnum);
 
-       io.openold.in.flags = OPEN_FLAGS_OPEN_WRITE;
+       io.openold.in.open_mode = OPEN_FLAGS_OPEN_WRITE;
        status = smb_raw_open(cli->tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.fnum;
        CHECK_RDWR(fnum, RDWR_WRONLY);
        smbcli_close(cli->tree, fnum);
 
-       io.openold.in.flags = OPEN_FLAGS_OPEN_RDWR;
+       io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR;
        status = smb_raw_open(cli->tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.fnum;
@@ -209,22 +209,22 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        smbcli_close(cli->tree, fnum);
 
        /* check the share modes roughly - not a complete matrix */
-       io.openold.in.flags = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
+       io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_WRITE;
        status = smb_raw_open(cli->tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.fnum;
        CHECK_RDWR(fnum, RDWR_RDWR);
        
-       if (io.openold.in.flags != io.openold.out.rmode) {
-               printf("(%s) rmode should equal flags - 0x%x 0x%x\n",
-                      __location__, io.openold.out.rmode, io.openold.in.flags);
+       if (io.openold.in.open_mode != io.openold.out.rmode) {
+               printf("(%s) rmode should equal open_mode - 0x%x 0x%x\n",
+                      __location__, io.openold.out.rmode, io.openold.in.open_mode);
        }
 
-       io.openold.in.flags = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
+       io.openold.in.open_mode = OPEN_FLAGS_OPEN_RDWR | OPEN_FLAGS_DENY_NONE;
        status = smb_raw_open(cli->tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
 
-       io.openold.in.flags = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
+       io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ | OPEN_FLAGS_DENY_NONE;
        status = smb_raw_open(cli->tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum2 = io.openold.out.fnum;
@@ -237,7 +237,7 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        io.openold.level = RAW_OPEN_OPEN;
        io.openold.in.fname = fname;
        io.openold.in.search_attrs = 0;
-       io.openold.in.flags = OPEN_FLAGS_OPEN_READ;
+       io.openold.in.open_mode = OPEN_FLAGS_OPEN_READ;
        status = smb_raw_open(cli->tree, mem_ctx, &io);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.openold.out.fnum;
@@ -319,12 +319,16 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                               i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_func);
                        ret = False;
                }
-               if (NT_STATUS_IS_OK(status) || open_funcs[i].with_file) {
+               if (NT_STATUS_IS_OK(status)) {
                        smbcli_close(cli->tree, io.openx.out.fnum);
+               }
+               if (open_funcs[i].with_file) {
                        smbcli_unlink(cli->tree, fname);
                }
        }
 
+       smbcli_unlink(cli->tree, fname);
+
        /* 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);
@@ -434,6 +438,10 @@ static BOOL test_openx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
        smbcli_close(cli->tree, io.openx.out.fnum);
 
+       io.openx.in.fname = "\\A.+,;=[].B";
+       status = smb_raw_open(cli->tree, mem_ctx, &io);
+       CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+
 done:
        smbcli_close(cli->tree, fnum);
        smbcli_unlink(cli->tree, fname);
@@ -445,9 +453,7 @@ done:
 /*
   test RAW_OPEN_T2OPEN
 
-  I can't work out how to get win2003 to accept a create file via TRANS2_OPEN, which
-  is why you see all the ACCESS_DENIED results below. When we finally work this out then this
-  test will make more sense
+  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)
 {
@@ -468,15 +474,15 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                { 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_ACCESS_DENIED },
+               { 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_ACCESS_DENIED },
+               { 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_ACCESS_DENIED },
-               { OPENX_OPEN_FUNC_TRUNC,                          True,  NT_STATUS_ACCESS_DENIED },
-               { OPENX_OPEN_FUNC_TRUNC,                          False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
-               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, True,  NT_STATUS_ACCESS_DENIED },
-               { OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_ACCESS_DENIED },
+               { 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);
@@ -490,20 +496,26 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        printf("Checking RAW_OPEN_T2OPEN\n");
 
        io.t2open.level = RAW_OPEN_T2OPEN;
-       io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO | 
-               OPENX_FLAGS_EA_LEN | OPENX_FLAGS_EXTENDED_RETURN;
+       io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
        io.t2open.in.open_mode = OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR;
        io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
+       io.t2open.in.search_attrs = 0;
        io.t2open.in.file_attrs = 0;
        io.t2open.in.write_time = 0;
        io.t2open.in.size = 0;
        io.t2open.in.timeout = 0;
 
-       io.t2open.in.eas = talloc_p(mem_ctx, struct ea_struct);
-       io.t2open.in.num_eas = 1;
+       io.t2open.in.num_eas = 3;
+       io.t2open.in.eas = talloc_array_p(mem_ctx, struct ea_struct, io.t2open.in.num_eas);
        io.t2open.in.eas[0].flags = 0;
-       io.t2open.in.eas[0].name.s = "EAONE";
-       io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "1", 1);
+       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[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[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);
 
        /* check all combinations of open_func */
        for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
@@ -526,25 +538,35 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        }
 
        smbcli_unlink(cli->tree, fname1);
+       smbcli_unlink(cli->tree, fname2);
 
        /* check the basic return fields */
-       fnum = create_complex_file(cli, mem_ctx, fname);
-       smbcli_close(cli->tree, fnum);
        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);
        CHECK_STATUS(status, NT_STATUS_OK);
        fnum = io.t2open.out.fnum;
 
        CHECK_ALL_INFO(io.t2open.out.size, size);
+#if 0
+       /* windows appears to leak uninitialised memory here */
        CHECK_VAL(io.t2open.out.write_time, 0);
+#endif
        CHECK_ALL_INFO(io.t2open.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
        CHECK_VAL(io.t2open.out.access, OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR);
        CHECK_VAL(io.t2open.out.ftype, 0);
        CHECK_VAL(io.t2open.out.devstate, 0);
-       CHECK_VAL(io.t2open.out.action, OPENX_ACTION_EXISTED);
+       CHECK_VAL(io.t2open.out.action, OPENX_ACTION_CREATED);
        smbcli_close(cli->tree, fnum);
 
+       status = torture_check_ea(cli, fname, ".CLASSINFO", "first value");
+       CHECK_STATUS(status, NT_STATUS_OK);
+       status = torture_check_ea(cli, fname, "EA TWO", "foo");
+       CHECK_STATUS(status, NT_STATUS_OK);
+       status = torture_check_ea(cli, fname, "X THIRD", "xy");
+       CHECK_STATUS(status, NT_STATUS_OK);
+
        /* now check the search attrib for hidden files - win2003 ignores this? */
        SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
        CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
@@ -564,14 +586,15 @@ static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
        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);
-       CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+       CHECK_STATUS(status, NT_STATUS_OK);
 
        /* check timeout on create - win2003 ignores the timeout! */
        io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
        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);
-       CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
+       CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
 
 done:
        smbcli_close(cli->tree, fnum);
index f159c4e15455d1402666442a54500a8f12d12627..395b9ff559e9d0ceb7956d94d0da17c0d240e5b5 100644 (file)
@@ -1150,7 +1150,7 @@ static BOOL test_os2_delete(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
                }
 
                if (i>0) {
-                       io2.t2fnext.in.resume_key = 0;
+                       io2.t2fnext.in.resume_key = result.list[i-1].ea_size.resume_key;
                        io2.t2fnext.in.last_name = result.list[i-1].ea_size.name.s;
                }
        } while (NT_STATUS_IS_OK(status) && result.count != 0);
index 63700868384216b131533450e9e1795341f2f93a..05b06c6d0e842572fbbbb130a47cd9333af163c7 100644 (file)
@@ -356,3 +356,59 @@ NTSTATUS torture_set_sparse(struct smbcli_tree *tree, int fnum)
 
        return status;
 }
+
+/*
+  check that an EA has the right value 
+*/
+NTSTATUS torture_check_ea(struct smbcli_state *cli, 
+                         const char *fname, const char *eaname, const char *value)
+{
+       union smb_fileinfo info;
+       NTSTATUS status;
+       int i;
+       TALLOC_CTX *mem_ctx = talloc(cli, 0);
+
+       info.all_eas.level = RAW_FILEINFO_ALL_EAS;
+       info.all_eas.in.fname = fname;
+
+       status = smb_raw_pathinfo(cli->tree, mem_ctx, &info);
+       if (!NT_STATUS_IS_OK(status)) {
+               talloc_free(mem_ctx);
+               return status;
+       }
+
+       for (i=0;i<info.all_eas.out.num_eas;i++) {
+               if (StrCaseCmp(eaname, info.all_eas.out.eas[i].name.s) == 0) {
+                       if (value == NULL) {
+                               printf("attr '%s' should not be present\n", eaname);
+                               talloc_free(mem_ctx);
+                               return NT_STATUS_EA_CORRUPT_ERROR;
+                       }
+                       if (strlen(value) == info.all_eas.out.eas[i].value.length &&
+                           memcmp(value, 
+                                  info.all_eas.out.eas[i].value.data,
+                                  info.all_eas.out.eas[i].value.length) == 0) {
+                               talloc_free(mem_ctx);
+                               return NT_STATUS_OK;
+                       } else {
+                               printf("attr '%s' has wrong value '%*.*s'\n", 
+                                      eaname, 
+                                      info.all_eas.out.eas[i].value.length,
+                                      info.all_eas.out.eas[i].value.length,
+                                      info.all_eas.out.eas[i].value.data);
+                               talloc_free(mem_ctx);
+                               return NT_STATUS_EA_CORRUPT_ERROR;
+                       }
+               }
+       }
+
+       talloc_free(mem_ctx);
+
+       if (value != NULL) {
+               printf("attr '%s' not found\n", eaname);
+               return NT_STATUS_NONEXISTENT_EA_ENTRY;
+       }
+
+       return NT_STATUS_OK;
+}
+