mirror of
https://github.com/samba-team/samba.git
synced 2025-01-22 22:04:08 +03:00
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)
This commit is contained in:
parent
e08e2645de
commit
fbd8c61ff7
@ -1133,6 +1133,7 @@ union smb_open {
|
|||||||
struct {
|
struct {
|
||||||
uint16_t flags;
|
uint16_t flags;
|
||||||
uint16_t open_mode;
|
uint16_t open_mode;
|
||||||
|
uint16_t search_attrs;
|
||||||
uint16_t file_attrs;
|
uint16_t file_attrs;
|
||||||
time_t write_time;
|
time_t write_time;
|
||||||
uint16_t open_func;
|
uint16_t open_func;
|
||||||
@ -1152,7 +1153,7 @@ union smb_open {
|
|||||||
uint16_t ftype;
|
uint16_t ftype;
|
||||||
uint16_t devstate;
|
uint16_t devstate;
|
||||||
uint16_t action;
|
uint16_t action;
|
||||||
uint32_t unknown;
|
uint32_t file_id;
|
||||||
} out;
|
} out;
|
||||||
} t2open;
|
} t2open;
|
||||||
|
|
||||||
@ -1161,7 +1162,7 @@ union smb_open {
|
|||||||
enum smb_open_level level;
|
enum smb_open_level level;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint16_t flags;
|
uint16_t open_mode;
|
||||||
uint16_t search_attrs;
|
uint16_t search_attrs;
|
||||||
const char *fname;
|
const char *fname;
|
||||||
} in;
|
} in;
|
||||||
|
@ -51,7 +51,7 @@ struct smbcli_session *smbcli_session_init(struct smbcli_transport *transport)
|
|||||||
|
|
||||||
capabilities = transport->negotiate.capabilities;
|
capabilities = transport->negotiate.capabilities;
|
||||||
|
|
||||||
flags2 = FLAGS2_LONG_PATH_COMPONENTS;
|
flags2 = FLAGS2_LONG_PATH_COMPONENTS | FLAGS2_EXTENDED_ATTRIBUTES;
|
||||||
|
|
||||||
if (capabilities & CAP_UNICODE) {
|
if (capabilities & CAP_UNICODE) {
|
||||||
flags2 |= FLAGS2_UNICODE_STRINGS;
|
flags2 |= FLAGS2_UNICODE_STRINGS;
|
||||||
|
@ -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(0), parms->t2open.in.flags);
|
||||||
SSVAL(t2.in.params.data, VWV(1), parms->t2open.in.open_mode);
|
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);
|
SSVAL(t2.in.params.data, VWV(3), parms->t2open.in.file_attrs);
|
||||||
raw_push_dos_date(tree->session->transport,
|
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);
|
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(7), parms->t2open.in.size);
|
||||||
SIVAL(t2.in.params.data, VWV(9), parms->t2open.in.timeout);
|
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);
|
SSVAL(t2.in.params.data, VWV(13), 0);
|
||||||
|
|
||||||
smbcli_blob_append_string(tree->session, mem_ctx,
|
smbcli_blob_append_string(tree->session, mem_ctx,
|
||||||
&t2.in.params, parms->t2open.in.fname,
|
&t2.in.params, parms->t2open.in.fname,
|
||||||
STR_TERMINATE);
|
STR_TERMINATE);
|
||||||
|
|
||||||
ea_put_list(t2.in.data.data, parms->t2open.in.num_eas, parms->t2open.in.eas);
|
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.ftype = SVAL(t2.out.params.data, VWV(7));
|
||||||
parms->t2open.out.devstate = SVAL(t2.out.params.data, VWV(8));
|
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.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;
|
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:
|
case RAW_OPEN_OPEN:
|
||||||
SETUP_REQUEST(SMBopen, 2, 0);
|
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);
|
SSVAL(req->out.vwv, VWV(1), parms->openold.in.search_attrs);
|
||||||
smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE);
|
smbcli_req_append_ascii4(req, parms->openold.in.fname, STR_TERMINATE);
|
||||||
break;
|
break;
|
||||||
|
@ -150,13 +150,6 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req,
|
|||||||
union smb_setfileinfo *sf;
|
union smb_setfileinfo *sf;
|
||||||
uint_t state;
|
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)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
return 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.attrib = io2->generic.out.attrib;
|
||||||
io->openold.out.write_time = nt_time_to_unix(io2->generic.out.write_time);
|
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.size = io2->generic.out.size;
|
||||||
io->openold.out.rmode = io->openold.in.flags;
|
io->openold.out.rmode = io->openold.in.open_mode;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RAW_OPEN_OPENX:
|
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.attrib = io2->generic.out.attrib;
|
||||||
io->openx.out.write_time = nt_time_to_unix(io2->generic.out.write_time);
|
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.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.ftype = 0;
|
||||||
io->openx.out.devstate = 0;
|
io->openx.out.devstate = 0;
|
||||||
io->openx.out.action = io2->generic.out.create_action;
|
io->openx.out.action = io2->generic.out.create_action;
|
||||||
@ -190,15 +184,15 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RAW_OPEN_T2OPEN:
|
case RAW_OPEN_T2OPEN:
|
||||||
io->t2open.out.fnum = io2->openx.out.fnum;
|
io->t2open.out.fnum = io2->generic.out.fnum;
|
||||||
io->t2open.out.attrib = io2->openx.out.attrib;
|
io->t2open.out.attrib = io2->generic.out.attrib;
|
||||||
io->t2open.out.write_time = 0;
|
io->t2open.out.write_time = nt_time_to_unix(io2->generic.out.write_time);
|
||||||
io->t2open.out.size = io2->openx.out.size;
|
io->t2open.out.size = io2->generic.out.size;
|
||||||
io->t2open.out.access = io->t2open.in.open_mode;
|
io->t2open.out.access = io->t2open.in.open_mode;
|
||||||
io->t2open.out.ftype = io2->openx.out.ftype;
|
io->t2open.out.ftype = 0;
|
||||||
io->t2open.out.devstate = io2->openx.out.devstate;
|
io->t2open.out.devstate = 0;
|
||||||
io->t2open.out.action = io2->openx.out.action;
|
io->t2open.out.action = io2->generic.out.create_action;
|
||||||
io->t2open.out.unknown = 0;
|
io->t2open.out.file_id = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RAW_OPEN_MKNEW:
|
case RAW_OPEN_MKNEW:
|
||||||
@ -248,6 +242,106 @@ static NTSTATUS ntvfs_map_open_finish(struct smbsrv_request *req,
|
|||||||
return NT_STATUS_OK;
|
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
|
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) {
|
switch (io->generic.level) {
|
||||||
case RAW_OPEN_OPENX:
|
case RAW_OPEN_OPENX:
|
||||||
if (io->openx.in.flags & OPENX_FLAGS_REQUEST_OPLOCK) {
|
status = map_openx_open(io->openx.in.flags,
|
||||||
io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_OPLOCK;
|
io->openx.in.open_mode,
|
||||||
}
|
io->openx.in.open_func,
|
||||||
if (io->openx.in.flags & OPENX_FLAGS_REQUEST_BATCH_OPLOCK) {
|
io->openx.in.fname,
|
||||||
io2->generic.in.flags |= NTCREATEX_FLAGS_REQUEST_BATCH_OPLOCK;
|
io2);
|
||||||
}
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
|
||||||
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;
|
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;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
io2->generic.in.alloc_size = 0;
|
|
||||||
io2->generic.in.file_attr = io->openx.in.file_attrs;
|
io2->generic.in.file_attr = io->openx.in.file_attrs;
|
||||||
io2->generic.in.fname = io->openx.in.fname;
|
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:
|
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.file_attr = io->openold.in.search_attrs;
|
||||||
io2->generic.in.fname = io->openold.in.fname;
|
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;
|
|
||||||
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;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = ntvfs->ops->openfile(ntvfs, req, io2);
|
status = ntvfs->ops->openfile(ntvfs, req, io2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RAW_OPEN_T2OPEN:
|
case RAW_OPEN_T2OPEN:
|
||||||
io2->generic.level = RAW_OPEN_OPENX;
|
io2->generic.level = RAW_OPEN_NTTRANS_CREATE;
|
||||||
io2->openx.in.flags = io->t2open.in.flags;
|
|
||||||
io2->openx.in.open_mode = io->t2open.in.open_mode;
|
if (io->t2open.in.open_func == 0) {
|
||||||
io2->openx.in.search_attrs = 0;
|
status = NT_STATUS_OBJECT_NAME_COLLISION;
|
||||||
io2->openx.in.file_attrs = io->t2open.in.file_attrs;
|
goto done;
|
||||||
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;
|
status = map_openx_open(io->t2open.in.flags,
|
||||||
io2->openx.in.timeout = io->t2open.in.timeout;
|
io->t2open.in.open_mode,
|
||||||
io2->openx.in.fname = io->t2open.in.fname;
|
io->t2open.in.open_func,
|
||||||
|
io->t2open.in.fname,
|
||||||
|
io2);
|
||||||
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
status = ntvfs->ops->openfile(ntvfs, req, io2);
|
status = ntvfs->ops->openfile(ntvfs, req, io2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -508,7 +471,6 @@ NTSTATUS ntvfs_map_open(struct smbsrv_request *req, union smb_open *io,
|
|||||||
status = NT_STATUS_INVALID_LEVEL;
|
status = NT_STATUS_INVALID_LEVEL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return ntvfs_map_async_finish(req, status);
|
return ntvfs_map_async_finish(req, status);
|
||||||
}
|
}
|
||||||
|
@ -794,38 +794,6 @@ static NTSTATUS pvfs_open_setup_retry(struct ntvfs_module_context *ntvfs,
|
|||||||
return NT_STATUS_OK;
|
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
|
open a file
|
||||||
*/
|
*/
|
||||||
@ -844,10 +812,6 @@ NTSTATUS pvfs_open(struct ntvfs_module_context *ntvfs,
|
|||||||
uint32_t access_mask;
|
uint32_t access_mask;
|
||||||
BOOL stream_existed;
|
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
|
/* use the generic mapping code to avoid implementing all the
|
||||||
different open calls. */
|
different open calls. */
|
||||||
if (io->generic.level != RAW_OPEN_GENERIC &&
|
if (io->generic.level != RAW_OPEN_GENERIC &&
|
||||||
|
@ -430,7 +430,7 @@ void reply_open(struct smbsrv_request *req)
|
|||||||
REQ_TALLOC(oi, sizeof(*oi));
|
REQ_TALLOC(oi, sizeof(*oi));
|
||||||
|
|
||||||
oi->openold.level = RAW_OPEN_OPEN;
|
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));
|
oi->openold.in.search_attrs = SVAL(req->in.vwv, VWV(1));
|
||||||
|
|
||||||
req_pull_ascii4(req, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
|
req_pull_ascii4(req, &oi->openold.in.fname, req->in.data, STR_TERMINATE);
|
||||||
|
@ -1089,14 +1089,14 @@ static BOOL handler_open(int instance)
|
|||||||
NTSTATUS status[NSERVERS];
|
NTSTATUS status[NSERVERS];
|
||||||
|
|
||||||
parm[0].openold.level = RAW_OPEN_OPEN;
|
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.search_attrs = gen_attrib();
|
||||||
parm[0].openold.in.fname = gen_fname_open(instance);
|
parm[0].openold.in.fname = gen_fname_open(instance);
|
||||||
|
|
||||||
if (!options.use_oplocks) {
|
if (!options.use_oplocks) {
|
||||||
/* mask out oplocks */
|
/* mask out oplocks */
|
||||||
parm[0].openold.in.flags &= ~(OPENX_FLAGS_REQUEST_OPLOCK|
|
parm[0].openold.in.open_mode &= ~(OPENX_FLAGS_REQUEST_OPLOCK|
|
||||||
OPENX_FLAGS_REQUEST_BATCH_OPLOCK);
|
OPENX_FLAGS_REQUEST_BATCH_OPLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
GEN_COPY_PARM;
|
GEN_COPY_PARM;
|
||||||
|
@ -34,55 +34,6 @@
|
|||||||
goto done; \
|
goto done; \
|
||||||
}} while (0)
|
}} 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)
|
static DATA_BLOB data_blob_string_const(const char *str)
|
||||||
{
|
{
|
||||||
DATA_BLOB blob;
|
DATA_BLOB blob;
|
||||||
@ -91,6 +42,12 @@ static DATA_BLOB data_blob_string_const(const char *str)
|
|||||||
return blob;
|
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)
|
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);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.ntcreatex.out.fnum;
|
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");
|
printf("Adding first EA\n");
|
||||||
setfile.generic.level = RAW_SFILEINFO_EA_SET;
|
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);
|
status = smb_raw_setfileinfo(cli->tree, &setfile);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
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.name.s = "SECONDEA";
|
||||||
setfile.ea_set.in.ea.value = data_blob_string_const("ValueTwo");
|
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);
|
status = smb_raw_setfileinfo(cli->tree, &setfile);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
|
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "EAONE", "VALUE1");
|
ret &= check_ea(cli, fname, "EAONE", "VALUE1");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", "ValueTwo");
|
ret &= check_ea(cli, fname, "SECONDEA", "ValueTwo");
|
||||||
|
|
||||||
printf("Modifying 2nd EA\n");
|
printf("Modifying 2nd EA\n");
|
||||||
setfile.ea_set.in.ea.value = data_blob_string_const(" Changed Value");
|
setfile.ea_set.in.ea.value = data_blob_string_const(" Changed Value");
|
||||||
status = smb_raw_setfileinfo(cli->tree, &setfile);
|
status = smb_raw_setfileinfo(cli->tree, &setfile);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
|
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "EAONE", "VALUE1");
|
ret &= check_ea(cli, fname, "EAONE", "VALUE1");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", " Changed Value");
|
ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
|
||||||
|
|
||||||
printf("Setting a NULL EA\n");
|
printf("Setting a NULL EA\n");
|
||||||
setfile.ea_set.in.ea.value = data_blob(NULL, 0);
|
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);
|
status = smb_raw_setfileinfo(cli->tree, &setfile);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
|
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "EAONE", "VALUE1");
|
ret &= check_ea(cli, fname, "EAONE", "VALUE1");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", " Changed Value");
|
ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "NULLEA", NULL);
|
ret &= check_ea(cli, fname, "NULLEA", NULL);
|
||||||
|
|
||||||
printf("Deleting first EA\n");
|
printf("Deleting first EA\n");
|
||||||
setfile.ea_set.in.ea.flags = 0;
|
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);
|
status = smb_raw_setfileinfo(cli->tree, &setfile);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
|
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "EAONE", NULL);
|
ret &= check_ea(cli, fname, "EAONE", NULL);
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", " Changed Value");
|
ret &= check_ea(cli, fname, "SECONDEA", " Changed Value");
|
||||||
|
|
||||||
printf("Deleting second EA\n");
|
printf("Deleting second EA\n");
|
||||||
setfile.ea_set.in.ea.flags = 0;
|
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);
|
status = smb_raw_setfileinfo(cli->tree, &setfile);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
|
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "EAONE", NULL);
|
ret &= check_ea(cli, fname, "EAONE", NULL);
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "SECONDEA", NULL);
|
ret &= check_ea(cli, fname, "SECONDEA", NULL);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
smbcli_close(cli->tree, fnum);
|
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);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.ntcreatex.out.fnum;
|
fnum = io.ntcreatex.out.fnum;
|
||||||
|
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "EAONE", NULL);
|
ret &= check_ea(cli, fname, "EAONE", NULL);
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "1st EA", "Value One");
|
ret &= check_ea(cli, fname, "1st EA", "Value One");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "2nd EA", "Second Value");
|
ret &= check_ea(cli, fname, "2nd EA", "Second Value");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "and 3rd", "final value");
|
ret &= check_ea(cli, fname, "and 3rd", "final value");
|
||||||
|
|
||||||
smbcli_close(cli->tree, fnum);
|
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);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.ntcreatex.out.fnum;
|
fnum = io.ntcreatex.out.fnum;
|
||||||
|
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "1st EA", "Value One");
|
ret &= check_ea(cli, fname, "1st EA", "Value One");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "2nd EA", "Second Value");
|
ret &= check_ea(cli, fname, "2nd EA", "Second Value");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "and 3rd", "final value");
|
ret &= check_ea(cli, fname, "and 3rd", "final value");
|
||||||
ret &= check_ea(cli, mem_ctx, fname, "Fourth EA", NULL);
|
ret &= check_ea(cli, fname, "Fourth EA", NULL);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
smbcli_close(cli->tree, fnum);
|
smbcli_close(cli->tree, fnum);
|
||||||
|
@ -160,7 +160,7 @@ static BOOL test_open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
|||||||
|
|
||||||
io.openold.level = RAW_OPEN_OPEN;
|
io.openold.level = RAW_OPEN_OPEN;
|
||||||
io.openold.in.fname = fname;
|
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;
|
io.openold.in.search_attrs = 0;
|
||||||
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
|
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.fname = fname;
|
||||||
io.openold.in.search_attrs = 0;
|
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);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.openold.out.fnum;
|
fnum = io.openold.out.fnum;
|
||||||
CHECK_RDWR(fnum, RDWR_RDONLY);
|
CHECK_RDWR(fnum, RDWR_RDONLY);
|
||||||
smbcli_close(cli->tree, fnum);
|
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);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.openold.out.fnum;
|
fnum = io.openold.out.fnum;
|
||||||
CHECK_RDWR(fnum, RDWR_WRONLY);
|
CHECK_RDWR(fnum, RDWR_WRONLY);
|
||||||
smbcli_close(cli->tree, fnum);
|
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);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.openold.out.fnum;
|
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);
|
smbcli_close(cli->tree, fnum);
|
||||||
|
|
||||||
/* check the share modes roughly - not a complete matrix */
|
/* 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);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.openold.out.fnum;
|
fnum = io.openold.out.fnum;
|
||||||
CHECK_RDWR(fnum, RDWR_RDWR);
|
CHECK_RDWR(fnum, RDWR_RDWR);
|
||||||
|
|
||||||
if (io.openold.in.flags != io.openold.out.rmode) {
|
if (io.openold.in.open_mode != io.openold.out.rmode) {
|
||||||
printf("(%s) rmode should equal flags - 0x%x 0x%x\n",
|
printf("(%s) rmode should equal open_mode - 0x%x 0x%x\n",
|
||||||
__location__, io.openold.out.rmode, io.openold.in.flags);
|
__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);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
|
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);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum2 = io.openold.out.fnum;
|
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.level = RAW_OPEN_OPEN;
|
||||||
io.openold.in.fname = fname;
|
io.openold.in.fname = fname;
|
||||||
io.openold.in.search_attrs = 0;
|
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);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.openold.out.fnum;
|
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);
|
i, (int)open_funcs[i].with_file, (int)open_funcs[i].open_func);
|
||||||
ret = False;
|
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);
|
smbcli_close(cli->tree, io.openx.out.fnum);
|
||||||
|
}
|
||||||
|
if (open_funcs[i].with_file) {
|
||||||
smbcli_unlink(cli->tree, fname);
|
smbcli_unlink(cli->tree, fname);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
smbcli_unlink(cli->tree, fname);
|
||||||
|
|
||||||
/* check the basic return fields */
|
/* check the basic return fields */
|
||||||
io.openx.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
|
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, 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);
|
CHECK_VAL(io.openx.out.access_mask, SEC_STD_ALL);
|
||||||
smbcli_close(cli->tree, io.openx.out.fnum);
|
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:
|
done:
|
||||||
smbcli_close(cli->tree, fnum);
|
smbcli_close(cli->tree, fnum);
|
||||||
smbcli_unlink(cli->tree, fname);
|
smbcli_unlink(cli->tree, fname);
|
||||||
@ -445,9 +453,7 @@ done:
|
|||||||
/*
|
/*
|
||||||
test RAW_OPEN_T2OPEN
|
test RAW_OPEN_T2OPEN
|
||||||
|
|
||||||
I can't work out how to get win2003 to accept a create file via TRANS2_OPEN, which
|
many thanks to kukks for a sniff showing how this works with os2->w2k
|
||||||
is why you see all the ACCESS_DENIED results below. When we finally work this out then this
|
|
||||||
test will make more sense
|
|
||||||
*/
|
*/
|
||||||
static BOOL test_t2open(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
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, True, NT_STATUS_OK },
|
||||||
{ OPENX_OPEN_FUNC_OPEN, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
|
{ 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, 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, 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, True, NT_STATUS_OBJECT_NAME_COLLISION },
|
||||||
{ OPENX_OPEN_FUNC_FAIL | 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_ACCESS_DENIED },
|
{ OPENX_OPEN_FUNC_TRUNC, True, NT_STATUS_OK },
|
||||||
{ OPENX_OPEN_FUNC_TRUNC, False, NT_STATUS_OBJECT_NAME_NOT_FOUND },
|
{ OPENX_OPEN_FUNC_TRUNC, False, NT_STATUS_OK },
|
||||||
{ OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, True, NT_STATUS_ACCESS_DENIED },
|
{ OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, True, NT_STATUS_OK },
|
||||||
{ OPENX_OPEN_FUNC_TRUNC | OPENX_OPEN_FUNC_CREATE, False, NT_STATUS_ACCESS_DENIED },
|
{ 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, 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");
|
printf("Checking RAW_OPEN_T2OPEN\n");
|
||||||
|
|
||||||
io.t2open.level = RAW_OPEN_T2OPEN;
|
io.t2open.level = RAW_OPEN_T2OPEN;
|
||||||
io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO |
|
io.t2open.in.flags = OPENX_FLAGS_ADDITIONAL_INFO;
|
||||||
OPENX_FLAGS_EA_LEN | OPENX_FLAGS_EXTENDED_RETURN;
|
|
||||||
io.t2open.in.open_mode = OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR;
|
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.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.file_attrs = 0;
|
||||||
io.t2open.in.write_time = 0;
|
io.t2open.in.write_time = 0;
|
||||||
io.t2open.in.size = 0;
|
io.t2open.in.size = 0;
|
||||||
io.t2open.in.timeout = 0;
|
io.t2open.in.timeout = 0;
|
||||||
|
|
||||||
io.t2open.in.eas = talloc_p(mem_ctx, struct ea_struct);
|
io.t2open.in.num_eas = 3;
|
||||||
io.t2open.in.num_eas = 1;
|
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].flags = 0;
|
||||||
io.t2open.in.eas[0].name.s = "EAONE";
|
io.t2open.in.eas[0].name.s = ".CLASSINFO";
|
||||||
io.t2open.in.eas[0].value = data_blob_talloc(mem_ctx, "1", 1);
|
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 */
|
/* check all combinations of open_func */
|
||||||
for (i=0; i<ARRAY_SIZE(open_funcs); i++) {
|
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, fname1);
|
||||||
|
smbcli_unlink(cli->tree, fname2);
|
||||||
|
|
||||||
/* check the basic return fields */
|
/* 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.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
|
||||||
|
io.t2open.in.write_time = 0;
|
||||||
io.t2open.in.fname = fname;
|
io.t2open.in.fname = fname;
|
||||||
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_OK);
|
CHECK_STATUS(status, NT_STATUS_OK);
|
||||||
fnum = io.t2open.out.fnum;
|
fnum = io.t2open.out.fnum;
|
||||||
|
|
||||||
CHECK_ALL_INFO(io.t2open.out.size, size);
|
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);
|
CHECK_VAL(io.t2open.out.write_time, 0);
|
||||||
|
#endif
|
||||||
CHECK_ALL_INFO(io.t2open.out.attrib, attrib & ~FILE_ATTRIBUTE_NONINDEXED);
|
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.access, OPENX_MODE_DENY_NONE | OPENX_MODE_ACCESS_RDWR);
|
||||||
CHECK_VAL(io.t2open.out.ftype, 0);
|
CHECK_VAL(io.t2open.out.ftype, 0);
|
||||||
CHECK_VAL(io.t2open.out.devstate, 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);
|
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? */
|
/* now check the search attrib for hidden files - win2003 ignores this? */
|
||||||
SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
|
SET_ATTRIB(FILE_ATTRIBUTE_HIDDEN);
|
||||||
CHECK_ALL_INFO(FILE_ATTRIBUTE_HIDDEN, attrib);
|
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.open_func = OPENX_OPEN_FUNC_FAIL | OPENX_OPEN_FUNC_CREATE;
|
||||||
io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
|
io.t2open.in.file_attrs = FILE_ATTRIBUTE_SYSTEM;
|
||||||
status = smb_raw_open(cli->tree, mem_ctx, &io);
|
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! */
|
/* check timeout on create - win2003 ignores the timeout! */
|
||||||
io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
|
io.t2open.in.open_func = OPENX_OPEN_FUNC_OPEN | OPENX_OPEN_FUNC_CREATE;
|
||||||
io.t2open.in.file_attrs = 0;
|
io.t2open.in.file_attrs = 0;
|
||||||
|
io.t2open.in.timeout = 20000;
|
||||||
io.t2open.in.open_mode = OPENX_MODE_ACCESS_RDWR | OPENX_MODE_DENY_ALL;
|
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, mem_ctx, &io);
|
||||||
CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED);
|
CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
smbcli_close(cli->tree, fnum);
|
smbcli_close(cli->tree, fnum);
|
||||||
|
@ -1150,7 +1150,7 @@ static BOOL test_os2_delete(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i>0) {
|
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;
|
io2.t2fnext.in.last_name = result.list[i-1].ea_size.name.s;
|
||||||
}
|
}
|
||||||
} while (NT_STATUS_IS_OK(status) && result.count != 0);
|
} while (NT_STATUS_IS_OK(status) && result.count != 0);
|
||||||
|
@ -356,3 +356,59 @@ NTSTATUS torture_set_sparse(struct smbcli_tree *tree, int fnum)
|
|||||||
|
|
||||||
return status;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user