[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Mon Sep 5 11:31:02 MDT 2011
The branch, master has been updated
via 012c9d0 s3:smb2_server: add basic support for SMB 2.1
via 1c8e8c7 s3:smb2_server: return NOT_SUPPORTED if we don't find a common dialect with the client
via e603929 s3:smb2_server: max_trans, max_read and max_write are limited to 64 kilobytes
via a44d3d1 s3:smb2cli: make sure we don't try to send requests on a disconnected cli_state
via 4dca2ac s3:smb2cli: make sure requests are not finished, when we send when to the network
via 0b6087c s3:smb2cli: disconnect the connection, if we're out of message ids
via 5155a15 s3:smb2cli: don't use state->cli->smb2.mid++ as macro argument
from 3e8c665 s3-smbd: Rename reload_printers() and add documentation.
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 012c9d06a94b532377e9e96f60b20b5f0975af74
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 5 13:14:40 2011 +0200
s3:smb2_server: add basic support for SMB 2.1
This adds support for the 2 stage negprot, from SMB 1 to SMB 2.1.
Support for this of for now and "max protocol = SMB2" still maps
to "max protocol = SMB2_02" PROTOCOL_SMB2_02.
In order to activate smb2.1, you need to use "max protocol = SMB2_10".
metze
Autobuild-User: Stefan Metzmacher <metze at samba.org>
Autobuild-Date: Mon Sep 5 19:30:58 CEST 2011 on sn-devel-104
commit 1c8e8c7e7b4cc00628b91e2e0596bfa428a2bcdb
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 5 12:23:51 2011 +0200
s3:smb2_server: return NOT_SUPPORTED if we don't find a common dialect with the client
metze
commit e603929b9801ad6cc47dead19d27b42fe46489c7
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 5 12:14:06 2011 +0200
s3:smb2_server: max_trans, max_read and max_write are limited to 64 kilobytes
Only if SMB2_CAP_LARGE_MTU is supported we should announce larger limits.
metze
commit a44d3d176400d0c6500fc8d3c05ee73e930fd140
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 5 09:49:53 2011 +0200
s3:smb2cli: make sure we don't try to send requests on a disconnected cli_state
metze
commit 4dca2acfe43fda00637615548fecab1e3313b204
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 5 09:35:43 2011 +0200
s3:smb2cli: make sure requests are not finished, when we send when to the network
metze
commit 0b6087c7be01983be96f3f3cb892ba2f32a8266a
Author: Stefan Metzmacher <metze at samba.org>
Date: Mon Sep 5 09:31:54 2011 +0200
s3:smb2cli: disconnect the connection, if we're out of message ids
metze
commit 5155a15c5cadd2dec9386576c1b4b566be1e4536
Author: Stefan Metzmacher <metze at samba.org>
Date: Sat Sep 3 15:23:44 2011 +0200
s3:smb2cli: don't use state->cli->smb2.mid++ as macro argument
It gets expanded multiple times.
metze
-----------------------------------------------------------------------
Summary of changes:
source3/libsmb/smb2cli_base.c | 31 +++++++++++++-
source3/param/loadparm.c | 3 +-
source3/smbd/globals.h | 2 +
source3/smbd/negprot.c | 1 +
source3/smbd/smb2_negprot.c | 94 ++++++++++++++++++++++++++++++++++++----
5 files changed, 118 insertions(+), 13 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/libsmb/smb2cli_base.c b/source3/libsmb/smb2cli_base.c
index 9fc824c..7f4b176 100644
--- a/source3/libsmb/smb2cli_base.c
+++ b/source3/libsmb/smb2cli_base.c
@@ -22,6 +22,7 @@
#include "client.h"
#include "read_smb.h"
#include "smb2cli_base.h"
+#include "libsmb/proto.h"
#include "lib/async_req/async_sock.h"
#include "lib/util/tevent_ntstatus.h"
@@ -252,10 +253,26 @@ NTSTATUS smb2cli_req_compound_submit(struct tevent_req **reqs,
for (i=0; i<num_reqs; i++) {
size_t reqlen;
bool ret;
+ uint64_t mid;
+
+ if (!tevent_req_is_in_progress(reqs[i])) {
+ return NT_STATUS_INTERNAL_ERROR;
+ }
state = tevent_req_data(reqs[i], struct smb2cli_req_state);
- SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, state->cli->smb2.mid++);
+ if (!cli_state_is_connected(state->cli)) {
+ return NT_STATUS_CONNECTION_DISCONNECTED;
+ }
+
+ if (state->cli->smb2.mid == UINT64_MAX) {
+ return NT_STATUS_CONNECTION_ABORTED;
+ }
+
+ mid = state->cli->smb2.mid;
+ state->cli->smb2.mid += 1;
+
+ SBVAL(state->hdr, SMB2_HDR_MESSAGE_ID, mid);
iov[num_iov].iov_base = state->hdr;
iov[num_iov].iov_len = sizeof(state->hdr);
@@ -576,7 +593,17 @@ static void smb2cli_inbuf_received(struct tevent_req *subreq)
num_pending = talloc_array_length(cli->conn.pending);
if (num_pending == 0) {
- /* no more pending requests, so we are done for now */
+ if (state->cli->smb2.mid < UINT64_MAX) {
+ /* no more pending requests, so we are done for now */
+ return;
+ }
+
+ /*
+ * If there are no more requests possible,
+ * because we are out of message ids,
+ * we need to disconnect.
+ */
+ smb2cli_notify_pending(cli, NT_STATUS_CONNECTION_ABORTED);
return;
}
req = cli->conn.pending[0];
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index b0c64c7..305ff2c 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -312,7 +312,8 @@ static void add_to_file_list(const char *fname, const char *subfname);
static bool lp_set_cmdline_helper(const char *pszParmName, const char *pszParmValue, bool store_values);
static const struct enum_list enum_protocol[] = {
- {PROTOCOL_SMB2_02, "SMB2"},
+ {PROTOCOL_SMB2_02, "SMB2"}, /* for now keep PROTOCOL_SMB2_02 */
+ {PROTOCOL_SMB2_10, "SMB2_10"},
{PROTOCOL_SMB2_02, "SMB2_02"},
{PROTOCOL_NT1, "NT1"},
{PROTOCOL_LANMAN2, "LANMAN2"},
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 2e59d9b..6ce9835 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -241,6 +241,7 @@ const char *smb2_opcode_name(uint16_t opcode);
bool smbd_is_smb2_header(const uint8_t *inbuf, size_t size);
void reply_smb2002(struct smb_request *req, uint16_t choice);
+void reply_smb20ff(struct smb_request *req, uint16_t choice);
void smbd_smb2_first_negprot(struct smbd_server_connection *sconn,
const uint8_t *inbuf, size_t size);
@@ -578,6 +579,7 @@ struct smbd_server_connection {
struct tevent_queue *recv_queue;
struct tevent_queue *send_queue;
struct tstream_context *stream;
+ bool negprot_2ff;
struct {
/* an id tree used to allocate vuids */
/* this holds info on session vuids that are already
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 49b9420..a38534f 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -536,6 +536,7 @@ static const struct {
void (*proto_reply_fn)(struct smb_request *req, uint16 choice);
int protocol_level;
} supported_protocols[] = {
+ {"SMB 2.???", "SMB2_FF", reply_smb20ff, PROTOCOL_SMB2_10},
{"SMB 2.002", "SMB2_02", reply_smb2002, PROTOCOL_SMB2_02},
{"NT LANMAN 1.0", "NT1", reply_nt1, PROTOCOL_NT1},
{"NT LM 0.12", "NT1", reply_nt1, PROTOCOL_NT1},
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index 5ae9163..56a30d0 100644
--- a/source3/smbd/smb2_negprot.c
+++ b/source3/smbd/smb2_negprot.c
@@ -25,9 +25,9 @@
/*
* this is the entry point if SMB2 is selected via
- * the SMB negprot
+ * the SMB negprot and the given dialect.
*/
-void reply_smb2002(struct smb_request *req, uint16_t choice)
+static void reply_smb20xx(struct smb_request *req, uint16_t dialect)
{
uint8_t *smb2_inbuf;
uint8_t *smb2_hdr;
@@ -51,7 +51,7 @@ void reply_smb2002(struct smb_request *req, uint16_t choice)
SSVAL(smb2_body, 0x00, 0x0024); /* struct size */
SSVAL(smb2_body, 0x02, 0x0001); /* dialect count */
- SSVAL(smb2_dyn, 0x00, 0x0202); /* dialect 2.002 */
+ SSVAL(smb2_dyn, 0x00, dialect);
req->outbuf = NULL;
@@ -59,6 +59,25 @@ void reply_smb2002(struct smb_request *req, uint16_t choice)
return;
}
+/*
+ * this is the entry point if SMB2 is selected via
+ * the SMB negprot and the "SMB 2.002" dialect.
+ */
+void reply_smb2002(struct smb_request *req, uint16_t choice)
+{
+ reply_smb20xx(req, SMB2_DIALECT_REVISION_202);
+}
+
+/*
+ * this is the entry point if SMB2 is selected via
+ * the SMB negprot and the "SMB 2.???" dialect.
+ */
+void reply_smb20ff(struct smb_request *req, uint16_t choice)
+{
+ req->sconn->smb2.negprot_2ff = true;
+ reply_smb20xx(req, SMB2_DIALECT_REVISION_2FF);
+}
+
NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
{
const uint8_t *inbody;
@@ -77,6 +96,11 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
uint16_t dialect_count;
uint16_t dialect = 0;
uint32_t capabilities;
+ enum protocol_types protocol = PROTOCOL_NONE;
+ uint32_t max_limit;
+ uint32_t max_trans = lp_smb2_max_trans();
+ uint32_t max_read = lp_smb2_max_read();
+ uint32_t max_write = lp_smb2_max_write();
/* TODO: drop the connection with INVALID_PARAMETER */
@@ -102,18 +126,58 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
}
indyn = (const uint8_t *)req->in.vector[i+2].iov_base;
- for (c=0; c < dialect_count; c++) {
+ for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
+ if (lp_maxprotocol() < PROTOCOL_SMB2_10) {
+ break;
+ }
+ if (lp_minprotocol() > PROTOCOL_SMB2_10) {
+ break;
+ }
+
+ dialect = SVAL(indyn, c*2);
+ if (dialect == SMB2_DIALECT_REVISION_210) {
+ protocol = PROTOCOL_SMB2_10;
+ break;
+ }
+ }
+
+ for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
+ if (lp_maxprotocol() < PROTOCOL_SMB2_02) {
+ break;
+ }
+ if (lp_minprotocol() > PROTOCOL_SMB2_02) {
+ break;
+ }
+
dialect = SVAL(indyn, c*2);
if (dialect == SMB2_DIALECT_REVISION_202) {
+ protocol = PROTOCOL_SMB2_02;
break;
}
}
- if (dialect != SMB2_DIALECT_REVISION_202) {
- return smbd_smb2_request_error(req, NT_STATUS_INVALID_PARAMETER);
+ for (c=0; protocol == PROTOCOL_NONE && c < dialect_count; c++) {
+ if (lp_maxprotocol() < PROTOCOL_SMB2_10) {
+ break;
+ }
+
+ dialect = SVAL(indyn, c*2);
+ if (dialect == SMB2_DIALECT_REVISION_2FF) {
+ if (req->sconn->smb2.negprot_2ff) {
+ req->sconn->smb2.negprot_2ff = false;
+ protocol = PROTOCOL_SMB2_10;
+ break;
+ }
+ }
}
- set_Protocol(PROTOCOL_SMB2_02);
+ if (protocol == PROTOCOL_NONE) {
+ return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
+ }
+
+ if (dialect != SMB2_DIALECT_REVISION_2FF) {
+ set_Protocol(protocol);
+ }
if (get_remote_arch() != RA_SAMBA) {
set_remote_arch(RA_VISTA);
@@ -139,6 +203,16 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
capabilities |= SMB2_CAP_DFS;
}
+ /*
+ * Unless we implement SMB2_CAP_LARGE_MTU,
+ * 0x10000 (65536) is the maximum allowed message size
+ */
+ max_limit = 0x10000;
+
+ max_trans = MIN(max_limit, max_trans);
+ max_read = MIN(max_limit, max_read);
+ max_write = MIN(max_limit, max_write);
+
security_offset = SMB2_HDR_BODY + 0x40;
#if 1
@@ -164,9 +238,9 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
negprot_spnego_blob.data, 16); /* server guid */
SIVAL(outbody.data, 0x18,
capabilities); /* capabilities */
- SIVAL(outbody.data, 0x1C, lp_smb2_max_trans()); /* max transact size */
- SIVAL(outbody.data, 0x20, lp_smb2_max_read()); /* max read size */
- SIVAL(outbody.data, 0x24, lp_smb2_max_write()); /* max write size */
+ 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 */
SBVAL(outbody.data, 0x28, 0); /* system time */
SBVAL(outbody.data, 0x30, 0); /* server start time */
SSVAL(outbody.data, 0x38,
--
Samba Shared Repository
More information about the samba-cvs
mailing list