summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/param/loadparm.c3
-rw-r--r--source3/smbd/globals.h2
-rw-r--r--source3/smbd/negprot.c1
-rw-r--r--source3/smbd/smb2_negprot.c66
4 files changed, 67 insertions, 5 deletions
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index b0c64c7fa3..305ff2cec9 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 2e59d9bc5f..6ce9835dee 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 49b9420fbf..a38534f323 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 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);