mirror of
https://github.com/samba-team/samba.git
synced 2025-02-08 05:57:51 +03:00
r11691: added reply buffer code checks and oplock flags for create request/reply
(This used to be commit 26ed781375c03958241d8c93324e04e948944d01)
This commit is contained in:
parent
222e197b84
commit
91e1893741
@ -35,8 +35,9 @@ struct smb2_request *smb2_close_send(struct smb2_tree *tree, struct smb2_close *
|
|||||||
req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18);
|
req = smb2_request_init_tree(tree, SMB2_OP_CLOSE, 0x18);
|
||||||
if (req == NULL) return NULL;
|
if (req == NULL) return NULL;
|
||||||
|
|
||||||
SIVAL(req->out.body, 0x00, io->in.unknown1);
|
SSVAL(req->out.body, 0x00, io->in.buffer_code);
|
||||||
SIVAL(req->out.body, 0x04, io->in.unknown2);
|
SSVAL(req->out.body, 0x02, io->in.flags);
|
||||||
|
SIVAL(req->out.body, 0x04, io->in._pad);
|
||||||
SBVAL(req->out.body, 0x08, io->in.handle.data[0]);
|
SBVAL(req->out.body, 0x08, io->in.handle.data[0]);
|
||||||
SBVAL(req->out.body, 0x10, io->in.handle.data[1]);
|
SBVAL(req->out.body, 0x10, io->in.handle.data[1]);
|
||||||
|
|
||||||
@ -60,8 +61,9 @@ NTSTATUS smb2_close_recv(struct smb2_request *req, struct smb2_close *io)
|
|||||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
io->out.unknown1 = IVAL(req->in.body, 0x00);
|
io->out.buffer_code = SVAL(req->in.body, 0x00);
|
||||||
io->out.unknown2 = IVAL(req->in.body, 0x04);
|
io->out.flags = SVAL(req->in.body, 0x02);
|
||||||
|
io->out._pad = IVAL(req->in.body, 0x04);
|
||||||
io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08);
|
io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08);
|
||||||
io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10);
|
io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10);
|
||||||
io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18);
|
io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18);
|
||||||
|
@ -43,7 +43,8 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
|
|||||||
req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x50 + path.length);
|
req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x50 + path.length);
|
||||||
if (req == NULL) return NULL;
|
if (req == NULL) return NULL;
|
||||||
|
|
||||||
SIVAL(req->out.body, 0x00, io->in.unknown1);
|
SSVAL(req->out.body, 0x00, io->in.buffer_code);
|
||||||
|
SSVAL(req->out.body, 0x02, io->in.oplock_flags);
|
||||||
SIVAL(req->out.body, 0x04, io->in.unknown2);
|
SIVAL(req->out.body, 0x04, io->in.unknown2);
|
||||||
SIVAL(req->out.body, 0x08, io->in.unknown3[0]);
|
SIVAL(req->out.body, 0x08, io->in.unknown3[0]);
|
||||||
SIVAL(req->out.body, 0x0C, io->in.unknown3[1]);
|
SIVAL(req->out.body, 0x0C, io->in.unknown3[1]);
|
||||||
@ -84,6 +85,9 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
|
|||||||
*/
|
*/
|
||||||
NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io)
|
NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io)
|
||||||
{
|
{
|
||||||
|
smb2_request_receive(req);
|
||||||
|
dump_data(0, req->in.body, req->in.body_size);
|
||||||
|
|
||||||
if (!smb2_request_receive(req) ||
|
if (!smb2_request_receive(req) ||
|
||||||
smb2_request_is_error(req)) {
|
smb2_request_is_error(req)) {
|
||||||
return smb2_request_destroy(req);
|
return smb2_request_destroy(req);
|
||||||
@ -93,16 +97,18 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, struct smb2_create *io)
|
|||||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
io->out.unknown1 = IVAL(req->in.body, 0x00);
|
SMB2_CHECK_BUFFER_CODE(req, 0x59);
|
||||||
io->out.unknown2 = IVAL(req->in.body, 0x04);
|
|
||||||
io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08);
|
io->out.oplock_flags = SVAL(req->in.body, 0x02);
|
||||||
io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10);
|
io->out.create_action = IVAL(req->in.body, 0x04);
|
||||||
io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18);
|
io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08);
|
||||||
io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20);
|
io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10);
|
||||||
io->out.alloc_size = BVAL(req->in.body, 0x28);
|
io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18);
|
||||||
io->out.size = BVAL(req->in.body, 0x30);
|
io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20);
|
||||||
io->out.file_attr = IVAL(req->in.body, 0x38);
|
io->out.alloc_size = BVAL(req->in.body, 0x28);
|
||||||
io->out.unknown3 = IVAL(req->in.body, 0x3C);
|
io->out.size = BVAL(req->in.body, 0x30);
|
||||||
|
io->out.file_attr = IVAL(req->in.body, 0x38);
|
||||||
|
io->out._pad = IVAL(req->in.body, 0x3C);
|
||||||
io->out.handle.data[0] = BVAL(req->in.body, 0x40);
|
io->out.handle.data[0] = BVAL(req->in.body, 0x40);
|
||||||
io->out.handle.data[1] = BVAL(req->in.body, 0x48);
|
io->out.handle.data[1] = BVAL(req->in.body, 0x48);
|
||||||
io->out.unknown4 = IVAL(req->in.body, 0x50);
|
io->out.unknown4 = IVAL(req->in.body, 0x50);
|
||||||
|
@ -62,7 +62,9 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
|
|||||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
io->out.unknown1 = IVAL(req->in.body, 0x00);
|
SMB2_CHECK_BUFFER_CODE(req, 0x41);
|
||||||
|
|
||||||
|
io->out._pad = SVAL(req->in.body, 0x02);
|
||||||
io->out.unknown2 = IVAL(req->in.body, 0x04);
|
io->out.unknown2 = IVAL(req->in.body, 0x04);
|
||||||
memcpy(io->out.sessid, req->in.body + 0x08, 16);
|
memcpy(io->out.sessid, req->in.body + 0x08, 16);
|
||||||
io->out.unknown3 = IVAL(req->in.body, 0x18);
|
io->out.unknown3 = IVAL(req->in.body, 0x18);
|
||||||
|
@ -103,7 +103,9 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx,
|
|||||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
io->out.unknown1 = IVAL(req->in.body, 0x00);
|
SMB2_CHECK_BUFFER_CODE(req, 0x09);
|
||||||
|
|
||||||
|
io->out._pad = SVAL(req->in.body, 0x02);
|
||||||
io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID);
|
io->out.uid = BVAL(req->in.hdr, SMB2_HDR_UID);
|
||||||
|
|
||||||
status = smb2_pull_ofs_blob(req, req->in.body+0x04, &io->out.secblob);
|
status = smb2_pull_ofs_blob(req, req->in.body+0x04, &io->out.secblob);
|
||||||
|
@ -168,3 +168,14 @@ struct smb2_request {
|
|||||||
|
|
||||||
#define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */
|
#define SMB2_MAGIC 0x424D53FE /* 0xFE 'S' 'M' 'B' */
|
||||||
|
|
||||||
|
/*
|
||||||
|
check that a buffer code matches the expected value
|
||||||
|
*/
|
||||||
|
#define SMB2_CHECK_BUFFER_CODE(req, code) do { \
|
||||||
|
io->out.buffer_code = SVAL(req->in.body, 0); \
|
||||||
|
if (io->out.buffer_code != (code)) { \
|
||||||
|
DEBUG(0,("Unexpected buffer code 0x%x. Expected 0x%x\n", \
|
||||||
|
io->out.buffer_code, code)); \
|
||||||
|
return NT_STATUS_INVALID_PARAMETER; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
@ -28,7 +28,8 @@ struct smb2_negprot {
|
|||||||
uint8_t unknown3[32]; /* all zero */
|
uint8_t unknown3[32]; /* all zero */
|
||||||
} in;
|
} in;
|
||||||
struct {
|
struct {
|
||||||
uint32_t unknown1; /* 0x41 */
|
uint16_t buffer_code;
|
||||||
|
uint16_t _pad;
|
||||||
uint32_t unknown2; /* 0x06 */
|
uint32_t unknown2; /* 0x06 */
|
||||||
uint8_t sessid[16];
|
uint8_t sessid[16];
|
||||||
uint32_t unknown3; /* 0x0d */
|
uint32_t unknown3; /* 0x0d */
|
||||||
@ -54,7 +55,8 @@ struct smb2_session_setup {
|
|||||||
DATA_BLOB secblob;
|
DATA_BLOB secblob;
|
||||||
} in;
|
} in;
|
||||||
struct {
|
struct {
|
||||||
uint32_t unknown1; /* 0x09 */
|
uint16_t buffer_code;
|
||||||
|
uint16_t _pad;
|
||||||
/* uint16_t secblob ofs/size here */
|
/* uint16_t secblob ofs/size here */
|
||||||
DATA_BLOB secblob;
|
DATA_BLOB secblob;
|
||||||
uint64_t uid; /* returned in header */
|
uint64_t uid; /* returned in header */
|
||||||
@ -67,7 +69,8 @@ struct smb2_tree_connect {
|
|||||||
const char *path;
|
const char *path;
|
||||||
} in;
|
} in;
|
||||||
struct {
|
struct {
|
||||||
uint32_t unknown1; /* 0x00020010 */
|
uint16_t buffer_code;
|
||||||
|
uint16_t unknown1; /* 0x02 */
|
||||||
uint32_t unknown2; /* 0x00 */
|
uint32_t unknown2; /* 0x00 */
|
||||||
uint32_t unknown3; /* 0x00 */
|
uint32_t unknown3; /* 0x00 */
|
||||||
uint32_t access_mask;
|
uint32_t access_mask;
|
||||||
@ -82,10 +85,17 @@ struct smb2_handle {
|
|||||||
uint64_t data[2];
|
uint64_t data[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define SMB2_CREATE_FLAG_REQUEST_OPLOCK 0x0100
|
||||||
|
#define SMB2_CREATE_FLAG_REQUEST_EXCLUSIVE_OPLOCK 0x0800
|
||||||
|
#define SMB2_CREATE_FLAG_GRANT_OPLOCK 0x0001
|
||||||
|
#define SMB2_CREATE_FLAG_GRANT_EXCLUSIVE_OPLOCK 0x0080
|
||||||
|
|
||||||
struct smb2_create {
|
struct smb2_create {
|
||||||
struct {
|
struct {
|
||||||
uint32_t unknown1; /* 0x09000039 */
|
uint16_t buffer_code; /* 0x39 */
|
||||||
uint32_t unknown2; /* 2 */
|
uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */
|
||||||
|
uint32_t unknown2;
|
||||||
uint32_t unknown3[4];
|
uint32_t unknown3[4];
|
||||||
uint32_t access_mask;
|
uint32_t access_mask;
|
||||||
uint32_t file_attr;
|
uint32_t file_attr;
|
||||||
@ -103,8 +113,9 @@ struct smb2_create {
|
|||||||
} in;
|
} in;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t unknown1;
|
uint16_t buffer_code; /* 0x59 */
|
||||||
uint32_t unknown2;
|
uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */
|
||||||
|
uint32_t create_action;
|
||||||
NTTIME create_time;
|
NTTIME create_time;
|
||||||
NTTIME access_time;
|
NTTIME access_time;
|
||||||
NTTIME write_time;
|
NTTIME write_time;
|
||||||
@ -112,23 +123,28 @@ struct smb2_create {
|
|||||||
uint64_t alloc_size;
|
uint64_t alloc_size;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint32_t file_attr;
|
uint32_t file_attr;
|
||||||
uint32_t unknown3;
|
uint32_t _pad;
|
||||||
struct smb2_handle handle;
|
struct smb2_handle handle;
|
||||||
uint32_t unknown4;
|
uint32_t unknown4;
|
||||||
|
uint32_t unknown5;
|
||||||
} out;
|
} out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0)
|
||||||
|
|
||||||
struct smb2_close {
|
struct smb2_close {
|
||||||
struct {
|
struct {
|
||||||
uint32_t unknown1;
|
uint16_t buffer_code;
|
||||||
uint32_t unknown2;
|
uint16_t flags; /* SMB2_CLOSE_FLAGS_* */
|
||||||
|
uint32_t _pad;
|
||||||
struct smb2_handle handle;
|
struct smb2_handle handle;
|
||||||
} in;
|
} in;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
uint32_t unknown1;
|
uint16_t buffer_code;
|
||||||
uint32_t unknown2;
|
uint16_t flags;
|
||||||
|
uint32_t _pad;
|
||||||
NTTIME create_time;
|
NTTIME create_time;
|
||||||
NTTIME access_time;
|
NTTIME access_time;
|
||||||
NTTIME write_time;
|
NTTIME write_time;
|
||||||
|
@ -93,9 +93,11 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne
|
|||||||
return NT_STATUS_BUFFER_TOO_SMALL;
|
return NT_STATUS_BUFFER_TOO_SMALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMB2_CHECK_BUFFER_CODE(req, 0x10);
|
||||||
|
|
||||||
io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID);
|
io->out.tid = IVAL(req->in.hdr, SMB2_HDR_TID);
|
||||||
|
|
||||||
io->out.unknown1 = IVAL(req->in.body, 0x00);
|
io->out.unknown1 = SVAL(req->in.body, 0x02);
|
||||||
io->out.unknown2 = IVAL(req->in.body, 0x04);
|
io->out.unknown2 = IVAL(req->in.body, 0x04);
|
||||||
io->out.unknown3 = IVAL(req->in.body, 0x08);
|
io->out.unknown3 = IVAL(req->in.body, 0x08);
|
||||||
io->out.access_mask = IVAL(req->in.body, 0x0C);
|
io->out.access_mask = IVAL(req->in.body, 0x0C);
|
||||||
|
@ -205,7 +205,8 @@ static NTSTATUS torture_smb2_close(struct smb2_tree *tree, struct smb2_handle ha
|
|||||||
TALLOC_CTX *tmp_ctx = talloc_new(tree);
|
TALLOC_CTX *tmp_ctx = talloc_new(tree);
|
||||||
|
|
||||||
ZERO_STRUCT(io);
|
ZERO_STRUCT(io);
|
||||||
io.in.unknown1 = 0x10018;
|
io.in.buffer_code = 0x18;
|
||||||
|
io.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION;
|
||||||
io.in.handle = handle;
|
io.in.handle = handle;
|
||||||
status = smb2_close(tree, &io);
|
status = smb2_close(tree, &io);
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
if (!NT_STATUS_IS_OK(status)) {
|
||||||
@ -239,11 +240,11 @@ static struct smb2_handle torture_smb2_create(struct smb2_tree *tree,
|
|||||||
TALLOC_CTX *tmp_ctx = talloc_new(tree);
|
TALLOC_CTX *tmp_ctx = talloc_new(tree);
|
||||||
|
|
||||||
ZERO_STRUCT(io);
|
ZERO_STRUCT(io);
|
||||||
io.in.unknown1 = 0x09000039; /* gets an oplock */
|
io.in.buffer_code = 0x39;
|
||||||
io.in.unknown1 = 0x00000039; /* no oplock */
|
io.in.oplock_flags = 0;
|
||||||
io.in.access_mask = SEC_RIGHTS_FILE_ALL;
|
io.in.access_mask = SEC_RIGHTS_FILE_ALL;
|
||||||
io.in.file_attr = FILE_ATTRIBUTE_NORMAL;
|
io.in.file_attr = FILE_ATTRIBUTE_NORMAL;
|
||||||
io.in.open_disposition = NTCREATEX_DISP_OPEN;
|
io.in.open_disposition = NTCREATEX_DISP_OPEN_IF;
|
||||||
io.in.share_access =
|
io.in.share_access =
|
||||||
NTCREATEX_SHARE_ACCESS_DELETE|
|
NTCREATEX_SHARE_ACCESS_DELETE|
|
||||||
NTCREATEX_SHARE_ACCESS_READ|
|
NTCREATEX_SHARE_ACCESS_READ|
|
||||||
@ -258,6 +259,8 @@ static struct smb2_handle torture_smb2_create(struct smb2_tree *tree,
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Open gave:\n");
|
printf("Open gave:\n");
|
||||||
|
printf("oplock_flags = 0x%x\n", io.out.oplock_flags);
|
||||||
|
printf("create_action = 0x%x\n", io.out.create_action);
|
||||||
printf("create_time = %s\n", nt_time_string(tmp_ctx, io.out.create_time));
|
printf("create_time = %s\n", nt_time_string(tmp_ctx, io.out.create_time));
|
||||||
printf("access_time = %s\n", nt_time_string(tmp_ctx, io.out.access_time));
|
printf("access_time = %s\n", nt_time_string(tmp_ctx, io.out.access_time));
|
||||||
printf("write_time = %s\n", nt_time_string(tmp_ctx, io.out.write_time));
|
printf("write_time = %s\n", nt_time_string(tmp_ctx, io.out.write_time));
|
||||||
@ -291,8 +294,8 @@ BOOL torture_smb2_connect(void)
|
|||||||
transport = torture_smb2_negprot(mem_ctx, host);
|
transport = torture_smb2_negprot(mem_ctx, host);
|
||||||
session = torture_smb2_session(transport, credentials);
|
session = torture_smb2_session(transport, credentials);
|
||||||
tree = torture_smb2_tree(session, share);
|
tree = torture_smb2_tree(session, share);
|
||||||
h1 = torture_smb2_create(tree, "test.dat");
|
h1 = torture_smb2_create(tree, "test9.dat");
|
||||||
h2 = torture_smb2_create(tree, "test1.dat");
|
h2 = torture_smb2_create(tree, "test9.dat");
|
||||||
torture_smb2_close(tree, h1);
|
torture_smb2_close(tree, h1);
|
||||||
torture_smb2_close(tree, h2);
|
torture_smb2_close(tree, h2);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user