summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2004-12-13 10:48:21 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:07:22 -0500
commitfbd8c61ff7a7c41d16c400ddb87ad290f4af167d (patch)
treef8755bbce13d03e39e58c86ba6a541d1ff1cd8c3
parente08e2645de81a89902adcd84e405bfc5baf1fab6 (diff)
downloadsamba-fbd8c61ff7a7c41d16c400ddb87ad290f4af167d.tar.gz
samba-fbd8c61ff7a7c41d16c400ddb87ad290f4af167d.tar.bz2
samba-fbd8c61ff7a7c41d16c400ddb87ad290f4af167d.zip
r4173: - new t2open code, that can cope with "create with EAs". Many thanks
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 (This used to be commit a56d95ad89b4f32a05974c4fe9a816d67aa369e3)
-rw-r--r--source4/include/smb_interfaces.h5
-rw-r--r--source4/libcli/raw/clisession.c2
-rw-r--r--source4/libcli/raw/rawfile.c12
-rw-r--r--source4/ntvfs/ntvfs_generic.c332
-rw-r--r--source4/ntvfs/posix/pvfs_open.c36
-rw-r--r--source4/smb_server/reply.c2
-rw-r--r--source4/torture/gentest.c6
-rw-r--r--source4/torture/raw/eas.c97
-rw-r--r--source4/torture/raw/open.c89
-rw-r--r--source4/torture/raw/search.c2
-rw-r--r--source4/torture/torture_util.c56
11 files changed, 301 insertions, 338 deletions
diff --git a/source4/include/smb_interfaces.h b/source4/include/smb_interfaces.h
index 4b767c8d70..4ba8ea3442 100644
--- a/source4/include/smb_interfaces.h
+++ b/source4/include/smb_interfaces.h
@@ -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;
diff --git a/source4/libcli/raw/clisession.c b/source4/libcli/raw/clisession.c
index 4f77145d4d..519f112ceb 100644
--- a/source4/libcli/raw/clisession.c
+++ b/source4/libcli/raw/clisession.c
@@ -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;
diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c
index 028d8734e1..bfd96bd360 100644
--- a/source4/libcli/raw/rawfile.c
+++ b/source4/libcli/raw/rawfile.c
@@ -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;
diff --git a/source4/ntvfs/ntvfs_generic.c b/source4/ntvfs/ntvfs_generic.c
index 49de8944ff..407bd38f74 100644
--- a/source4/ntvfs/ntvfs_generic.c
+++ b/source4/ntvfs/ntvfs_generic.c
@@ -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);
}
diff --git a/source4/ntvfs/posix/pvfs_open.c b/source4/ntvfs/posix/pvfs_open.c
index a53deda270..af0858f639 100644
--- a/source4/ntvfs/posix/pvfs_open.c
+++ b/source4/ntvfs/posix/pvfs_open.c
@@ -795,38 +795,6 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
}
/*
- 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
*/
NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
@@ -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 &&
diff --git a/source4/smb_server/reply.c b/source4/smb_server/reply.c
index 9fba5063b8..91423b05f8 100644
--- a/source4/smb_server/reply.c
+++ b/source4/smb_server/reply.c
@@ -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);
diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c
index e49267e162..6c2f9d37fa 100644
--- a/source4/torture/gentest.c
+++ b/source4/torture/gentest.c
@@ -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;
diff --git a/source4/torture/raw/eas.c b/source4/torture/raw/eas.c
index 044fe9ebb4..00c2fac74a 100644
--- a/source4/torture/raw/eas.c
+++ b/source4/torture/raw/eas.c
@@ -34,55 +34,6 @@
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);
diff --git a/source4/torture/raw/open.c b/source4/torture/raw/open.c
index a1cc76ebd8..f3d5daeade 100644
--- a/source4/torture/raw/open.c
+++ b/source4/torture/raw/open.c
@@ -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);
diff --git a/source4/torture/raw/search.c b/source4/torture/raw/search.c
index f159c4e154..395b9ff559 100644
--- a/source4/torture/raw/search.c
+++ b/source4/torture/raw/search.c
@@ -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);
diff --git a/source4/torture/torture_util.c b/source4/torture/torture_util.c
index 6370086838..05b06c6d0e 100644
--- a/source4/torture/torture_util.c
+++ b/source4/torture/torture_util.c
@@ -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;
+}
+