diff options
author | Stefan Metzmacher <metze@samba.org> | 2011-09-05 13:14:40 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2011-09-05 19:30:58 +0200 |
commit | 012c9d06a94b532377e9e96f60b20b5f0975af74 (patch) | |
tree | 0065c2161af15c9cf92c23e1fb931bc838e71a14 /source3/smbd | |
parent | 1c8e8c7e7b4cc00628b91e2e0596bfa428a2bcdb (diff) | |
download | samba-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')
-rw-r--r-- | source3/smbd/globals.h | 2 | ||||
-rw-r--r-- | source3/smbd/negprot.c | 1 | ||||
-rw-r--r-- | source3/smbd/smb2_negprot.c | 66 |
3 files changed, 65 insertions, 4 deletions
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); |