From 839ab724dc2d204bfbb0693aeed64f6f83a4266b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 14 Feb 2008 12:30:31 +1100 Subject: Fixed SMB2 rename operations from Vista clients We needed a flag in bufinfo to mark packets as SMB2, as it seems that SMB2 uses a different format for the RenameInformation buffer than SMB does Also handle the fact that SMB2 clients give the full path to the target file in the rename, not a relative path (This used to be commit 52d7972d95ddc19d22a4187b4d4428a6c3ed32d5) --- source4/smb_server/blob.c | 27 ++++++++++++++++++--------- source4/smb_server/smb/request.c | 7 +++++-- source4/smb_server/smb2/receive.c | 2 +- 3 files changed, 24 insertions(+), 12 deletions(-) (limited to 'source4/smb_server') diff --git a/source4/smb_server/blob.c b/source4/smb_server/blob.c index caf6fb447d..795e7ce585 100644 --- a/source4/smb_server/blob.c +++ b/source4/smb_server/blob.c @@ -523,7 +523,7 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, int default_str_flags, struct request_bufinfo *bufinfo) { - uint32_t len; + uint32_t len, ofs; DATA_BLOB str_blob; switch (level) { @@ -563,14 +563,23 @@ NTSTATUS smbsrv_pull_passthru_sfileinfo(TALLOC_CTX *mem_ctx, if (!bufinfo) { return NT_STATUS_INTERNAL_ERROR; } - BLOB_CHECK_MIN_SIZE(blob, 12); - - st->rename_information.in.overwrite = CVAL(blob->data, 0); - st->rename_information.in.root_fid = IVAL(blob->data, 4); - len = IVAL(blob->data, 8); - str_blob.data = blob->data+12; - str_blob.length = MIN(blob->length, len); - smbsrv_blob_pull_string(bufinfo, &str_blob, 0, + if (bufinfo->flags & BUFINFO_FLAG_SMB2) { + /* SMB2 uses a different format for rename information */ + BLOB_CHECK_MIN_SIZE(blob, 20); + st->rename_information.in.overwrite = CVAL(blob->data, 0); + st->rename_information.in.root_fid = BVAL(blob->data, 4); + len = IVAL(blob->data,16); + ofs = 20; + } else { + BLOB_CHECK_MIN_SIZE(blob, 12); + st->rename_information.in.overwrite = CVAL(blob->data, 0); + st->rename_information.in.root_fid = IVAL(blob->data, 4); + len = IVAL(blob->data, 8); + ofs = 12; + } + str_blob = *blob; + str_blob.length = MIN(str_blob.length, ofs+len); + smbsrv_blob_pull_string(bufinfo, &str_blob, ofs, &st->rename_information.in.new_name, STR_UNICODE); if (st->rename_information.in.new_name == NULL) { diff --git a/source4/smb_server/smb/request.c b/source4/smb_server/smb/request.c index 724055499b..d7f3793f23 100644 --- a/source4/smb_server/smb/request.c +++ b/source4/smb_server/smb/request.c @@ -37,7 +37,10 @@ void smbsrv_setup_bufinfo(struct smbsrv_request *req) { req->in.bufinfo.mem_ctx = req; - req->in.bufinfo.unicode = (req->flags2 & FLAGS2_UNICODE_STRINGS)?true:false; + req->in.bufinfo.flags = 0; + if (req->flags2 & FLAGS2_UNICODE_STRINGS) { + req->in.bufinfo.flags |= BUFINFO_FLAG_UNICODE; + } req->in.bufinfo.align_base = req->in.buffer; req->in.bufinfo.data = req->in.data; req->in.bufinfo.data_size = req->in.data_size; @@ -582,7 +585,7 @@ static size_t req_pull_ascii(struct request_bufinfo *bufinfo, const char **dest, size_t req_pull_string(struct request_bufinfo *bufinfo, const char **dest, const uint8_t *src, int byte_len, uint_t flags) { if (!(flags & STR_ASCII) && - (((flags & STR_UNICODE) || bufinfo->unicode))) { + (((flags & STR_UNICODE) || (bufinfo->flags & BUFINFO_FLAG_UNICODE)))) { return req_pull_ucs2(bufinfo, dest, src, byte_len, flags); } diff --git a/source4/smb_server/smb2/receive.c b/source4/smb_server/smb2/receive.c index 58070065fc..dea7c9e79e 100644 --- a/source4/smb_server/smb2/receive.c +++ b/source4/smb_server/smb2/receive.c @@ -35,7 +35,7 @@ void smb2srv_setup_bufinfo(struct smb2srv_request *req) { req->in.bufinfo.mem_ctx = req; - req->in.bufinfo.unicode = true; + req->in.bufinfo.flags = BUFINFO_FLAG_UNICODE | BUFINFO_FLAG_SMB2; req->in.bufinfo.align_base = req->in.buffer; if (req->in.dynamic) { req->in.bufinfo.data = req->in.dynamic; -- cgit