From 91e1893741741de04b73a098495c697434105803 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Nov 2005 23:27:47 +0000 Subject: r11691: added reply buffer code checks and oplock flags for create request/reply (This used to be commit 26ed781375c03958241d8c93324e04e948944d01) --- source4/libcli/smb2/close.c | 10 ++++++---- source4/libcli/smb2/create.c | 28 +++++++++++++++++----------- source4/libcli/smb2/negprot.c | 4 +++- source4/libcli/smb2/session.c | 4 +++- source4/libcli/smb2/smb2.h | 11 +++++++++++ source4/libcli/smb2/smb2_calls.h | 40 ++++++++++++++++++++++++++++------------ source4/libcli/smb2/tcon.c | 4 +++- 7 files changed, 71 insertions(+), 30 deletions(-) (limited to 'source4/libcli/smb2') diff --git a/source4/libcli/smb2/close.c b/source4/libcli/smb2/close.c index 4429cd557b..b60c1b3071 100644 --- a/source4/libcli/smb2/close.c +++ b/source4/libcli/smb2/close.c @@ -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); if (req == NULL) return NULL; - SIVAL(req->out.body, 0x00, io->in.unknown1); - SIVAL(req->out.body, 0x04, io->in.unknown2); + SSVAL(req->out.body, 0x00, io->in.buffer_code); + 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, 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; } - io->out.unknown1 = IVAL(req->in.body, 0x00); - io->out.unknown2 = IVAL(req->in.body, 0x04); + io->out.buffer_code = SVAL(req->in.body, 0x00); + 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.access_time = smbcli_pull_nttime(req->in.body, 0x10); io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index f234e6cb35..e4b0773758 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -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); 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, 0x08, io->in.unknown3[0]); 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) { + smb2_request_receive(req); + dump_data(0, req->in.body, req->in.body_size); + if (!smb2_request_receive(req) || smb2_request_is_error(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; } - io->out.unknown1 = IVAL(req->in.body, 0x00); - io->out.unknown2 = IVAL(req->in.body, 0x04); - io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); - io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); - io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); - io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); - io->out.alloc_size = BVAL(req->in.body, 0x28); - io->out.size = BVAL(req->in.body, 0x30); - io->out.file_attr = IVAL(req->in.body, 0x38); - io->out.unknown3 = IVAL(req->in.body, 0x3C); + SMB2_CHECK_BUFFER_CODE(req, 0x59); + + io->out.oplock_flags = SVAL(req->in.body, 0x02); + io->out.create_action = IVAL(req->in.body, 0x04); + io->out.create_time = smbcli_pull_nttime(req->in.body, 0x08); + io->out.access_time = smbcli_pull_nttime(req->in.body, 0x10); + io->out.write_time = smbcli_pull_nttime(req->in.body, 0x18); + io->out.change_time = smbcli_pull_nttime(req->in.body, 0x20); + io->out.alloc_size = BVAL(req->in.body, 0x28); + 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[1] = BVAL(req->in.body, 0x48); io->out.unknown4 = IVAL(req->in.body, 0x50); diff --git a/source4/libcli/smb2/negprot.c b/source4/libcli/smb2/negprot.c index 5cd4810909..758b06fcae 100644 --- a/source4/libcli/smb2/negprot.c +++ b/source4/libcli/smb2/negprot.c @@ -62,7 +62,9 @@ NTSTATUS smb2_negprot_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, 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); memcpy(io->out.sessid, req->in.body + 0x08, 16); io->out.unknown3 = IVAL(req->in.body, 0x18); diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 031360fcb9..9d945243d2 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -103,7 +103,9 @@ NTSTATUS smb2_session_setup_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, 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); status = smb2_pull_ofs_blob(req, req->in.body+0x04, &io->out.secblob); diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 76f00cc573..f6847bfc9b 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -168,3 +168,14 @@ struct smb2_request { #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) diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index f3d158dadd..859655355d 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -28,7 +28,8 @@ struct smb2_negprot { uint8_t unknown3[32]; /* all zero */ } in; struct { - uint32_t unknown1; /* 0x41 */ + uint16_t buffer_code; + uint16_t _pad; uint32_t unknown2; /* 0x06 */ uint8_t sessid[16]; uint32_t unknown3; /* 0x0d */ @@ -54,7 +55,8 @@ struct smb2_session_setup { DATA_BLOB secblob; } in; struct { - uint32_t unknown1; /* 0x09 */ + uint16_t buffer_code; + uint16_t _pad; /* uint16_t secblob ofs/size here */ DATA_BLOB secblob; uint64_t uid; /* returned in header */ @@ -67,7 +69,8 @@ struct smb2_tree_connect { const char *path; } in; struct { - uint32_t unknown1; /* 0x00020010 */ + uint16_t buffer_code; + uint16_t unknown1; /* 0x02 */ uint32_t unknown2; /* 0x00 */ uint32_t unknown3; /* 0x00 */ uint32_t access_mask; @@ -82,10 +85,17 @@ struct smb2_handle { 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 { - uint32_t unknown1; /* 0x09000039 */ - uint32_t unknown2; /* 2 */ + uint16_t buffer_code; /* 0x39 */ + uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ + uint32_t unknown2; uint32_t unknown3[4]; uint32_t access_mask; uint32_t file_attr; @@ -103,8 +113,9 @@ struct smb2_create { } in; struct { - uint32_t unknown1; - uint32_t unknown2; + uint16_t buffer_code; /* 0x59 */ + uint16_t oplock_flags; /* SMB2_CREATE_FLAG_* */ + uint32_t create_action; NTTIME create_time; NTTIME access_time; NTTIME write_time; @@ -112,23 +123,28 @@ struct smb2_create { uint64_t alloc_size; uint64_t size; uint32_t file_attr; - uint32_t unknown3; + uint32_t _pad; struct smb2_handle handle; uint32_t unknown4; + uint32_t unknown5; } out; }; +#define SMB2_CLOSE_FLAGS_FULL_INFORMATION (1<<0) + struct smb2_close { struct { - uint32_t unknown1; - uint32_t unknown2; + uint16_t buffer_code; + uint16_t flags; /* SMB2_CLOSE_FLAGS_* */ + uint32_t _pad; struct smb2_handle handle; } in; struct { - uint32_t unknown1; - uint32_t unknown2; + uint16_t buffer_code; + uint16_t flags; + uint32_t _pad; NTTIME create_time; NTTIME access_time; NTTIME write_time; diff --git a/source4/libcli/smb2/tcon.c b/source4/libcli/smb2/tcon.c index 88a2d0a67d..f68987acf7 100644 --- a/source4/libcli/smb2/tcon.c +++ b/source4/libcli/smb2/tcon.c @@ -93,9 +93,11 @@ NTSTATUS smb2_tree_connect_recv(struct smb2_request *req, struct smb2_tree_conne return NT_STATUS_BUFFER_TOO_SMALL; } + SMB2_CHECK_BUFFER_CODE(req, 0x10); + 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.unknown3 = IVAL(req->in.body, 0x08); io->out.access_mask = IVAL(req->in.body, 0x0C); -- cgit