[SCM] Samba Shared Repository - branch master updated
Jeremy Allison
jra at samba.org
Fri Mar 9 19:48:02 MST 2012
The branch, master has been updated
via 981e977 Ensure the right tsocket.h is included.
via 97e1652 Fix up Christian Ambach's multi-credit code - the CreditCharge field is a 16-bit int read, not a 32-bit one.
via 6e8e3c4 s3:smb2_server validate message ids with largemtu
via f6afda0 s3:smb2_server verify creditcharge
via eec5ece s3:smb2_server add function to verify creditcharge
via bd0ad2b s3:smb2_server: announce LargeMTU for SMB2.1
via 6d128aa s3:smb2_server increase defaults for read/write/trans sizes to 1MB
via 7f131d3 s3:smb2_server: add supports_multicredit to sconn
via 880f64b s3:smb2_server use the correct variables for max read/write
from 1e8141f Fix bug #8797 - Samba does not correctly handle DENY ACEs when privileges apply. Signed-off-by: Jeremy Allison <jra at samba.org>
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 981e9776f84dcf03f0297f47f63ee548ca089c0f
Author: Jeremy Allison <jra at samba.org>
Date: Fri Mar 9 17:08:36 2012 -0800
Ensure the right tsocket.h is included.
Autobuild-User: Jeremy Allison <jra at samba.org>
Autobuild-Date: Sat Mar 10 03:47:04 CET 2012 on sn-devel-104
commit 97e1652125a46ffbc1510b26abb0379d7df690d3
Author: Jeremy Allison <jra at samba.org>
Date: Fri Mar 9 16:47:21 2012 -0800
Fix up Christian Ambach's multi-credit code - the CreditCharge field is a 16-bit int read, not a 32-bit one.
commit 6e8e3c46130ce5882a3bd06bcccf4c383280e583
Author: Christian Ambach <ambi at samba.org>
Date: Mon Feb 27 17:53:04 2012 -0800
s3:smb2_server validate message ids with largemtu
Signed-off-by: Jeremy Allison <jra at samba.org>
commit f6afda0bc867f1080c45e1f6f79d5032c41d2b1a
Author: Christian Ambach <ambi at samba.org>
Date: Mon Feb 27 17:51:40 2012 -0800
s3:smb2_server verify creditcharge
for all requests that have max_???? checks, also do a check of the
creditcharge the client has sent (when using largemtu)
Signed-off-by: Jeremy Allison <jra at samba.org>
commit eec5ece6f59c5ff30de88af0e182c3b2f7b9579c
Author: Christian Ambach <ambi at samba.org>
Date: Mon Feb 27 17:49:12 2012 -0800
s3:smb2_server add function to verify creditcharge
Signed-off-by: Jeremy Allison <jra at samba.org>
commit bd0ad2bbb5361a92f349ef42171b9bdd1d99b281
Author: Christian Ambach <ambi at samba.org>
Date: Mon Feb 27 05:57:47 2012 -0800
s3:smb2_server: announce LargeMTU for SMB2.1
Signed-off-by: Jeremy Allison <jra at samba.org>
commit 6d128aac119d948f0ecb0dcf6b400b4eb4027fe6
Author: Christian Ambach <ambi at samba.org>
Date: Mon Feb 27 21:33:13 2012 -0800
s3:smb2_server increase defaults for read/write/trans sizes to 1MB
Signed-off-by: Jeremy Allison <jra at samba.org>
commit 7f131d3cee260e5943dc1e113b6eabb677fd4945
Author: Christian Ambach <ambi at samba.org>
Date: Mon Feb 27 17:45:09 2012 -0800
s3:smb2_server: add supports_multicredit to sconn
Signed-off-by: Jeremy Allison <jra at samba.org>
commit 880f64b5560b0b27d7f1313c8a78044d871d27ad
Author: Christian Ambach <ambi at samba.org>
Date: Mon Feb 27 05:56:57 2012 -0800
s3:smb2_server use the correct variables for max read/write
Signed-off-by: Jeremy Allison <jra at samba.org>
-----------------------------------------------------------------------
Summary of changes:
source3/include/local.h | 6 +-
source3/smbd/globals.h | 4 ++
source3/smbd/smb2_find.c | 8 +++
source3/smbd/smb2_getinfo.c | 6 ++
source3/smbd/smb2_negprot.c | 35 ++++++++++--
source3/smbd/smb2_notify.c | 7 +++
source3/smbd/smb2_read.c | 5 ++
source3/smbd/smb2_server.c | 122 +++++++++++++++++++++++++++++++++----------
source3/smbd/smb2_setinfo.c | 6 ++
source3/smbd/smb2_write.c | 5 ++
10 files changed, 168 insertions(+), 36 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/local.h b/source3/include/local.h
index 281248c..11166df 100644
--- a/source3/include/local.h
+++ b/source3/include/local.h
@@ -232,9 +232,9 @@
#define CLIENT_NDR_PADDING_SIZE 8
#define SERVER_NDR_PADDING_SIZE 8
-#define DEFAULT_SMB2_MAX_READ (64*1024)
-#define DEFAULT_SMB2_MAX_WRITE (64*1024)
-#define DEFAULT_SMB2_MAX_TRANSACT (64*1024)
+#define DEFAULT_SMB2_MAX_READ (1024*1024)
+#define DEFAULT_SMB2_MAX_WRITE (1024*1024)
+#define DEFAULT_SMB2_MAX_TRANSACT (1024*1024)
#define DEFAULT_SMB2_MAX_CREDITS 8192
#define DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR 2
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 5b65711..caf7357 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -258,6 +258,9 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req,
struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req);
void remove_smb2_chained_fsp(files_struct *fsp);
+NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
+ uint32_t data_length);
+
NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
size_t expected_body_size);
@@ -590,6 +593,7 @@ struct smbd_server_connection {
uint32_t max_trans;
uint32_t max_read;
uint32_t max_write;
+ bool supports_multicredit;
struct bitmap *credits_bitmap;
bool compound_related_in_progress;
} smb2;
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index 99d3447..9c0d18b 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -282,6 +282,14 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
return tevent_req_post(req, ev);
}
+ status = smbd_smb2_request_verify_creditcharge(smb2req,
+ in_output_buffer_length);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return tevent_req_post(req, ev);
+ }
+
switch (in_file_info_class) {
case SMB2_FIND_DIRECTORY_INFO:
info_level = SMB_FIND_FILE_DIRECTORY_INFO;
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 7d0f946..e8d918d 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -97,6 +97,12 @@ 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));
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
if (req->compat_chain_fsp) {
/* skip check */
} else if (in_file_id_persistent != in_file_id_volatile) {
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index d971fba..0351475 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -22,6 +22,7 @@
#include "smbd/smbd.h"
#include "smbd/globals.h"
#include "../libcli/smb/smb_common.h"
+#include "../lib/tsocket/tsocket.h"
/*
* this is the entry point if SMB2 is selected via
@@ -226,14 +227,36 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
}
/*
- * Unless we implement SMB2_CAP_LARGE_MTU,
* 0x10000 (65536) is the maximum allowed message size
+ * for SMB 2.0
*/
max_limit = 0x10000;
- max_trans = MIN(max_limit, max_trans);
- max_read = MIN(max_limit, max_read);
- max_write = MIN(max_limit, max_write);
+ if (protocol >= PROTOCOL_SMB2_10) {
+ /* largeMTU is only available on port 445 */
+ if (TCP_SMB_PORT ==
+ tsocket_address_inet_port(req->sconn->local_address))
+ {
+
+ capabilities |= SMB2_CAP_LARGE_MTU;
+ req->sconn->smb2.supports_multicredit = true;
+
+ /* SMB2.1 has 1 MB of allowed size */
+ max_limit = 0x100000; /* 1MB */
+ }
+ }
+
+ /*
+ * the defaults are 1MB, but we'll limit this to max_limit based on
+ * the dialect (64kb for SMB2.0, 1MB for SMB2.1 with LargeMTU)
+ *
+ * user configured values exceeding the limits will be overwritten,
+ * only smaller values will be accepted
+ */
+
+ max_trans = MIN(max_limit, lp_smb2_max_trans());
+ max_read = MIN(max_limit, lp_smb2_max_read());
+ max_write = MIN(max_limit, lp_smb2_max_write());
security_offset = SMB2_HDR_BODY + 0x40;
@@ -261,8 +284,8 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
SIVAL(outbody.data, 0x18,
capabilities); /* capabilities */
SIVAL(outbody.data, 0x1C, max_trans); /* max transact size */
- SIVAL(outbody.data, 0x20, max_trans); /* max read size */
- SIVAL(outbody.data, 0x24, max_trans); /* max write size */
+ SIVAL(outbody.data, 0x20, max_read); /* max read size */
+ SIVAL(outbody.data, 0x24, max_write); /* max write size */
SBVAL(outbody.data, 0x28, 0); /* system time */
SBVAL(outbody.data, 0x30, 0); /* server start time */
SSVAL(outbody.data, 0x38,
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index be56b18..3f5365c 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -77,6 +77,13 @@ 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);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
if (req->compat_chain_fsp) {
/* skip check */
} else if (in_file_id_persistent != in_file_id_volatile) {
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 13bcbdf..0b6e2ee 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -80,6 +80,11 @@ NTSTATUS smbd_smb2_request_process_read(struct smbd_smb2_request *req)
return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
}
+ status = smbd_smb2_request_verify_creditcharge(req, in_length);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
if (req->compat_chain_fsp) {
/* skip check */
} else if (in_file_id_persistent != in_file_id_volatile) {
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index 8533157..3993673 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -306,6 +306,8 @@ static bool smb2_validate_message_id(struct smbd_server_connection *sconn,
struct bitmap *credits_bm = sconn->smb2.credits_bitmap;
uint16_t opcode = IVAL(inhdr, SMB2_HDR_OPCODE);
unsigned int bitmap_offset;
+ uint16_t credit_charge = 1;
+ uint64_t i;
if (opcode == SMB2_OP_CANCEL) {
/* SMB2_CANCEL requests by definition resend messageids. */
@@ -325,38 +327,65 @@ static bool smb2_validate_message_id(struct smbd_server_connection *sconn,
if (sconn->smb2.credits_granted == 0) {
DEBUG(0,("smb2_validate_message_id: client used more "
- "credits than granted message_id (%llu)\n",
+ "credits than granted, message_id (%llu)\n",
(unsigned long long)message_id));
return false;
}
- /* client just used a credit. */
- sconn->smb2.credits_granted -= 1;
-
- /* Mark the message_id as seen in the bitmap. */
- bitmap_offset = (unsigned int)(message_id %
- (uint64_t)(sconn->smb2.max_credits * DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR));
- if (bitmap_query(credits_bm, bitmap_offset)) {
- DEBUG(0,("smb2_validate_message_id: duplicate message_id "
- "%llu (bm offset %u)\n",
- (unsigned long long)message_id,
- bitmap_offset));
- return false;
+ if (sconn->smb2.supports_multicredit) {
+ credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
+ credit_charge = MAX(credit_charge, 1);
}
- bitmap_set(credits_bm, bitmap_offset);
- if (message_id == sconn->smb2.seqnum_low + 1) {
- /* Move the window forward by all the message_id's
- already seen. */
- while (bitmap_query(credits_bm, bitmap_offset)) {
- DEBUG(10,("smb2_validate_message_id: clearing "
- "id %llu (position %u) from bitmap\n",
- (unsigned long long)(sconn->smb2.seqnum_low + 1),
- bitmap_offset ));
- bitmap_clear(credits_bm, bitmap_offset);
- sconn->smb2.seqnum_low += 1;
- bitmap_offset = (bitmap_offset + 1) %
- (sconn->smb2.max_credits * DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR);
+ DEBUG(11, ("smb2_validate_message_id: mid %llu, credits_granted %llu, "
+ "charge %llu, max_credits %llu, seqnum_low: %llu\n",
+ (unsigned long long) message_id,
+ (unsigned long long) sconn->smb2.credits_granted,
+ (unsigned long long) credit_charge,
+ (unsigned long long) sconn->smb2.max_credits,
+ (unsigned long long) sconn->smb2.seqnum_low));
+
+ /* substract used credits */
+ sconn->smb2.credits_granted -= credit_charge;
+
+ /*
+ * now check the message ids
+ *
+ * for multi-credit requests we need to check all current mid plus
+ * the implicit mids caused by the credit charge
+ * e.g. current mid = 15, charge 5 => mark 15-19 as used
+ */
+
+ for (i = message_id; i <= (message_id+credit_charge-1); i++) {
+
+ DEBUG(11, ("Iterating mid %llu\n", (unsigned long long) i));
+
+ /* Mark the message_ids as seen in the bitmap. */
+ bitmap_offset = (unsigned int)(i %
+ (uint64_t)(sconn->smb2.max_credits *
+ DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR));
+ if (bitmap_query(credits_bm, bitmap_offset)) {
+ DEBUG(0,("smb2_validate_message_id: duplicate "
+ "message_id %llu (bm offset %u)\n",
+ (unsigned long long)i, bitmap_offset));
+ return false;
+ }
+ bitmap_set(credits_bm, bitmap_offset);
+
+ if (i == sconn->smb2.seqnum_low + 1) {
+ /* Move the window forward by all the message_id's
+ already seen. */
+ while (bitmap_query(credits_bm, bitmap_offset)) {
+ DEBUG(10,("smb2_validate_message_id: clearing "
+ "id %llu (position %u) from bitmap\n",
+ (unsigned long long)(sconn->smb2.seqnum_low + 1),
+ bitmap_offset));
+ bitmap_clear(credits_bm, bitmap_offset);
+ sconn->smb2.seqnum_low += 1;
+ bitmap_offset = (bitmap_offset + 1) %
+ (sconn->smb2.max_credits *
+ DEFAULT_SMB2_MAX_CREDIT_BITMAP_FACTOR);
+ }
}
}
@@ -1252,6 +1281,45 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
return NT_STATUS_OK;
}
+NTSTATUS smbd_smb2_request_verify_creditcharge(struct smbd_smb2_request *req,
+ uint32_t data_length)
+{
+ uint16_t needed_charge;
+ uint16_t credit_charge;
+ const uint8_t *inhdr;
+ int i = req->current_idx;
+
+ if (!req->sconn->smb2.supports_multicredit) {
+ if (data_length > 65536) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ return NT_STATUS_OK;
+ }
+
+ inhdr = (const uint8_t *)req->in.vector[i+0].iov_base;
+ credit_charge = SVAL(inhdr, SMB2_HDR_CREDIT_CHARGE);
+
+ /* requests larger than 64 KB need credit charge */
+ if (credit_charge == 0 && data_length > 65536) {
+ DEBUG(2, ("Request larger than 64KB w/o creditcharge\n"));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ needed_charge = (data_length - 1)/ 65536 + 1;
+
+ DEBUG(10, ("mid %lu, CreditCharge: %d, NeededCharge: %d\n",
+ BVAL(inhdr, SMB2_HDR_MESSAGE_ID), credit_charge,
+ needed_charge));
+
+ if (needed_charge > credit_charge) {
+ DEBUG(2, ("CreditCharge too low, given %d, needed %d\n",
+ credit_charge, needed_charge));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ return NT_STATUS_OK;
+}
+
NTSTATUS smbd_smb2_request_verify_sizes(struct smbd_smb2_request *req,
size_t expected_body_size)
{
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index ac6adc3..be506cc 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -85,6 +85,12 @@ 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);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
if (req->compat_chain_fsp) {
/* skip check */
} else if (in_file_id_persistent != in_file_id_volatile) {
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index b0ffd44..163672c 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -88,6 +88,11 @@ NTSTATUS smbd_smb2_request_process_write(struct smbd_smb2_request *req)
in_data_buffer.data = (uint8_t *)req->in.vector[i+2].iov_base;
in_data_buffer.length = in_data_length;
+ status = smbd_smb2_request_verify_creditcharge(req, in_data_length);
+ if (!NT_STATUS_IS_OK(status)) {
+ return smbd_smb2_request_error(req, status);
+ }
+
if (req->compat_chain_fsp) {
/* skip check */
} else if (in_file_id_persistent != in_file_id_volatile) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list