summaryrefslogtreecommitdiff
path: root/source3/smbd/smb2_negprot.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2011-09-05 13:14:40 +0200
committerStefan Metzmacher <metze@samba.org>2011-09-05 19:30:58 +0200
commit012c9d06a94b532377e9e96f60b20b5f0975af74 (patch)
tree0065c2161af15c9cf92c23e1fb931bc838e71a14 /source3/smbd/smb2_negprot.c
parent1c8e8c7e7b4cc00628b91e2e0596bfa428a2bcdb (diff)
downloadsamba-012c9d06a94b532377e9e96f60b20b5f0975af74.tar.gz
samba-012c9d06a94b532377e9e96f60b20b5f0975af74.tar.bz2
samba-012c9d06a94b532377e9e96f60b20b5f0975af74.zip
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@samba.org> Autobuild-Date: Mon Sep 5 19:30:58 CEST 2011 on sn-devel-104
Diffstat (limited to 'source3/smbd/smb2_negprot.c')
-rw-r--r--source3/smbd/smb2_negprot.c66
1 files changed, 62 insertions, 4 deletions
diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c
index dfb2da3fda..56a30d0d71 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 and the "SMB 2.002" dialect.
+ * 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, SMB2_DIALECT_REVISION_202);
+ 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;
@@ -108,6 +127,28 @@ 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; 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;
@@ -115,11 +156,28 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req)
}
}
+ 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;
+ }
+ }
+ }
+
if (protocol == PROTOCOL_NONE) {
return smbd_smb2_request_error(req, NT_STATUS_NOT_SUPPORTED);
}
- set_Protocol(protocol);
+ if (dialect != SMB2_DIALECT_REVISION_2FF) {
+ set_Protocol(protocol);
+ }
if (get_remote_arch() != RA_SAMBA) {
set_remote_arch(RA_VISTA);