[PATCH] smbd: Fix bug 10839
Volker Lendecke
Volker.Lendecke at SerNet.DE
Wed Feb 25 14:03:31 MST 2015
Hi!
This is a patch I'd like to propse for master. The bug is
not strictly a Samba bug, Windows->Windows must have the
same problem, but it's unlikely to get fixed in Windows. As
it affects a real user I've talked to recently, I would like
to get this in.
Comments?
Thanks,
Volker
--
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:kontakt at sernet.de
-------------- next part --------------
From 575fe80b7e2de0a9637412130b92232fe74339c7 Mon Sep 17 00:00:00 2001
From: Volker Lendecke <vl at samba.org>
Date: Fri, 6 Feb 2015 16:11:13 +0100
Subject: [PATCH] smbd: Fix bug 10839
Signed-off-by: Volker Lendecke <vl at samba.org>
---
source3/smbd/globals.h | 17 +++++++++++++++++
source3/smbd/smb2_getinfo.c | 13 +++++++++++--
source3/smbd/smb2_negprot.c | 4 ++++
source3/smbd/smb2_notify.c | 12 ++++++++++--
source3/smbd/smb2_setinfo.c | 17 +++++++++++++++--
5 files changed, 57 insertions(+), 6 deletions(-)
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 7726c24..2c142b6 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -495,6 +495,23 @@ struct smbXsrv_connection {
*/
struct bitmap *bitmap;
bool multicredit;
+
+ /*
+ * See Samba bug 10839.
+ *
+ * According to [MS-SMB2] 3.2.4.1.5 Sending
+ * Multi-Credit Requests:
+ *
+ * > For all other requests, the client MUST set
+ * > CreditCharge to 1, even if the payload size of a
+ * > request or the anticipated response is greater
+ * > than 65536
+ *
+ * For notify, getinfo and setinfo we can only check
+ * for 1 credit and ignore in_output_buffer_length
+ * here.
+ */
+ bool ignore_broken_multicredit;
} credits;
bool allow_2ff;
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 7f44868..67f5a3b 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -59,6 +59,7 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
uint64_t in_file_id_volatile;
struct files_struct *in_fsp;
struct tevent_req *subreq;
+ uint32_t credit_charge;
status = smbd_smb2_request_verify_sizes(req, 0x29);
if (!NT_STATUS_IS_OK(status)) {
@@ -106,8 +107,16 @@ NTSTATUS smbd_smb2_request_process_getinfo(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
- status = smbd_smb2_request_verify_creditcharge(req,
- MAX(in_input_buffer.length,in_output_buffer_length));
+ credit_charge = MAX(in_input_buffer.length, in_output_buffer_length);
+ if (xconn->smb2.credits.ignore_broken_multicredit) {
+ /*
+ * see comment in globals.h where ignore_broken_multicredit
+ * is defined
+ */
+ credit_charge = 65536;
+ }
+
+ status = smbd_smb2_request_verify_creditcharge(req, credit_charge);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 9a1ca9c..be73391 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -361,6 +361,10 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
xconn->smb2.server.max_trans = max_trans;
xconn->smb2.server.max_read = max_read;
xconn->smb2.server.max_write = max_write;
+
+ xconn->smb2.credits.ignore_broken_multicredit =
+ lp_parm_bool(-1, "smbd", "ignore broken multicredit",
+ false);
}
return smbd_smb2_request_done(req, outbody, &outdyn);
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index 573635b..d9b5cfe 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -58,6 +58,7 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req)
struct files_struct *in_fsp;
uint64_t in_completion_filter;
struct tevent_req *subreq;
+ uint32_t credit_charge;
status = smbd_smb2_request_verify_sizes(req, 0x20);
if (!NT_STATUS_IS_OK(status)) {
@@ -79,9 +80,16 @@ NTSTATUS smbd_smb2_request_process_notify(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
- status = smbd_smb2_request_verify_creditcharge(req,
- in_output_buffer_length);
+ credit_charge = in_output_buffer_length;
+ if (xconn->smb2.credits.ignore_broken_multicredit) {
+ /*
+ * see comment in globals.h where ignore_broken_multicredit
+ * is defined
+ */
+ credit_charge = 65536;
+ }
+ status = smbd_smb2_request_verify_creditcharge(req, credit_charge);
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index e6981d1..1988cfc 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -55,6 +55,7 @@ NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req)
uint64_t in_file_id_volatile;
struct files_struct *in_fsp;
struct tevent_req *subreq;
+ uint32_t credit_charge;
status = smbd_smb2_request_verify_sizes(req, 0x21);
if (!NT_STATUS_IS_OK(status)) {
@@ -93,8 +94,20 @@ NTSTATUS smbd_smb2_request_process_setinfo(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
- status = smbd_smb2_request_verify_creditcharge(req,
- in_input_buffer.length);
+ credit_charge = in_input_buffer.length;
+ if (xconn->smb2.credits.ignore_broken_multicredit) {
+ /*
+ * see comment in globals.h where ignore_broken_multicredit
+ * is defined
+ */
+ credit_charge = 65536;
+ }
+
+ status = smbd_smb2_request_verify_creditcharge(req, credit_charge);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
if (!NT_STATUS_IS_OK(status)) {
return smbd_smb2_request_error(req, status);
}
--
1.9.1
More information about the samba-technical
mailing list