diff options
-rw-r--r-- | source4/libcli/smb2/close.c | 10 | ||||
-rw-r--r-- | source4/libcli/smb2/create.c | 28 | ||||
-rw-r--r-- | source4/libcli/smb2/negprot.c | 4 | ||||
-rw-r--r-- | source4/libcli/smb2/session.c | 4 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2.h | 11 | ||||
-rw-r--r-- | source4/libcli/smb2/smb2_calls.h | 40 | ||||
-rw-r--r-- | source4/libcli/smb2/tcon.c | 4 | ||||
-rw-r--r-- | source4/torture/smb2/connect.c | 15 |
8 files changed, 80 insertions, 36 deletions
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); diff --git a/source4/torture/smb2/connect.c b/source4/torture/smb2/connect.c index 68eb922b55..2af6bfb576 100644 --- a/source4/torture/smb2/connect.c +++ b/source4/torture/smb2/connect.c @@ -205,7 +205,8 @@ static NTSTATUS torture_smb2_close(struct smb2_tree *tree, struct smb2_handle ha TALLOC_CTX *tmp_ctx = talloc_new(tree); ZERO_STRUCT(io); - io.in.unknown1 = 0x10018; + io.in.buffer_code = 0x18; + io.in.flags = SMB2_CLOSE_FLAGS_FULL_INFORMATION; io.in.handle = handle; status = smb2_close(tree, &io); 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); ZERO_STRUCT(io); - io.in.unknown1 = 0x09000039; /* gets an oplock */ - io.in.unknown1 = 0x00000039; /* no oplock */ + io.in.buffer_code = 0x39; + io.in.oplock_flags = 0; io.in.access_mask = SEC_RIGHTS_FILE_ALL; 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 = NTCREATEX_SHARE_ACCESS_DELETE| NTCREATEX_SHARE_ACCESS_READ| @@ -258,6 +259,8 @@ static struct smb2_handle torture_smb2_create(struct smb2_tree *tree, } 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("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)); @@ -291,8 +294,8 @@ BOOL torture_smb2_connect(void) transport = torture_smb2_negprot(mem_ctx, host); session = torture_smb2_session(transport, credentials); tree = torture_smb2_tree(session, share); - h1 = torture_smb2_create(tree, "test.dat"); - h2 = torture_smb2_create(tree, "test1.dat"); + h1 = torture_smb2_create(tree, "test9.dat"); + h2 = torture_smb2_create(tree, "test9.dat"); torture_smb2_close(tree, h1); torture_smb2_close(tree, h2); |