From ccdc227aed688c10a858fe6eae63157adfbdcae5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 25 Feb 2015 16:59:26 +0100 Subject: [PATCH 1/9] smbd: Make SMB3 clients use encryption with "smb encrypt = auto" Signed-off-by: Volker Lendecke Reviewed-by: Stefan Metzmacher BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Tue Mar 3 10:40:42 CET 2015 on sn-devel-104 (cherry picked from commit b3385f74db54bd8a07a0be5515151b633c067da4) --- source3/smbd/smb2_sesssetup.c | 5 +++++ source3/smbd/smb2_tcon.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 85f8a9a..28c74bd 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -190,6 +190,11 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, x->global->signing_required = true; } + if ((lp_smb_encrypt(-1) > SMB_SIGNING_OFF) && + (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) { + x->global->encryption_required = true; + } + if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) { x->global->encryption_required = true; } diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c index 8a6d339..da06ea9 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -235,6 +235,11 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, return NT_STATUS_BAD_NETWORK_NAME; } + if ((lp_smb_encrypt(snum) > SMB_SIGNING_OFF) && + (conn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) { + encryption_required = true; + } + if (lp_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) { encryption_required = true; } -- 2.4.3 From 81e9151d2ccebb2568b19cedab1d85e6c34f0477 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 30 Jun 2015 14:16:19 +0200 Subject: [PATCH 2/9] Introduce setting "desired" for 'smb encrypt' and 'client/server signing' This should trigger the behaviour where the server requires signing when the client supports it, but does not reject clients that don't support it. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner (cherry picked from commit 204cbe3645c59b43175beeadad792b4a00e80da3) --- lib/param/loadparm.c | 1 + lib/param/param_table.c | 1 + libcli/smb/smbXcli_base.c | 6 ++++++ libcli/smb/smb_constants.h | 1 + source4/smb_server/smb2/negprot.c | 1 + 5 files changed, 10 insertions(+) diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index dff1ca9..ae60cbf 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -3189,6 +3189,7 @@ bool lpcfg_server_signing_allowed(struct loadparm_context *lp_ctx, bool *mandato case SMB_SIGNING_REQUIRED: *mandatory = true; break; + case SMB_SIGNING_DESIRED: case SMB_SIGNING_IF_REQUIRED: break; case SMB_SIGNING_DEFAULT: diff --git a/lib/param/param_table.c b/lib/param/param_table.c index 1b9656b..530d858 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -113,6 +113,7 @@ static const struct enum_list enum_smb_signing_vals[] = { {SMB_SIGNING_IF_REQUIRED, "On"}, {SMB_SIGNING_IF_REQUIRED, "enabled"}, {SMB_SIGNING_IF_REQUIRED, "auto"}, + {SMB_SIGNING_DESIRED, "desired"}, {SMB_SIGNING_REQUIRED, "required"}, {SMB_SIGNING_REQUIRED, "mandatory"}, {SMB_SIGNING_REQUIRED, "force"}, diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index c27b317..803b6ee 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -357,6 +357,12 @@ struct smbXcli_conn *smbXcli_conn_create(TALLOC_CTX *mem_ctx, conn->desire_signing = false; conn->mandatory_signing = false; break; + case SMB_SIGNING_DESIRED: + /* if the server desires it */ + conn->allow_signing = true; + conn->desire_signing = true; + conn->mandatory_signing = false; + break; case SMB_SIGNING_REQUIRED: /* always */ conn->allow_signing = true; diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h index f841ca9..9b57078 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -96,6 +96,7 @@ enum smb_signing_setting { SMB_SIGNING_DEFAULT = -1, SMB_SIGNING_OFF = 0, SMB_SIGNING_IF_REQUIRED = 1, + SMB_SIGNING_DESIRED = 2, SMB_SIGNING_REQUIRED = 3, }; diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 81f2547..b48b170 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -150,6 +150,7 @@ static NTSTATUS smb2srv_negprot_backend(struct smb2srv_request *req, struct smb2 case SMB_SIGNING_OFF: io->out.security_mode = 0; break; + case SMB_SIGNING_DESIRED: case SMB_SIGNING_IF_REQUIRED: io->out.security_mode = SMB2_NEGOTIATE_SIGNING_ENABLED; break; -- 2.4.3 From 148d1db291135b4355a72a362d466a577c908298 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 1 Jul 2015 17:34:45 +0200 Subject: [PATCH 3/9] smbXsrv: add bools encryption_desired to session and tcon This is to indicate that we should sen the ENCRYPT_DATA flag on session or tcon replies. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner (cherry picked from commit a3ea6dbef53e049701326497e684e1563344e6d8) --- source3/librpc/idl/smbXsrv.idl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl index 0035442..e32496a 100644 --- a/source3/librpc/idl/smbXsrv.idl +++ b/source3/librpc/idl/smbXsrv.idl @@ -190,6 +190,7 @@ interface smbXsrv [ignore] gensec_security *gensec; [ignore] user_struct *compat; [ignore] smbXsrv_tcon_table *tcon_table; + boolean8 encryption_desired; } smbXsrv_session; typedef union { @@ -284,6 +285,7 @@ interface smbXsrv NTSTATUS status; NTTIME idle_time; [ignore] connection_struct *compat; + boolean8 encryption_desired; } smbXsrv_tcon; typedef union { -- 2.4.3 From 0cd551368326d078c87f8d8af88b7cdfcf807988 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 1 Jul 2015 17:42:58 +0200 Subject: [PATCH 4/9] smbd:smb2: separate between encryption required and enc desired this means we: - accept unencrypted requests if encryption only desired and not required, - but we always send encrypted responses in the desired case, not only when the request was encrypted. For this purpose, the do_encryption in the request structure is separated into was_encrypted and do_encryption. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner (cherry picked from commit 3bb299944391633c45d87d5e8ad48c2c14428592) --- source3/smbd/globals.h | 3 +++ source3/smbd/smb2_server.c | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 2aed98e..3194b45 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -646,6 +646,9 @@ struct smbd_smb2_request { int current_idx; bool do_signing; + /* Was the request encrypted? */ + bool was_encrypted; + /* Should we encrypt? */ bool do_encryption; struct tevent_timer *async_te; bool compound_related; diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 2739734..ebfe1d6 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -1939,6 +1939,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) NTSTATUS return_value; struct smbXsrv_session *x = NULL; bool signing_required = false; + bool encryption_desired = false; bool encryption_required = false; inhdr = SMBD_SMB2_IN_HDR_PTR(req); @@ -1984,11 +1985,13 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) x = req->session; if (x != NULL) { signing_required = x->global->signing_required; + encryption_desired = x->encryption_desired; encryption_required = x->global->encryption_required; } req->do_signing = false; req->do_encryption = false; + req->was_encrypted = false; if (intf_v->iov_len == SMB2_TF_HDR_SIZE) { const uint8_t *intf = SMBD_SMB2_IN_TF_PTR(req); uint64_t tf_session_id = BVAL(intf, SMB2_TF_SESSION_ID); @@ -2010,10 +2013,10 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) NT_STATUS_ACCESS_DENIED); } - req->do_encryption = true; + req->was_encrypted = true; } - if (encryption_required && !req->do_encryption) { + if (encryption_required && !req->was_encrypted) { return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); } @@ -2045,7 +2048,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) req->compat_chain_fsp = NULL; } - if (req->do_encryption) { + if (req->was_encrypted) { signing_required = false; } else if (signing_required || (flags & SMB2_HDR_FLAG_SIGNED)) { DATA_BLOB signing_key = data_blob_null; @@ -2131,15 +2134,22 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) if (!NT_STATUS_IS_OK(status)) { return smbd_smb2_request_error(req, status); } + if (req->tcon->encryption_desired) { + encryption_desired = true; + } if (req->tcon->global->encryption_required) { encryption_required = true; } - if (encryption_required && !req->do_encryption) { + if (encryption_required && !req->was_encrypted) { return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED); } } + if (req->was_encrypted || encryption_desired) { + req->do_encryption = true; + } + if (call->fileid_ofs != 0) { size_t needed = call->fileid_ofs + 16; const uint8_t *body = SMBD_SMB2_IN_BODY_PTR(req); -- 2.4.3 From 4261bb75c040428259a9af8d3618dfd31c3ca991 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 1 Jul 2015 18:07:26 +0200 Subject: [PATCH 5/9] smbd:smb2: only enable encryption in session if desired Don't enforce it but only announce ENCRYPT_DATA, using the encryption_desired flag in session setup. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner (cherry picked from commit fc228025d78f165815d3fa1670d51f0c27ed2091) --- source3/smbd/smb2_sesssetup.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 28c74bd..e255e46 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -190,12 +190,13 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, x->global->signing_required = true; } - if ((lp_smb_encrypt(-1) > SMB_SIGNING_OFF) && + if ((lp_smb_encrypt(-1) >= SMB_SIGNING_DESIRED) && (xconn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) { - x->global->encryption_required = true; + x->encryption_desired = true; } if (lp_smb_encrypt(-1) == SMB_SIGNING_REQUIRED) { + x->encryption_desired = true; x->global->encryption_required = true; } @@ -222,7 +223,7 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, } } - if (x->global->encryption_required) { + if (x->encryption_desired) { *out_session_flags |= SMB2_SESSION_FLAG_ENCRYPT_DATA; } -- 2.4.3 From d3a3814f936be2ab2b38a08e35f245f4344ce554 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 1 Jul 2015 18:07:52 +0200 Subject: [PATCH 6/9] smbd:smb2: only enable encryption in tcon if desired Don't enforce it but only announce DATA_ENCRYPT, making use of encryption_desired in tcon. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner (cherry picked from commit 41cb881e775ea7eb0c59d9e0cafb6ab5531918d9) --- source3/smbd/smb2_tcon.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c index da06ea9..e3680a0 100644 --- a/source3/smbd/smb2_tcon.c +++ b/source3/smbd/smb2_tcon.c @@ -184,6 +184,7 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, connection_struct *compat_conn = NULL; struct user_struct *compat_vuser = req->session->compat; NTSTATUS status; + bool encryption_desired = req->session->encryption_desired; bool encryption_required = req->session->global->encryption_required; bool guest_session = false; @@ -235,12 +236,13 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, return NT_STATUS_BAD_NETWORK_NAME; } - if ((lp_smb_encrypt(snum) > SMB_SIGNING_OFF) && + if ((lp_smb_encrypt(snum) >= SMB_SIGNING_DESIRED) && (conn->smb2.client.capabilities & SMB2_CAP_ENCRYPTION)) { - encryption_required = true; + encryption_desired = true; } if (lp_smb_encrypt(snum) == SMB_SIGNING_REQUIRED) { + encryption_desired = true; encryption_required = true; } @@ -269,6 +271,7 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, return status; } + tcon->encryption_desired = encryption_desired; tcon->global->encryption_required = encryption_required; compat_conn = make_connection_smb2(req, @@ -339,7 +342,7 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req, *out_share_flags |= SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM; } - if (encryption_required) { + if (encryption_desired) { *out_share_flags |= SMB2_SHAREFLAG_ENCRYPT_DATA; } -- 2.4.3 From eda3d35a535322a84a6aadc0e242d6880f9d8a7f Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 1 Jul 2015 17:41:38 +0200 Subject: [PATCH 7/9] smbd:smb2: use encryption_desired in send_break BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner (cherry picked from commit 14357700fd69291995ce6adebb13e7340a63c209) --- source3/smbd/smb2_server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index ebfe1d6..e723f6d 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -2780,8 +2780,8 @@ static NTSTATUS smbd_smb2_send_break(struct smbXsrv_connection *xconn, if (session != NULL) { session_wire_id = session->global->session_wire_id; - do_encryption = session->global->encryption_required; - if (tcon->global->encryption_required) { + do_encryption = session->encryption_desired; + if (tcon->encryption_desired) { do_encryption = true; } } -- 2.4.3 From e9e6b3466a6ffe1fabf21ac8e68f4a4629fb8f4e Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 30 Jun 2015 17:46:36 +0200 Subject: [PATCH 8/9] docs:smb.conf: explain effect of new setting 'desired' of smb encrypt Thereby clarify some details. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner (cherry picked from commit 365d9d8bdfe9759ef9662d0080cf9c9a0767dbf2) --- docs-xml/smbdotconf/security/smbencrypt.xml | 66 ++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/docs-xml/smbdotconf/security/smbencrypt.xml b/docs-xml/smbdotconf/security/smbencrypt.xml index 14b32c2..284fe9e 100644 --- a/docs-xml/smbdotconf/security/smbencrypt.xml +++ b/docs-xml/smbdotconf/security/smbencrypt.xml @@ -31,11 +31,15 @@ This parameter can be set globally and on a per-share bases. Possible values are - off or disabled, - auto or enabled, and - mandatory or required. + off (or disabled), + enabled (or auto, or + if_required), + desired, + and + required + (or mandatory). A special value is default which is - the implicit default setting. + the implicit default setting of enabled. @@ -104,7 +108,7 @@ The capability to perform SMB encryption can be - negotiated during prorocol negotiation. + negotiated during protocol negotiation. @@ -146,8 +150,9 @@ - Leaving it as default or explicitly setting - default globally will enable + Leaving it as default, explicitly setting + default, or setting it to + enabled globally will enable negotiation of encryption but will not turn on data encryption globally or per share. @@ -155,16 +160,20 @@ - Setting it to enabled globally will - enable negotiation and turn on data encryption globally. + Setting it to desired globally + will enable negotiation and will turn on data encryption + on sessions and share connections for those clients + that support it. Setting it to required globally - will enable negotiation and enforce data encryption - globally. + will enable negotiation and turn on data encryption + on sessions and share connections. Clients that do + not support encryption will be denied access to the + server. @@ -177,9 +186,10 @@ - Setting it to enabled on a share - will turn on data encryption for this share if - negotiation has been enabled globally. + Setting it to desired on a share + will turn on data encryption for this share for clients + that support encryption if negotiation has been + enabled globally. @@ -187,16 +197,34 @@ Setting it to required on a share will enforce data encryption for this share if - negotiation has been enabled globally. Note that this - allows enforcing to be controlled in Samba more - fine-grainedly than in Windows. This is a small - deviation from the MS-SMB2 protocol document. + negotiation has been enabled globally. I.e. clients that + do not support encryption will be denied access to the + share. + + + Note that this allows per-share enforcing to be + controlled in Samba differently from Windows: + In Windows, RejectUnencryptedAccess + is a global setting, and if it is set, all shares with + data encryption turned on + are automatically enforcing encryption. In order to + achieve the same effect in Samba, one + has to globally set smb encrypt to + enabled, and then set all shares + that should be encrypted to + required. + Additionally, it is possible in Samba to have some + shares with encryption required + and some other shares with encryption only + desired, which is not possible in + Windows. - Setting it to off for a share has + Setting it to off or + enabled for a share has no effect. -- 2.4.3 From 06e0bc4273d7740c6e1f7e56a1f3626b9dbca22b Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 7 Jul 2015 17:15:00 +0200 Subject: [PATCH 9/9] smbd:trans2: treat new SMB_SIGNING_DESIRED in case BUG: https://bugzilla.samba.org/show_bug.cgi?id=11372 Signed-off-by: Michael Adam Reviewed-by: Guenther Deschner (cherry picked from commit 76f8d0fbada15c9466f66a2d9961bebd1425d141) --- source3/smbd/trans2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 40983cc..a937023 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -3608,6 +3608,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned case SMB_SIGNING_OFF: encrypt_caps = 0; break; + case SMB_SIGNING_DESIRED: case SMB_SIGNING_IF_REQUIRED: case SMB_SIGNING_DEFAULT: encrypt_caps = CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP; -- 2.4.3