1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

changed BCC handling for SMBwriteX to handle broken MacOSX client

see bug #6610

The MacOSX SMB client sets the BCC value in SMBwriteX calls to zero
instead of the correct size. Checking against WindowsXP, I've found
that Windows uses the maximum of the computed buffer size and the
given BCC value. I've changed Samba4 to do the same to allow MacOSX to
work.

I've limited this change to non-chained packets to ensure we don't get
the possibility of exploits based on overlapping chained requests
This commit is contained in:
Andrew Tridgell 2009-08-05 20:23:12 +10:00
parent 67b6f5784a
commit 3854b5e614

View File

@ -407,19 +407,14 @@ NTSTATUS smbsrv_recv_smb_request(void *private_data, DATA_BLOB blob)
req->in.data = req->in.vwv + VWV(req->in.wct) + 2; req->in.data = req->in.vwv + VWV(req->in.wct) + 2;
req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct)); req->in.data_size = SVAL(req->in.vwv, VWV(req->in.wct));
/* the bcc length is only 16 bits, but some packets /* special handling for oversize calls. Windows seems
(such as SMBwriteX) can be much larger than 64k. We to take the maximum of the BCC value and the
detect this by looking for a large non-chained NBT computed buffer size. This handles oversized writeX
packet (at least 64k bigger than what is calls, and possibly oversized SMBtrans calls */
specified). If it is detected then the NBT size is if ((message_flags(command) & LARGE_REQUEST) &&
used instead of the bcc size */ ( !(message_flags(command) & AND_X) ||
if (req->in.data_size + 0x10000 <= (req->in.wct < 1 || SVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE)) &&
req->in.size - PTR_DIFF(req->in.data, req->in.buffer) && req->in.data_size < req->in.size - PTR_DIFF(req->in.data,req->in.buffer)) {
( message_flags(command) & LARGE_REQUEST) &&
( !(message_flags(command) & AND_X) ||
(req->in.wct < 1 || SVAL(req->in.vwv, VWV(0)) == SMB_CHAIN_NONE) )
) {
/* its an oversized packet! fun for all the family */
req->in.data_size = req->in.size - PTR_DIFF(req->in.data,req->in.buffer); req->in.data_size = req->in.size - PTR_DIFF(req->in.data,req->in.buffer);
} }
} }